Skip to content
Snippets Groups Projects
Commit 83b3d5d3 authored by Leigh B. Stoller's avatar Leigh B. Stoller
Browse files

Checkpoint widearea changes; add privkey support. Right now we

take the key and verify it, but do not require that it be sent.
We can make it required later.
parent 66aa173f
No related branches found
No related tags found
No related merge requests found
......@@ -4,9 +4,10 @@
* All rights reserved.
*/
#define TBSERVER_PORT 7777
#define TBSERVER_PORT2 14443
#define MYBUFSIZE 2048
#define TBSERVER_PORT 7777
#define TBSERVER_PORT2 14443
#define MYBUFSIZE 2048
#define BOSSNODE_FILENAME "bossnode"
/*
* As the tmcd changes, incompatable changes with older version of
......
......@@ -28,18 +28,22 @@
#include "config.h"
#endif
#ifndef STANDALONE
#undef BOSSNODE
#endif
#ifdef BOSSNODE
#define DEFAULT_BOSSNODE BOSSNODE
#else
#define DEFAULT_BOSSNODE NULL
#endif
#ifndef BOSSNODEFILE
#define BOSSNODEFILE "/usr/local/etc/testbed/bossnode"
#undef BOSSNODE
#ifndef KEYFILE
#define KEYFILE "/etc/emulab.pkey"
#endif
/*
* We search a couple of dirs for the bossnode file.
*/
static char *bossnodedirs[] = {
"/etc/testbed",
"/etc/rc.d/testbed",
"/usr/local/etc/testbed",
"/usr/local/etc/emulab",
0
};
/*
* Need to try several ports cause of firewalling.
*/
......@@ -61,6 +65,7 @@ char *usagestr =
" -p portnum Specify a port number to connect to\n"
" -v versnum Specify a version number for tmcd\n"
" -n vnodeid Specify the vnodeid\n"
" -k keyfile Specify the private keyfile\n"
" -u Use UDP instead of TCP\n"
" -t timeout Timeout waiting for the controller.\n"
"\n";
......@@ -81,10 +86,13 @@ main(int argc, char **argv)
struct hostent *he;
struct in_addr serverip;
char buf[MYBUFSIZE], *bp, *response = "";
char *bossnode = DEFAULT_BOSSNODE;
char *bossnode = NULL;
int version = CURRENT_VERSION;
char *vnodeid = NULL;
char *keyfile = NULL;
char *privkey = NULL;
int waitfor = 0;
FILE *fp;
#ifdef UDP
int useudp = 0;
#endif
......@@ -101,6 +109,9 @@ main(int argc, char **argv)
case 'n':
vnodeid = optarg;
break;
case 'k':
keyfile = optarg;
break;
case 'v':
version = atoi(optarg);
break;
......@@ -126,20 +137,30 @@ main(int argc, char **argv)
* How do we find our bossnode?
*
* 1. Command line.
* 2. Compiled in.
* 3. /usr/local/etc/bossnode
* 4. nameserver goo below.
* 2. From a file in the list above.
* 3. nameserver goo below.
*/
if (!bossnode) {
FILE *fp;
if ((fp = fopen(BOSSNODEFILE, "r")) != NULL) {
if (fgets(buf, sizeof(buf), fp)) {
if ((bp = strchr(buf, '\n')))
*bp = (char) NULL;
bossnode = strdup(buf);
/*
* Search for the file.
*/
char **cp = bossnodedirs;
while (*cp) {
sprintf(buf, "%s/%s", *cp, BOSSNODE_FILENAME);
if (access(buf, R_OK) == 0)
break;
cp++;
}
if (*cp) {
if ((fp = fopen(buf, "r")) != NULL) {
if (fgets(buf, sizeof(buf), fp)) {
if ((bp = strchr(buf, '\n')))
*bp = (char) NULL;
bossnode = strdup(buf);
}
fclose(fp);
}
fclose(fp);
}
}
if (!bossnode)
......@@ -152,6 +173,28 @@ main(int argc, char **argv)
exit(1);
}
/*
* Grab the key. Its not an error if we do not find it.
*/
if (keyfile) {
/* Well, if one was specifed it has to exist. */
if (access(keyfile, R_OK) < 0) {
perror("keyfile");
exit(1);
}
}
else
keyfile = KEYFILE;
if ((fp = fopen(keyfile, "r")) != NULL) {
if (fgets(buf, sizeof(buf), fp)) {
if ((bp = strchr(buf, '\n')))
*bp = (char) NULL;
privkey = strdup(buf);
}
fclose(fp);
}
if (waitfor) {
alarm(waitfor);
}
......@@ -226,6 +269,11 @@ main(int argc, char **argv)
sprintf(&buf[strlen(buf)], "VNODEID=%s ", vnodeid);
}
/* Tack on privkey */
if (privkey) {
sprintf(&buf[strlen(buf)], "PRIVKEY=%s ", privkey);
}
/*
* Since we've gone through a getopt() pass, argv[0] is now the
* first argument
......
......@@ -66,6 +66,7 @@ static int iptonodeid(struct in_addr, char *,char *,char *,char *,int *);
static int nodeidtonickname(char *nodeid, char *nickname);
static int nodeidtocontrolnet(char *nodeid, int *net);
static int checkdbredirect(char *nodeid);
static int checkprivkey(struct in_addr, char *);
static void tcpserver(int sock);
static void udpserver(int sock);
static int handle_request(int, struct sockaddr_in *, char *, int);
......@@ -262,6 +263,9 @@ main(int argc, char **argv)
fgets(fshostid, HOSTID_SIZE, fp);
if (rindex(fshostid, '\n')) {
*rindex(fshostid, '\n') = 0;
if (debug) {
info("fshostid: %s\n", fshostid);
}
}
else {
error("fshostid from %s may be corrupt: %s",
......@@ -489,11 +493,12 @@ static int
handle_request(int sock, struct sockaddr_in *client, char *rdata, int istcp)
{
struct sockaddr_in redirect_client;
int redirect = 0, isvnode = 0;
int redirect = 0, isvnode = 0, havekey = 0;
char buf[BUFSIZ], *bp, *cp;
char nodeid[TBDB_FLEN_NODEID];
char vnodeid[TBDB_FLEN_NODEID];
char class[TBDB_FLEN_NODECLASS];
char privkey[TBDB_FLEN_PRIVKEY];
char type[TBDB_FLEN_NODETYPE];
int i, islocal, err = 0;
int version = DEFAULT_VERSION;
......@@ -503,6 +508,20 @@ handle_request(int sock, struct sockaddr_in *client, char *rdata, int istcp)
*/
bp = rdata;
while ((bp = strsep(&rdata, " ")) != NULL) {
/*
* Look for PRIVKEY.
*/
if (sscanf(bp, "PRIVKEY=%64s", buf)) {
havekey = 1;
strncpy(privkey, buf, sizeof(privkey));
if (debug) {
info("PRIVKEY %s\n", buf);
}
continue;
}
/*
* Look for VERSION.
*/
......@@ -651,6 +670,26 @@ handle_request(int sock, struct sockaddr_in *client, char *rdata, int istcp)
goto skipit;
}
/*
* Do private key check. widearea nodes must report a private key
* It comes over ssl of course. At present we skip this check for
* ron nodes.
*/
if (!islocal) {
if (!havekey) {
error("%s: No privkey sent!\n", nodeid);
/*
* Skip. Okay, the problem is that the nodes out
* there are not reporting the key!
goto skipit;
*/
}
else if (checkprivkey(client->sin_addr, privkey)) {
error("%s: privkey mismatch: %s!\n", nodeid, privkey);
goto skipit;
}
}
/*
* Figure out what command was given.
*/
......@@ -2297,9 +2336,10 @@ COMMAND_PROTOTYPE(dosfshostid)
signal(SIGALRM, dosfshostiddead);
alarm(1);
unlink(dspath);
if (symlink(sfspath, dspath) < 0)
if (unlink(dspath) < 0 ||
symlink(sfspath, dspath) < 0) {
sfshostiddeadfl = 1;
}
}
alarm(0);
if (sfshostiddeadfl) {
......@@ -3217,6 +3257,37 @@ checkdbredirect(char *nodeid)
return 0;
}
/*
* Check private key.
*/
static int
checkprivkey(struct in_addr ipaddr, char *privkey)
{
MYSQL_RES *res;
MYSQL_ROW row;
res = mydb_query("select privkey from widearea_privkeys "
"where IP='%s'",
1, inet_ntoa(ipaddr));
if (!res) {
error("checkprivkey: %s: DB Error getting privkey!\n",
inet_ntoa(ipaddr));
return 1;
}
if (! (int)mysql_num_rows(res)) {
mysql_free_result(res);
return 1;
}
row = mysql_fetch_row(res);
mysql_free_result(res);
if (! row[0] || !row[0][0])
return 1;
return strcmp(privkey, row[0]);
}
#ifdef EVENTSYS
/*
* Connect to the event system. It's not an error to call this function if
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment