#define Maxfdata 8192
#define MaxStr 128
-void remoteside(int);
+void remoteside(void);
void fatal(char*, ...);
void lclnoteproc(int);
void rmtnoteproc(void);
int readstr(int, char*, int);
char *rexcall(int*, char*, char*);
int setamalg(char*);
-char *keyspec = "";
+char *keyspec = "";
int notechan;
int exportpid;
/* message size for exportfs; may be larger so we can do big graphics in CPU window */
int msgsize = Maxfdata+IOHDRSZ;
+/* encryption mechanisms */
+static int clear(int);
+
+int (*encryption)(int) = clear;
+
/* authentication mechanisms */
static int netkeyauth(int);
static int netkeysrvauth(int, char*);
char *name; /* name of method */
int (*cf)(int); /* client side authentication */
int (*sf)(int, char*); /* server side authentication */
-} authmethod[] =
-{
+} authmethod[] = {
{ "p9", p9auth, srvp9auth,},
{ "netkey", netkeyauth, netkeysrvauth,},
{ "none", noauth, srvnoauth,},
};
AuthMethod *am = authmethod; /* default is p9 */
-char *p9authproto = "p9any";
-
int setam(char*);
char *aan = "/bin/aan";
char *anstring = "tcp!*!0";
char *filterp = nil;
-int filter(int fd, char *host);
+int filter(int fd, char *host);
void
usage(void)
case 'A':
anstring = EARGF(usage());
break;
- case 'O':
- p9authproto = "p9sk2";
- remoteside(1); /* From listen */
- break;
case 'R': /* From listen */
- remoteside(0);
+ remoteside();
break;
case 'h':
system = EARGF(usage());
char *negstr = "negotiating authentication method";
-int
-old9p(int fd)
-{
- int p[2];
-
- if(pipe(p) < 0)
- fatal("pipe: %r");
-
- switch(rfork(RFPROC|RFMEM|RFFDG|RFNAMEG|RFREND)) {
- case -1:
- fatal("rfork srvold9p: %r");
- case 0:
- if(fd != 1){
- dup(fd, 1);
- close(fd);
- }
- if(p[0] != 0){
- dup(p[0], 0);
- close(p[0]);
- }
- close(p[1]);
- if(0){
- fd = open("/sys/log/cpu", OWRITE);
- if(fd != 2){
- dup(fd, 2);
- close(fd);
- }
- execl("/bin/srvold9p", "srvold9p", "-ds", nil);
- } else
- execl("/bin/srvold9p", "srvold9p", "-s", nil);
- fatal("exec srvold9p: %r");
- default:
- close(fd);
- close(p[0]);
- }
- return p[1];
-}
-
/* Invoked with stdin and stdout connected to the network connection */
void
-remoteside(int old)
+remoteside(void)
{
char user[MaxStr], buf[MaxStr], xdir[MaxStr], cmd[MaxStr];
int i, n, fd, badchdir, gotcmd;
if(n < 0)
fatal("authenticating: %r");
filterp = nil;
- if(!old && strcmp(cmd, "aan") == 0){
+ if(strcmp(cmd, "aan") == 0){
filterp = aan;
writestr(fd, "", nil, 1);
n = readstr(fd, cmd, sizeof(cmd));
} else
writestr(fd, "", "", 1);
- fd = (*am->sf)(fd, user);
- if(fd < 0)
+ if((fd = (*am->sf)(fd, user)) < 0)
fatal("srvauth: %r");
+ if((fd = filter(fd, nil)) < 0)
+ fatal("filter: %r");
+ if((fd = encryption(fd)) < 0)
+ fatal("encrypt: %r");
/* Now collect invoking cpu's current directory or possibly a command */
gotcmd = 0;
if(n != 2 || buf[0] != 'O' || buf[1] != 'K')
exits("remote tree");
- if(old)
- fd = old9p(fd);
-
/* make sure buffers are big by doing fversion explicitly; pick a huge number; other side will trim */
strcpy(buf, VERSION9P);
if(fversion(fd, 64*1024, buf, sizeof buf) < 0)
/* authenticate */
procsetname("%s: auth via %s", origargs, am->name);
- *fd = (*am->cf)(*fd);
- if(*fd < 0)
+ if((*fd = (*am->cf)(*fd)) < 0)
return "can't authenticate";
- return 0;
+ if((*fd = filter(*fd, system)) < 0)
+ return "can't filter";
+ if((*fd = encryption(*fd)) < 0)
+ return "can't encrypt";
+ return nil;
}
void
if(readstr(fd, chall, sizeof chall) < 0)
break;
if(*chall == 0)
- return filter(fd, system);
+ return fd;
print("challenge: %s\nresponse: ", chall);
if(readln(resp, sizeof(resp)) < 0)
break;
if(auth_chuid(ai, 0) < 0)
fatal("newns: %r");
auth_freeAI(ai);
- return filter(fd, nil);
+ return fd;
+}
+
+static int
+clear(int fd)
+{
+ return fd;
+}
+
+static char sslsecret[2][21];
+
+static int
+sslencrypt(int fd)
+{
+ return pushssl(fd, ealgs, sslsecret[0], sslsecret[1], nil);
}
static void
f[0], f[1], f[2], f[3], f[4], f[5], f[6], f[7], f[8], f[9]);
}
-/*
- * plan9 authentication followed by rc4 encryption
- */
static int
-p9auth(int fd)
+sslsetup(int fd, uchar *secret, int nsecret, int isclient)
{
uchar key[16], digest[SHA1dlen];
- char fromclientsecret[21];
- char fromserversecret[21];
- AuthInfo *ai;
int i;
- procsetname("%s: auth_proxy proto=%q role=client %s",
- origargs, p9authproto, keyspec);
- ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s", p9authproto, keyspec);
- if(ai == nil)
- return -1;
- if(ealgs == nil){
- auth_freeAI(ai);
+ if(ealgs == nil)
return fd;
+
+ if(nsecret < 8){
+ werrstr("secret too small to ssl");
+ return -1;
}
- assert(ai->nsecret <= sizeof(key)-4);
- memmove(key+4, ai->secret, ai->nsecret);
- auth_freeAI(ai);
+ memmove(key+4, secret, 8);
/* exchange random numbers */
srand(truerand());
- for(i = 0; i < 4; i++)
- key[i] = rand();
- procsetname("writing p9 key");
- if(write(fd, key, 4) != 4)
- return -1;
- procsetname("reading p9 key");
- if(readn(fd, key+12, 4) != 4)
- return -1;
+
+ if(isclient){
+ for(i = 0; i < 4; i++)
+ key[i] = rand();
+ if(write(fd, key, 4) != 4)
+ return -1;
+ if(readn(fd, key+12, 4) != 4)
+ return -1;
+ } else {
+ for(i = 0; i < 4; i++)
+ key[i+12] = rand();
+ if(readn(fd, key, 4) != 4)
+ return -1;
+ if(write(fd, key+12, 4) != 4)
+ return -1;
+ }
/* scramble into two secrets */
sha1(key, sizeof(key), digest, nil);
- mksecret(fromclientsecret, digest);
- mksecret(fromserversecret, digest+10);
+ mksecret(sslsecret[isclient == 0], digest);
+ mksecret(sslsecret[isclient != 0], digest+10);
- if((fd = filter(fd, system)) < 0)
- return -1;
+ encryption = sslencrypt;
+
+ return fd;
+}
+
+/*
+ * plan9 authentication followed by rc4 encryption
+ */
+static int
+p9auth(int fd)
+{
+ AuthInfo *ai;
- /* set up encryption */
- procsetname("pushssl");
- fd = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
- if(fd < 0)
- werrstr("can't establish ssl connection: %r");
+ ai = auth_proxy(fd, auth_getkey, "proto=p9any role=client %s", keyspec);
+ if(ai == nil)
+ return -1;
+ fd = sslsetup(fd, ai->secret, ai->nsecret, 1);
+ auth_freeAI(ai);
return fd;
}
return fd;
}
-void
-loghex(uchar *p, int n)
-{
- char buf[100];
- int i;
-
- for(i = 0; i < n; i++)
- sprint(buf+2*i, "%2.2ux", p[i]);
- syslog(0, "cpu", "%s", buf);
-}
-
static int
srvp9auth(int fd, char *user)
{
- uchar key[16], digest[SHA1dlen];
- char fromclientsecret[21];
- char fromserversecret[21];
AuthInfo *ai;
- int i;
- ai = auth_proxy(fd, nil, "proto=%q role=server %s", p9authproto, keyspec);
+ ai = auth_proxy(fd, nil, "proto=p9any role=server %s", keyspec);
if(ai == nil)
return -1;
if(auth_chuid(ai, nil) < 0)
fatal("newns: %r");
snprint(user, MaxStr, "%s", ai->cuid);
- if(ealgs == nil){
- auth_freeAI(ai);
- return fd;
- }
- assert(ai->nsecret <= sizeof(key)-4);
- memmove(key+4, ai->secret, ai->nsecret);
+ fd = sslsetup(fd, ai->secret, ai->nsecret, 0);
auth_freeAI(ai);
-
- /* exchange random numbers */
- srand(truerand());
- for(i = 0; i < 4; i++)
- key[i+12] = rand();
- if(readn(fd, key, 4) != 4)
- return -1;
- if(write(fd, key+12, 4) != 4)
- return -1;
-
- /* scramble into two secrets */
- sha1(key, sizeof(key), digest, nil);
- mksecret(fromclientsecret, digest);
- mksecret(fromserversecret, digest+10);
-
- if((fd = filter(fd, nil)) < 0)
- return -1;
-
- /* set up encryption */
- fd = pushssl(fd, ealgs, fromserversecret, fromclientsecret, nil);
- if(fd < 0)
- werrstr("can't establish ssl connection: %r");
return fd;
}