X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2Fcmd%2Fcpu.c;h=1994aaf282be381d4ff6823d1fcad69fa986d976;hb=c4fdc6bfdb2211e13643d5fba75edf437c122eef;hp=f6b70bf13e283736aeee61860b7316e382c1aead;hpb=0b003bb7c701037ddc69e4bb145d04dbb99b58e2;p=plan9front.git diff --git a/sys/src/cmd/cpu.c b/sys/src/cmd/cpu.c index f6b70bf13..1994aaf28 100644 --- a/sys/src/cmd/cpu.c +++ b/sys/src/cmd/cpu.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -15,7 +14,7 @@ #define Maxfdata 8192 #define MaxStr 128 -void remoteside(int); +void remoteside(void); void fatal(char*, ...); void lclnoteproc(int); void rmtnoteproc(void); @@ -25,12 +24,13 @@ void writestr(int, char*, char*, int); int readstr(int, char*, int); char *rexcall(int*, char*, char*); int setamalg(char*); -char *keyspec = ""; +char *keyspec = ""; int notechan; int exportpid; char *system; int cflag; +int nflag; int dbg; char *user; char *patternfile; @@ -43,6 +43,11 @@ char *ealgs = "rc4_256 sha1"; /* 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,24 +61,21 @@ struct AuthMethod { 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,}, + { "none", noauth, srvnoauth,}, { nil, nil} }; 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) @@ -177,15 +179,15 @@ main(int argc, char **argv) case 'f': /* ignored but accepted for compatibility */ break; + case 'n': + /* must be specified before -R/-O */ + nflag++; + break; 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()); @@ -289,49 +291,11 @@ fatal(char *fmt, ...) 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)) { - 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, stdout and stderr connected to the network connection */ +/* Invoked with stdin and stdout connected to the network connection */ void -remoteside(int old) +remoteside(void) { - char user[MaxStr], home[MaxStr], buf[MaxStr], xdir[MaxStr], cmd[MaxStr]; + char user[MaxStr], buf[MaxStr], xdir[MaxStr], cmd[MaxStr]; int i, n, fd, badchdir, gotcmd; rfork(RFENVG); @@ -343,27 +307,25 @@ remoteside(int old) 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)); if(n < 0) fatal("authenticating: %r"); } - if(setamalg(cmd) < 0){ + if(setamalg(cmd) < 0 || (nflag == 0 && am->sf == srvnoauth)) { writestr(fd, "unsupported auth method", nil, 0); - fatal("bad auth method %s: %r", cmd); + fatal("bad auth method %s", cmd); } else writestr(fd, "", "", 1); - fd = (*am->sf)(fd, user); - if(fd < 0) + if((fd = (*am->sf)(fd, user)) < 0) fatal("srvauth: %r"); - - /* Set environment values for the user */ - putenv("user", user); - snprint(home, sizeof(home), "/usr/%s", user); - putenv("home", home); + 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; @@ -376,15 +338,11 @@ remoteside(int old) fatal("dir: %r"); } - /* Establish the new process at the current working directory of the - * gnot */ + /* Establish the new process at the current working directory of the gnot */ badchdir = 0; - if(strcmp(xdir, "NO") == 0) - chdir(home); - else if(chdir(xdir) < 0) { - badchdir = 1; - chdir(home); - } + if(strcmp(xdir, "NO") != 0) + if(chdir(xdir) < 0) + badchdir = 1; /* Start the gnot serving its namespace */ writestr(fd, "FS", "FS", 0); @@ -394,9 +352,6 @@ remoteside(int old) 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) @@ -432,14 +387,13 @@ char* rexcall(int *fd, char *host, char *service) { char *na; - char dir[MaxStr]; char err[ERRMAX]; char msg[MaxStr]; int n; na = netmkaddr(host, 0, service); procsetname("dialing %s", na); - if((*fd = dial(na, 0, dir, 0)) < 0) + if((*fd = dial(na, 0, 0, 0)) < 0) return "can't dial"; /* negotiate aan filter extension */ @@ -449,7 +403,7 @@ rexcall(int *fd, char *host, char *service) if(n < 0) return "negotiating aan"; if(*err){ - werrstr(err); + errstr(err, sizeof err); return negstr; } } @@ -466,16 +420,19 @@ rexcall(int *fd, char *host, char *service) if(n < 0) return negstr; if(*err){ - werrstr(err); + errstr(err, sizeof err); return negstr; } /* 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 @@ -546,7 +503,7 @@ netkeyauth(int fd) 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; @@ -586,7 +543,21 @@ netkeysrvauth(int fd, char *user) 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 @@ -596,55 +567,63 @@ mksecret(char *t, uchar *f) 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=p9any role=client %s", keyspec); + if(ai == nil) + return -1; + fd = sslsetup(fd, ai->secret, ai->nsecret, 1); + auth_freeAI(ai); return fd; } @@ -664,61 +643,19 @@ srvnoauth(int fd, char *user) 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; } @@ -756,7 +693,7 @@ filter(int fd, char *host) if(filterp == nil) return fd; procsetname("filter %s", filterp); - flags = RFNOWAIT|RFPROC|RFMEM|RFFDG; + flags = RFNOWAIT|RFPROC|RFMEM|RFFDG|RFREND; if(host == nil){ /* remote side */ if(announce(anstring, addr) < 0) @@ -780,7 +717,8 @@ filter(int fd, char *host) buf[len] = '\0'; if((s = strrchr(buf, '!')) == nil) fatal("filter: malformed remote port: %s", buf); - snprint(addr, sizeof(addr), "%s", netmkaddr(host, "tcp", s+1)); + strecpy(addr, addr+sizeof(addr), netmkaddr(host, "tcp", s+1)); + strecpy(strrchr(addr, '!'), addr+sizeof(addr), s); } snprint(buf, sizeof(buf), "%s", filterp); @@ -1090,11 +1028,13 @@ notefs(int fd) ncpunote = 0; for(;;){ n = read9pmsg(fd, buf, sizeof(buf)); - if(n <= 0){ + if(n < 0){ if(dbg) fprint(2, "read9pmsg(%d) returns %d: %r\n", fd, n); break; } + if(n == 0) + continue; if(convM2S(buf, n, &f) <= BIT16SZ) break; if(dbg)