]> git.lizzy.rs Git - plan9front.git/blobdiff - sys/src/cmd/cpu.c
fix fuckup
[plan9front.git] / sys / src / cmd / cpu.c
index f6b70bf13e283736aeee61860b7316e382c1aead..1994aaf282be381d4ff6823d1fcad69fa986d976 100644 (file)
@@ -7,7 +7,6 @@
 
 #include <u.h>
 #include <libc.h>
-#include <bio.h>
 #include <auth.h>
 #include <fcall.h>
 #include <libsec.h>
@@ -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)