Commit d7ffcbca authored by Jonathon Duerig's avatar Jonathon Duerig

Merge branch 'master' of git-public.flux.utah.edu:/flux/git/emulab-devel

parents e55f33a2 35ed496a
......@@ -94,12 +94,15 @@ use vars qw(@ISA @EXPORT);
TBDB_NODESTATE_PXEFAILED TBDB_NODESTATE_PXELIMBO
TBDB_NODESTATE_PXEBOOTING TBDB_NODESTATE_ALWAYSUP
TBDB_NODESTATE_MFSSETUP TBDB_NODESTATE_TBFAILED
TBDB_NODESTATE_POWEROFF
TBDB_NODESTATE_POWEROFF TBDB_NODESTATE_SECVIOLATION
TBDB_NODESTATE_TPMSIGNOFF
TBDB_NODEOPMODE_NORMAL TBDB_NODEOPMODE_DELAYING
TBDB_NODEOPMODE_UNKNOWNOS TBDB_NODEOPMODE_RELOADING
TBDB_NODEOPMODE_NORMALv1 TBDB_NODEOPMODE_MINIMAL TBDB_NODEOPMODE_PCVM
TBDB_NODEOPMODE_RELOAD TBDB_NODEOPMODE_RELOADMOTE TBDB_NODEOPMODE_RELOADPCVM
TBDB_NODEOPMODE_RELOAD TBDB_NODEOPMODE_RELOADMOTE
TBDB_NODEOPMODE_RELOADPCVM
TBDB_NODEOPMODE_SECUREBOOT TBDB_NODEOPMODE_SECURELOAD
TBDB_NODEOPMODE_DELAY
TBDB_NODEOPMODE_BOOTWHAT
TBDB_NODEOPMODE_ANY
......@@ -399,6 +402,9 @@ sub TBDB_NODESTATE_PXEWAKEUP() { "PXEWAKEUP"; }
sub TBDB_NODESTATE_PXEFAILED() { "PXEFAILED"; }
sub TBDB_NODESTATE_PXEBOOTING() { "PXEBOOTING"; }
sub TBDB_NODESTATE_POWEROFF() { "POWEROFF"; }
sub TBDB_NODESTATE_TPMSIGNOFF() { "TPMSIGNOFF"; }
sub TBDB_NODESTATE_SECVIOLATION(){ "SECVIOLATION"; }
sub TBDB_NODESTATE_MFSBOOTING() { "MFSBOOTING"; }
sub TBDB_NODEOPMODE_ANY { "*"; } # A wildcard opmode
sub TBDB_NODEOPMODE_NORMAL { "NORMAL"; }
......@@ -410,6 +416,8 @@ sub TBDB_NODEOPMODE_MINIMAL { "MINIMAL"; }
sub TBDB_NODEOPMODE_PCVM { "PCVM"; }
sub TBDB_NODEOPMODE_RELOAD { "RELOAD"; }
sub TBDB_NODEOPMODE_RELOADMOTE { "RELOAD-MOTE"; }
sub TBDB_NODEOPMODE_SECUREBOOT { "SECUREBOOT"; }
sub TBDB_NODEOPMODE_SECURELOAD { "SECURELOAD"; }
sub TBDB_NODEOPMODE_RELOADPCVM { "RELOAD-PCVM"; }
sub TBDB_NODEOPMODE_DELAY { "DELAY"; }
sub TBDB_NODEOPMODE_BOOTWHAT { "_BOOTWHAT_"; } # A redirection opmode
......
Some notes about the TPM-enforced boot path (SECURELOAD state machine).
The current implementation requires that we boot from a flash device
BEFORE we network boot (see the paper for details). Unfortunately,
there is a lot of magic associated with the PXEBOOTING state, which is
assumed to always be the first state we will see when a node boots.
However, in the secure boot path the first thing we see is a secure
transition to the GPXEBOOTING state, so magic had to be added for that!
In particular:
* When stated gets a transition to GPXEBOOTING, it forces the node into
the SECURELOAD op_mode. This is a new trigger called SECURELOAD and
a new trigger table entry:
insert into state_triggers values \
('*','*','GPXEBOOTING','SECURELOAD');
* Later, when we do get a PXEBOOTING state, we DON'T push the machine
into the PXEBOOT op_mode. We do this with an override trigger:
insert into state_triggers values \
('*','SECURELOAD','PXEBOOTING','SECURELOAD');
This is supposed to override the more general any ('*') op_mode trigger
for the PXEBOOTING state and will just make sure we state in SECURELOAD.
Updates on 9/7/10:
We need two secure state machines, one for loading and one for booting.
The latter will be used for all boots on machines which have gPXE dongles,
regardless of what they are booting. So we need to amend the above to
account for:
* some nodes will always see GPXEBOOTING first
* nodes which have just undergone the secure load will then reboot into
the secure boot path
* if a node was in the SECURELOAD op_mode but didn't finish, it cannot
be allowed to SECUREBOOT (which shouldn't happen, it should wind up in
SECVIOLATION).
I think what we needs is a SECUREBOOT op_mode which is entered whenever
a node transitions to GPXEBOOTING. This is allowed from any op_mode/state
except from */SECVIOLATION.
SECURELOAD consists of:
!SECVIOLATION -- "quote ok" --> GPXEBOOTING
GPXEBOOTING -- "DHCP" --> PXEBOOTING
PXEBOOTING -- "bootinfo" --> BOOTING
BOOTING -- "quote ok" --> RELOADSETUP
RELOADSETUP -- "reload ready" --> RELOADING
RELOADING -- "image ok" --> RELOADDONE
RELOADDONE -- "quote ok" --> TPMSIGNOFF
SECUREBOOT consists of:
!SECVIOLATION -- "quote ok" --> GPXEBOOTING
GPXEBOOTING -- "DHCP" --> PXEBOOTING
PXEBOOTING -- "bootinfo" --> BOOTING
BOOTING -- "quote ok" --> TPMSIGNOFF
How do we differentiate the two op_modes when they arrive at GPXEBOOTING?
Well, os_load should have set the next_op_mode to SECURELOAD (assuming the
MFS is listed with that as its op_mode), so we check that in the SECUREBOOT
trigger used by a transition to GPXEBOOTING.
For a regular "untrusted" node boot through gPXE, we will arrive at
GPXEBOOTING from some arbitrary state, get forced into SECUREBOOT and
go through the steps. We neuter the actions that PXEBOOTING and BOOTING
normally take. As part of the TPMSIGNOFF, we perform those actions,
which include putting the node into PXEKERNEL op_mode (PXEBOOT action) and
then setting the nodes.op_mode as appropriate for the next boot (BOOTING
action).
For a secure load, we again arrive at GPXEBOOTING from any state, get
forced into SECURELOAD, and work through the state machine. Again we
perform none of the normal triggers along the way: PXEBOOTING, BOOTING,
RELOADDONE. SIGNOFF, does the RELOADDONE triggers (RESET, RELOADDONEV2)
which leave the node in SECURELOAD/TPMSIGNOFF. Now we have a problem
because next_op_mode is still set to SECURELOAD which will tell the
SECUREBOOT trigger to keep us in the SECURELOAD op_mode. Hmm...I think
next_op_mode will get set by the os_select in RESET.
How do we do this? If we associate the SECUREBOOT trigger with
SECURELOAD/TPMSIGNOFF, then as soon as we get the TPMSIGNOFF event
(from the MFS?) it will get to step #5 below where it will trigger
RESET (clear the one-time boot info), RELOADDONEV2 (send apod), and
then SECUREBOOT. The last should:
* set DB next_op_mode to SECUREBOOT?
* directly change op_mode?
to get the opmode from SECURELOAD/TPMSIGNOFF to SECUREBOOT/SHUTDOWN.
What happens if a node in a secure reload reboots in the middle?
stated will see a transition from SECURELOAD/!TPMSIGNOFF -> GPXEBOOTING
which is okay; since the op_mode is still SECURELOAD we will just restart.
For nodes that have a gPXE dongle, should we allow them to boot via the
"standard" boot path or require that they always boot via the dongle?
If the latter, we would have to be a bit more rigerous about making sure
they boot through GPXEBOOTING.
Notes on state transitions:
If a node state transition is reported, stated:
1. Check for invalid state transitions, reporting them if so
NEW: if mode==SECURELOAD, set state to SECVIOLATION
2. Update nodes.eventstate in DB
3. Check to see if there is a TBCOMMAND "timeout" for this node.
If so and command is REBOOT, see if we have rebooted and report if so.
NOTE: this step appears to just report and not ever do anything else.
4. Queue any per-node timeout associated with the current mode and new state
(from state_timeouts). This removes old timeouts for the node queued by
the previous state.
5. Check for per-node triggers associated with the current mode and new state
(from state_triggers) and execute them. Several of these triggers can
force op_mode transitions: PXEBOOT (to PXEBOOT), SECURELOAD (to
SECURELOAD), BOOTING (to DB bootopmode if in PXEKERNEL op_mode, to DB
nodes.next_op_mode if curstate==ISUP).
6. Check if current mode and new state should trigger an op_mode transition
(allowed transitions from mode_transitions). The actual next op_mode
comes from nodes.next_op_mode which is cleared afterward.
Notes on triggers:
"PXEBOOT":
* Transitions node into PXEKERNEL op_mode
"BOOTING":
Queries DB to find what opmode/osid to boot next, order is: next, temp, def.
Updates DB nodes table with osid. Update op_mode of node:
* if current mode is PXEKERNEL, transition into new mode
* else if came from ISUP state, transition into mode nodes.next_op_mode (?)
* else if next mode is RELOAD, update DB and stated state to make current
mode be RELOAD (does not do an opModeTransition like the others)
"RESET":
Marks end of successful boot. Resets internal stated flags, calls osselect
to clear DB one-time (next) boot info.
"RELOADDONE","RELOADDONEV2":
Marks end of reload and reboots machine (V2 only). Clears DB reload state
and sends an apod (V2 only).
"CHECKGENISUP":
Sends ISUP if node cannot.
* if nodes.osfeatures includes "isup", do nothing
* else if includes "ping", fire off "eventping" to send ISUP when node pings
* else generate an ISUP event for the node
"ISUP":
Always generates an ISUP event, regardless of osfeatures
(used by the ALWAYSUP op_mode).
"CHECKPORTREG":
Ensures that certain DB port_registration entries exist (backward compat
for older images). Right now: if emulab_syncd port is not registered,
insert an entry with the default port.
"POWERCYCLE","POWEROFF":
Invokes the "power" command to perform the appropriate action.
"EMAILNOTIFY":
Send an email notification to testbed-ops informing them that the node
has entered a particular op_mode/state.
"SCRIPT:<path>":
Invokes the given script in the background, not waiting for the result.
If <path> is not absolute, use /usr/testbed/sbin/<path>.
"RELOADOLDMFS":
Special hack to detect old diskload MFSes that cannot load multiple images,
and sends email to testbed-ops.
Notes on timeouts.
Timeouts define the length of time a node should stay in a particular
op_mode/state combo. If the node is in that state longer, the associated
action is triggered.
Actions are:
"REBOOT":
Reboot the node. This doesn't really do anything right now, it just sends
email to testbed-ops that a reboot was requested. According to the comment,
os_load and os_setup are still doing the actual reboots.
"NOTIFY":
Send email that node has timed out in a particular state, to testbed-ops.
"STATE:<state>":
Transition node into a particular state. Does not change the op_mode.
Timeouts can also be associated with commands that stated is performing,
indicated by the op_mode being "TBCOMMAND" and state being a command,
instead of a real op_mode/state. The only recognized action is CMDRETRY
to retry the command. This is only used for rebooting and power "events",
so that those actions can be retried if necessary.
......@@ -140,6 +140,9 @@ my $TB_OSID_MBKERNEL = TB_OSID_MBKERNEL;
# Special PXEBOOT state machine that all local nodes use.
my $PXEKERNEL = "PXEKERNEL";
# Even special-er SECUREBOOT state machine that local nodes may use.
my $SECUREBOOT = "SECUREBOOT";
# Protos.
sub debug(@);
sub fatal($);
......@@ -625,6 +628,23 @@ sub stateTransition($$) {
!$valid{$mode}{$oldstate}{$newstate}) {
notify("Invalid transition for node $node from $mode/$oldstate " .
"to $newstate\n");
#
# Machines in the secure boot path are not allowed to jump
# willy-nilly into unknown states.
#
if ($mode eq TBDB_NODEOPMODE_SECUREBOOT ||
$mode eq TBDB_NODEOPMODE_SECURELOAD) {
$newstate = TBDB_NODESTATE_SECVIOLATION;
notify("Moving $node to $newstate because it's in $mode\n");
}
}
#
# Nodes that are in the SECVIOLATION state are not allowed to leave!
#
if ($oldstate eq TBDB_NODESTATE_SECVIOLATION &&
$newstate ne TBDB_NODESTATE_SECVIOLATION) {
notify("$node tried to leave SECVIOLATION (to $newstate)\n");
$newstate = TBDB_NODESTATE_SECVIOLATION;
}
my $now = time();
......@@ -718,6 +738,32 @@ sub stateTransition($$) {
}
next;
};
/^$SECUREBOOT$/ && do {
#
# Force machine into the SECUREBOOT/LOAD op_mode.
# Currently triggered by receipt of GPXEBOOTING state.
# This could come from any state as it just indicates that
# a machine with a gPXE dongle has rebooted.
#
# To differentiate BOOT from LOAD we check next_op_mode.
# It will be set to SECURELOAD when we need to go there,
# otherwise we force it to SECUREBOOT.
#
debug("Running $SECUREBOOT trigger\n");
my $query_result =
DBQueryWarn("select next_op_mode from nodes ".
"where node_id='$node'");
my ($nextmode) = $query_result->fetchrow();
if (!$nextmode || $nextmode ne TBDB_NODEOPMODE_SECURELOAD) {
$nextmode = TBDB_NODEOPMODE_SECUREBOOT;
}
if ($mode ne $nextmode) {
info("$node: Forcing mode transition to $nextmode!\n");
opModeTransition($node, $nextmode, 1);
$mode=$nextmode;
}
next;
};
/^$BOOTING$/ && do {
#
# See if we are in the right mode/osid.
......@@ -819,10 +865,24 @@ sub stateTransition($$) {
objname => $node);
next;
};
(/^$TBREBOOT$/ || /^$TBPOWERCYCLE$/) && do {
(/^$TBREBOOT$/ || /^$TBPOWERCYCLE$/ || /^$TBPOWEROFF$/) && do {
handleCommand($node,$trig);
next;
};
(/^EMAILNOTIFY$/) && do {
my $msg = "$node entered state $mode/$newstate from " .
"$mode/$oldstate";
if ($newstate eq TBDB_NODESTATE_SECVIOLATION) {
$msg .= "\n\nNode $node has been powered off.\n" .
"You must address the cause of the violation ".
"and reset the eventstate before powering on.";
}
SENDMAIL($REALTBOPS,
"STATED: $node entered state $newstate",
$msg,
"Stated Daemon <".$TBOPS.">");
next;
};
/^RELOADOLDMFS$/ && do {
my $frisbee_osid = TBNodeDiskloadOSID($node);
my $frisbee_name = DBQuerySingleFatal("select osname from os_info where osid=$frisbee_osid");
......@@ -1040,6 +1100,11 @@ sub handleCtrlEvent($$) {
/^$TBTIMEOUTNOTIFY/ && do {
notify("Node $node has timed out in state $mode/$state\n");
last; };
/^STATE:([-\w\/]+)$/ && do {
my $newstate = $1;
# Force the node into a new state
stateTransition($node,$newstate);
last; };
notify("$node: Unknown Timeout Action: $action\n");
}
next;
......@@ -1128,10 +1193,13 @@ sub handleCommand($$;$$) {
$TBPOWEROFF => "off");
my $func = $funcmap{$command};
info("Sending power $func for nodes: $nodelist\n");
#
# Permissions were checked in order to send the message,
# so we don't need to do any fancy stuff here.
my $cmd = "$power $func $nodelist &";
# We do invoke with -e to prevent power from sending a
# further SHUTDOWN event.
#
my $cmd = "$power -e $func $nodelist &";
debug("$cmd\n");
system($cmd) and
notify("$params/$command: ".
......@@ -1634,4 +1702,3 @@ END {
# Restore $? in case one of the things I called changed it
$? = $stat;
}
......@@ -1574,6 +1574,9 @@ CREATE TABLE `images` (
`mbr_version` varchar(50) NOT NULL default '1',
`updated` datetime default NULL,
`access_key` varchar(64) default NULL,
`auth_uuid` varchar(64) default NULL,
`auth_key` varchar(512) default NULL,
`decryption_key` varchar(256) default NULL,
PRIMARY KEY (`imageid`),
UNIQUE KEY `pid` (`pid`,`imagename`),
KEY `gid` (`gid`),
......@@ -2178,6 +2181,7 @@ CREATE TABLE `node_hostkeys` (
`sshdsa_v2` mediumtext,
`tpmblob` mediumtext,
`tpmx509` mediumtext,
`tpmidentity` mediumtext,
`sfshostid` varchar(128) default NULL,
PRIMARY KEY (`node_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
......@@ -2445,6 +2449,19 @@ CREATE TABLE `nologins` (
PRIMARY KEY (`nologins`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `nonces`
--
DROP TABLE IF EXISTS `nonces`;
CREATE TABLE `nonces` (
`node_id` varchar(32) NOT NULL,
`purpose` varchar(64) NOT NULL,
`nonce` mediumtext,
`expires` int(10) NOT NULL,
PRIMARY KEY (`node_id`,`purpose`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `nonlocal_user_pubkeys`
--
......@@ -3469,6 +3486,20 @@ CREATE TABLE `tmcd_redirect` (
PRIMARY KEY (`node_id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `tpm_quote_values`
--
DROP TABLE IF EXISTS `tpm_quote_values`;
CREATE TABLE `tpm_quote_values` (
`node_id` varchar(32) NOT NULL default '',
`op_mode` varchar(20) NOT NULL,
`state` varchar(20) NOT NULL,
`pcr` int(11) NOT NULL,
`value` mediumtext,
PRIMARY KEY (`node_id`,`op_mode`,`state`,`pcr`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `traces`
--
......@@ -3520,7 +3551,7 @@ CREATE TABLE `unixgroup_membership` (
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
--
-- Table structure for table `user_policies`
-- Table structure for table `user_features`
--
DROP TABLE IF EXISTS `user_features`;
......
......@@ -279,6 +279,10 @@ REPLACE INTO mode_transitions VALUES ('ALWAYSUP','ISUP','RELOAD-MOTE','ISUP','Re
REPLACE INTO mode_transitions VALUES ('RELOAD-MOTE','SHUTDOWN','ALWAYSUP','ISUP','ReloadDone');
REPLACE INTO mode_transitions VALUES ('PCVM','SHUTDOWN','RELOAD-PCVM','SHUTDOWN','ReloadSetup');
REPLACE INTO mode_transitions VALUES ('RELOAD-PCVM','SHUTDOWN','PCVM','SHUTDOWN','ReloadDone');
REPLACE INTO mode_transitions VALUES ('SECUREBOOT','TPMSIGNOFF','MINIMAL','SHUTDOWN','');
REPLACE INTO mode_transitions VALUES ('SECUREBOOT','TPMSIGNOFF','NORMAL','SHUTDOWN','');
REPLACE INTO mode_transitions VALUES ('SECUREBOOT','TPMSIGNOFF','NORMALv2','SHUTDOWN','');
REPLACE INTO mode_transitions VALUES ('SECUREBOOT','TPMSIGNOFF','PXEFBSD','SHUTDOWN','');
--
-- Dumping data for table `priorities`
......@@ -344,6 +348,19 @@ REPLACE INTO state_timeouts VALUES ('NORMALv2','TBSETUP',600,'NOTIFY');
REPLACE INTO state_timeouts VALUES ('NORMALv2','BOOTING',180,'REBOOT');
REPLACE INTO state_timeouts VALUES ('GARCIA-STARGATEv1','TBSETUP',600,'NOTIFY');
REPLACE INTO state_timeouts VALUES ('PXEKERNEL','PXEWAKEUP',20,'REBOOT');
REPLACE INTO state_timeouts VALUES ('SECUREBOOT','BOOTING',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECUREBOOT','GPXEBOOTING',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECUREBOOT','PXEBOOTING',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECUREBOOT','SHUTDOWN',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECUREBOOT','TPMSIGNOFF',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECURELOAD','BOOTING',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECURELOAD','GPXEBOOTING',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECURELOAD','PXEBOOTING',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECURELOAD','RELOADDONE',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECURELOAD','RELOADING',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECURELOAD','RELOADSETUP',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECURELOAD','SHUTDOWN',3600,'STATE:SECVIOLATION');
REPLACE INTO state_timeouts VALUES ('SECURELOAD','TPMSIGNOFF',3600,'STATE:SECVIOLATION');
--
-- Dumping data for table `state_transitions`
......@@ -539,6 +556,22 @@ REPLACE INTO state_transitions VALUES ('RELOAD','TBSETUP','ISUP','FailedBoot');
REPLACE INTO state_transitions VALUES ('RELOAD','TBSETUP','TBFAILED','FailedBoot');
REPLACE INTO state_transitions VALUES ('RELOAD','ISUP','SHUTDOWN','RebootAfterFail');
REPLACE INTO state_transitions VALUES ('RELOAD','TBFAILED','SHUTDOWN','RebootAfterFail');
REPLACE INTO state_transitions VALUES ('SECUREBOOT','BOOTING','SECVIOLATION','QuoteFailed');
REPLACE INTO state_transitions VALUES ('SECUREBOOT','BOOTING','TPMSIGNOFF','QuoteOK');
REPLACE INTO state_transitions VALUES ('SECUREBOOT','GPXEBOOTING','PXEBOOTING','DHCP');
REPLACE INTO state_transitions VALUES ('SECUREBOOT','PXEBOOTING','BOOTING','BootInfo');
REPLACE INTO state_transitions VALUES ('SECURELOAD','BOOTING','PXEBOOTING','re-BootInfo');
REPLACE INTO state_transitions VALUES ('SECURELOAD','BOOTING','RELOADSETUP','QuoteOK');
REPLACE INTO state_transitions VALUES ('SECURELOAD','BOOTING','SECVIOLATION','QuoteFailed');
REPLACE INTO state_transitions VALUES ('SECURELOAD','GPXEBOOTING','PXEBOOTING','DHCP');
REPLACE INTO state_transitions VALUES ('SECURELOAD','PXEBOOTING','BOOTING','BootInfo');
REPLACE INTO state_transitions VALUES ('SECURELOAD','RELOADDONE','SECVIOLATION','QuoteFailed');
REPLACE INTO state_transitions VALUES ('SECURELOAD','RELOADDONE','TPMSIGNOFF','QuoteOK');
REPLACE INTO state_transitions VALUES ('SECURELOAD','RELOADING','RELOADDONE','ImageOK');
REPLACE INTO state_transitions VALUES ('SECURELOAD','RELOADING','SECVIOLATION','ImageBad');
REPLACE INTO state_transitions VALUES ('SECURELOAD','RELOADSETUP','RELOADING','ReloadReady');
REPLACE INTO state_transitions VALUES ('SECURELOAD','SHUTDOWN','GPXEBOOTING','QuoteOK');
REPLACE INTO state_transitions VALUES ('SECURELOAD','SHUTDOWN','SECVIOLATION','QuoteFailed');
--
-- Dumping data for table `state_triggers`
......@@ -559,6 +592,14 @@ REPLACE INTO state_triggers VALUES ('*','RELOAD','RELOADOLDMFS','RELOADOLDMFS');
REPLACE INTO state_triggers VALUES ('*','RELOAD-PCVM','RELOADDONE','RESET, RELOADDONE');
REPLACE INTO state_triggers VALUES ('*','RELOAD','ISUP','REBOOT');
REPLACE INTO state_triggers VALUES ('*','RELOAD','TBFAILED','REBOOT');
REPLACE INTO state_triggers VALUES ('*','*','GPXEBOOTING','SECUREBOOT');
REPLACE INTO state_triggers VALUES ('*','*','SECVIOLATION','POWEROFF, EMAILNOTIFY');
REPLACE INTO state_triggers VALUES ('*','SECUREBOOT','BOOTING','');
REPLACE INTO state_triggers VALUES ('*','SECUREBOOT','PXEBOOTING','');
REPLACE INTO state_triggers VALUES ('*','SECUREBOOT','TPMSIGNOFF','PXEBOOT, BOOTING, CHECKGENISUP');
REPLACE INTO state_triggers VALUES ('*','SECURELOAD','BOOTING','');
REPLACE INTO state_triggers VALUES ('*','SECURELOAD','PXEBOOTING','');
REPLACE INTO state_triggers VALUES ('*','SECURELOAD','RELOADDONE','RESET, RELOADDONE');
--
-- Dumping data for table `table_regex`
......@@ -994,6 +1035,10 @@ REPLACE INTO table_regex VALUES ('elabinelab_attributes','attrkey','text','regex
REPLACE INTO table_regex VALUES ('elabinelab_attributes','attrvalue','text','regex','^[-\\w\\.\\+,\\s\\/]+$',0,255,NULL);
REPLACE INTO table_regex VALUES ('elabinelab_attributes','ordering','int','redirect','default:tinyint',0,0,NULL);
REPLACE INTO table_regex VALUES ('images','auth_key','text','regex','^[0-9a-fA-F,]+$',0,0,NULL);
REPLACE INTO table_regex VALUES ('images','auth_uuid','text','regex','^[0-9a-fA-F]+$',0,0,NULL);
REPLACE INTO table_regex VALUES ('images','decryption_key','text','regex','^[0-9a-fA-F]+$',0,0,NULL);
REPLACE INTO table_regex VALUES ('default','tinytext_utf8','text','regex','^(?:[\\x20-\\x7E]|[\\xC2-\\xDF][\\x80-\\xBF]|\\xE0[\\xA0-\\xBF][\\x80-\\xBF]|[\\xE1-\\xEC\\xEE\\xEF][\\x80-\\xBF]{2}|\\xED[\\x80-\\x9F][\\x80-\\xBF])*$',0,256,'adopted from http://www.w3.org/International/questions/qa-forms-utf-8.en.php');
REPLACE INTO table_regex VALUES ('default','text_utf8','text','regex','^(?:[\\x20-\\x7E]|[\\xC2-\\xDF][\\x80-\\xBF]|\\xE0[\\xA0-\\xBF][\\x80-\\xBF]|[\\xE1-\\xEC\\xEE\\xEF][\\x80-\\xBF]{2}|\\xED[\\x80-\\x9F][\\x80-\\xBF])*$',0,65535,'adopted from http://www.w3.org/International/questions/qa-forms-utf-8.en.php');
REPLACE INTO table_regex VALUES ('default','fulltext_utf8','text','regex','^(?:[\\x09\\x0A\\x0D\\x20-\\x7E]|[\\xC2-\\xDF][\\x80-\\xBF]|\\xE0[\\xA0-\\xBF][\\x80-\\xBF]|[\\xE1-\\xEC\\xEE\\xEF][\\x80-\\xBF]{2}|\\xED[\\x80-\\x9F][\\x80-\\xBF])*$',0,65535,'adopted from http://www.w3.org/International/questions/qa-forms-utf-8.en.php');
......
#
# DB state for secure boot and loading.
#
use strict;
use libdb;
sub DoUpdate($$$)
{
my ($dbhandle, $dbname, $version) = @_;
my @mode_transitions = (
["SECUREBOOT","TPMSIGNOFF","MINIMAL","SHUTDOWN",""],
["SECUREBOOT","TPMSIGNOFF","NORMAL","SHUTDOWN",""],
["SECUREBOOT","TPMSIGNOFF","NORMALv2","SHUTDOWN",""],
["SECUREBOOT","TPMSIGNOFF","PXEFBSD","SHUTDOWN",""]
);
my @timeouts = (
["SECUREBOOT","BOOTING",3600,"STATE:SECVIOLATION"],
["SECUREBOOT","GPXEBOOTING",3600,"STATE:SECVIOLATION"],
["SECUREBOOT","PXEBOOTING",3600,"STATE:SECVIOLATION"],
["SECUREBOOT","SHUTDOWN",3600,"STATE:SECVIOLATION"],
["SECUREBOOT","TPMSIGNOFF",3600,"STATE:SECVIOLATION"],
["SECURELOAD","BOOTING",3600,"STATE:SECVIOLATION"],
["SECURELOAD","GPXEBOOTING",3600,"STATE:SECVIOLATION"],
["SECURELOAD","PXEBOOTING",3600,"STATE:SECVIOLATION"],
["SECURELOAD","RELOADDONE",3600,"STATE:SECVIOLATION"],
["SECURELOAD","RELOADING",3600,"STATE:SECVIOLATION"],
["SECURELOAD","RELOADSETUP",3600,"STATE:SECVIOLATION"],
["SECURELOAD","SHUTDOWN",3600,"STATE:SECVIOLATION"],
["SECURELOAD","TPMSIGNOFF",3600,"STATE:SECVIOLATION"]
);
my @transitions = (
["SECUREBOOT","BOOTING","SECVIOLATION","QuoteFailed"],
["SECUREBOOT","BOOTING","TPMSIGNOFF","QuoteOK"],
["SECUREBOOT","GPXEBOOTING","PXEBOOTING","DHCP"],
["SECUREBOOT","PXEBOOTING","BOOTING","BootInfo"],
["SECURELOAD","BOOTING","PXEBOOTING","re-BootInfo"],
["SECURELOAD","BOOTING","RELOADSETUP","QuoteOK"],
["SECURELOAD","BOOTING","SECVIOLATION","QuoteFailed"],
["SECURELOAD","GPXEBOOTING","PXEBOOTING","DHCP"],
["SECURELOAD","PXEBOOTING","BOOTING","BootInfo"],
["SECURELOAD","RELOADDONE","SECVIOLATION","QuoteFailed"],
["SECURELOAD","RELOADDONE","TPMSIGNOFF","QuoteOK"],
["SECURELOAD","RELOADING","RELOADDONE","ImageOK"],
["SECURELOAD","RELOADING","SECVIOLATION","ImageBad"],
["SECURELOAD","RELOADSETUP","RELOADING","ReloadReady"],
["SECURELOAD","SHUTDOWN","GPXEBOOTING","QuoteOK"],
["SECURELOAD","SHUTDOWN","SECVIOLATION","QuoteFailed"]
);
my @triggers = (
["*","*","GPXEBOOTING","SECUREBOOT"],
["*","*","SECVIOLATION","POWEROFF, EMAILNOTIFY"],
["*","SECUREBOOT","BOOTING",""],
["*","SECUREBOOT","PXEBOOTING",""],
["*","SECUREBOOT","TPMSIGNOFF","PXEBOOT, BOOTING, CHECKGENISUP"],
["*","SECURELOAD","BOOTING",""],
["*","SECURELOAD","PXEBOOTING",""],
["*","SECURELOAD","RELOADDONE","RESET, RELOADDONE"]
);
foreach my $row (@mode_transitions) {
my ($opm1,$s1,$opm2,$s2,$lab) = @$row;
my $query_result =
DBQueryFatal("SELECT op_mode1 FROM mode_transitions WHERE ".
"op_mode1='$opm1' AND state1='$s1' AND ".
"op_mode2='$opm2' AND state2='$s2'");
if ($query_result->numrows == 0) {
DBQueryFatal("INSERT INTO mode_transitions VALUES ".
"('$opm1','$s1','$opm2', '$s2','$lab')");
}
}
foreach my $row (@timeouts) {
my ($opm,$s,$to,$act) = @$row;
my $query_result =
DBQueryFatal("SELECT op_mode FROM state_timeouts WHERE ".
"op_mode='$opm' AND state='$s'");
if ($query_result->numrows == 0) {
DBQueryFatal("INSERT INTO state_timeouts VALUES ".
"('$opm','$s','$to', '$act')");
}
}
foreach my $row (@transitions) {
my ($opm,$s1,$s2,$lab) = @$row;
my $query_result =
DBQueryFatal("SELECT op_mode FROM state_transitions WHERE ".
"op_mode='$opm' AND state1='$s1' AND state2='$s2'");
if ($query_result->numrows == 0) {
DBQueryFatal("INSERT INTO state_transitions VALUES ".
"('$opm','$s1','$s2','$lab')");
}
}
foreach my $row (@triggers) {
my ($node,$opm,$s,$trig) = @$row;
my $query_result =
DBQueryFatal("SELECT node_id FROM state_triggers WHERE ".
"node_id='$node' AND op_mode='$opm' AND state='$s'");
if ($query_result->numrows == 0) {
DBQueryFatal("INSERT INTO state_triggers VALUES ".
"('$node','$opm','$s','$trig')");
}
}
#
# Add fields to images table for authentication/decryption keys
#
if (!DBSlotExists("images", "auth_uuid")) {
DBQueryFatal("ALTER TABLE images ADD `auth_uuid`".
" varchar(64) DEFAULT NULL AFTER access_key");
}
DBQueryFatal("REPLACE INTO table_regex VALUES ".
"('images','auth_uuid','text','regex', ".
" '^[0-9a-fA-F]+\$',0,0,NULL)");
if (!DBSlotExists("images", "auth_key")) {
DBQueryFatal("ALTER TABLE images ADD `auth_key