Commit a14d74c8 authored by Mike Hibler's avatar Mike Hibler

Make secure diskload path handle multiple images.

Make sure "tmcd imagekey" returns info for all images.
Make Linux rc.frisbee handle it.

Also: change to elabinelab setup to not load secure image info
into the elabinelab DB (i.e., so we don't propogate the secret keys).
parent df41b309
......@@ -856,9 +856,12 @@ sub DumpDBGoo()
#
# Initial images; note that these images are not going to exist inside!
# Note that we exclude any encrypted images because we cannot expose
# the encryption keys that they would need to decode the images!
#
DBQueryWarn("select * from images ".
"where pid='$pid' or (pid='$TBOPSPID' and global=1) ".
"where (pid='$pid' or (pid='$TBOPSPID' and global=1)) ".
" and decryption_key is null ".
"into outfile '$statedir/images'")
or die("*** $0:\n".
" Could not dump table images\n");
......
......@@ -79,7 +79,7 @@ tweakmbr()
echo "WARNING: custom MBR on $disk, not changed"
return 0
fi
;;
;;
esac
if [ "$cur_mbr_ver" = $new_mbr_ver ]; then
......@@ -285,6 +285,28 @@ handle_loadinfo()
local PREPARE=`get_value "$LOADINFO" PREPARE`
local PTYPE=''
#
# XXX check for secure diskloading info.
# XXX only return info for a single image right now
#
if [ -r /tmp/secureloadinfo.out ]; then
local SINFO=`grep $IMAGEID /tmp/secureloadinfo.out`
local UUID=`get_value "$SINFO" UUID`
if [ -n "$UUID" ]; then
FRISBEE_OPTS="$FRISBEE_OPTS -u $UUID"
fi
local SIGKEY=`get_value "$SINFO" SIGKEY`
if [ -n "$SIGKEY" ]; then
echo "$SIGKEY" | tr ',' '\n' > /tmp/sig.key
FRISBEE_OPTS="$FRISBEE_OPTS -c /tmp/sig.key"
fi
local ENCKEY=`get_value "$SINFO" ENCKEY`
if [ -n "$ENCKEY" ]; then
echo "$ENCKEY" > /tmp/enc.key
FRISBEE_OPTS="$FRISBEE_OPTS -e /tmp/enc.key"
fi
fi
if [ -z "$ADDRESS" ]; then
if [ -z "$IMAGEID" ]; then
echo "Unable to get imageid or address for loading image"
......@@ -350,6 +372,11 @@ handle_loadinfo()
exit 1
fi
# remove keyfiles
if [ -r /tmp/secureloadinfo.out ]; then
rm -f /tmp/enc.key /tmp/sig.key
fi
# we resize the 4th partition after writing the image
# if we used a full disk image. Otherwise, the resize
# happens before the image write in case we need the
......@@ -482,7 +509,7 @@ while read line; do
exit 1
fi
done < /tmp/loadinfo.out
rm -f /tmp/loadinfo.out
rm -f /tmp/loadinfo.out /tmp/secureloadinfo.out
#
# If requested to reboot, do so.
......
......@@ -5514,7 +5514,8 @@ COMMAND_PROTOTYPE(doimagekey)
int nrows;
unsigned long *nlen;
/* No arguments - we don't allow the client to ask for a specific image
/*
* No arguments - we don't allow the client to ask for a specific image
* key, just the one for the image they are supposed to be loading
* according to the database
*/
......@@ -5523,17 +5524,16 @@ COMMAND_PROTOTYPE(doimagekey)
* Make sure that this node is in the right state - hardcoding it is
* probably not a good idea, but the right way to get it isn't clear
*/
res = mydb_query("select op_mode, eventstate from nodes where "
"node_id='%s'",2,reqp->nodeid);
res = mydb_query("select op_mode,eventstate from nodes where "
"node_id='%s'", 2, reqp->nodeid);
if (!res) {
error("IMAGEKEY: %s: DB Error getting event state\n",
reqp->nodeid);
reqp->nodeid);
return 1;
}
if ((nrows = (int)mysql_num_rows(res)) != 1) {
error("IMAGEKEY: %s: DB Error getting event state\n",
reqp->nodeid);
reqp->nodeid);
mysql_free_result(res);
return 1;
}
......@@ -5542,15 +5542,15 @@ COMMAND_PROTOTYPE(doimagekey)
nlen = mysql_fetch_lengths(res);
if (!nlen) {
error("IMAGEKEY: %s: DB Error getting event state\n",
reqp->nodeid);
reqp->nodeid);
mysql_free_result(res);
return 1;
}
if (strncmp(row[0],SECURELOAD_OPMODE,nlen[0]) ||
strncmp(row[1],SECURELOAD_STATE,nlen[1])) {
if (strncmp(row[0],SECURELOAD_OPMODE, nlen[0]) ||
strncmp(row[1],SECURELOAD_STATE, nlen[1])) {
error("IMAGEKEY: %s: Node is in the wrong state\n",
reqp->nodeid);
reqp->nodeid);
mysql_free_result(res);
return 1;
}
......@@ -5559,47 +5559,88 @@ COMMAND_PROTOTYPE(doimagekey)
/*
* Grab and return the key itself
*/
res = mydb_query("select i.auth_uuid,i.auth_key,i.decryption_key "
res = mydb_query("select i.auth_uuid,i.auth_key,i.decryption_key,"
" i.imagename,p.pid,g.gid "
"from current_reloads as r "
"left join images as i on i.imageid=r.image_id "
"left join projects as p on i.pid_idx=p.pid_idx "
"left join groups as g on i.gid_idx=g.gid_idx "
"where node_id='%s' order by r.idx",
3, reqp->nodeid);
6, reqp->nodeid);
if (!res) {
error("IMAGEKEY: %s: DB Error getting key\n", reqp->nodeid);
return 1;
}
if ((nrows = (int)mysql_num_rows(res)) == 0) {
info("IMAGEKEY: %s: No current reload for this node\n",
reqp->nodeid);
reqp->nodeid);
mysql_free_result(res);
return 0;
}
/*
* Note: if there is more than one reload, we are only grabbing the
* 'most recent' due to the 'order by' clause.
* Prior to version 33 there was no extended image info send along
* in loadinfo and thus no way to match an image with the
* corresponding secure load info. Hence we allow only a single
* image in this case and return it in the old format of one field
* per line.
*/
row = mysql_fetch_row(res);
nlen = mysql_fetch_lengths(res);
if (!row || !nlen) {
error("IMAGEKEY: %s: no auth/encryption key information\n",
reqp->nodeid);
mysql_free_result(res);
return 1;
if (vers < 33) {
if (nrows > 1) {
info("IMAGEKEY: %s: client cannot handle multiple images\n",
reqp->nodeid);
mysql_free_result(res);
return 0;
}
row = mysql_fetch_row(res);
if (row[0])
bufp += OUTPUT(bufp, bufe - bufp,
"UUID=%s\n", row[0]);
if (row[1])
bufp += OUTPUT(bufp, bufe - bufp,
"SIGKEY=%s\n", row[1]);
if (row[2])
bufp += OUTPUT(bufp, bufe - bufp,
"ENCKEY=%s\n", row[2]);
nrows = 0;
}
/*
* Put out the authentication UUID and signing key.
* XXX these don't need to be protected as the encryption key,
* they could be sent back via "loadinfo".
* Note: if there is more than one reload, we are only grabbing the
* 'most recent' due to the 'order by' clause.
*/
if (row[0])
bufp += OUTPUT(bufp, bufe - bufp, "UUID=%s\n", row[0]);
if (row[1])
bufp += OUTPUT(bufp, bufe - bufp, "SIGKEY=%s\n", row[1]);
if (row[2])
bufp += OUTPUT(bufp, bufe - bufp, "ENCKEY=%s\n", row[2]);
while (nrows) {
row = mysql_fetch_row(res);
nlen = mysql_fetch_lengths(res);
if (!row || !nlen) {
error("IMAGEKEY: %s: no auth/encryption key info\n",
reqp->nodeid);
mysql_free_result(res);
return 1;
}
if (!row[3] || !row[3][0] || !row[4] || !row[4][0] ||
!row[5] || !row[5][0]) {
error("IMAGEKEY: %s: missing or incomplete imageinfo\n",
reqp->nodeid);
mysql_free_result(res);
return 1;
}
bufp += OUTPUT(bufp, bufe - bufp,
"IMAGEID=%s,%s,%s", row[4], row[5], row[3]);
if (row[0])
bufp += OUTPUT(bufp, bufe - bufp,
" UUID=%s", row[0]);
if (row[1])
bufp += OUTPUT(bufp, bufe - bufp,
" SIGKEY=%s", row[1]);
if (row[2])
bufp += OUTPUT(bufp, bufe - bufp,
" ENCKEY=%s", row[2]);
bufp += OUTPUT(bufp, bufe - bufp, "\n");
nrows--;
}
client_writeback(sock, buf, strlen(buf), tcp);
mysql_free_result(res);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment