#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)
return strdup(lp+1);
}
-/*
- * based on libthread's threadsetname, but drags in less library code.
- * actually just sets the arguments displayed.
- */
-void
-procsetname(char *fmt, ...)
-{
- int fd;
- char *cmdname;
- char buf[128];
- va_list arg;
-
- va_start(arg, fmt);
- cmdname = vsmprint(fmt, arg);
- va_end(arg);
- if (cmdname == nil)
- return;
- snprint(buf, sizeof buf, "#p/%d/args", getpid());
- if((fd = open(buf, OWRITE)) >= 0){
- write(fd, cmdname, strlen(cmdname)+1);
- close(fd);
- }
- free(cmdname);
-}
-
void
main(int argc, char **argv)
{
origargs = procgetname();
/* see if we should use a larger message size */
fd = open("/dev/draw", OREAD);
- if(fd > 0){
+ if(fd >= 0){
ms = iounit(fd);
if(msgsize < ms+IOHDRSZ)
msgsize = ms+IOHDRSZ;
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());
*s++ = '!';
*s = 0;
while(p = ARGF())
- s = seprint(s, cmd+sizeof(cmd), " %s", p);
+ s = seprint(s, cmd+sizeof(cmd), " %q", p);
break;
case 'k':
keyspec = smprint("%s %s", keyspec, 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], 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);
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");
-
- /* 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;
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);
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)
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 */
if(n < 0)
return "negotiating aan";
if(*err){
- werrstr(err);
+ errstr(err, sizeof err);
return negstr;
}
}
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
return p-buf;
}
+/*
+ * chown network connection
+ */
+static void
+setnetuser(int fd, char *user)
+{
+ Dir nd;
+ nulldir(&nd);
+ nd.mode = 0660;
+ nd.uid = user;
+ dirfwstat(fd, &nd);
+}
+
/*
* user level challenge/response
*/
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;
writestr(fd, "", "challenge", 1);
if(auth_chuid(ai, 0) < 0)
fatal("newns: %r");
+ setnetuser(fd, ai->cuid);
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;
- /* 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;
}
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");
+ setnetuser(fd, ai->cuid);
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;
}
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);
_exits(0);
case 0:
fd = open(rmtnotefile, OREAD);
- if(fd < 0){
- syslog(0, "cpu", "cpu -R: can't open %s", rmtnotefile);
+ if(fd < 0)
_exits(0);
- }
for(;;){
n = read(fd, buf, sizeof(buf)-1);
ncpunote = 0;
for(;;){
n = read9pmsg(fd, buf, sizeof(buf));
- 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)
+ if(n <= 0 || convM2S(buf, n, &f) != n)
break;
if(dbg)
fprint(2, "notefs: ->%F\n", &f);