X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;ds=sidebyside;f=sys%2Fsrc%2Fcmd%2Fcpu.c;h=a7e10fcbce2aef135fc97e291ede3978930a0e6f;hb=5c000bbe6378de33b55080bcc8be1cfb907c2d22;hp=0d256c4078fd325a7549c59732ab8b35e28633c4;hpb=e5888a1ffdae813d7575f5fb02275c6bb07e5199;p=plan9front.git diff --git a/sys/src/cmd/cpu.c b/sys/src/cmd/cpu.c old mode 100755 new mode 100644 index 0d256c407..a7e10fcbc --- a/sys/src/cmd/cpu.c +++ b/sys/src/cmd/cpu.c @@ -7,7 +7,6 @@ #include #include -#include #include #include #include @@ -16,7 +15,7 @@ #define MaxStr 128 void remoteside(int); -void fatal(int, char*, ...); +void fatal(char*, ...); void lclnoteproc(int); void rmtnoteproc(void); void catcher(void*, char*); @@ -31,6 +30,7 @@ int notechan; int exportpid; char *system; int cflag; +int nflag; int dbg; char *user; char *patternfile; @@ -60,7 +60,7 @@ struct AuthMethod { { { "p9", p9auth, srvp9auth,}, { "netkey", netkeyauth, netkeysrvauth,}, -// { "none", noauth, srvnoauth,}, + { "none", noauth, srvnoauth,}, { nil, nil} }; AuthMethod *am = authmethod; /* default is p9 */ @@ -69,10 +69,16 @@ char *p9authproto = "p9any"; int setam(char*); +char *aan = "/bin/aan"; +char *anstring = "tcp!*!0"; +char *filterp = nil; + +int filter(int fd, char *host); + void usage(void) { - fprint(2, "usage: cpu [-h system] [-u user] [-a authmethod] " + fprint(2, "usage: cpu [-p] [-h system] [-u user] [-a authmethod] " "[-e 'crypt hash'] [-k keypattern] [-P patternfile] " "[-c cmd arg ...]\n"); exits("usage"); @@ -136,7 +142,7 @@ procsetname(char *fmt, ...) void main(int argc, char **argv) { - char dat[MaxStr], buf[MaxStr], cmd[MaxStr], *p, *err; + char dat[MaxStr], buf[MaxStr], cmd[MaxStr], *p, *s, *err; int ac, fd, ms, data; char *av[10]; @@ -153,12 +159,12 @@ main(int argc, char **argv) user = getuser(); if(user == nil) - fatal(1, "can't read user name"); + fatal("can't read user name: %r"); ARGBEGIN{ case 'a': p = EARGF(usage()); if(setam(p) < 0) - fatal(0, "unknown auth method %s", p); + fatal("unknown auth method %s", p); break; case 'e': ealgs = EARGF(usage()); @@ -171,6 +177,13 @@ 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 */ @@ -183,12 +196,11 @@ main(int argc, char **argv) break; case 'c': cflag++; - cmd[0] = '!'; - cmd[1] = '\0'; - while(p = ARGF()) { - strcat(cmd, " "); - strcat(cmd, p); - } + s = cmd; + *s++ = '!'; + *s = 0; + while(p = ARGF()) + s = seprint(s, cmd+sizeof(cmd), " %s", p); break; case 'k': keyspec = smprint("%s %s", keyspec, EARGF(usage())); @@ -200,6 +212,9 @@ main(int argc, char **argv) user = EARGF(usage()); keyspec = smprint("%s user=%s", keyspec, user); break; + case 'p': + filterp = aan; + break; default: usage(); }ARGEND; @@ -211,12 +226,12 @@ main(int argc, char **argv) if(system == nil) { p = getenv("cpu"); if(p == 0) - fatal(0, "set $cpu"); + fatal("set $cpu"); system = p; } if(err = rexcall(&data, system, srvname)) - fatal(1, "%s: %s", err, system); + fatal("%s: %s: %r", err, system); procsetname("%s", origargs); /* Tell the remote side the command to execute and where our working directory is */ @@ -235,7 +250,7 @@ main(int argc, char **argv) * of /mnt/term */ if(readstr(data, buf, sizeof(buf)) < 0) - fatal(1, "waiting for FS: %r"); + fatal("waiting for FS: %r"); if(strncmp("FS", buf, 2) != 0) { print("remote cpu: %s", buf); exits(buf); @@ -259,45 +274,36 @@ main(int argc, char **argv) } av[ac] = nil; exec(exportfs, av); - fatal(1, "starting exportfs"); + fatal("starting exportfs: %r"); } void -fatal(int syserr, char *fmt, ...) +fatal(char *fmt, ...) { - Fmt f; - char *str; + char buf[1024]; va_list arg; - fmtstrinit(&f); - fmtprint(&f, "cpu: "); va_start(arg, fmt); - fmtvprint(&f, fmt, arg); + vsnprint(buf, sizeof(buf), fmt, arg); va_end(arg); - if(syserr) - fmtprint(&f, ": %r"); - str = fmtstrflush(&f); - - fprint(2, "%s\n", str); - syslog(0, "cpu", str); - exits(str); + fprint(2, "cpu: %s\n", buf); + syslog(0, "cpu", "%s", buf); + exits(buf); } char *negstr = "negotiating authentication method"; -char bug[256]; - int old9p(int fd) { int p[2]; if(pipe(p) < 0) - fatal(1, "pipe"); + fatal("pipe: %r"); - switch(rfork(RFPROC|RFFDG|RFNAMEG)) { + switch(rfork(RFPROC|RFMEM|RFFDG|RFNAMEG)) { case -1: - fatal(1, "rfork srvold9p"); + fatal("rfork srvold9p: %r"); case 0: if(fd != 1){ dup(fd, 1); @@ -317,7 +323,7 @@ old9p(int fd) execl("/bin/srvold9p", "srvold9p", "-ds", nil); } else execl("/bin/srvold9p", "srvold9p", "-s", nil); - fatal(1, "exec srvold9p"); + fatal("exec srvold9p: %r"); default: close(fd); close(p[0]); @@ -325,7 +331,7 @@ old9p(int fd) 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) { @@ -339,31 +345,39 @@ remoteside(int old) /* negotiate authentication mechanism */ n = readstr(fd, cmd, sizeof(cmd)); if(n < 0) - fatal(1, "authenticating"); - if(setamalg(cmd) < 0){ + fatal("authenticating: %r"); + filterp = nil; + if(!old && 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 || (nflag == 0 && am->sf == srvnoauth)) { writestr(fd, "unsupported auth method", nil, 0); - fatal(1, "bad auth method %s", cmd); + fatal("bad auth method %s", cmd); } else writestr(fd, "", "", 1); fd = (*am->sf)(fd, user); if(fd < 0) - fatal(1, "srvauth"); + fatal("srvauth: %r"); /* Set environment values for the user */ putenv("user", user); - sprint(home, "/usr/%s", user); + snprint(home, sizeof(home), "/usr/%s", user); putenv("home", home); /* Now collect invoking cpu's current directory or possibly a command */ gotcmd = 0; if(readstr(fd, xdir, sizeof(xdir)) < 0) - fatal(1, "dir/cmd"); + fatal("dir/cmd: %r"); if(xdir[0] == '!') { strcpy(cmd, &xdir[1]); gotcmd = 1; if(readstr(fd, xdir, sizeof(xdir)) < 0) - fatal(1, "dir"); + fatal("dir: %r"); } /* Establish the new process at the current working directory of the @@ -415,7 +429,7 @@ remoteside(int old) execl("/bin/rc", "rc", "-lc", cmd, nil); else execl("/bin/rc", "rc", "-li", nil); - fatal(1, "exec shell"); + fatal("exec shell: %r"); } char* @@ -432,6 +446,18 @@ rexcall(int *fd, char *host, char *service) if((*fd = dial(na, 0, dir, 0)) < 0) return "can't dial"; + /* negotiate aan filter extension */ + if(filterp == aan){ + writestr(*fd, "aan", "negotiating aan", 0); + n = readstr(*fd, err, sizeof err); + if(n < 0) + return "negotiating aan"; + if(*err){ + werrstr(err); + return negstr; + } + } + /* negotiate authentication mechanism */ if(ealgs != nil) snprint(msg, sizeof(msg), "%s %s", am->name, ealgs); @@ -464,7 +490,7 @@ writestr(int fd, char *str, char *thing, int ignore) l = strlen(str); n = write(fd, str, l+1); if(!ignore && n < 0) - fatal(1, "writing network: %s", thing); + fatal("writing network: %s: %r", thing); } int @@ -524,7 +550,7 @@ netkeyauth(int fd) if(readstr(fd, chall, sizeof chall) < 0) break; if(*chall == 0) - return fd; + return filter(fd, system); print("challenge: %s\nresponse: ", chall); if(readln(resp, sizeof(resp)) < 0) break; @@ -541,7 +567,7 @@ netkeysrvauth(int fd, char *user) int tries; AuthInfo *ai; - if(readstr(fd, user, 32) < 0) + if(readstr(fd, user, MaxStr) < 0) return -1; ai = nil; @@ -562,9 +588,9 @@ netkeysrvauth(int fd, char *user) return -1; writestr(fd, "", "challenge", 1); if(auth_chuid(ai, 0) < 0) - fatal(1, "newns"); + fatal("newns: %r"); auth_freeAI(ai); - return fd; + return filter(fd, nil); } static void @@ -580,21 +606,24 @@ mksecret(char *t, uchar *f) static int p9auth(int fd) { - uchar key[16]; - uchar digest[SHA1dlen]; + uchar key[16], digest[SHA1dlen]; char fromclientsecret[21]; char fromserversecret[21]; - int i; 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; - memmove(key+4, ai->secret, ai->nsecret); - if(ealgs == nil) + if(ealgs == nil){ + auth_freeAI(ai); return fd; + } + assert(ai->nsecret <= sizeof(key)-4); + memmove(key+4, ai->secret, ai->nsecret); + auth_freeAI(ai); /* exchange random numbers */ srand(truerand()); @@ -612,12 +641,15 @@ p9auth(int fd) mksecret(fromclientsecret, digest); mksecret(fromserversecret, digest+10); + if((fd = filter(fd, system)) < 0) + return -1; + /* set up encryption */ procsetname("pushssl"); - i = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil); - if(i < 0) + fd = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil); + if(fd < 0) werrstr("can't establish ssl connection: %r"); - return i; + return fd; } static int @@ -644,29 +676,31 @@ loghex(uchar *p, int n) for(i = 0; i < n; i++) sprint(buf+2*i, "%2.2ux", p[i]); - syslog(0, "cpu", buf); + syslog(0, "cpu", "%s", buf); } static int srvp9auth(int fd, char *user) { - uchar key[16]; - uchar digest[SHA1dlen]; + uchar key[16], digest[SHA1dlen]; char fromclientsecret[21]; char fromserversecret[21]; - int i; AuthInfo *ai; + int i; - ai = auth_proxy(0, nil, "proto=%q role=server %s", p9authproto, keyspec); + ai = auth_proxy(fd, nil, "proto=%q role=server %s", p9authproto, keyspec); if(ai == nil) return -1; if(auth_chuid(ai, nil) < 0) - return -1; - strecpy(user, user+MaxStr, ai->cuid); - memmove(key+4, ai->secret, ai->nsecret); - - if(ealgs == nil) + 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); + auth_freeAI(ai); /* exchange random numbers */ srand(truerand()); @@ -682,11 +716,14 @@ srvp9auth(int fd, char *user) mksecret(fromclientsecret, digest); mksecret(fromserversecret, digest+10); + if((fd = filter(fd, nil)) < 0) + return -1; + /* set up encryption */ - i = pushssl(fd, ealgs, fromserversecret, fromclientsecret, nil); - if(i < 0) + fd = pushssl(fd, ealgs, fromserversecret, fromclientsecret, nil); + if(fd < 0) werrstr("can't establish ssl connection: %r"); - return i; + return fd; } /* @@ -714,6 +751,75 @@ setamalg(char *s) return setam(s); } +int +filter(int fd, char *host) +{ + char addr[128], buf[256], *s, *file, *argv[16]; + int p[2], lfd, flags, len, argc; + + if(filterp == nil) + return fd; + procsetname("filter %s", filterp); + flags = RFNOWAIT|RFPROC|RFMEM|RFFDG; + if(host == nil){ + /* remote side */ + if(announce(anstring, addr) < 0) + fatal("filter: Cannot announce %s: %r", anstring); + snprint(buf, sizeof(buf), "%s/local", addr); + if((lfd = open(buf, OREAD)) < 0) + fatal("filter: Cannot open %s: %r", buf); + if((len = read(lfd, buf, sizeof buf - 1)) < 0) + fatal("filter: Cannot read %s: %r", buf); + close(lfd); + buf[len] = 0; + if(s = strchr(buf, '\n')) + len = s - buf; + if(write(fd, buf, len) != len) + fatal("filter: cannot write port; %r"); + } else { + /* client side */ + flags |= RFNOTEG; + if((len = read(fd, buf, sizeof buf - 1)) < 0) + fatal("filter: cannot read port; %r"); + 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)); + } + + snprint(buf, sizeof(buf), "%s", filterp); + if((argc = tokenize(buf, argv, nelem(argv)-3)) <= 0) + fatal("filter: empty command"); + if(host) + argv[argc++] = "-c"; + argv[argc++] = addr; + argv[argc] = nil; + file = argv[0]; + if(s = strrchr(argv[0], '/')) + argv[0] = s+1; + + if(pipe(p) < 0) + fatal("filter: pipe; %r"); + + switch(rfork(flags)) { + case -1: + fatal("filter: rfork; %r\n"); + case 0: + if (dup(p[0], 1) < 0) + fatal("filter: Cannot dup to 1; %r"); + if (dup(p[0], 0) < 0) + fatal("filter: Cannot dup to 0; %r"); + close(p[0]); + close(p[1]); + exec(file, argv); + fatal("filter: exec; %r"); + default: + close(fd); + close(p[0]); + } + return p[1]; +} + char *rmtnotefile = "/mnt/term/dev/cpunote"; /* @@ -988,11 +1094,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)