ref: 5e07e5840aced5826880a31ceac23f2d0c5046f9
parent: e9e53fe7b6a29e52e73f59d5b6080561b925a3be
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sat Aug 15 21:47:10 EDT 2015
cpu: cleanup ssl code, make sure -p works for any auth method
--- a/sys/src/cmd/cpu.c
+++ b/sys/src/cmd/cpu.c
@@ -24,7 +24,7 @@
int readstr(int, char*, int);
char *rexcall(int*, char*, char*);
int setamalg(char*);
-char *keyspec = "";
+char *keyspec = "";
int notechan;
int exportpid;
@@ -43,6 +43,11 @@
/* 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*);
@@ -56,8 +61,7 @@
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,},
@@ -73,7 +77,7 @@
char *anstring = "tcp!*!0";
char *filterp = nil;
-int filter(int fd, char *host);
+int filter(int fd, char *host);
void
usage(void)
@@ -360,9 +364,12 @@
} 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;
@@ -466,10 +473,13 @@
/* 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
@@ -540,7 +550,7 @@
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;
@@ -580,9 +590,23 @@
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
mksecret(char *t, uchar *f)
{
@@ -590,59 +614,67 @@
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;
- /* set up encryption */
- procsetname("pushssl");
- fd = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
- if(fd < 0)
- werrstr("can't establish ssl connection: %r");
return fd;
}
+/*
+ * plan9 authentication followed by rc4 encryption
+ */
static int
+p9auth(int fd)
+{
+ AuthInfo *ai;
+
+ ai = auth_proxy(fd, auth_getkey, "proto=%q role=client %s", p9authproto, keyspec);
+ if(ai == nil)
+ return -1;
+ fd = sslsetup(fd, ai->secret, ai->nsecret, 1);
+ auth_freeAI(ai);
+ return fd;
+}
+
+static int
noauth(int fd)
{
ealgs = nil;
@@ -658,25 +690,10 @@
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);
if(ai == nil)
@@ -684,35 +701,8 @@
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;
}