Commit 04725ae3 authored by David Johnson's avatar David Johnson

Add support for rmanage to query the database and grab ASF keys itself for

a nodeid.  rmanage is much more convenient to use for debugging than the
ASF libreboot wrapper...
parent 59d17026
......@@ -11,7 +11,7 @@ SUBDIR = tools/rmanage
include $(OBJDIR)/Makeconf
CFLAGS = -Wall
CFLAGS = -Wall -g
LDFLAGS = -lssl
SWIG_INCS = -I/usr/local/lib/perl5/5.8.8/mach/CORE -I$(SRCDIR)
LIB_STUFF = rmcp.so rmcp.pm
......@@ -31,13 +31,23 @@ swig-wrappers: rmcp.h rmcp.i
rmcp_wrap.o: $(SRCDIR)/rmcp_wrap.c
$(CC) -fpic -c $(CFLAGS) $(SWIG_INCS) $(LDFLAGS) $(SRCDIR)/rmcp_wrap.c
rmanage: GNUmakefile rmanage.o rmcp.o
$(CC) $(CFLAGS) $(LDFLAGS) rmanage.o rmcp.o -o rmanage
rmanage: GNUmakefile rmanage.o rmcp.o \
${OBJDIR}/lib/libtb/tbdb.o ${OBJDIR}/lib/libtb/log.o
$(CC) $(CFLAGS) $(LDFLAGS) -L/usr/local/lib/mysql -lmysqlclient \
rmanage.o rmcp.o ${OBJDIR}/lib/libtb/tbdb.o \
${OBJDIR}/lib/libtb/log.o -o rmanage
cp rmanage rmanage.debug
strip rmanage
#
# Here so that we get libtb tbdb stuff.
#
${OBJDIR}/lib/libtb/%:
cd ${OBJDIR}/lib/tbdb && gmake $<
rmanage.o: rmanage.c rmcp.c
$(CC) -c -o rmanage.o $(CFLAGS) $<
$(CC) -c -o rmanage.o $(CFLAGS) \
-I$(TESTBED_SRCDIR)/lib/libtb -I/usr/local/include $<
rmcp.o: rmcp.c rmcp.h
$(CC) -c -o rmcp.o $(CFLAGS) $<
......
......@@ -11,7 +11,8 @@
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <mysql/mysql.h>
#include "tbdb.h"
extern char *optarg;
extern int optopt;
......@@ -47,22 +48,26 @@ void usage(char *prog) {
int i;
fprintf(stderr,
"Usage: %s [-hHds] [-tmrkgu <arg>] -c <clientname> <command>\n"
"Usage: %s [-hHdsE] [-tmrkgu <arg>] <clientname> <command>\n"
"\n"
" -h Print this message\n"
" -d Turn on debugging (more d's mean more debug info)\n"
" -s Use secure RMCP\n"
" -H Interpret keys as hex strings instead of char strings\n"
" -E Resolve client and keys using the Emulab database\n"
" (this option implies -H)\n"
" -c host The hostname of the managed client\n"
" -t timeout Timeout (in seconds) for individual RMCP messages\n"
" (default: %d)\n"
" -m retries Retry N times for unacknowledged RMCP sends\n"
" (default: %d)\n"
" -r role Use this role (either 'operator' or 'administrator')\n"
" (default 'administrator')\n"
" -k key Use this key with the role specified by '-r'\n"
" -g key Use this generation key\n"
" -u uid Send the specified username\n"
"\n"
" clientname IP or hostname (or Emulab node_id if -E specified)\n"
" command This argument performs an operation on the managed\n"
" client. The available commands are:\n",
prog,DEFAULT_TIMEOUT,DEFAULT_RETRIES);
......@@ -88,18 +93,25 @@ int main(int argc,char **argv) {
int secure = 0;
int hex_mode = 0;
char *client = NULL;
u_int8_t *rkey;
u_int8_t *rkey = NULL;
int rkey_len;
u_int8_t *gkey;
u_int8_t *gkey = NULL;
int gkey_len;
int timeout = DEFAULT_TIMEOUT;
int retries = DEFAULT_RETRIES;
char *role = NULL;
char *role = "administrator";
int roleno;
char *uid = NULL;
char *command = NULL;
int emulab = 0;
char emip[16];
MYSQL_RES *res;
MYSQL_ROW row;
int nrows;
char *src;
int clen;
while ((c = getopt(argc,argv,"c:t:m:r:k:g:u:hdsH")) != -1) {
while ((c = getopt(argc,argv,"t:m:r:k:g:u:hdsHE")) != -1) {
switch (c) {
case 'h':
usage(argv[0]);
......@@ -114,8 +126,10 @@ int main(int argc,char **argv) {
case 'H':
hex_mode = 1;
break;
case 'c':
client = optarg;
case 'E':
emulab = 1;
/* assume keys in the Emulab db are in hex mode... */
hex_mode = 1;
break;
case 't':
timeout = atoi(optarg);
......@@ -158,12 +172,14 @@ int main(int argc,char **argv) {
argc -= optind;
argv += optind;
if (argc != 1) {
fprintf(stderr,"ERROR: required command argument is missing!\n");
if (argc != 2) {
fprintf(stderr,
"ERROR: must supply both clientname and command args!\n");
exit(-1);
}
else {
command = argv[0];
client = argv[0];
command = argv[1];
}
if (!secure && (!strcmp(command,"reset") || !strcmp(command,"cycle")
......@@ -177,6 +193,89 @@ int main(int argc,char **argv) {
ctx = rmcp_ctx_init(timeout,retries);
if (emulab) {
dbinit();
/* Attempt lookup in Emulab db */
if (debug) {
fprintf(stderr,"Resolving %s... ",client);
}
if (!mydb_nodeidtoip(client,emip)) {
fprintf(stderr,"ERROR: could not resolve node_id %s",client);
exit(9);
}
if (debug) {
fprintf(stderr,"%s.\n",emip);
}
/*
* If we're in secure mode, grab keys out of the db too if we
* need them.
*/
if (rkey == NULL) {
res = mydb_query("select mykey from outlets_remoteauth"
" where node_id='%s' and key_role='%s'",
1,client,role);
if (!res) {
fprintf(stderr,
"ERROR: could not find keys for %s in Emulab db!\n",
client);
exit(10);
}
nrows = (int)mysql_num_rows(res);
if (nrows != 1) {
fprintf(stderr,"ERROR: could not find role key for Emulab"
" nodeid %s\n",client);
exit(11);
}
row = mysql_fetch_row(res);
rkey = (char *)malloc(strlen(row[0])+1);
src = row[0];
clen = strlen(row[0]) + 1;
if (!strncmp("0x",row[0],2)) {
src = &row[0][2];
clen -= 2;
}
strncpy(rkey,src,clen);
rkey_len = strlen(rkey);
mysql_free_result(res);
}
if (gkey == NULL) {
res = mydb_query("select mykey from outlets_remoteauth"
" where node_id='%s' and key_role='%s'",
1,client,"generation");
if (!res) {
fprintf(stderr,
"ERROR: could not find gkey for %s in Emulab db!\n",
client);
exit(10);
}
nrows = (int)mysql_num_rows(res);
if (nrows != 1) {
fprintf(stderr,"ERROR: could not find generation key for"
" Emulab nodeid %s\n",client);
exit(11);
}
row = mysql_fetch_row(res);
gkey = (char *)malloc(strlen(row[0])+1);
src = row[0];
clen = strlen(row[0]) + 1;
if (!strncmp("0x",row[0],2)) {
src = &row[0][2];
clen -= 2;
}
strncpy(gkey,src,clen);
gkey_len = strlen(gkey);
mysql_free_result(res);
}
client = emip;
}
if (secure) {
if (strcmp(role,"administrator") == 0) {
roleno = RMCP_ROLE_ADM;
......@@ -185,7 +284,7 @@ int main(int argc,char **argv) {
roleno = RMCP_ROLE_OP;
}
else {
fprintf(stderr,"Unknown role '%s'!\n",role);
fprintf(stderr,"Unknown role '%s'!\n",role);
exit(-4);
}
......
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