Commit Diff


commit - 7637c81af02c49ef508b946dfdec39f757a658d4
commit + 0f8ec41b0ae522b73085fa1662461e6351ba7e54
blob - 7aed917f52a27e4f384673158244d293cfba9f4d (mode 644)
blob + /dev/null
--- src/cmd/factotum/BUGS
+++ /dev/null
@@ -1 +0,0 @@
-key, delkey, wipe should be in ctl not rpc.
blob - f555c39484e63dff1bf88b6119d649d7544763b6 (mode 644)
blob + /dev/null
--- src/cmd/factotum/apop.c
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * APOP, CRAM - MD5 challenge/response authentication
- *
- * The client does not authenticate the server, hence no CAI.
- *
- * Protocol:
- *
- *	S -> C:	random@domain
- *	C -> S:	hex-response
- *	S -> C:	ok
- *
- * Note that this is the protocol between factotum and the local
- * program, not between the two factotums.  The information 
- * exchanged here is wrapped in the APOP protocol by the local
- * programs.
- *
- * If S sends "bad [msg]" instead of "ok", that is a hint that the key is bad.
- * The protocol goes back to "C -> S: user".
- */
-
-#include "std.h"
-#include "dat.h"
-
-static int
-apopcheck(Key *k)
-{
-	if(!strfindattr(k->attr, "user") || !strfindattr(k->privattr, "!password")){
-		werrstr("need user and !password attributes");
-		return -1;
-	}
-	return 0;
-}
-
-static int
-apopclient(Conv *c)
-{
-	char *chal, *pw, *res;
-	int astype, nchal, npw, ntry, ret;
-	uchar resp[MD5dlen];
-	Attr *attr;
-	DigestState *ds;
-	Key *k;
-	
-	chal = nil;
-	k = nil;
-	res = nil;
-	ret = -1;
-	attr = c->attr;
-
-	if(c->proto == &apop)
-		astype = AuthApop;
-	else if(c->proto == &cram)
-		astype = AuthCram;
-	else{
-		werrstr("bad proto");
-		goto out;
-	}
-
-	c->state = "find key";
-	k = keyfetch(c, "%A %s", attr, c->proto->keyprompt);
-	if(k == nil)
-		goto out;
-
-	c->state = "read challenge";
-	if((nchal = convreadm(c, &chal)) < 0)
-		goto out;
-
-  	for(ntry=1;; ntry++){
-		if(c->attr != attr)
-			freeattr(c->attr);
-		c->attr = addattrs(copyattr(attr), k->attr);
-		if((pw = strfindattr(k->privattr, "!password")) == nil){
-			werrstr("key has no password (cannot happen?)");
-			goto out;
-		}
-		npw = strlen(pw);
-
-		switch(astype){
-		case AuthApop:
-			ds = md5((uchar*)chal, nchal, nil, nil);
-			md5((uchar*)pw, npw, resp, ds);
-			break;
-		case AuthCram:
-			hmac_md5((uchar*)chal, nchal, (uchar*)pw, npw, resp, nil);
-			break;
-		}
-
-		/* C->S: APOP user hex-response\n */
-		if(ntry == 1)
-			c->state = "write user";
-		else{
-			sprint(c->statebuf, "write user (auth attempt #%d)", ntry);
-			c->state = c->statebuf;
-		}
-		if(convprint(c, "%s", strfindattr(k->attr, "user")) < 0)
-			goto out;
-
-		c->state = "write response";
-		if(convprint(c, "%.*H", sizeof resp, resp) < 0)
-			goto out;
-
-		c->state = "read result";
-		if(convreadm(c, &res) < 0)
-			goto out;
-
-		if(strcmp(res, "ok") == 0)
-			break;
-
-		if(strncmp(res, "bad ", 4) != 0){
-			werrstr("bad result: %s", res);
-			goto out;
-		}
-
-		c->state = "replace key";
-		if((k = keyreplace(c, k, "%s", res+4)) == nil){
-			c->state = "auth failed";
-			werrstr("%s", res+4);
-			goto out;
-		}
-		free(res);
-		res = nil;
-	}
-
-	werrstr("succeeded");
-	ret = 0;
-
-out:
-	keyclose(k);
-	free(chal);
-	if(c->attr != attr)
-		freeattr(attr);
-	return ret;
-}
-
-/* shared with auth dialing routines */
-typedef struct ServerState ServerState;
-struct ServerState
-{
-	int asfd;
-	Key *k;
-	Ticketreq tr;
-	Ticket t;
-	char *dom;
-	char *hostid;
-};
-
-enum
-{
-	APOPCHALLEN = 128,
-};
-
-static int apopchal(ServerState*, int, char[APOPCHALLEN]);
-static int apopresp(ServerState*, char*, char*);
-
-static int
-apopserver(Conv *c)
-{
-	char chal[APOPCHALLEN], *user, *resp;
-	ServerState s;
-	int astype, ret;
-	Attr *a;
-
-	ret = -1;
-	user = nil;
-	resp = nil;
-	memset(&s, 0, sizeof s);
-	s.asfd = -1;
-
-	if(c->proto == &apop)
-		astype = AuthApop;
-	else if(c->proto == &cram)
-		astype = AuthCram;
-	else{
-		werrstr("bad proto");
-		goto out;
-	}
-
-	c->state = "find key";
-	if((s.k = plan9authkey(c->attr)) == nil)
-		goto out;
-
-	a = copyattr(s.k->attr);
-	a = delattr(a, "proto");
-	c->attr = addattrs(c->attr, a);
-	freeattr(a);
-
-	c->state = "authdial";
-	s.hostid = strfindattr(s.k->attr, "user");
-	s.dom = strfindattr(s.k->attr, "dom");
-	if((s.asfd = xioauthdial(nil, s.dom)) < 0){
-		werrstr("authdial %s: %r", s.dom);
-		goto out;
-	}
-
-	c->state = "authchal";
-	if(apopchal(&s, astype, chal) < 0)
-		goto out;
-
-	c->state = "write challenge";
-	if(convprint(c, "%s", chal) < 0)
-		goto out;
-
-	for(;;){
-		c->state = "read user";
-		if(convreadm(c, &user) < 0)
-			goto out;
-
-		c->state = "read response";
-		if(convreadm(c, &resp) < 0)
-			goto out;
-
-		c->state = "authwrite";
-		switch(apopresp(&s, user, resp)){
-		case -1:
-			goto out;
-		case 0:
-			c->state = "write status";
-			if(convprint(c, "bad authentication failed") < 0)
-				goto out;
-			break;
-		case 1:
-			c->state = "write status";
-			if(convprint(c, "ok") < 0)
-				goto out;
-			goto ok;
-		}
-		free(user);
-		free(resp);
-		user = nil;
-		resp = nil;
-	}
-
-ok:
-	ret = 0;
-	c->attr = addcap(c->attr, c->sysuser, &s.t);
-
-out:
-	keyclose(s.k);
-	free(user);
-	free(resp);
-//	xioclose(s.asfd);
-	return ret;
-}
-
-static int
-apopchal(ServerState *s, int astype, char chal[APOPCHALLEN])
-{
-	char trbuf[TICKREQLEN];
-	Ticketreq tr;
-
-	memset(&tr, 0, sizeof tr);
-
-	tr.type = astype;
-
-	if(strlen(s->hostid) >= sizeof tr.hostid){
-		werrstr("hostid too long");
-		return -1;
-	}
-	strcpy(tr.hostid, s->hostid);
-
-	if(strlen(s->dom) >= sizeof tr.authdom){
-		werrstr("domain too long");
-		return -1;
-	}
-	strcpy(tr.authdom, s->dom);
-
-	convTR2M(&tr, trbuf);
-	if(xiowrite(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN)
-		return -1;
-
-	if(xioasrdresp(s->asfd, chal, APOPCHALLEN) <= 5)
-		return -1;
-
-	s->tr = tr;
-	return 0;
-}
-
-static int
-apopresp(ServerState *s, char *user, char *resp)
-{
-	char tabuf[TICKETLEN+AUTHENTLEN];
-	char trbuf[TICKREQLEN];
-	int len;
-	Authenticator a;
-	Ticket t;
-	Ticketreq tr;
-
-	tr = s->tr;
-	if(memrandom(tr.chal, CHALLEN) < 0)
-		return -1;
-
-	if(strlen(user) >= sizeof tr.uid){
-		werrstr("uid too long");
-		return -1;
-	}
-	strcpy(tr.uid, user);
-
-	convTR2M(&tr, trbuf);
-	if(xiowrite(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN)
-		return -1;
-
-	len = strlen(resp);
-	if(xiowrite(s->asfd, resp, len) != len)
-		return -1;
-
-	if(xioasrdresp(s->asfd, tabuf, TICKETLEN+AUTHENTLEN) != TICKETLEN+AUTHENTLEN)
-		return 0;
-
-	convM2T(tabuf, &t, s->k->priv);
-	if(t.num != AuthTs
-	|| memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){
-		werrstr("key mismatch with auth server");
-		return -1;
-	}
-
-	convM2A(tabuf+TICKETLEN, &a, t.key);
-	if(a.num != AuthAc
-	|| memcmp(a.chal, tr.chal, sizeof a.chal) != 0
-	|| a.id != 0){
-		werrstr("key2 mismatch with auth server");
-		return -1;
-	}
-
-	s->t = t;
-	return 1;
-}
-
-static Role
-apoproles[] = 
-{
-	"client",	apopclient,
-	"server",	apopserver,
-	0
-};
-
-Proto apop = {
-.name=		"apop",
-.roles=		apoproles,
-.checkkey=	apopcheck,
-.keyprompt=	"user? !password?",
-};
-
-Proto cram = {
-.name=		"cram",
-.roles=		apoproles,
-.checkkey=	apopcheck,
-.keyprompt=	"user? !password?",
-};
blob - b92e96a02a284f92a80b874fd22f6baadb087fc6 (mode 644)
blob + /dev/null
--- src/cmd/factotum/attr.c
+++ /dev/null
@@ -1,231 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-Attr*
-addattr(Attr *a, char *fmt, ...)
-{
-	char buf[1024];
-	va_list arg;
-	Attr *b;
-
-	va_start(arg, fmt);
-	vseprint(buf, buf+sizeof buf, fmt, arg);
-	va_end(arg);
-	b = _parseattr(buf);
-	a = addattrs(a, b);
-	setmalloctag(a, getcallerpc(&a));
-	_freeattr(b);
-	return a;
-}
-
-/*
- *  add attributes in list b to list a.  If any attributes are in
- *  both lists, replace those in a by those in b.
- */
-Attr*
-addattrs(Attr *a, Attr *b)
-{
-	int found;
-	Attr **l, *aa;
-
-	for(; b; b=b->next){
-		switch(b->type){
-		case AttrNameval:
-			for(l=&a; *l; ){
-				if(strcmp((*l)->name, b->name) != 0){
-					l=&(*l)->next;
-					continue;
-				}
-				aa = *l;
-				*l = aa->next;
-				aa->next = nil;
-				freeattr(aa);
-			}
-			*l = mkattr(AttrNameval, b->name, b->val, nil);
-			break;
-		case AttrQuery:
-			found = 0;
-			for(l=&a; *l; l=&(*l)->next)
-				if((*l)->type==AttrNameval && strcmp((*l)->name, b->name) == 0)
-					found++;
-			if(!found)
-				*l = mkattr(AttrQuery, b->name, b->val, nil);
-			break;
-		}
-	}
-	return a;		
-}
-
-void
-setmalloctaghere(void *v)
-{
-	setmalloctag(v, getcallerpc(&v));
-}
-
-Attr*
-sortattr(Attr *a)
-{
-	int i;
-	Attr *anext, *a0, *a1, **l;
-
-	if(a == nil || a->next == nil)
-		return a;
-
-	/* cut list in halves */
-	a0 = nil;
-	a1 = nil;
-	i = 0;
-	for(; a; a=anext){
-		anext = a->next;
-		if(i++%2){
-			a->next = a0;
-			a0 = a;
-		}else{
-			a->next = a1;
-			a1 = a;
-		}
-	}
-
-	/* sort */
-	a0 = sortattr(a0);
-	a1 = sortattr(a1);
-
-	/* merge */
-	l = &a;
-	while(a0 || a1){
-		if(a1==nil){
-			anext = a0;
-			a0 = a0->next;
-		}else if(a0==nil){
-			anext = a1;
-			a1 = a1->next;
-		}else if(strcmp(a0->name, a1->name) < 0){
-			anext = a0;
-			a0 = a0->next;
-		}else{
-			anext = a1;
-			a1 = a1->next;
-		}
-		*l = anext;
-		l = &(*l)->next;
-	}
-	*l = nil;
-	return a;
-}
-
-int
-attrnamefmt(Fmt *fmt)
-{
-	char *b, buf[1024], *ebuf;
-	Attr *a;
-
-	ebuf = buf+sizeof buf;
-	b = buf;
-	strcpy(buf, " ");
-	for(a=va_arg(fmt->args, Attr*); a; a=a->next){
-		if(a->name == nil)
-			continue;
-		b = seprint(b, ebuf, " %q?", a->name);
-	}
-	return fmtstrcpy(fmt, buf+1);
-}
-
-/*
-static int
-hasqueries(Attr *a)
-{
-	for(; a; a=a->next)
-		if(a->type == AttrQuery)
-			return 1;
-	return 0;
-}
-*/
-
-char *ignored[] = {
-	"role",
-	"disabled",
-};
-
-static int
-ignoreattr(char *s)
-{
-	int i;
-
-	for(i=0; i<nelem(ignored); i++)
-		if(strcmp(ignored[i], s)==0)
-			return 1;
-	return 0;
-}
-
-static int
-hasname(Attr *a0, Attr *a1, char *name)
-{
-	return _findattr(a0, name) || _findattr(a1, name);
-}
-
-static int
-hasnameval(Attr *a0, Attr *a1, char *name, char *val)
-{
-	Attr *a;
-
-	for(a=_findattr(a0, name); a; a=_findattr(a->next, name))
-		if(strcmp(a->val, val) == 0)
-			return 1;
-	for(a=_findattr(a1, name); a; a=_findattr(a->next, name))
-		if(strcmp(a->val, val) == 0)
-			return 1;
-	return 0;
-}
-
-int
-matchattr(Attr *pat, Attr *a0, Attr *a1)
-{
-	int type;
-
-	for(; pat; pat=pat->next){
-		type = pat->type;
-		if(ignoreattr(pat->name))
-			type = AttrDefault;
-		switch(type){
-		case AttrQuery:		/* name=something be present */
-			if(!hasname(a0, a1, pat->name))
-				return 0;
-			break;
-		case AttrNameval:	/* name=val must be present */
-			if(!hasnameval(a0, a1, pat->name, pat->val))
-				return 0;
-			break;
-		case AttrDefault:	/* name=val must be present if name=anything is present */
-			if(hasname(a0, a1, pat->name) && !hasnameval(a0, a1, pat->name, pat->val))
-				return 0;
-			break;
-		}
-	}
-	return 1;		
-}
-
-Attr*
-parseattrfmtv(char *fmt, va_list arg)
-{
-	char *s;
-	Attr *a;
-
-	s = vsmprint(fmt, arg);
-	if(s == nil)
-		sysfatal("vsmprint: out of memory");
-	a = parseattr(s);
-	free(s);
-	return a;
-}
-
-Attr*
-parseattrfmt(char *fmt, ...)
-{
-	va_list arg;
-	Attr *a;
-
-	va_start(arg, fmt);
-	a = parseattrfmtv(fmt, arg);
-	va_end(arg);
-	return a;
-}
blob - debf8d0ec9de804352725313b3d654e2960f5173 (mode 644)
blob + /dev/null
--- src/cmd/factotum/chap.c
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * CHAP, MSCHAP
- * 
- * The client does not authenticate the server, hence no CAI
- *
- * Protocol:
- *
- *	S -> C: random 8-byte challenge
- *	C -> S: user in UTF-8
- *	C -> S: Chapreply or MSchapreply structure
- *	S -> C: ok or 'bad why'
- *
- * The chap protocol requires the client to give it id=%d, the id of
- * the PPP message containing the challenge, which is used
- * as part of the response.  Because the client protocol is message-id
- * specific, there is no point in looping to try multiple keys.
- *
- * The MS chap protocol actually uses two different hashes, an
- * older insecure one called the LM (Lan Manager) hash, and a newer
- * more secure one called the NT hash.  By default we send back only
- * the NT hash, because the LM hash can help an eavesdropper run
- * a brute force attack.  If the key has an lm attribute, then we send only the
- * LM hash.
- */
-
-#include "std.h"
-#include "dat.h"
-
-enum {
-	ChapChallen = 8,
-
-	MShashlen = 16,
-	MSchallen = 8,
-	MSresplen = 24,
-};
-
-static int
-chapcheck(Key *k)
-{
-	if(!strfindattr(k->attr, "user") || !strfindattr(k->privattr, "!password")){
-		werrstr("need user and !password attributes");
-		return -1;
-	}
-	return 0;
-}
-
-static void
-nthash(uchar hash[MShashlen], char *passwd)
-{
-	uchar buf[512];
-	int i;
-	
-	for(i=0; *passwd && i<sizeof(buf); passwd++) {
-		buf[i++] = *passwd;
-		buf[i++] = 0;
-	}
-
-	memset(hash, 0, 16);
-
-	md4(buf, i, hash, 0);
-}
-
-static void
-desencrypt(uchar data[8], uchar key[7])
-{
-	ulong ekey[32];
-
-	key_setup(key, ekey);
-	block_cipher(ekey, data, 0);
-}
-
-static void
-lmhash(uchar hash[MShashlen], char *passwd)
-{
-	uchar buf[14];
-	char *stdtext = "KGS!@#$%";
-	int i;
-
-	strncpy((char*)buf, passwd, sizeof(buf));
-	for(i=0; i<sizeof(buf); i++)
-		if(buf[i] >= 'a' && buf[i] <= 'z')
-			buf[i] += 'A' - 'a';
-
-	memset(hash, 0, 16);
-	memcpy(hash, stdtext, 8);
-	memcpy(hash+8, stdtext, 8);
-
-	desencrypt(hash, buf);
-	desencrypt(hash+8, buf+7);
-}
-
-static void
-mschalresp(uchar resp[MSresplen], uchar hash[MShashlen], uchar chal[MSchallen])
-{
-	int i;
-	uchar buf[21];
-	
-	memset(buf, 0, sizeof(buf));
-	memcpy(buf, hash, MShashlen);
-
-	for(i=0; i<3; i++) {
-		memmove(resp+i*MSchallen, chal, MSchallen);
-		desencrypt(resp+i*MSchallen, buf+i*7);
-	}
-}
-
-static int
-chapclient(Conv *c)
-{
-	int id, astype, nchal, npw, ret;
-	uchar *chal;
-	char *s, *pw, *user, *res;
-	Attr *attr;
-	Key *k;
-	Chapreply cr;
-	MSchapreply mscr;
-	DigestState *ds;
-
-	ret = -1;
-	chal = nil;
-	k = nil;
-	attr = c->attr;
-
-	if(c->proto == &chap){
-		astype = AuthChap;
-		s = strfindattr(attr, "id");
-		if(s == nil || *s == 0){
-			werrstr("need id=n attr in start message");
-			goto out;
-		}
-		id = strtol(s, &s, 10);
-		if(*s != 0 || id < 0 || id >= 256){
-			werrstr("bad id=n attr in start message");
-			goto out;
-		}
-		cr.id = id;
-	}else if(c->proto == &mschap)
-		astype = AuthMSchap;
-	else{
-		werrstr("bad proto");
-		goto out;
-	}
-
-	c->state = "find key";
-	k = keyfetch(c, "%A %s", attr, c->proto->keyprompt);
-	if(k == nil)
-		goto out;
-
-	c->attr = addattrs(copyattr(attr), k->attr);
-
-	c->state = "read challenge";
-	if((nchal = convreadm(c, (char**)(void*)&chal)) < 0)
-		goto out;
-	if(astype == AuthMSchap && nchal != MSchallen)
-	c->state = "write user";
-	if((user = strfindattr(k->attr, "user")) == nil){
-		werrstr("key has no user (cannot happen?)");
-		goto out;
-	}
-	if(convprint(c, "%s", user) < 0)
-		goto out;
-
-	c->state = "write response";
-	if((pw = strfindattr(k->privattr, "!password")) == nil){
-		werrstr("key has no password (cannot happen?)");
-		goto out;
-	}
-	npw = strlen(pw);
-
-	if(astype == AuthChap){
-		ds = md5(&cr.id, 1, 0, 0);
-		md5((uchar*)pw, npw, 0, ds);
-		md5(chal, nchal, (uchar*)cr.resp, ds);
-		if(convwrite(c, &cr, sizeof cr) < 0)
-			goto out;
-	}else{
-		uchar hash[MShashlen];
-
-		memset(&mscr, 0, sizeof mscr);
-		if(strfindattr(k->attr, "lm")){
-			lmhash(hash, pw);
-			mschalresp((uchar*)mscr.LMresp, hash, chal);
-		}else{
-			nthash(hash, pw);
-			mschalresp((uchar*)mscr.NTresp, hash, chal);
-		}
-		if(convwrite(c, &mscr, sizeof mscr) < 0)
-			goto out;
-	}
-
-	c->state = "read result";
-	if(convreadm(c, &res) < 0)
-		goto out;
-	if(strcmp(res, "ok") == 0){
-		ret = 0;
-		werrstr("succeeded");
-		goto out;
-	}
-	if(strncmp(res, "bad ", 4) != 0){
-		werrstr("bad result: %s", res);
-		goto out;
-	}
-
-	c->state = "replace key";
-	keyevict(c, k, "%s", res+4);
-	werrstr("%s", res+4);
-
-out:
-	free(res);
-	keyclose(k);
-	free(chal);
-	if(c->attr != attr)
-		freeattr(attr);
-	return ret;
-}
-
-/* shared with auth dialing routines */
-typedef struct ServerState ServerState;
-struct ServerState
-{
-	int asfd;
-	Key *k;
-	Ticketreq tr;
-	Ticket t;
-	char *dom;
-	char *hostid;
-};
-
-static int chapchal(ServerState*, int, char[ChapChallen]);
-static int chapresp(ServerState*, char*, char*);
-
-static int
-chapserver(Conv *c)
-{
-	char chal[ChapChallen], *user, *resp;
-	ServerState s;
-	int astype, ret;
-	Attr *a;
-
-	ret = -1;
-	user = nil;
-	resp = nil;
-	memset(&s, 0, sizeof s);
-	s.asfd = -1;
-
-	if(c->proto == &chap)
-		astype = AuthChap;
-	else if(c->proto == &mschap)
-		astype = AuthMSchap;
-	else{
-		werrstr("bad proto");
-		goto out;
-	}
-
-	c->state = "find key";
-	if((s.k = plan9authkey(c->attr)) == nil)
-		goto out;
-
-	a = copyattr(s.k->attr);
-	a = delattr(a, "proto");
-	c->attr = addattrs(c->attr, a);
-	freeattr(a);
-
-	c->state = "authdial";
-	s.hostid = strfindattr(s.k->attr, "user");
-	s.dom = strfindattr(s.k->attr, "dom");
-	if((s.asfd = xioauthdial(nil, s.dom)) < 0){
-		werrstr("authdial %s: %r", s.dom);
-		goto out;
-	}
-
-	c->state = "authchal";
-	if(chapchal(&s, astype, chal) < 0)
-		goto out;
-
-	c->state = "write challenge";
-	if(convprint(c, "%s", chal) < 0)
-		goto out;
-
-	c->state = "read user";
-	if(convreadm(c, &user) < 0)
-		goto out;
-
-	c->state = "read response";
-	if(convreadm(c, &resp) < 0)
-		goto out;
-
-	c->state = "authwrite";
-	switch(chapresp(&s, user, resp)){
-	default:
-		fprint(2, "factotum: bad result from chapresp\n");
-		goto out;
-	case -1:
-		goto out;
-	case 0:
-		c->state = "write status";
-		if(convprint(c, "bad authentication failed") < 0)
-			goto out;
-		goto out;
-
-	case 1:
-		c->state = "write status";
-		if(convprint(c, "ok") < 0)
-			goto out;
-		goto ok;
-	}
-
-ok:
-	ret = 0;
-	c->attr = addcap(c->attr, c->sysuser, &s.t);
-
-out:
-	keyclose(s.k);
-	free(user);
-	free(resp);
-//	xioclose(s.asfd);
-	return ret;
-}
-
-static int
-chapchal(ServerState *s, int astype, char chal[ChapChallen])
-{
-	char trbuf[TICKREQLEN];
-	Ticketreq tr;
-
-	memset(&tr, 0, sizeof tr);
-
-	tr.type = astype;
-
-	if(strlen(s->hostid) >= sizeof tr.hostid){
-		werrstr("hostid too long");
-		return -1;
-	}
-	strcpy(tr.hostid, s->hostid);
-
-	if(strlen(s->dom) >= sizeof tr.authdom){
-		werrstr("domain too long");
-		return -1;
-	}
-	strcpy(tr.authdom, s->dom);
-
-	convTR2M(&tr, trbuf);
-	if(xiowrite(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN)
-		return -1;
-
-	if(xioasrdresp(s->asfd, chal, ChapChallen) <= 5)
-		return -1;
-
-	s->tr = tr;
-	return 0;
-}
-
-static int
-chapresp(ServerState *s, char *user, char *resp)
-{
-	char tabuf[TICKETLEN+AUTHENTLEN];
-	char trbuf[TICKREQLEN];
-	int len;
-	Authenticator a;
-	Ticket t;
-	Ticketreq tr;
-
-	tr = s->tr;
-	if(memrandom(tr.chal, CHALLEN) < 0)
-		return -1;
-
-	if(strlen(user) >= sizeof tr.uid){
-		werrstr("uid too long");
-		return -1;
-	}
-	strcpy(tr.uid, user);
-
-	convTR2M(&tr, trbuf);
-	if(xiowrite(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN)
-		return -1;
-
-	len = strlen(resp);
-	if(xiowrite(s->asfd, resp, len) != len)
-		return -1;
-
-	if(xioasrdresp(s->asfd, tabuf, TICKETLEN+AUTHENTLEN) != TICKETLEN+AUTHENTLEN)
-		return 0;
-
-	convM2T(tabuf, &t, s->k->priv);
-	if(t.num != AuthTs
-	|| memcmp(t.chal, tr.chal, sizeof tr.chal) != 0){
-		werrstr("key mismatch with auth server");
-		return -1;
-	}
-
-	convM2A(tabuf+TICKETLEN, &a, t.key);
-	if(a.num != AuthAc
-	|| memcmp(a.chal, tr.chal, sizeof a.chal) != 0
-	|| a.id != 0){
-		werrstr("key2 mismatch with auth server");
-		return -1;
-	}
-
-	s->t = t;
-	return 1;
-}
-
-static Role
-chaproles[] = 
-{
-	"client",	chapclient,
-	"server",	chapserver,
-	0
-};
-
-Proto chap = {
-.name=		"chap",
-.roles=		chaproles,
-.checkkey=	chapcheck,
-.keyprompt=	"user? !password?",
-};
-
-Proto mschap = {
-.name=		"mschap",
-.roles=		chaproles,
-.checkkey=	chapcheck,
-.keyprompt=	"user? !password?",
-};
-
blob - 8f49245043b90a6fed49bd1f90336db5d1ac1b16 (mode 644)
blob + /dev/null
--- src/cmd/factotum/confirm.c
+++ /dev/null
@@ -1,139 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-Logbuf confbuf;
-
-void
-confirmread(Req *r)
-{
-	lbread(&confbuf, r);
-}
-
-void
-confirmflush(Req *r)
-{
-	lbflush(&confbuf, r);
-}
-
-int
-confirmwrite(char *s)
-{
-	char *t, *ans;
-	int allow;
-	ulong tag;
-	Attr *a;
-	Conv *c;
-
-	a = _parseattr(s);
-	if(a == nil){
-		werrstr("bad attr");
-		return -1;
-	}
-	if((t = _strfindattr(a, "tag")) == nil){
-		werrstr("no tag");
-		return -1;
-	}
-	tag = strtoul(t, 0, 0);
-	if((ans = _strfindattr(a, "answer")) == nil){
-		werrstr("no answer");
-		return -1;
-	}
-	if(strcmp(ans, "yes") == 0)
-		allow = 1;
-	else if(strcmp(ans, "no") == 0)
-		allow = 0;
-	else{
-		werrstr("bad answer");
-		return -1;
-	}
-	for(c=conv; c; c=c->next){
-		if(tag == c->tag){
-			nbsendul(c->keywait, allow);
-			break;
-		}
-	}
-	if(c == nil){
-		werrstr("tag not found");
-		return -1;
-	}
-	return 0;
-}
-
-int
-confirmkey(Conv *c, Key *k)
-{
-	if(*confirminuse == 0)
-		return -1;
-
-	lbappend(&confbuf, "confirm tag=%lud %A %N", c->tag, k->attr, k->privattr);
-	c->state = "keyconfirm";
-	return recvul(c->keywait);
-}
-
-Logbuf needkeybuf;
-
-void
-needkeyread(Req *r)
-{
-	lbread(&needkeybuf, r);
-}
-
-void
-needkeyflush(Req *r)
-{
-	lbflush(&needkeybuf, r);
-}
-
-int
-needkeywrite(char *s)
-{
-	char *t;
-	ulong tag;
-	Attr *a;
-	Conv *c;
-
-	a = _parseattr(s);
-	if(a == nil){
-		werrstr("empty write");
-		return -1;
-	}
-	if((t = _strfindattr(a, "tag")) == nil){
-		werrstr("no tag");
-		freeattr(a);
-		return -1;
-	}
-	tag = strtoul(t, 0, 0);
-	for(c=conv; c; c=c->next)
-		if(c->tag == tag){
-			nbsendul(c->keywait, 0);
-			break;
-		}
-	if(c == nil){
-		werrstr("tag not found");
-		freeattr(a);
-		return -1;
-	}
-	freeattr(a);
-	return 0;
-}
-
-int
-needkey(Conv *c, Attr *a)
-{
-	if(c == nil || *needkeyinuse == 0)
-		return -1;
-
-	lbappend(&needkeybuf, "needkey tag=%lud %A", c->tag, a);
-	return nbrecvul(c->keywait);
-}
-
-int
-badkey(Conv *c, Key *k, char *msg, Attr *a)
-{
-	if(c == nil || *needkeyinuse == 0)
-		return -1;
-
-	lbappend(&needkeybuf, "badkey tag=%lud %A %N\n%s\n%A",
-		c->tag, k->attr, k->privattr, msg, a);
-	return nbrecvul(c->keywait);
-}
blob - 862993f9a5d0ba879789de766123e5c1bda715e9 (mode 644)
blob + /dev/null
--- src/cmd/factotum/conv.c
+++ /dev/null
@@ -1,254 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-Conv *conv;
-
-ulong taggen = 1;
-
-Conv*
-convalloc(char *sysuser)
-{
-	Conv *c;
-
-	c = mallocz(sizeof(Conv), 1);
-	if(c == nil)
-		return nil;
-	c->ref = 1;
-	c->tag = taggen++;
-	c->next = conv;
-	c->sysuser = estrdup(sysuser);
-	c->state = "nascent";
-	c->rpcwait = chancreate(sizeof(void*), 0);
-	c->keywait = chancreate(sizeof(void*), 0);
-	strcpy(c->err, "protocol has not started");
-	conv = c;
-	convreset(c);
-	return c;
-}
-
-void
-convreset(Conv *c)
-{
-	if(c->ref != 1){
-		c->hangup = 1;
-		nbsendp(c->rpcwait, 0);
-		while(c->ref > 1)
-			yield();
-		c->hangup = 0;
-	}
-	c->state = "nascent";
-	c->err[0] = '\0';
-	freeattr(c->attr);
-	c->attr = nil;
-	c->proto = nil;
-	c->rpc.op = 0;
-	c->active = 0;
-	c->done = 0;
-	c->hangup = 0;
-}
-
-void
-convhangup(Conv *c)
-{
-	c->hangup = 1;
-	c->rpc.op = 0;
-	(*c->kickreply)(c);
-	nbsendp(c->rpcwait, 0);
-}
-
-void
-convclose(Conv *c)
-{
-	Conv *p;
-
-	if(c == nil)
-		return;
-
-	if(--c->ref > 0)
-		return;
-
-	if(c == conv){
-		conv = c->next;
-		goto free;
-	}
-	for(p=conv; p && p->next!=c; p=p->next)
-		;
-	if(p == nil){
-		print("cannot find conv in list\n");
-		return;
-	}
-	p->next = c->next;
-
-free:
-	c->next = nil;
-	free(c);
-}
-
-static Rpc*
-convgetrpc(Conv *c, int want)
-{
-	for(;;){
-		if(c->hangup){
-			werrstr("hangup");
-			return nil;
-		}
-		if(c->rpc.op == RpcUnknown){
-			recvp(c->rpcwait);
-			if(c->hangup){
-				werrstr("hangup");
-				return nil;
-			}
-			if(c->rpc.op == RpcUnknown)
-				continue;
-		}
-		if(want < 0 || c->rpc.op == want)
-			return &c->rpc;
-		rpcrespond(c, "phase in state '%s' want '%s'", c->state, rpcname[want]);
-	}
-	return nil;	/* not reached */
-}
-
-/* read until the done function tells us that's enough */
-int
-convreadfn(Conv *c, int (*done)(void*, int), char **ps)
-{
-	int n;
-	Rpc *r;
-	char *s;
-
-	for(;;){
-		r = convgetrpc(c, RpcWrite);
-		if(r == nil)
-			return -1;
-		n = (*done)(r->data, r->count);
-		if(n == r->count)
-			break;
-		rpcrespond(c, "toosmall %d", n);
-	}
-
-	s = emalloc(r->count+1);
-	memmove(s, r->data, r->count);
-	s[r->count] = 0;
-	*ps = s;
-	rpcrespond(c, "ok");
-	return r->count;
-}
-
-/*
- * read until we get a non-zero write.  assumes remote side
- * knows something about the protocol (is not auth_proxy).
- * the remote side typically won't bother with the zero-length
- * write to find out the length -- the loop is there only so the
- * test program can call auth_proxy on both sides of a pipe
- * to play a conversation.
- */
-int
-convreadm(Conv *c, char **ps)
-{
-	char *s;
-	Rpc *r;
-
-	for(;;){
-		r = convgetrpc(c, RpcWrite);
-		if(r == nil)
-			return -1;
-		if(r->count > 0)
-			break;
-		rpcrespond(c, "toosmall %d", AuthRpcMax);
-	}
-	s = emalloc(r->count+1);
-	memmove(s, r->data, r->count);
-	s[r->count] = 0;
-	*ps = s;
-	rpcrespond(c, "ok");
-	return r->count;
-}
-
-/* read exactly count bytes */
-int
-convread(Conv *c, void *data, int count)
-{
-	Rpc *r;
-
-	for(;;){
-		r = convgetrpc(c, RpcWrite);
-		if(r == nil)
-			return -1;
-		if(r->count == count)
-			break;
-		if(r->count < count)
-			rpcrespond(c, "toosmall %d", count);
-		else
-			rpcrespond(c, "error too much data; want %d got %d", count, r->count);
-	}
-	memmove(data, r->data, count);
-	rpcrespond(c, "ok");
-	return 0;
-}
-
-/* write exactly count bytes */
-int
-convwrite(Conv *c, void *data, int count)
-{
-	Rpc *r;
-
-	for(;;){
-		r = convgetrpc(c, RpcRead);
-		if(r == nil)
-			return -1;
-		break;
-	}
-	rpcrespondn(c, "ok", data, count);
-	return 0;
-}
-
-/* print to the conversation */
-int
-convprint(Conv *c, char *fmt, ...)
-{
-	char *s;
-	va_list arg;
-	int ret;
-
-	va_start(arg, fmt);
-	s = vsmprint(fmt, arg);
-	va_end(arg);
-	if(s == nil)
-		return -1;
-	ret = convwrite(c, s, strlen(s));
-	free(s);
-	return ret;
-}
-
-/* ask for a key */
-int
-convneedkey(Conv *c, Attr *a)
-{
-	/*
-	 * Piggyback key requests in the usual RPC channel.
-	 * Wait for the next RPC and then send a key request
-	 * in response.  The keys get added out-of-band (via the
-	 * ctl file), so assume the key has been added when the
-	 * next request comes in.
-	 */
-	if(convgetrpc(c, -1) == nil)
-		return -1;
-	rpcrespond(c, "needkey %A", a);
-	if(convgetrpc(c, -1) == nil)
-		return -1;
-	return 0;
-}
-
-/* ask for a replacement for a bad key*/
-int
-convbadkey(Conv *c, Key *k, char *msg, Attr *a)
-{
-	if(convgetrpc(c, -1) == nil)
-		return -1;
-	rpcrespond(c, "badkey %A %N\n%s\n%A",
-		k->attr, k->privattr, msg, a);
-	if(convgetrpc(c, -1) == nil)
-		return -1;
-	return 0;
-}
-
blob - da8280ada929d6305234c49dc6c57fadea6876e7 (mode 644)
blob + /dev/null
--- src/cmd/factotum/cpu.c
+++ /dev/null
@@ -1,1117 +0,0 @@
-/*
- * cpu.c - Make a connection to a cpu server
- *
- *	   Invoked by listen as 'cpu -R | -N service net netdir'
- *	    	   by users  as 'cpu [-h system] [-c cmd args ...]'
- */
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <auth.h>
-#include <fcall.h>
-#include <libsec.h>
-
-#define	Maxfdata 8192
-
-void	remoteside(int);
-void	fatal(int, char*, ...);
-void	lclnoteproc(int);
-void	rmtnoteproc(void);
-void	catcher(void*, char*);
-void	usage(void);
-void	writestr(int, char*, char*, int);
-int	readstr(int, char*, int);
-char	*rexcall(int*, char*, char*);
-int	setamalg(char*);
-
-int 	notechan;
-char	system[32];
-int	cflag;
-int	hflag;
-int	dbg;
-char	*user;
-
-char	*srvname = "ncpu";
-char	*exportfs = "/bin/exportfs";
-char	*ealgs = "rc4_256 sha1";
-
-/* message size for exportfs; may be larger so we can do big graphics in CPU window */
-int	msgsize = 8192+IOHDRSZ;
-
-/* authentication mechanisms */
-static int	netkeyauth(int);
-static int	netkeysrvauth(int, char*);
-static int	p9auth(int);
-static int	srvp9auth(int, char*);
-static int	noauth(int);
-static int	srvnoauth(int, char*);
-
-typedef struct AuthMethod AuthMethod;
-struct AuthMethod {
-	char	*name;			/* name of method */
-	int	(*cf)(int);		/* client side authentication */
-	int	(*sf)(int, char*);	/* server side authentication */
-} authmethod[] =
-{
-	{ "p9",		p9auth,		srvp9auth,},
-	{ "netkey",	netkeyauth,	netkeysrvauth,},
-//	{ "none",	noauth,		srvnoauth,},
-	{ nil,	nil}
-};
-AuthMethod *am = authmethod;	/* default is p9 */
-
-char *p9authproto = "p9any";
-
-int setam(char*);
-
-void
-usage(void)
-{
-	fprint(2, "usage: cpu [-h system] [-a authmethod] [-e 'crypt hash'] [-c cmd args ...]\n");
-	exits("usage");
-}
-int fdd;
-
-void
-main(int argc, char **argv)
-{
-	char dat[128], buf[128], cmd[128], *p, *err;
-	int fd, ms, kms, data;
-
-	/* see if we should use a larger message size */
-	fd = open("/dev/draw", OREAD);
-	if(fd > 0){
-		ms = iounit(fd);
-		if(ms != 0 && ms < ms+IOHDRSZ)
-			msgsize = ms+IOHDRSZ;
-		close(fd);
-	}
-	kms = kiounit();
-	if(msgsize > kms-IOHDRSZ-100)	/* 100 for network packets, etc. */
-		msgsize = kms-IOHDRSZ-100;
-
-	user = getuser();
-	if(user == nil)
-		fatal(1, "can't read user name");
-	ARGBEGIN{
-	case 'a':
-		p = EARGF(usage());
-		if(setam(p) < 0)
-			fatal(0, "unknown auth method %s", p);
-		break;
-	case 'e':
-		ealgs = EARGF(usage());
-		if(*ealgs == 0 || strcmp(ealgs, "clear") == 0)
-			ealgs = nil;
-		break;
-	case 'd':
-		dbg++;
-		break;
-	case 'f':
-		/* ignored but accepted for compatibility */
-		break;
-	case 'O':
-		p9authproto = "p9sk2";
-		remoteside(1);				/* From listen */
-		break;
-	case 'R':				/* From listen */
-		remoteside(0);
-		break;
-	case 'h':
-		hflag++;
-		p = EARGF(usage());
-		strcpy(system, p);
-		break;
-	case 'c':
-		cflag++;
-		cmd[0] = '!';
-		cmd[1] = '\0';
-		while(p = ARGF()) {
-			strcat(cmd, " ");
-			strcat(cmd, p);
-		}
-		break;
-	case 'o':
-		p9authproto = "p9sk2";
-		srvname = "cpu";
-		break;
-	case 'u':
-		user = EARGF(usage());
-		break;
-	default:
-		usage();
-	}ARGEND;
-
-
-	if(argc != 0)
-		usage();
-
-	if(hflag == 0) {
-		p = getenv("cpu");
-		if(p == 0)
-			fatal(0, "set $cpu");
-		strcpy(system, p);
-	}
-
-	if(err = rexcall(&data, system, srvname))
-		fatal(1, "%s: %s", err, system);
-
-	/* Tell the remote side the command to execute and where our working directory is */
-	if(cflag)
-		writestr(data, cmd, "command", 0);
-	if(getwd(dat, sizeof(dat)) == 0)
-		writestr(data, "NO", "dir", 0);
-	else
-		writestr(data, dat, "dir", 0);
-
-	/* start up a process to pass along notes */
-	lclnoteproc(data);
-
-	/* 
-	 *  Wait for the other end to execute and start our file service
-	 *  of /mnt/term
-	 */
-	if(readstr(data, buf, sizeof(buf)) < 0)
-		fatal(1, "waiting for FS");
-	if(strncmp("FS", buf, 2) != 0) {
-		print("remote cpu: %s", buf);
-		exits(buf);
-	}
-
-	/* Begin serving the gnot namespace */
-	close(0);
-	dup(data, 0);
-	close(data);
-	sprint(buf, "%d", msgsize);
-	if(dbg)
-		execl(exportfs, exportfs, "-dm", buf, 0);
-	else
-		execl(exportfs, exportfs, "-m", buf, 0);
-	fatal(1, "starting exportfs");
-}
-
-void
-fatal(int syserr, char *fmt, ...)
-{
-	char buf[ERRMAX];
-	va_list arg;
-
-	va_start(arg, fmt);
-	doprint(buf, buf+sizeof(buf), fmt, arg);
-	va_end(arg);
-	if(syserr)
-		fprint(2, "cpu: %s: %r\n", buf);
-	else
-		fprint(2, "cpu: %s\n", 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");
-
-	switch(rfork(RFPROC|RFFDG|RFNAMEG)) {
-	case -1:
-		fatal(1, "rfork srvold9p");
-	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", 0);
-		} else
-			execl("/bin/srvold9p", "srvold9p", "-s", 0);
-		fatal(1, "exec srvold9p");
-	default:
-		close(fd);
-		close(p[0]);
-	}
-	return p[1];	
-}
-
-/* Invoked with stdin, stdout and stderr connected to the network connection */
-void
-remoteside(int old)
-{
-	char user[128], home[128], buf[128], xdir[128], cmd[128];
-	int i, n, fd, badchdir, gotcmd;
-
-	fd = 0;
-
-	/* negotiate authentication mechanism */
-	n = readstr(fd, cmd, sizeof(cmd));
-	if(n < 0)
-		fatal(1, "authenticating");
-	if(setamalg(cmd) < 0){
-		writestr(fd, "unsupported auth method", nil, 0);
-		fatal(1, "bad auth method %s", cmd);
-	} else
-		writestr(fd, "", "", 1);
-
-	fd = (*am->sf)(fd, user);
-	if(fd < 0)
-		fatal(1, "srvauth");
-
-	/* Set environment values for the user */
-	putenv("user", user);
-	sprint(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");
-	if(xdir[0] == '!') {
-		strcpy(cmd, &xdir[1]);
-		gotcmd = 1;
-		if(readstr(fd, xdir, sizeof(xdir)) < 0)
-			fatal(1, "dir");
-	}
-
-	/* 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);
-	}
-
-	/* Start the gnot serving its namespace */
-	writestr(fd, "FS", "FS", 0);
-	writestr(fd, "/", "exportfs dir", 0);
-
-	n = read(fd, buf, sizeof(buf));
-	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)
-		exits("fversion failed");
-	if(mount(fd, -1, "/mnt/term", MCREATE|MREPL, "") < 0)
-		exits("mount failed");
-
-	close(fd);
-
-	/* the remote noteproc uses the mount so it must follow it */
-	rmtnoteproc();
-
-	for(i = 0; i < 3; i++)
-		close(i);
-
-	if(open("/mnt/term/dev/cons", OREAD) != 0)
-		exits("open stdin");
-	if(open("/mnt/term/dev/cons", OWRITE) != 1)
-		exits("open stdout");
-	dup(1, 2);
-
-	if(badchdir)
-		print("cpu: failed to chdir to '%s'\n", xdir);
-
-	if(gotcmd)
-		execl("/bin/rc", "rc", "-lc", cmd, 0);
-	else
-		execl("/bin/rc", "rc", "-li", 0);
-	fatal(1, "exec shell");
-}
-
-char*
-rexcall(int *fd, char *host, char *service)
-{
-	char *na;
-	char dir[128];
-	char err[ERRMAX];
-	char msg[128];
-	int n;
-
-	na = netmkaddr(host, 0, service);
-	if((*fd = dial(na, 0, dir, 0)) < 0)
-		return "can't dial";
-
-	/* negotiate authentication mechanism */
-	if(ealgs != nil)
-		snprint(msg, sizeof(msg), "%s %s", am->name, ealgs);
-	else
-		snprint(msg, sizeof(msg), "%s", am->name);
-	writestr(*fd, msg, negstr, 0);
-	n = readstr(*fd, err, sizeof err);
-	if(n < 0)
-		return negstr;
-	if(*err){
-		werrstr(err);
-		return negstr;
-	}
-
-	/* authenticate */
-	*fd = (*am->cf)(*fd);
-	if(*fd < 0)
-		return "can't authenticate";
-	return 0;
-}
-
-void
-writestr(int fd, char *str, char *thing, int ignore)
-{
-	int l, n;
-
-	l = strlen(str);
-	n = write(fd, str, l+1);
-	if(!ignore && n < 0)
-		fatal(1, "writing network: %s", thing);
-}
-
-int
-readstr(int fd, char *str, int len)
-{
-	int n;
-
-	while(len) {
-		n = read(fd, str, 1);
-		if(n < 0) 
-			return -1;
-		if(*str == '\0')
-			return 0;
-		str++;
-		len--;
-	}
-	return -1;
-}
-
-static int
-readln(char *buf, int n)
-{
-	char *p = buf;
-
-	n--;
-	while(n > 0){
-		if(read(0, p, 1) != 1)
-			break;
-		if(*p == '\n' || *p == '\r'){
-			*p = 0;
-			return p-buf;
-		}
-		p++;
-	}
-	*p = 0;
-	return p-buf;
-}
-
-/*
- *  user level challenge/response
- */
-static int
-netkeyauth(int fd)
-{
-	char chall[32];
-	char resp[32];
-
-	strcpy(chall, getuser());
-	print("user[%s]: ", chall);
-	if(readln(resp, sizeof(resp)) < 0)
-		return -1;
-	if(*resp != 0)
-		strcpy(chall, resp);
-	writestr(fd, chall, "challenge/response", 1);
-
-	for(;;){
-		if(readstr(fd, chall, sizeof chall) < 0)
-			break;
-		if(*chall == 0)
-			return fd;
-		print("challenge: %s\nresponse: ", chall);
-		if(readln(resp, sizeof(resp)) < 0)
-			break;
-		writestr(fd, resp, "challenge/response", 1);
-	}
-	return -1;
-}
-
-static int
-netkeysrvauth(int fd, char *user)
-{
-	char response[32];
-	Chalstate *ch;
-	int tries;
-	AuthInfo *ai;
-
-	if(readstr(fd, user, 32) < 0)
-		return -1;
-
-	ai = nil;
-	ch = nil;
-	for(tries = 0; tries < 10; tries++){
-		if((ch = auth_challenge("p9cr", user, nil)) == nil)
-			return -1;
-		writestr(fd, ch->chal, "challenge", 1);
-		if(readstr(fd, response, sizeof response) < 0)
-			return -1;
-		ch->resp = response;
-		ch->nresp = strlen(response);
-		if((ai = auth_response(ch)) != nil)
-			break;
-	}
-	auth_freechal(ch);
-	if(ai == nil)
-		return -1;
-	writestr(fd, "", "challenge", 1);
-	if(auth_chuid(ai, 0) < 0)
-		fatal(1, "newns");
-	auth_freeAI(ai);
-	return fd;
-}
-
-static void
-mksecret(char *t, uchar *f)
-{
-	sprint(t, "%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux%2.2ux",
-		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)
-{
-	uchar key[16];
-	uchar digest[SHA1dlen];
-	char fromclientsecret[21];
-	char fromserversecret[21];
-	int i;
-	AuthInfo *ai;
-
-	ai = auth_proxy(fd, auth_getkey, "proto=%q user=%q role=client", p9authproto, user);
-	if(ai == nil)
-		return -1;
-	memmove(key+4, ai->secret, ai->nsecret);
-	if(ealgs == nil)
-		return fd;
-
-	/* exchange random numbers */
-	srand(truerand());
-	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;
-
-	/* scramble into two secrets */
-	sha1(key, sizeof(key), digest, nil);
-	mksecret(fromclientsecret, digest);
-	mksecret(fromserversecret, digest+10);
-
-	/* set up encryption */
-	i = pushssl(fd, ealgs, fromclientsecret, fromserversecret, nil);
-	if(i < 0)
-		werrstr("can't establish ssl connection: %r");
-	return i;
-}
-
-static int
-noauth(int fd)
-{
-	ealgs = nil;
-	return fd;
-}
-
-static int
-srvnoauth(int fd, char *user)
-{
-	strcpy(user, getuser());
-	ealgs = nil;
-	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", buf);
-}
-
-static int
-srvp9auth(int fd, char *user)
-{
-	uchar key[16];
-	uchar digest[SHA1dlen];
-	char fromclientsecret[21];
-	char fromserversecret[21];
-	int i;
-	AuthInfo *ai;
-
-	ai = auth_proxy(0, nil, "proto=%q role=server", p9authproto);
-	if(ai == nil)
-		return -1;
-	if(auth_chuid(ai, nil) < 0)
-		return -1;
-	strcpy(user, ai->cuid);
-	memmove(key+4, ai->secret, ai->nsecret);
-
-	if(ealgs == nil)
-		return fd;
-
-	/* 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);
-
-	/* set up encryption */
-	i = pushssl(fd, ealgs, fromserversecret, fromclientsecret, nil);
-	if(i < 0)
-		werrstr("can't establish ssl connection: %r");
-	return i;
-}
-
-/*
- *  set authentication mechanism
- */
-int
-setam(char *name)
-{
-	for(am = authmethod; am->name != nil; am++)
-		if(strcmp(am->name, name) == 0)
-			return 0;
-	am = authmethod;
-	return -1;
-}
-
-/*
- *  set authentication mechanism and encryption/hash algs
- */
-int
-setamalg(char *s)
-{
-	ealgs = strchr(s, ' ');
-	if(ealgs != nil)
-		*ealgs++ = 0;
-	return setam(s);
-}
-
-char *rmtnotefile = "/mnt/term/dev/cpunote";
-
-/*
- *  loop reading /mnt/term/dev/note looking for notes.
- *  The child returns to start the shell.
- */
-void
-rmtnoteproc(void)
-{
-	int n, fd, pid, notepid;
-	char buf[256];
-
-	/* new proc returns to start shell */
-	pid = rfork(RFPROC|RFFDG|RFNOTEG|RFNAMEG|RFMEM);
-	switch(pid){
-	case -1:
-		syslog(0, "cpu", "cpu -R: can't start noteproc: %r");
-		return;
-	case 0:
-		return;
-	}
-
-	/* new proc reads notes from other side and posts them to shell */
-	switch(notepid = rfork(RFPROC|RFFDG|RFMEM)){
-	case -1:
-		syslog(0, "cpu", "cpu -R: can't start wait proc: %r");
-		_exits(0);
-	case 0:
-		fd = open(rmtnotefile, OREAD);
-		if(fd < 0){
-			syslog(0, "cpu", "cpu -R: can't open %s", rmtnotefile);
-			_exits(0);
-		}
-	
-		for(;;){
-			n = read(fd, buf, sizeof(buf)-1);
-			if(n <= 0){
-				postnote(PNGROUP, pid, "hangup");
-				_exits(0);
-			}
-			buf[n] = 0;
-			postnote(PNGROUP, pid, buf);
-		}
-		break;
-	}
-
-	/* original proc waits for shell proc to die and kills note proc */
-	for(;;){
-		n = waitpid();
-		if(n < 0 || n == pid)
-			break;
-	}
-	postnote(PNPROC, notepid, "kill");
-	_exits(0);
-}
-
-enum
-{
-	Qdir,
-	Qcpunote,
-
-	Nfid = 32,
-};
-
-struct {
-	char	*name;
-	Qid	qid;
-	ulong	perm;
-} fstab[] =
-{
-	[Qdir]		{ ".",		{Qdir, 0, QTDIR},	DMDIR|0555	},
-	[Qcpunote]	{ "cpunote",	{Qcpunote, 0},		0444		},
-};
-
-typedef struct Note Note;
-struct Note
-{
-	Note *next;
-	char msg[ERRMAX];
-};
-
-typedef struct Request Request;
-struct Request
-{
-	Request *next;
-	Fcall f;
-};
-
-typedef struct Fid Fid;
-struct Fid
-{
-	int	fid;
-	int	file;
-};
-Fid fids[Nfid];
-
-struct {
-	Lock;
-	Note *nfirst, *nlast;
-	Request *rfirst, *rlast;
-} nfs;
-
-int
-fsreply(int fd, Fcall *f)
-{
-	uchar buf[IOHDRSZ+Maxfdata];
-	int n;
-
-	if(dbg)
-		fprint(2, "<-%F\n", f);
-	n = convS2M(f, buf, sizeof buf);
-	if(n > 0){
-		if(write(fd, buf, n) != n){
-			close(fd);
-			return -1;
-		}
-	}
-	return 0;
-}
-
-/* match a note read request with a note, reply to the request */
-int
-kick(int fd)
-{
-	Request *rp;
-	Note *np;
-	int rv;
-
-	for(;;){
-		lock(&nfs);
-		rp = nfs.rfirst;
-		np = nfs.nfirst;
-		if(rp == nil || np == nil){
-			unlock(&nfs);
-			break;
-		}
-		nfs.rfirst = rp->next;
-		nfs.nfirst = np->next;
-		unlock(&nfs);
-
-		rp->f.type = Rread;
-		rp->f.count = strlen(np->msg);
-		rp->f.data = np->msg;
-		rv = fsreply(fd, &rp->f);
-		free(rp);
-		free(np);
-		if(rv < 0)
-			return -1;
-	}
-	return 0;
-}
-
-void
-flushreq(int tag)
-{
-	Request **l, *rp;
-
-	lock(&nfs);
-	for(l = &nfs.rfirst; *l != nil; l = &(*l)->next){
-		rp = *l;
-		if(rp->f.tag == tag){
-			*l = rp->next;
-			unlock(&nfs);
-			free(rp);
-			return;
-		}
-	}
-	unlock(&nfs);
-}
-
-Fid*
-getfid(int fid)
-{
-	int i, freefid;
-
-	freefid = -1;
-	for(i = 0; i < Nfid; i++){
-		if(freefid < 0 && fids[i].file < 0)
-			freefid = i;
-		if(fids[i].fid == fid)
-			return &fids[i];
-	}
-	if(freefid >= 0){
-		fids[freefid].fid = fid;
-		return &fids[freefid];
-	}
-	return nil;
-}
-
-int
-fsstat(int fd, Fid *fid, Fcall *f)
-{
-	Dir d;
-	uchar statbuf[256];
-
-	memset(&d, 0, sizeof(d));
-	d.name = fstab[fid->file].name;
-	d.uid = user;
-	d.gid = user;
-	d.muid = user;
-	d.qid = fstab[fid->file].qid;
-	d.mode = fstab[fid->file].perm;
-	d.atime = d.mtime = time(0);
-	f->stat = statbuf;
-	f->nstat = convD2M(&d, statbuf, sizeof statbuf);
-	return fsreply(fd, f);
-}
-
-int
-fsread(int fd, Fid *fid, Fcall *f)
-{
-	Dir d;
-	uchar buf[256];
-	Request *rp;
-
-	switch(fid->file){
-	default:
-		return -1;
-	case Qdir:
-		if(f->offset == 0 && f->count >0){
-			memset(&d, 0, sizeof(d));
-			d.name = fstab[Qcpunote].name;
-			d.uid = user;
-			d.gid = user;
-			d.muid = user;
-			d.qid = fstab[Qcpunote].qid;
-			d.mode = fstab[Qcpunote].perm;
-			d.atime = d.mtime = time(0);
-			f->count = convD2M(&d, buf, sizeof buf);
-			f->data = (char*)buf;
-		} else
-			f->count = 0;
-		return fsreply(fd, f);
-	case Qcpunote:
-		rp = mallocz(sizeof(*rp), 1);
-		if(rp == nil)
-			return -1;
-		rp->f = *f;
-		lock(&nfs);
-		if(nfs.rfirst == nil)
-			nfs.rfirst = rp;
-		else
-			nfs.rlast->next = rp;
-		nfs.rlast = rp;
-		unlock(&nfs);
-		return kick(fd);;
-	}
-}
-
-char Eperm[] = "permission denied";
-char Enofile[] = "out of files";
-char Enotdir[] = "not a directory";
-
-void
-notefs(int fd)
-{
-	uchar buf[IOHDRSZ+Maxfdata];
-	int i, j, n;
-	char err[ERRMAX];
-	Fcall f;
-	Fid *fid, *nfid;
-	int doreply;
-
-	rfork(RFNOTEG);
-	fmtinstall('F', fcallconv);
-
-	for(n = 0; n < Nfid; n++)
-		fids[n].file = -1;
-
-	for(;;){
-		n = read9pmsg(fd, buf, sizeof(buf));
-		if(n <= 0){
-			if(dbg)
-				fprint(2, "read9pmsg(%d) returns %d: %r\n", fd, n);
-			break;
-		}
-		if(convM2S(buf, n, &f) < 0)
-			break;
-		if(dbg)
-			fprint(2, "->%F\n", &f);
-		doreply = 1;
-		fid = getfid(f.fid);
-		if(fid == nil){
-nofids:
-			f.type = Rerror;
-			f.ename = Enofile;
-			fsreply(fd, &f);
-			continue;
-		}
-		switch(f.type++){
-		default:
-			f.type = Rerror;
-			f.ename = "unknown type";
-			break;
-		case Tflush:
-			flushreq(f.oldtag);
-			break;
-		case Tversion:
-			if(f.msize > IOHDRSZ+Maxfdata)
-				f.msize = IOHDRSZ+Maxfdata;
-			break;
-		case Tauth:
-			f.type = Rerror;
-			f.ename = "cpu: authentication not required";
-			break;
-		case Tattach:
-			f.qid = fstab[Qdir].qid;
-			fid->file = Qdir;
-			break;
-		case Twalk:
-			nfid = nil;
-			if(f.newfid != f.fid){
-				nfid = getfid(f.newfid);
-				if(nfid == nil)
-					goto nofids;
-				nfid->file = fid->file;
-				fid = nfid;
-			}
-
-			f.ename = nil;
-			for(i=0; i<f.nwname; i++){
-				if(i > MAXWELEM){
-					f.type = Rerror;
-					f.ename = "too many name elements";
-					break;
-				}
-				if(fid->file != Qdir){
-					f.type = Rerror;
-					f.ename = Enotdir;
-					break;
-				}
-				if(strcmp(f.wname[i], "cpunote") == 0){
-					fid->file = Qcpunote;
-					f.wqid[i] = fstab[Qcpunote].qid;
-					continue;
-				}
-				f.type = Rerror;
-				f.ename = err;
-				strcpy(err, "cpu: file \"");
-				for(j=0; j<=i; j++){
-					if(strlen(err)+1+strlen(f.wname[j])+32 > sizeof err)
-						break;
-					if(j != 0)
-						strcat(err, "/");
-					strcat(err, f.wname[j]);
-				}
-				strcat(err, "\" does not exist");
-				break;
-			}
-			if(nfid != nil && (f.ename != nil || i < f.nwname))
-				nfid ->file = -1;
-			if(f.type != Rerror)
-				f.nwqid = i;
-			break;
-		case Topen:
-			if(f.mode != OREAD){
-				f.type = Rerror;
-				f.ename = Eperm;
-			}
-			f.qid = fstab[fid->file].qid;
-			break;
-		case Tcreate:
-			f.type = Rerror;
-			f.ename = Eperm;
-			break;
-		case Tread:
-			if(fsread(fd, fid, &f) < 0)
-				goto err;
-			doreply = 0;
-			break;
-		case Twrite:
-			f.type = Rerror;
-			f.ename = Eperm;
-			break;
-		case Tclunk:
-			fid->file = -1;
-			break;
-		case Tremove:
-			f.type = Rerror;
-			f.ename = Eperm;
-			break;
-		case Tstat:
-			if(fsstat(fd, fid, &f) < 0)
-				goto err;
-			doreply = 0;
-			break;
-		case Twstat:
-			f.type = Rerror;
-			f.ename = Eperm;
-			break;
-		}
-		if(doreply)
-			if(fsreply(fd, &f) < 0)
-				break;
-	}
-err:
-	if(dbg)
-		fprint(2, "notefs exiting: %r\n");
-	close(fd);
-}
-
-char 	notebuf[ERRMAX];
-
-void
-catcher(void*, char *text)
-{
-	int n;
-
-	n = strlen(text);
-	if(n >= sizeof(notebuf))
-		n = sizeof(notebuf)-1;
-	memmove(notebuf, text, n);
-	notebuf[n] = '\0';
-	noted(NCONT);
-}
-
-/*
- *  mount in /dev a note file for the remote side to read.
- */
-void
-lclnoteproc(int netfd)
-{
-	int exportfspid;
-	Waitmsg *w;
-	Note *np;
-	int pfd[2];
-
-	if(pipe(pfd) < 0){
-		fprint(2, "cpu: can't start note proc: pipe: %r\n");
-		return;
-	}
-
-	/* new proc mounts and returns to start exportfs */
-	switch(exportfspid = rfork(RFPROC|RFNAMEG|RFFDG|RFMEM)){
-	case -1:
-		fprint(2, "cpu: can't start note proc: rfork: %r\n");
-		return;
-	case 0:
-		close(pfd[0]);
-		if(mount(pfd[1], -1, "/dev", MBEFORE, "") < 0)
-			fprint(2, "cpu: can't mount note proc: %r\n");
-		close(pfd[1]);
-		return;
-	}
-
-	close(netfd);
-	close(pfd[1]);
-
-	/* new proc listens for note file system rpc's */
-	switch(rfork(RFPROC|RFNAMEG|RFMEM)){
-	case -1:
-		fprint(2, "cpu: can't start note proc: rfork1: %r\n");
-		_exits(0);
-	case 0:
-		notefs(pfd[0]);
-		_exits(0);
-	}
-
-	/* original proc waits for notes */
-	notify(catcher);
-	w = nil;
-	for(;;) {
-		*notebuf = 0;
-		free(w);
-		w = wait();
-		if(w == nil) {
-			if(*notebuf == 0)
-				break;
-			np = mallocz(sizeof(Note), 1);
-			if(np != nil){
-				strcpy(np->msg, notebuf);
-				lock(&nfs);
-				if(nfs.nfirst == nil)
-					nfs.nfirst = np;
-				else
-					nfs.nlast->next = np;
-				nfs.nlast = np;
-				unlock(&nfs);
-				kick(pfd[0]);
-			}
-			unlock(&nfs);
-		} else if(w->pid == exportfspid)
-			break;
-	}
-
-	if(w == nil)
-		exits(nil);
-	exits(w->msg);
-}
blob - df44b97da1a66add949dfc0478761c60fa4a2895 (mode 644)
blob + /dev/null
--- src/cmd/factotum/ctl.c
+++ /dev/null
@@ -1,158 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-/*
- *	key attr=val... - add a key
- *		the attr=val pairs are protocol-specific.
- *		for example, both of these are valid:
- *			key p9sk1 gre cs.bell-labs.com mysecret
- *			key p9sk1 gre cs.bell-labs.com 11223344556677 fmt=des7hex
- *	delkey ... - delete a key
- *		if given, the attr=val pairs are used to narrow the search
- *		[maybe should require a password?]
- *
- *	debug - toggle debugging
- */
-
-static char *msg[] = {
-	"key",
-	"delkey",
-	"debug",
-};
-
-static int
-classify(char *s)
-{
-	int i;
-
-	for(i=0; i<nelem(msg); i++)
-		if(strcmp(msg[i], s) == 0)
-			return i;
-	return -1;
-}
-
-int
-ctlwrite(char *a)
-{
-	char *p;
-	int i, nmatch, ret;
-	Attr *attr, **l, **lpriv, **lprotos, *pa, *priv, *protos;
-	Key *k;
-	Proto *proto;
-
-	if(a[0] == '#' || a[0] == '\0')
-		return 0;
-
-	/*
-	 * it would be nice to emit a warning of some sort here.
-	 * we ignore all but the first line of the write.  this helps
-	 * both with things like "echo delkey >/mnt/factotum/ctl"
-	 * and writes that (incorrectly) contain multiple key lines.
-	 */
-	if(p = strchr(a, '\n')){
-		if(p[1] != '\0'){
-			werrstr("multiline write not allowed");
-			return -1;
-		}
-		*p = '\0';
-	}
-
-	if((p = strchr(a, ' ')) == nil)
-		p = "";
-	else
-		*p++ = '\0';
-	switch(classify(a)){
-	default:
-		werrstr("unknown verb");
-		return -1;
-	case 0:	/* key */
-		attr = parseattr(p);
-		/* separate out proto= attributes */
-		lprotos = &protos;
-		for(l=&attr; (*l); ){
-			if(strcmp((*l)->name, "proto") == 0){
-				*lprotos = *l;
-				lprotos = &(*l)->next;
-				*l = (*l)->next;
-			}else
-				l = &(*l)->next;
-		}
-		*lprotos = nil;
-		if(protos == nil){
-			werrstr("key without protos");
-			freeattr(attr);
-			return -1;
-		}
-
-		/* separate out private attributes */
-		lpriv = &priv;
-		for(l=&attr; (*l); ){
-			if((*l)->name[0] == '!'){
-				*lpriv = *l;
-				lpriv = &(*l)->next;
-				*l = (*l)->next;
-			}else
-				l = &(*l)->next;
-		}
-		*lpriv = nil;
-
-		/* add keys */
-		ret = 0;
-		for(pa=protos; pa; pa=pa->next){
-			if((proto = protolookup(pa->val)) == nil){
-				werrstr("unknown proto %s", pa->val);
-				ret = -1;
-				continue;
-			}
-			if(proto->checkkey == nil){
-				werrstr("proto %s does not accept keys", proto->name);
-				ret = -1;
-				continue;
-			}
-			k = emalloc(sizeof(Key));
-			k->attr = mkattr(AttrNameval, "proto", proto->name, copyattr(attr));
-			k->privattr = copyattr(priv);
-			k->ref = 1;
-			k->proto = proto;
-			if((*proto->checkkey)(k) < 0){
-				ret = -1;
-				keyclose(k);
-				continue;
-			}
-			keyadd(k);
-			keyclose(k);
-		}
-		freeattr(attr);
-		freeattr(priv);
-		freeattr(protos);
-		return ret;
-	case 1:	/* delkey */
-		nmatch = 0;
-		attr = parseattr(p);
-		for(pa=attr; pa; pa=pa->next){
-			if(pa->type != AttrQuery && pa->name[0]=='!'){
-				werrstr("only !private? patterns are allowed for private fields");
-				freeattr(attr);
-				return -1;
-			}
-		}
-		for(i=0; i<ring.nkey; ){
-			if(matchattr(attr, ring.key[i]->attr, ring.key[i]->privattr)){
-				nmatch++;
-				keyclose(ring.key[i]);
-				ring.nkey--;
-				memmove(&ring.key[i], &ring.key[i+1], (ring.nkey-i)*sizeof(ring.key[0]));
-			}else
-				i++;
-		}
-		freeattr(attr);
-		if(nmatch == 0){
-			werrstr("found no keys to delete");
-			return -1;
-		}
-		return 0;
-	case 2:	/* debug */
-		debug ^= 1;
-		return 0;
-	}
-}
blob - 1d4a3da242d7ba506e2506aa9ee9ec64af4be86f (mode 644)
blob + /dev/null
--- src/cmd/factotum/dat.h
+++ /dev/null
@@ -1,227 +0,0 @@
-enum
-{
-	MaxRpc = 2048,	/* max size of any protocol message */
-
-	/* keep in sync with rpc.c:/rpcname */
-	RpcUnknown = 0,		/* Rpc.op */
-	RpcAuthinfo,
-	RpcAttr,
-	RpcRead,
-	RpcStart,
-	RpcWrite,
-
-	/* thread stack size */
-	STACK = 8192,
-};
-
-typedef struct Conv Conv;
-typedef struct Key Key;
-typedef struct Logbuf Logbuf;
-typedef struct Proto Proto;
-typedef struct Ring Ring;
-typedef struct Role Role;
-typedef struct Rpc Rpc;
-
-struct Rpc
-{
-	int op;
-	void *data;
-	int count;
-};
-
-struct Conv
-{
-	int ref;			/* ref count */
-	int hangup;		/* flag: please hang up */
-	int active;			/* flag: there is an active thread */
-	int done;			/* flag: conversation finished successfully */
-	ulong tag;			/* identifying tag */
-	Conv *next;		/* in linked list */
-	char *sysuser;		/* system name for user speaking to us */
-	char *state;		/* for debugging */
-	char statebuf[128];	/* for formatted states */
-	char err[ERRMAX];	/* last error */
-
-	Attr *attr;			/* current attributes */
-	Proto *proto;		/* protocol */
-
-	Channel *rpcwait;		/* wait here for an rpc */
-	Rpc rpc;				/* current rpc. op==RpcUnknown means none */
-	char rpcbuf[MaxRpc];	/* buffer for rpc */
-	char reply[MaxRpc];		/* buffer for response */
-	int nreply;				/* count of response */
-	void (*kickreply)(Conv*);	/* call to send response */
-	Req *req;				/* 9P call to read response */
-
-	Channel *keywait;	/* wait here for key confirmation */
-	
-};
-
-struct Key
-{
-	int ref;			/* ref count */
-	ulong tag;			/* identifying tag: sequence number */
-	Attr *attr;			/* public attributes */
-	Attr *privattr;		/* private attributes, like !password */
-	Proto *proto;		/* protocol owner of key */
-	void *priv;		/* protocol-specific storage */
-};
-
-struct Logbuf
-{
-	Req *wait;
-	Req **waitlast;
-	int rp;
-	int wp;
-	char *msg[128];
-};
-
-struct Ring
-{
-	Key **key;
-	int nkey;
-};
-
-struct Proto
-{
-	char *name;		/* name of protocol */
-	Role *roles;		/* list of roles and service functions */
-	char *keyprompt;	/* required attributes for key proto=name */
-	int (*checkkey)(Key*);	/* initialize k->priv or reject key */
-	void (*closekey)(Key*);	/* free k->priv */
-};
-
-struct Role
-{
-	char *name;		/* name of role */
-	int (*fn)(Conv*);	/* service function */
-};
-
-extern char	*authaddr;	/* plan9.c */
-extern int		*confirminuse;	/* fs.c */
-extern Conv*	conv;		/* conv.c */
-extern int		debug;		/* main.c */
-extern char	*factname;	/* main.c */
-extern Srv		fs;			/* fs.c */
-extern int		*needkeyinuse;	/* fs.c */
-extern char	*owner;		/* main.c */
-extern Proto	*prototab[];	/* main.c */
-extern Ring	ring;			/* key.c */
-extern char	*rpcname[];	/* rpc.c */
-
-extern char	Easproto[];	/* err.c */
-
-extern Proto	apop;		/* apop.c */
-extern Proto	chap;		/* chap.c */
-extern Proto	cram;		/* cram.c */
-extern Proto	mschap;		/* mschap.c */
-extern Proto	p9any;		/* p9any.c */
-extern Proto	p9sk1;		/* p9sk1.c */
-extern Proto	p9sk2;		/* p9sk2.c */
-
-/* provided by lib9p */
-#define emalloc	emalloc9p
-#define erealloc	erealloc9p
-#define estrdup	estrdup9p
-
-/* hidden in libauth */
-#define attrfmt		_attrfmt
-#define copyattr	_copyattr
-#define delattr		_delattr
-#define findattr		_findattr
-#define freeattr		_freeattr
-#define mkattr		_mkattr
-#define parseattr	_parseattr
-#define strfindattr	_strfindattr
-
-extern Attr*	addattr(Attr*, char*, ...);
-/* #pragma varargck argpos addattr 2 */
-extern Attr*	addattrs(Attr*, Attr*);
-extern Attr*	sortattr(Attr*);
-extern int		attrnamefmt(Fmt*);
-/* #pragma varargck type "N" Attr* */
-extern int		matchattr(Attr*, Attr*, Attr*);
-extern Attr*	parseattrfmt(char*, ...);
-/* #pragma varargck argpos parseattrfmt 1 */
-extern Attr*	parseattrfmtv(char*, va_list);
-
-extern void	confirmflush(Req*);
-extern void	confirmread(Req*);
-extern int		confirmwrite(char*);
-extern int		needkey(Conv*, Attr*);
-extern int		badkey(Conv*, Key*, char*, Attr*);
-extern int		confirmkey(Conv*, Key*);
-
-extern Conv*	convalloc(char*);
-extern void	convclose(Conv*);
-extern void	convhangup(Conv*);
-extern int		convneedkey(Conv*, Attr*);
-extern int		convbadkey(Conv*, Key*, char*, Attr*);
-extern int		convread(Conv*, void*, int);
-extern int		convreadm(Conv*, char**);
-extern int		convprint(Conv*, char*, ...);
-/* #pragma varargck argpos convprint 2 */
-extern int		convreadfn(Conv*, int(*)(void*, int), char**);
-extern void	convreset(Conv*);
-extern int		convwrite(Conv*, void*, int);
-
-extern int		ctlwrite(char*);
-
-extern char*	estrappend(char*, char*, ...);
-/* #pragma varargck argpos estrappend 2 */
-extern int		hexparse(char*, uchar*, int);
-
-extern void	keyadd(Key*);
-extern Key*	keylookup(char*, ...);
-/* #pragma varargck argpos keylookup 1 */
-extern Key*	keyfetch(Conv*, char*, ...);
-/* #pragma varargck argpos keyfetch 2 */
-extern void	keyclose(Key*);
-extern void	keyevict(Conv*, Key*, char*, ...);
-/* #pragma varargck argpos keyevict 3 */
-extern Key*	keyreplace(Conv*, Key*, char*, ...);
-/* #pragma varargck argpos keyreplace 3 */
-
-extern void	lbkick(Logbuf*);
-extern void	lbappend(Logbuf*, char*, ...);
-extern void	lbvappend(Logbuf*, char*, va_list);
-/* #pragma varargck argpos lbappend 2 */
-extern void	lbread(Logbuf*, Req*);
-extern void	lbflush(Logbuf*, Req*);
-extern void	flog(char*, ...);
-/* #pragma varargck argpos flog 1 */
-
-extern void	logflush(Req*);
-extern void	logread(Req*);
-extern void	logwrite(Req*);
-
-extern void	needkeyread(Req*);
-extern void	needkeyflush(Req*);
-extern int		needkeywrite(char*);
-extern int		needkeyqueue(void);
-
-extern Attr*	addcap(Attr*, char*, Ticket*);
-extern Key*	plan9authkey(Attr*);
-extern int		_authdial(char*, char*);
-
-extern int		memrandom(void*, int);
-
-extern Proto*	protolookup(char*);
-
-extern int		rpcwrite(Conv*, void*, int);
-extern void	rpcrespond(Conv*, char*, ...);
-/* #pragma varargck argpos rpcrespond 2 */
-extern void	rpcrespondn(Conv*, char*, void*, int);
-extern void	rpcexec(Conv*);
-
-extern int		xioauthdial(char*, char*);
-extern void	xioclose(int);
-extern int		xiodial(char*, char*, char*, int*);
-extern int		xiowrite(int, void*, int);
-extern int		xioasrdresp(int, void*, int);
-extern int		xioasgetticket(int, char*, char*);
-
-extern int		extrafactotumdir;
-
-int		havesecstore(void);
-int		secstorefetch(void);
blob - 47d2a4e17aeb1754c31a134722adbf4f85e074f6 (mode 644)
blob + /dev/null
--- src/cmd/factotum/fs.acid
+++ /dev/null
@@ -1,1686 +0,0 @@
-sizeof_1_ = 8;
-aggr _1_
-{
-	'D' 0 lo;
-	'D' 4 hi;
-};
-
-defn
-_1_(addr) {
-	complex _1_ addr;
-	print("	lo	", addr.lo, "\n");
-	print("	hi	", addr.hi, "\n");
-};
-
-sizeofFPdbleword = 8;
-aggr FPdbleword
-{
-	'F' 0 x;
-	{
-	'D' 0 lo;
-	'D' 4 hi;
-	};
-};
-
-defn
-FPdbleword(addr) {
-	complex FPdbleword addr;
-	print("	x	", addr.x, "\n");
-	print("_1_ {\n");
-		_1_(addr+0);
-	print("}\n");
-};
-
-UTFmax = 3;
-Runesync = 128;
-Runeself = 128;
-Runeerror = 128;
-sizeofFconv = 24;
-aggr Fconv
-{
-	'X' 0 out;
-	'X' 4 eout;
-	'D' 8 f1;
-	'D' 12 f2;
-	'D' 16 f3;
-	'D' 20 chr;
-};
-
-defn
-Fconv(addr) {
-	complex Fconv addr;
-	print("	out	", addr.out\X, "\n");
-	print("	eout	", addr.eout\X, "\n");
-	print("	f1	", addr.f1, "\n");
-	print("	f2	", addr.f2, "\n");
-	print("	f3	", addr.f3, "\n");
-	print("	chr	", addr.chr, "\n");
-};
-
-sizeofTm = 40;
-aggr Tm
-{
-	'D' 0 sec;
-	'D' 4 min;
-	'D' 8 hour;
-	'D' 12 mday;
-	'D' 16 mon;
-	'D' 20 year;
-	'D' 24 wday;
-	'D' 28 yday;
-	'a' 32 zone;
-	'D' 36 tzoff;
-};
-
-defn
-Tm(addr) {
-	complex Tm addr;
-	print("	sec	", addr.sec, "\n");
-	print("	min	", addr.min, "\n");
-	print("	hour	", addr.hour, "\n");
-	print("	mday	", addr.mday, "\n");
-	print("	mon	", addr.mon, "\n");
-	print("	year	", addr.year, "\n");
-	print("	wday	", addr.wday, "\n");
-	print("	yday	", addr.yday, "\n");
-	print("	zone	", addr.zone, "\n");
-	print("	tzoff	", addr.tzoff, "\n");
-};
-
-PNPROC = 1;
-PNGROUP = 2;
-sizeofLock = 4;
-aggr Lock
-{
-	'D' 0 val;
-};
-
-defn
-Lock(addr) {
-	complex Lock addr;
-	print("	val	", addr.val, "\n");
-};
-
-sizeofQLp = 12;
-aggr QLp
-{
-	'D' 0 inuse;
-	'A' QLp 4 next;
-	'C' 8 state;
-};
-
-defn
-QLp(addr) {
-	complex QLp addr;
-	print("	inuse	", addr.inuse, "\n");
-	print("	next	", addr.next\X, "\n");
-	print("	state	", addr.state, "\n");
-};
-
-sizeofQLock = 16;
-aggr QLock
-{
-	Lock 0 lock;
-	'D' 4 locked;
-	'A' QLp 8 $head;
-	'A' QLp 12 $tail;
-};
-
-defn
-QLock(addr) {
-	complex QLock addr;
-	print("Lock lock {\n");
-	Lock(addr.lock);
-	print("}\n");
-	print("	locked	", addr.locked, "\n");
-	print("	$head	", addr.$head\X, "\n");
-	print("	$tail	", addr.$tail\X, "\n");
-};
-
-sizeofRWLock = 20;
-aggr RWLock
-{
-	Lock 0 lock;
-	'D' 4 readers;
-	'D' 8 writer;
-	'A' QLp 12 $head;
-	'A' QLp 16 $tail;
-};
-
-defn
-RWLock(addr) {
-	complex RWLock addr;
-	print("Lock lock {\n");
-	Lock(addr.lock);
-	print("}\n");
-	print("	readers	", addr.readers, "\n");
-	print("	writer	", addr.writer, "\n");
-	print("	$head	", addr.$head\X, "\n");
-	print("	$tail	", addr.$tail\X, "\n");
-};
-
-RFNAMEG = 1;
-RFENVG = 2;
-RFFDG = 4;
-RFNOTEG = 8;
-RFPROC = 16;
-RFMEM = 32;
-RFNOWAIT = 64;
-RFCNAMEG = 1024;
-RFCENVG = 2048;
-RFCFDG = 4096;
-RFREND = 8192;
-RFNOMNT = 16384;
-sizeofQid = 16;
-aggr Qid
-{
-	'W' 0 path;
-	'U' 8 vers;
-	'b' 12 type;
-};
-
-defn
-Qid(addr) {
-	complex Qid addr;
-	print("	path	", addr.path, "\n");
-	print("	vers	", addr.vers, "\n");
-	print("	type	", addr.type, "\n");
-};
-
-sizeofDir = 60;
-aggr Dir
-{
-	'u' 0 type;
-	'U' 4 dev;
-	Qid 8 qid;
-	'U' 24 mode;
-	'U' 28 atime;
-	'U' 32 mtime;
-	'V' 36 length;
-	'X' 44 name;
-	'X' 48 uid;
-	'X' 52 gid;
-	'X' 56 muid;
-};
-
-defn
-Dir(addr) {
-	complex Dir addr;
-	print("	type	", addr.type, "\n");
-	print("	dev	", addr.dev, "\n");
-	print("Qid qid {\n");
-	Qid(addr.qid);
-	print("}\n");
-	print("	mode	", addr.mode, "\n");
-	print("	atime	", addr.atime, "\n");
-	print("	mtime	", addr.mtime, "\n");
-	print("	length	", addr.length, "\n");
-	print("	name	", addr.name\X, "\n");
-	print("	uid	", addr.uid\X, "\n");
-	print("	gid	", addr.gid\X, "\n");
-	print("	muid	", addr.muid\X, "\n");
-};
-
-sizeofWaitmsg = 20;
-aggr Waitmsg
-{
-	'D' 0 pid;
-	'a' 4 time;
-	'X' 16 msg;
-};
-
-defn
-Waitmsg(addr) {
-	complex Waitmsg addr;
-	print("	pid	", addr.pid, "\n");
-	print("	time	", addr.time, "\n");
-	print("	msg	", addr.msg\X, "\n");
-};
-
-sizeofIOchunk = 8;
-aggr IOchunk
-{
-	'X' 0 addr;
-	'U' 4 len;
-};
-
-defn
-IOchunk(addr) {
-	complex IOchunk addr;
-	print("	addr	", addr.addr\X, "\n");
-	print("	len	", addr.len, "\n");
-};
-
-MAXCHLEN = 256;
-MAXNAMELEN = 256;
-MD5LEN = 16;
-ARok = 0;
-ARdone = 1;
-ARerror = 2;
-ARneedkey = 3;
-ARbadkey = 4;
-ARwritenext = 5;
-ARtoosmall = 6;
-ARtoobig = 7;
-ARrpcfailure = 8;
-ARphase = 9;
-AuthRpcMax = 4096;
-sizeofAuthRpc = 8208;
-aggr AuthRpc
-{
-	'D' 0 afd;
-	'X' 4 verb;
-	'a' 8 ibuf;
-	'a' 4104 obuf;
-	'X' 8200 arg;
-	'U' 8204 narg;
-};
-
-defn
-AuthRpc(addr) {
-	complex AuthRpc addr;
-	print("	afd	", addr.afd, "\n");
-	print("	verb	", addr.verb\X, "\n");
-	print("	ibuf	", addr.ibuf, "\n");
-	print("	obuf	", addr.obuf, "\n");
-	print("	arg	", addr.arg\X, "\n");
-	print("	narg	", addr.narg, "\n");
-};
-
-sizeofAuthInfo = 20;
-aggr AuthInfo
-{
-	'X' 0 cuid;
-	'X' 4 suid;
-	'X' 8 cap;
-	'D' 12 nsecret;
-	'X' 16 secret;
-};
-
-defn
-AuthInfo(addr) {
-	complex AuthInfo addr;
-	print("	cuid	", addr.cuid\X, "\n");
-	print("	suid	", addr.suid\X, "\n");
-	print("	cap	", addr.cap\X, "\n");
-	print("	nsecret	", addr.nsecret, "\n");
-	print("	secret	", addr.secret\X, "\n");
-};
-
-sizeofChalstate = 540;
-aggr Chalstate
-{
-	'X' 0 user;
-	'a' 4 chal;
-	'D' 260 nchal;
-	'X' 264 resp;
-	'D' 268 nresp;
-	'D' 272 afd;
-	'A' AuthRpc 276 rpc;
-	'a' 280 userbuf;
-	'D' 536 userinchal;
-};
-
-defn
-Chalstate(addr) {
-	complex Chalstate addr;
-	print("	user	", addr.user\X, "\n");
-	print("	chal	", addr.chal, "\n");
-	print("	nchal	", addr.nchal, "\n");
-	print("	resp	", addr.resp\X, "\n");
-	print("	nresp	", addr.nresp, "\n");
-	print("	afd	", addr.afd, "\n");
-	print("	rpc	", addr.rpc\X, "\n");
-	print("	userbuf	", addr.userbuf, "\n");
-	print("	userinchal	", addr.userinchal, "\n");
-};
-
-sizeofChapreply = 20;
-aggr Chapreply
-{
-	'b' 0 id;
-	'a' 1 resp;
-};
-
-defn
-Chapreply(addr) {
-	complex Chapreply addr;
-	print("	id	", addr.id, "\n");
-	print("	resp	", addr.resp, "\n");
-};
-
-sizeofMSchapreply = 48;
-aggr MSchapreply
-{
-	'a' 0 LMresp;
-	'a' 24 NTresp;
-};
-
-defn
-MSchapreply(addr) {
-	complex MSchapreply addr;
-	print("	LMresp	", addr.LMresp, "\n");
-	print("	NTresp	", addr.NTresp, "\n");
-};
-
-sizeofUserPasswd = 8;
-aggr UserPasswd
-{
-	'X' 0 user;
-	'X' 4 passwd;
-};
-
-defn
-UserPasswd(addr) {
-	complex UserPasswd addr;
-	print("	user	", addr.user\X, "\n");
-	print("	passwd	", addr.passwd\X, "\n");
-};
-
-ANAMELEN = 28;
-AERRLEN = 64;
-DOMLEN = 48;
-DESKEYLEN = 7;
-CHALLEN = 8;
-NETCHLEN = 16;
-CONFIGLEN = 14;
-SECRETLEN = 32;
-KEYDBOFF = 8;
-OKEYDBLEN = 41;
-KEYDBLEN = 73;
-OMD5LEN = 16;
-AuthTreq = 1;
-AuthChal = 2;
-AuthPass = 3;
-AuthOK = 4;
-AuthErr = 5;
-AuthMod = 6;
-AuthApop = 7;
-AuthOKvar = 9;
-AuthChap = 10;
-AuthMSchap = 11;
-AuthCram = 12;
-AuthHttp = 13;
-AuthVNC = 14;
-AuthTs = 64;
-AuthTc = 65;
-AuthAs = 66;
-AuthAc = 67;
-AuthTp = 68;
-AuthHr = 69;
-sizeofTicketreq = 144;
-aggr Ticketreq
-{
-	'C' 0 type;
-	'a' 1 authid;
-	'a' 29 authdom;
-	'a' 77 chal;
-	'a' 85 hostid;
-	'a' 113 uid;
-};
-
-defn
-Ticketreq(addr) {
-	complex Ticketreq addr;
-	print("	type	", addr.type, "\n");
-	print("	authid	", addr.authid, "\n");
-	print("	authdom	", addr.authdom, "\n");
-	print("	chal	", addr.chal, "\n");
-	print("	hostid	", addr.hostid, "\n");
-	print("	uid	", addr.uid, "\n");
-};
-
-sizeofTicket = 72;
-aggr Ticket
-{
-	'C' 0 num;
-	'a' 1 chal;
-	'a' 9 cuid;
-	'a' 37 suid;
-	'a' 65 key;
-};
-
-defn
-Ticket(addr) {
-	complex Ticket addr;
-	print("	num	", addr.num, "\n");
-	print("	chal	", addr.chal, "\n");
-	print("	cuid	", addr.cuid, "\n");
-	print("	suid	", addr.suid, "\n");
-	print("	key	", addr.key, "\n");
-};
-
-sizeofAuthenticator = 16;
-aggr Authenticator
-{
-	'C' 0 num;
-	'a' 1 chal;
-	'U' 12 id;
-};
-
-defn
-Authenticator(addr) {
-	complex Authenticator addr;
-	print("	num	", addr.num, "\n");
-	print("	chal	", addr.chal, "\n");
-	print("	id	", addr.id, "\n");
-};
-
-sizeofPasswordreq = 92;
-aggr Passwordreq
-{
-	'C' 0 num;
-	'a' 1 old;
-	'a' 29 new;
-	'C' 57 changesecret;
-	'a' 58 secret;
-};
-
-defn
-Passwordreq(addr) {
-	complex Passwordreq addr;
-	print("	num	", addr.num, "\n");
-	print("	old	", addr.old, "\n");
-	print("	new	", addr.new, "\n");
-	print("	changesecret	", addr.changesecret, "\n");
-	print("	secret	", addr.secret, "\n");
-};
-
-sizeofOChapreply = 48;
-aggr OChapreply
-{
-	'b' 0 id;
-	'a' 1 uid;
-	'a' 29 resp;
-};
-
-defn
-OChapreply(addr) {
-	complex OChapreply addr;
-	print("	id	", addr.id, "\n");
-	print("	uid	", addr.uid, "\n");
-	print("	resp	", addr.resp, "\n");
-};
-
-sizeofOMSchapreply = 76;
-aggr OMSchapreply
-{
-	'a' 0 uid;
-	'a' 28 LMresp;
-	'a' 52 NTresp;
-};
-
-defn
-OMSchapreply(addr) {
-	complex OMSchapreply addr;
-	print("	uid	", addr.uid, "\n");
-	print("	LMresp	", addr.LMresp, "\n");
-	print("	NTresp	", addr.NTresp, "\n");
-};
-
-NVwrite = 1;
-NVwriteonerr = 2;
-sizeofNvrsafe = 112;
-aggr Nvrsafe
-{
-	'a' 0 machkey;
-	'b' 7 machsum;
-	'a' 8 authkey;
-	'b' 15 authsum;
-	'a' 16 config;
-	'b' 30 configsum;
-	'a' 31 authid;
-	'b' 59 authidsum;
-	'a' 60 authdom;
-	'b' 108 authdomsum;
-};
-
-defn
-Nvrsafe(addr) {
-	complex Nvrsafe addr;
-	print("	machkey	", addr.machkey, "\n");
-	print("	machsum	", addr.machsum, "\n");
-	print("	authkey	", addr.authkey, "\n");
-	print("	authsum	", addr.authsum, "\n");
-	print("	config	", addr.config, "\n");
-	print("	configsum	", addr.configsum, "\n");
-	print("	authid	", addr.authid, "\n");
-	print("	authidsum	", addr.authidsum, "\n");
-	print("	authdom	", addr.authdom, "\n");
-	print("	authdomsum	", addr.authdomsum, "\n");
-};
-
-AESbsize = 16;
-AESmaxkey = 32;
-AESmaxrounds = 14;
-sizeofAESstate = 540;
-aggr AESstate
-{
-	'U' 0 setup;
-	'D' 4 rounds;
-	'D' 8 keybytes;
-	'a' 12 key;
-	'a' 44 ekey;
-	'a' 284 dkey;
-	'a' 524 ivec;
-};
-
-defn
-AESstate(addr) {
-	complex AESstate addr;
-	print("	setup	", addr.setup, "\n");
-	print("	rounds	", addr.rounds, "\n");
-	print("	keybytes	", addr.keybytes, "\n");
-	print("	key	", addr.key, "\n");
-	print("	ekey	", addr.ekey, "\n");
-	print("	dkey	", addr.dkey, "\n");
-	print("	ivec	", addr.ivec, "\n");
-};
-
-BFbsize = 8;
-BFrounds = 16;
-sizeofBFstate = 4236;
-aggr BFstate
-{
-	'U' 0 setup;
-	'a' 4 key;
-	'a' 60 ivec;
-	'a' 68 pbox;
-	'a' 140 sbox;
-};
-
-defn
-BFstate(addr) {
-	complex BFstate addr;
-	print("	setup	", addr.setup, "\n");
-	print("	key	", addr.key, "\n");
-	print("	ivec	", addr.ivec, "\n");
-	print("	pbox	", addr.pbox, "\n");
-	print("	sbox	", addr.sbox, "\n");
-};
-
-DESbsize = 8;
-sizeofDESstate = 148;
-aggr DESstate
-{
-	'U' 0 setup;
-	'a' 4 key;
-	'a' 12 expanded;
-	'a' 140 ivec;
-};
-
-defn
-DESstate(addr) {
-	complex DESstate addr;
-	print("	setup	", addr.setup, "\n");
-	print("	key	", addr.key, "\n");
-	print("	expanded	", addr.expanded, "\n");
-	print("	ivec	", addr.ivec, "\n");
-};
-
-DES3E = 0;
-DES3D = 1;
-DES3EEE = 0;
-DES3EDE = 2;
-DES3DED = 5;
-DES3DDD = 7;
-sizeofDES3state = 420;
-aggr DES3state
-{
-	'U' 0 setup;
-	'a' 4 key;
-	'a' 28 expanded;
-	'a' 412 ivec;
-};
-
-defn
-DES3state(addr) {
-	complex DES3state addr;
-	print("	setup	", addr.setup, "\n");
-	print("	key	", addr.key, "\n");
-	print("	expanded	", addr.expanded, "\n");
-	print("	ivec	", addr.ivec, "\n");
-};
-
-SHA1dlen = 20;
-MD4dlen = 16;
-MD5dlen = 16;
-sizeofDigestState = 160;
-aggr DigestState
-{
-	'U' 0 len;
-	'a' 4 state;
-	'a' 24 buf;
-	'D' 152 blen;
-	'C' 156 malloced;
-	'C' 157 seeded;
-};
-
-defn
-DigestState(addr) {
-	complex DigestState addr;
-	print("	len	", addr.len, "\n");
-	print("	state	", addr.state, "\n");
-	print("	buf	", addr.buf, "\n");
-	print("	blen	", addr.blen, "\n");
-	print("	malloced	", addr.malloced, "\n");
-	print("	seeded	", addr.seeded, "\n");
-};
-
-sizeofRC4state = 260;
-aggr RC4state
-{
-	'a' 0 state;
-	'b' 256 x;
-	'b' 257 y;
-};
-
-defn
-RC4state(addr) {
-	complex RC4state addr;
-	print("	state	", addr.state, "\n");
-	print("	x	", addr.x, "\n");
-	print("	y	", addr.y, "\n");
-};
-
-sizeofRSApub = 8;
-aggr RSApub
-{
-	'X' 0 n;
-	'X' 4 ek;
-};
-
-defn
-RSApub(addr) {
-	complex RSApub addr;
-	print("	n	", addr.n\X, "\n");
-	print("	ek	", addr.ek\X, "\n");
-};
-
-sizeofRSApriv = 32;
-aggr RSApriv
-{
-	RSApub 0 pub;
-	'X' 8 dk;
-	'X' 12 p;
-	'X' 16 q;
-	'X' 20 kp;
-	'X' 24 kq;
-	'X' 28 c2;
-};
-
-defn
-RSApriv(addr) {
-	complex RSApriv addr;
-	print("RSApub pub {\n");
-	RSApub(addr.pub);
-	print("}\n");
-	print("	dk	", addr.dk\X, "\n");
-	print("	p	", addr.p\X, "\n");
-	print("	q	", addr.q\X, "\n");
-	print("	kp	", addr.kp\X, "\n");
-	print("	kq	", addr.kq\X, "\n");
-	print("	c2	", addr.c2\X, "\n");
-};
-
-sizeofEGpub = 12;
-aggr EGpub
-{
-	'X' 0 p;
-	'X' 4 alpha;
-	'X' 8 key;
-};
-
-defn
-EGpub(addr) {
-	complex EGpub addr;
-	print("	p	", addr.p\X, "\n");
-	print("	alpha	", addr.alpha\X, "\n");
-	print("	key	", addr.key\X, "\n");
-};
-
-sizeofEGpriv = 16;
-aggr EGpriv
-{
-	EGpub 0 pub;
-	'X' 12 secret;
-};
-
-defn
-EGpriv(addr) {
-	complex EGpriv addr;
-	print("EGpub pub {\n");
-	EGpub(addr.pub);
-	print("}\n");
-	print("	secret	", addr.secret\X, "\n");
-};
-
-sizeofEGsig = 8;
-aggr EGsig
-{
-	'X' 0 r;
-	'X' 4 s;
-};
-
-defn
-EGsig(addr) {
-	complex EGsig addr;
-	print("	r	", addr.r\X, "\n");
-	print("	s	", addr.s\X, "\n");
-};
-
-sizeofString = 20;
-aggr String
-{
-	{
-	'D' 0 val;
-	};
-	'X' 4 base;
-	'X' 8 end;
-	'X' 12 ptr;
-	'd' 16 ref;
-	'b' 18 fixed;
-};
-
-defn
-String(addr) {
-	complex String addr;
-	print("Lock {\n");
-		Lock(addr+0);
-	print("}\n");
-	print("	base	", addr.base\X, "\n");
-	print("	end	", addr.end\X, "\n");
-	print("	ptr	", addr.ptr\X, "\n");
-	print("	ref	", addr.ref, "\n");
-	print("	fixed	", addr.fixed, "\n");
-};
-
-sizeofChannel = 156;
-aggr Channel
-{
-	'D' 0 s;
-	'U' 4 f;
-	'U' 8 n;
-	'D' 12 e;
-	'D' 16 freed;
-	'U' 20 qused;
-	'a' 24 qentry;
-	'a' 152 v;
-};
-
-defn
-Channel(addr) {
-	complex Channel addr;
-	print("	s	", addr.s, "\n");
-	print("	f	", addr.f, "\n");
-	print("	n	", addr.n, "\n");
-	print("	e	", addr.e, "\n");
-	print("	freed	", addr.freed, "\n");
-	print("	qused	", addr.qused, "\n");
-	print("	qentry	", addr.qentry, "\n");
-	print("	v	", addr.v, "\n");
-};
-
-sizeofAlt = 20;
-aggr Alt
-{
-	'A' Channel 0 c;
-	'X' 4 v;
-	'D' 8 op;
-	'A' Channel 12 tag;
-	'U' 16 q;
-};
-
-defn
-Alt(addr) {
-	complex Alt addr;
-	print("	c	", addr.c\X, "\n");
-	print("	v	", addr.v\X, "\n");
-	print("	op	", addr.op, "\n");
-	print("	tag	", addr.tag\X, "\n");
-	print("	q	", addr.q, "\n");
-};
-
-sizeofRef = 4;
-aggr Ref
-{
-	'D' 0 ref;
-};
-
-defn
-Ref(addr) {
-	complex Ref addr;
-	print("	ref	", addr.ref, "\n");
-};
-
-sizeof_2_ = 8;
-aggr _2_
-{
-	'U' 0 msize;
-	'X' 4 version;
-};
-
-defn
-_2_(addr) {
-	complex _2_ addr;
-	print("	msize	", addr.msize, "\n");
-	print("	version	", addr.version\X, "\n");
-};
-
-sizeof_3_ = 4;
-aggr _3_
-{
-	'u' 0 oldtag;
-};
-
-defn
-_3_(addr) {
-	complex _3_ addr;
-	print("	oldtag	", addr.oldtag, "\n");
-};
-
-sizeof_4_ = 4;
-aggr _4_
-{
-	'X' 0 ename;
-};
-
-defn
-_4_(addr) {
-	complex _4_ addr;
-	print("	ename	", addr.ename\X, "\n");
-};
-
-sizeof_5_ = 20;
-aggr _5_
-{
-	Qid 0 qid;
-	'U' 16 iounit;
-};
-
-defn
-_5_(addr) {
-	complex _5_ addr;
-	print("Qid qid {\n");
-	Qid(addr.qid);
-	print("}\n");
-	print("	iounit	", addr.iounit, "\n");
-};
-
-sizeof_6_ = 16;
-aggr _6_
-{
-	Qid 0 aqid;
-};
-
-defn
-_6_(addr) {
-	complex _6_ addr;
-	print("Qid aqid {\n");
-	Qid(addr.aqid);
-	print("}\n");
-};
-
-sizeof_7_ = 12;
-aggr _7_
-{
-	'U' 0 afid;
-	'X' 4 uname;
-	'X' 8 aname;
-};
-
-defn
-_7_(addr) {
-	complex _7_ addr;
-	print("	afid	", addr.afid, "\n");
-	print("	uname	", addr.uname\X, "\n");
-	print("	aname	", addr.aname\X, "\n");
-};
-
-sizeof_8_ = 12;
-aggr _8_
-{
-	'U' 0 perm;
-	'X' 4 name;
-	'b' 8 mode;
-};
-
-defn
-_8_(addr) {
-	complex _8_ addr;
-	print("	perm	", addr.perm, "\n");
-	print("	name	", addr.name\X, "\n");
-	print("	mode	", addr.mode, "\n");
-};
-
-sizeof_9_ = 72;
-aggr _9_
-{
-	'U' 0 newfid;
-	'u' 4 nwname;
-	'a' 8 wname;
-};
-
-defn
-_9_(addr) {
-	complex _9_ addr;
-	print("	newfid	", addr.newfid, "\n");
-	print("	nwname	", addr.nwname, "\n");
-	print("	wname	", addr.wname, "\n");
-};
-
-sizeof_10_ = 260;
-aggr _10_
-{
-	'u' 0 nwqid;
-	'a' 4 wqid;
-};
-
-defn
-_10_(addr) {
-	complex _10_ addr;
-	print("	nwqid	", addr.nwqid, "\n");
-	print("	wqid	", addr.wqid, "\n");
-};
-
-sizeof_11_ = 16;
-aggr _11_
-{
-	'V' 0 offset;
-	'U' 8 count;
-	'X' 12 data;
-};
-
-defn
-_11_(addr) {
-	complex _11_ addr;
-	print("	offset	", addr.offset, "\n");
-	print("	count	", addr.count, "\n");
-	print("	data	", addr.data\X, "\n");
-};
-
-sizeof_12_ = 8;
-aggr _12_
-{
-	'u' 0 nstat;
-	'X' 4 stat;
-};
-
-defn
-_12_(addr) {
-	complex _12_ addr;
-	print("	nstat	", addr.nstat, "\n");
-	print("	stat	", addr.stat\X, "\n");
-};
-
-sizeof_13_ = 260;
-aggr _13_
-{
-	{
-	'U' 0 msize;
-	'X' 4 version;
-	};
-	{
-	'u' 0 oldtag;
-	};
-	{
-	'X' 0 ename;
-	};
-	{
-	Qid 0 qid;
-	'U' 16 iounit;
-	};
-	{
-	Qid 0 aqid;
-	};
-	{
-	'U' 0 afid;
-	'X' 4 uname;
-	'X' 8 aname;
-	};
-	{
-	'U' 0 perm;
-	'X' 4 name;
-	'b' 8 mode;
-	};
-	{
-	'U' 0 newfid;
-	'u' 4 nwname;
-	'a' 8 wname;
-	};
-	{
-	'u' 0 nwqid;
-	'a' 4 wqid;
-	};
-	{
-	'V' 0 offset;
-	'U' 8 count;
-	'X' 12 data;
-	};
-	{
-	'u' 0 nstat;
-	'X' 4 stat;
-	};
-};
-
-defn
-_13_(addr) {
-	complex _13_ addr;
-	print("_2_ {\n");
-		_2_(addr+0);
-	print("}\n");
-	print("_3_ {\n");
-		_3_(addr+0);
-	print("}\n");
-	print("_4_ {\n");
-		_4_(addr+0);
-	print("}\n");
-	print("_5_ {\n");
-		_5_(addr+0);
-	print("}\n");
-	print("_6_ {\n");
-		_6_(addr+0);
-	print("}\n");
-	print("_7_ {\n");
-		_7_(addr+0);
-	print("}\n");
-	print("_8_ {\n");
-		_8_(addr+0);
-	print("}\n");
-	print("_9_ {\n");
-		_9_(addr+0);
-	print("}\n");
-	print("_10_ {\n");
-		_10_(addr+0);
-	print("}\n");
-	print("_11_ {\n");
-		_11_(addr+0);
-	print("}\n");
-	print("_12_ {\n");
-		_12_(addr+0);
-	print("}\n");
-};
-
-sizeofFcall = 272;
-aggr Fcall
-{
-	'b' 0 type;
-	'U' 4 fid;
-	'u' 8 tag;
-	{
-	{
-	'U' 12 msize;
-	'X' 16 version;
-	};
-	{
-	'u' 12 oldtag;
-	};
-	{
-	'X' 12 ename;
-	};
-	{
-	Qid 12 qid;
-	'U' 28 iounit;
-	};
-	{
-	Qid 12 aqid;
-	};
-	{
-	'U' 12 afid;
-	'X' 16 uname;
-	'X' 20 aname;
-	};
-	{
-	'U' 12 perm;
-	'X' 16 name;
-	'b' 20 mode;
-	};
-	{
-	'U' 12 newfid;
-	'u' 16 nwname;
-	'a' 20 wname;
-	};
-	{
-	'u' 12 nwqid;
-	'a' 16 wqid;
-	};
-	{
-	'V' 12 offset;
-	'U' 20 count;
-	'X' 24 data;
-	};
-	{
-	'u' 12 nstat;
-	'X' 16 stat;
-	};
-	};
-};
-
-defn
-Fcall(addr) {
-	complex Fcall addr;
-	print("	type	", addr.type, "\n");
-	print("	fid	", addr.fid, "\n");
-	print("	tag	", addr.tag, "\n");
-	print("_13_ {\n");
-		_13_(addr+12);
-	print("}\n");
-};
-
-Tversion = 100;
-Rversion = 101;
-Tauth = 102;
-Rauth = 103;
-Tattach = 104;
-Rattach = 105;
-Terror = 106;
-Rerror = 107;
-Tflush = 108;
-Rflush = 109;
-Twalk = 110;
-Rwalk = 111;
-Topen = 112;
-Ropen = 113;
-Tcreate = 114;
-Rcreate = 115;
-Tread = 116;
-Rread = 117;
-Twrite = 118;
-Rwrite = 119;
-Tclunk = 120;
-Rclunk = 121;
-Tremove = 122;
-Rremove = 123;
-Tstat = 124;
-Rstat = 125;
-Twstat = 126;
-Rwstat = 127;
-Tmax = 128;
-sizeofFid = 60;
-aggr Fid
-{
-	'U' 0 fid;
-	'C' 4 omode;
-	'X' 8 file;
-	'X' 12 uid;
-	Qid 16 qid;
-	'X' 32 aux;
-	'X' 36 rdir;
-	Ref 40 ref;
-	'X' 44 pool;
-	'V' 48 diroffset;
-	'D' 56 dirindex;
-};
-
-defn
-Fid(addr) {
-	complex Fid addr;
-	print("	fid	", addr.fid, "\n");
-	print("	omode	", addr.omode, "\n");
-	print("	file	", addr.file\X, "\n");
-	print("	uid	", addr.uid\X, "\n");
-	print("Qid qid {\n");
-	Qid(addr.qid);
-	print("}\n");
-	print("	aux	", addr.aux\X, "\n");
-	print("	rdir	", addr.rdir\X, "\n");
-	print("Ref ref {\n");
-	Ref(addr.ref);
-	print("}\n");
-	print("	pool	", addr.pool\X, "\n");
-	print("	diroffset	", addr.diroffset, "\n");
-	print("	dirindex	", addr.dirindex, "\n");
-};
-
-sizeofReq = 656;
-aggr Req
-{
-	'U' 0 tag;
-	'X' 4 aux;
-	Fcall 8 ifcall;
-	Fcall 280 ofcall;
-	Dir 552 d;
-	'A' Req 612 oldreq;
-	'A' Fid 616 fid;
-	'A' Fid 620 afid;
-	'A' Fid 624 newfid;
-	'X' 628 srv;
-	Ref 632 ref;
-	'X' 636 pool;
-	'X' 640 buf;
-	'b' 644 type;
-	'b' 645 responded;
-	'X' 648 error;
-	'X' 652 rbuf;
-};
-
-defn
-Req(addr) {
-	complex Req addr;
-	print("	tag	", addr.tag, "\n");
-	print("	aux	", addr.aux\X, "\n");
-	print("Fcall ifcall {\n");
-	Fcall(addr.ifcall);
-	print("}\n");
-	print("Fcall ofcall {\n");
-	Fcall(addr.ofcall);
-	print("}\n");
-	print("Dir d {\n");
-	Dir(addr.d);
-	print("}\n");
-	print("	oldreq	", addr.oldreq\X, "\n");
-	print("	fid	", addr.fid\X, "\n");
-	print("	afid	", addr.afid\X, "\n");
-	print("	newfid	", addr.newfid\X, "\n");
-	print("	srv	", addr.srv\X, "\n");
-	print("Ref ref {\n");
-	Ref(addr.ref);
-	print("}\n");
-	print("	pool	", addr.pool\X, "\n");
-	print("	buf	", addr.buf\X, "\n");
-	print("	type	", addr.type, "\n");
-	print("	responded	", addr.responded, "\n");
-	print("	error	", addr.error\X, "\n");
-	print("	rbuf	", addr.rbuf\X, "\n");
-};
-
-sizeofFidpool = 12;
-aggr Fidpool
-{
-	'X' 0 map;
-	'X' 4 destroy;
-	'X' 8 srv;
-};
-
-defn
-Fidpool(addr) {
-	complex Fidpool addr;
-	print("	map	", addr.map\X, "\n");
-	print("	destroy	", addr.destroy\X, "\n");
-	print("	srv	", addr.srv\X, "\n");
-};
-
-sizeofReqpool = 12;
-aggr Reqpool
-{
-	'X' 0 map;
-	'X' 4 destroy;
-	'X' 8 srv;
-};
-
-defn
-Reqpool(addr) {
-	complex Reqpool addr;
-	print("	map	", addr.map\X, "\n");
-	print("	destroy	", addr.destroy\X, "\n");
-	print("	srv	", addr.srv\X, "\n");
-};
-
-sizeofFile = 108;
-aggr File
-{
-	{
-	'D' 0 ref;
-	};
-	{
-	'u' 4 type;
-	'U' 8 dev;
-	Qid 12 qid;
-	'U' 28 mode;
-	'U' 32 atime;
-	'U' 36 mtime;
-	'V' 40 length;
-	'X' 48 name;
-	'X' 52 uid;
-	'X' 56 gid;
-	'X' 60 muid;
-	};
-	'A' File 64 parent;
-	'X' 68 aux;
-	{
-	Lock 72 lock;
-	'D' 76 readers;
-	'D' 80 writer;
-	'A' QLp 84 $head;
-	'A' QLp 88 $tail;
-	};
-	'X' 92 filelist;
-	'X' 96 tree;
-	'D' 100 nchild;
-	'D' 104 allocd;
-};
-
-defn
-File(addr) {
-	complex File addr;
-	print("Ref {\n");
-		Ref(addr+0);
-	print("}\n");
-	print("Dir {\n");
-		Dir(addr+4);
-	print("}\n");
-	print("	parent	", addr.parent\X, "\n");
-	print("	aux	", addr.aux\X, "\n");
-	print("RWLock {\n");
-		RWLock(addr+72);
-	print("}\n");
-	print("	filelist	", addr.filelist\X, "\n");
-	print("	tree	", addr.tree\X, "\n");
-	print("	nchild	", addr.nchild, "\n");
-	print("	allocd	", addr.allocd, "\n");
-};
-
-sizeofTree = 20;
-aggr Tree
-{
-	'A' File 0 root;
-	'X' 4 destroy;
-	Lock 8 genlock;
-	'U' 12 qidgen;
-	'U' 16 dirqidgen;
-};
-
-defn
-Tree(addr) {
-	complex Tree addr;
-	print("	root	", addr.root\X, "\n");
-	print("	destroy	", addr.destroy\X, "\n");
-	print("Lock genlock {\n");
-	Lock(addr.genlock);
-	print("}\n");
-	print("	qidgen	", addr.qidgen, "\n");
-	print("	dirqidgen	", addr.dirqidgen, "\n");
-};
-
-sizeofSrv = 136;
-aggr Srv
-{
-	'A' Tree 0 tree;
-	'X' 4 destroyfid;
-	'X' 8 destroyreq;
-	'X' 12 end;
-	'X' 16 aux;
-	'X' 20 attach;
-	'X' 24 auth;
-	'X' 28 open;
-	'X' 32 create;
-	'X' 36 read;
-	'X' 40 write;
-	'X' 44 remove;
-	'X' 48 flush;
-	'X' 52 stat;
-	'X' 56 wstat;
-	'X' 60 walk;
-	'X' 64 clone;
-	'X' 68 walk1;
-	'D' 72 infd;
-	'D' 76 outfd;
-	'D' 80 nopipe;
-	'A' Fidpool 84 fpool;
-	'A' Reqpool 88 rpool;
-	'U' 92 msize;
-	'X' 96 rbuf;
-	QLock 100 rlock;
-	'X' 116 wbuf;
-	QLock 120 wlock;
-};
-
-defn
-Srv(addr) {
-	complex Srv addr;
-	print("	tree	", addr.tree\X, "\n");
-	print("	destroyfid	", addr.destroyfid\X, "\n");
-	print("	destroyreq	", addr.destroyreq\X, "\n");
-	print("	end	", addr.end\X, "\n");
-	print("	aux	", addr.aux\X, "\n");
-	print("	attach	", addr.attach\X, "\n");
-	print("	auth	", addr.auth\X, "\n");
-	print("	open	", addr.open\X, "\n");
-	print("	create	", addr.create\X, "\n");
-	print("	read	", addr.read\X, "\n");
-	print("	write	", addr.write\X, "\n");
-	print("	remove	", addr.remove\X, "\n");
-	print("	flush	", addr.flush\X, "\n");
-	print("	stat	", addr.stat\X, "\n");
-	print("	wstat	", addr.wstat\X, "\n");
-	print("	walk	", addr.walk\X, "\n");
-	print("	clone	", addr.clone\X, "\n");
-	print("	walk1	", addr.walk1\X, "\n");
-	print("	infd	", addr.infd, "\n");
-	print("	outfd	", addr.outfd, "\n");
-	print("	nopipe	", addr.nopipe, "\n");
-	print("	fpool	", addr.fpool\X, "\n");
-	print("	rpool	", addr.rpool\X, "\n");
-	print("	msize	", addr.msize, "\n");
-	print("	rbuf	", addr.rbuf\X, "\n");
-	print("QLock rlock {\n");
-	QLock(addr.rlock);
-	print("}\n");
-	print("	wbuf	", addr.wbuf\X, "\n");
-	print("QLock wlock {\n");
-	QLock(addr.wlock);
-	print("}\n");
-};
-
-OMASK = 3;
-Maxname = 128;
-Maxrpc = 4096;
-Notstarted = -3;
-Broken = -2;
-Established = -1;
-RpcFailure = 0;
-RpcNeedkey = 1;
-RpcOk = 2;
-RpcErrstr = 3;
-RpcToosmall = 4;
-RpcPhase = 5;
-sizeofAttr = 12;
-aggr Attr
-{
-	'A' Attr 0 next;
-	'A' String 4 name;
-	'A' String 8 val;
-};
-
-defn
-Attr(addr) {
-	complex Attr addr;
-	print("	next	", addr.next\X, "\n");
-	print("	name	", addr.name\X, "\n");
-	print("	val	", addr.val\X, "\n");
-};
-
-sizeof_14_ = 4120;
-aggr _14_
-{
-	'X' 0 arg;
-	'a' 4 buf;
-	'X' 4100 verb;
-	'D' 4104 iverb;
-	'D' 4108 narg;
-	'D' 4112 nbuf;
-	'D' 4116 nwant;
-};
-
-defn
-_14_(addr) {
-	complex _14_ addr;
-	print("	arg	", addr.arg\X, "\n");
-	print("	buf	", addr.buf, "\n");
-	print("	verb	", addr.verb\X, "\n");
-	print("	iverb	", addr.iverb, "\n");
-	print("	narg	", addr.narg, "\n");
-	print("	nbuf	", addr.nbuf, "\n");
-	print("	nwant	", addr.nwant, "\n");
-};
-
-sizeofFsstate = 4700;
-aggr Fsstate
-{
-	'X' 0 sysuser;
-	'D' 4 listoff;
-	_14_ 8 rpc;
-	'a' 4128 err;
-	'a' 4256 keyinfo;
-	'X' 4640 phasename;
-	'D' 4644 isclient;
-	'D' 4648 haveai;
-	'D' 4652 maxphase;
-	'D' 4656 phase;
-	'D' 4660 started;
-	'A' Attr 4664 attr;
-	AuthInfo 4668 ai;
-	'X' 4688 proto;
-	'X' 4692 ps;
-	'X' 4696 ring;
-};
-
-defn
-Fsstate(addr) {
-	complex Fsstate addr;
-	print("	sysuser	", addr.sysuser\X, "\n");
-	print("	listoff	", addr.listoff, "\n");
-	print("_14_ rpc {\n");
-	_14_(addr.rpc);
-	print("}\n");
-	print("	err	", addr.err, "\n");
-	print("	keyinfo	", addr.keyinfo, "\n");
-	print("	phasename	", addr.phasename\X, "\n");
-	print("	isclient	", addr.isclient, "\n");
-	print("	haveai	", addr.haveai, "\n");
-	print("	maxphase	", addr.maxphase, "\n");
-	print("	phase	", addr.phase, "\n");
-	print("	started	", addr.started, "\n");
-	print("	attr	", addr.attr\X, "\n");
-	print("AuthInfo ai {\n");
-	AuthInfo(addr.ai);
-	print("}\n");
-	print("	proto	", addr.proto\X, "\n");
-	print("	ps	", addr.ps\X, "\n");
-	print("	ring	", addr.ring\X, "\n");
-};
-
-sizeofKey = 20;
-aggr Key
-{
-	'D' 0 ref;
-	'A' Attr 4 attr;
-	'A' Attr 8 privattr;
-	'X' 12 proto;
-	'X' 16 priv;
-};
-
-defn
-Key(addr) {
-	complex Key addr;
-	print("	ref	", addr.ref, "\n");
-	print("	attr	", addr.attr\X, "\n");
-	print("	privattr	", addr.privattr\X, "\n");
-	print("	proto	", addr.proto\X, "\n");
-	print("	priv	", addr.priv\X, "\n");
-};
-
-sizeofKeyring = 8;
-aggr Keyring
-{
-	'A' Key 0 key;
-	'D' 4 nkey;
-};
-
-defn
-Keyring(addr) {
-	complex Keyring addr;
-	print("	key	", addr.key\X, "\n");
-	print("	nkey	", addr.nkey, "\n");
-};
-
-sizeofLogbuf = 520;
-aggr Logbuf
-{
-	'D' 0 rp;
-	'D' 4 wp;
-	'a' 8 msg;
-};
-
-defn
-Logbuf(addr) {
-	complex Logbuf addr;
-	print("	rp	", addr.rp, "\n");
-	print("	wp	", addr.wp, "\n");
-	print("	msg	", addr.msg, "\n");
-};
-
-sizeofProto = 28;
-aggr Proto
-{
-	'X' 0 name;
-	'X' 4 init;
-	'X' 8 addkey;
-	'X' 12 closekey;
-	'X' 16 write;
-	'X' 20 read;
-	'X' 24 close;
-};
-
-defn
-Proto(addr) {
-	complex Proto addr;
-	print("	name	", addr.name\X, "\n");
-	print("	init	", addr.init\X, "\n");
-	print("	addkey	", addr.addkey\X, "\n");
-	print("	closekey	", addr.closekey\X, "\n");
-	print("	write	", addr.write\X, "\n");
-	print("	read	", addr.read\X, "\n");
-	print("	close	", addr.close\X, "\n");
-};
-
-complex Keyring ring;
-complex Logbuf logbuf;
-complex Proto apop;
-complex Proto cram;
-complex Proto p9any;
-complex Proto p9sk1;
-complex Proto p9sk2;
-complex Keyring ring;
-complex Srv fs;
-complex Proto main:p;
-Qroot = 0;
-Qfactotum = 1;
-Qrpc = 2;
-Qkeylist = 3;
-Qprotolist = 4;
-Qconfirm = 5;
-Qlog = 6;
-Qctl = 7;
-complex Qid mkqid:q;
-complex Req fsattach:r;
-sizeof_15_ = 12;
-aggr _15_
-{
-	'X' 0 name;
-	'D' 4 qidpath;
-	'U' 8 perm;
-};
-
-defn
-_15_(addr) {
-	complex _15_ addr;
-	print("	name	", addr.name\X, "\n");
-	print("	qidpath	", addr.qidpath, "\n");
-	print("	perm	", addr.perm, "\n");
-};
-
-complex Dir fillstat:dir;
-complex Dir fsdirgen:dir;
-complex Fid fswalk1:fid;
-complex Qid fswalk1:qid;
-complex Req fsstat:r;
-complex Req fsopen:r;
-complex Fsstate fsopen:fss;
-complex Fid fsdestroyfid:fid;
-complex Req readlist:r;
-complex Key keylist:k;
-complex Req fsread:r;
-complex Fsstate fsread:s;
-complex Req fswrite:r;
-complex Srv fs;
blob - f9ad785be85abca7d31c939827ad8b9617240f97 (mode 644)
blob + /dev/null
--- src/cmd/factotum/fs.c
+++ /dev/null
@@ -1,531 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-enum
-{
-	Qroot,
-	Qfactotum,
-	Qrpc,
-	Qkeylist,
-	Qprotolist,
-	Qconfirm,
-	Qlog,
-	Qctl,
-	Qneedkey,
-	Qconv,
-};
-
-static int qtop;
-
-Qid
-mkqid(int type, int path)
-{
-	Qid q;
-
-	q.type = type;
-	q.path = path;
-	q.vers = 0;
-	return q;
-}
-
-static struct
-{
-	char *name;
-	int qidpath;
-	ulong perm;
-} dirtab[] = {
-	/* positions of confirm and needkey known below */
-	"confirm",		Qconfirm,		0600|DMEXCL,
-	"needkey",	Qneedkey,	0600|DMEXCL,
-	"ctl",			Qctl,			0600,
-	"rpc",		Qrpc,		0666,
-	"proto",		Qprotolist,	0444,
-	"log",		Qlog,		0600|DMEXCL,
-	"conv",		Qconv,		0400,
-};
-
-static void
-fillstat(Dir *dir, char *name, int type, int path, ulong perm)
-{
-	dir->name = estrdup(name);
-	dir->uid = estrdup(owner);
-	dir->gid = estrdup(owner);
-	dir->mode = perm;
-	dir->length = 0;
-	dir->qid = mkqid(type, path);
-	dir->atime = time(0);
-	dir->mtime = time(0);
-	dir->muid = estrdup("");
-}
-
-static int
-rootdirgen(int n, Dir *dir, void *v)
-{
-	USED(v);
-
-	if(n > 0)
-		return -1;
-	
-	fillstat(dir, factname, QTDIR, Qfactotum, DMDIR|0555);
-	return 0;
-}
-
-static int
-fsdirgen(int n, Dir *dir, void *v)
-{
-	USED(v);
-
-	if(n >= nelem(dirtab))
-		return -1;
-	fillstat(dir, dirtab[n].name, 0, dirtab[n].qidpath, dirtab[n].perm);
-	return 0;
-}
-
-static char*
-fswalk1(Fid *fid, char *name, Qid *qid)
-{
-	int i;
-
-	switch((int)fid->qid.path){
-	default:
-		return "fswalk1: cannot happen";
-	case Qroot:
-		if(strcmp(name, factname) == 0){
-			*qid = mkqid(QTDIR, Qfactotum);
-			fid->qid = *qid;
-			return nil;
-		}
-		if(strcmp(name, "..") == 0){
-			*qid = fid->qid;
-			return nil;
-		}
-		return "not found";
-	case Qfactotum:
-		for(i=0; i<nelem(dirtab); i++)
-			if(strcmp(name, dirtab[i].name) == 0){
-				*qid = mkqid(0, dirtab[i].qidpath);
-				fid->qid = *qid;
-				return nil;
-			}
-		if(strcmp(name, "..") == 0){
-			*qid = mkqid(QTDIR, qtop);
-			fid->qid = *qid;
-			return nil;
-		}
-		return "not found";
-	}
-}
-
-static void
-fsstat(Req *r)
-{
-	int i, path;
-
-	path = r->fid->qid.path;
-	switch(path){
-	case Qroot:
-		fillstat(&r->d, "/", QTDIR, Qroot, 0555|DMDIR);
-		break;
-	case Qfactotum:
-		fillstat(&r->d, "factotum", QTDIR, Qfactotum, 0555|DMDIR);
-		break;
-	default:
-		for(i=0; i<nelem(dirtab); i++)
-			if(dirtab[i].qidpath == path){
-				fillstat(&r->d, dirtab[i].name, 0, dirtab[i].qidpath, dirtab[i].perm);
-				goto Break2;
-			}
-		respond(r, "file not found");
-		break;
-	}
-    Break2:
-	respond(r, nil);
-}
-
-static int
-readlist(int off, int (*gen)(int, char*, uint), Req *r)
-{
-	char *a, *ea;
-	int n;
-
-	a = r->ofcall.data;
-	ea = a+r->ifcall.count;
-	for(;;){
-		n = (*gen)(off, a, ea-a);
-		if(n == 0){
-			r->ofcall.count = a - (char*)r->ofcall.data;
-			return off;
-		}
-		a += n;
-		off++;
-	}
-	return -1;		/* not reached */
-}
-
-static int
-keylist(int i, char *a, uint nn)
-{
-	int n;
-	char buf[512];
-	Key *k;
-
-	if(i >= ring.nkey)
-		return 0;
-
-	k = ring.key[i];
-	k->attr = sortattr(k->attr);
-	n = snprint(buf, sizeof buf, "key %A %N\n", k->attr, k->privattr);
-	if(n >= sizeof(buf)-5)
-		strcpy(buf+sizeof(buf)-5, "...\n");
-	n = strlen(buf);
-	if(n > nn)
-		return 0;
-	memmove(a, buf, n);
-	return n;
-}
-
-static int
-protolist(int i, char *a, uint n)
-{
-	if(prototab[i] == nil)
-		return 0;
-	if(strlen(prototab[i]->name)+1 > n)
-		return 0;
-	n = strlen(prototab[i]->name)+1;
-	memmove(a, prototab[i]->name, n-1);
-	a[n-1] = '\n';
-	return n;
-}
-
-/* BUG this is O(n^2) to fill in the list */
-static int
-convlist(int i, char *a, uint nn)
-{
-	Conv *c;
-	char buf[512];
-	int n;
-
-	for(c=conv; c && i-- > 0; c=c->next)
-		;
-
-	if(c == nil)
-		return 0;
-
-	if(c->state)
-		n = snprint(buf, sizeof buf, "conv state=%q %A\n", c->state, c->attr);
-	else
-		n = snprint(buf, sizeof buf, "conv state=closed err=%q\n", c->err);
-
-	if(n >= sizeof(buf)-5)
-		strcpy(buf+sizeof(buf)-5, "...\n");
-	n = strlen(buf);
-	if(n > nn)
-		return 0;
-	memmove(a, buf, n);
-	return n;
-}
-	
-static void
-fskickreply(Conv *c)
-{
-	Req *r;
-
-	if(c->hangup){
-		if(c->req){
-			respond(c->req, "hangup");
-			c->req = nil;
-		}
-		return;
-	}
-
-	if(!c->req || !c->nreply)
-		return;
-
-	r = c->req;
-	r->ofcall.count = c->nreply;
-	r->ofcall.data = c->reply;
-	if(r->ofcall.count > r->ifcall.count)
-		r->ofcall.count = r->ifcall.count;
-	respond(r, nil);
-	c->req = nil;
-	c->nreply = 0;
-}
-		
-/*
- * Some of the file system work happens in the fs proc, but
- * fsopen, fsread, fswrite, fsdestroyfid, and fsflush happen in
- * the main proc so that they can access the various shared
- * data structures without worrying about locking.
- */
-static int inuse[nelem(dirtab)];
-int *confirminuse = &inuse[0];
-int *needkeyinuse = &inuse[1];
-static void
-fsopen(Req *r)
-{
-	int i, *inusep, perm;
-	static int need[4] = { 4, 2, 6, 1 };
-	Conv *c;
-
-	inusep = nil;
-	perm = 5;	/* directory */
-	for(i=0; i<nelem(dirtab); i++)
-		if(dirtab[i].qidpath == r->fid->qid.path){
-			if(dirtab[i].perm & DMEXCL)
-				inusep = &inuse[i];
-			if(strcmp(r->fid->uid, owner) == 0)
-				perm = dirtab[i].perm>>6;
-			else
-				perm = dirtab[i].perm;
-			break;
-		}
-
-	if((r->ifcall.mode&~(OMASK|OTRUNC))
-	|| (need[r->ifcall.mode&3] & ~perm)){
-		respond(r, "permission denied");
-		return;
-	}
-
-	if(inusep){
-		if(*inusep){
-			respond(r, "file in use");
-			return;
-		}
-		*inusep = 1;
-	}
-
-	if(r->fid->qid.path == Qrpc){
-		if((c = convalloc(r->fid->uid)) == nil){
-			char e[ERRMAX];
-
-			rerrstr(e, sizeof e);
-			respond(r, e);
-			return;
-		}
-		c->kickreply = fskickreply;
-		r->fid->aux = c;
-	}
-	
-	respond(r, nil);
-}
-
-static void
-fsread(Req *r)
-{
-	Conv *c;
-
-	switch((int)r->fid->qid.path){
-	default:
-		respond(r, "fsread: cannot happen");
-		break;
-	case Qroot:
-		dirread9p(r, rootdirgen, nil);
-		respond(r, nil);
-		break;
-	case Qfactotum:
-		dirread9p(r, fsdirgen, nil);
-		respond(r, nil);
-		break;
-	case Qrpc:
-		c = r->fid->aux;
-		if(c->rpc.op == RpcUnknown){
-			respond(r, "no rpc pending");
-			break;
-		}
-		if(c->req){
-			respond(r, "read already pending");
-			break;
-		}
-		c->req = r;
-		if(c->nreply)
-			(*c->kickreply)(c);
-		else
-			rpcexec(c);
-		break;
-	case Qconfirm:
-		confirmread(r);
-		break;
-	case Qlog:
-		logread(r);
-		break;
-	case Qctl:
-		r->fid->aux = (void*)readlist((int)r->fid->aux, keylist, r);
-		respond(r, nil);
-		break;
-	case Qneedkey:
-		needkeyread(r);
-		break;
-	case Qprotolist:
-		r->fid->aux = (void*)readlist((int)r->fid->aux, protolist, r);
-		respond(r, nil);
-		break;
-	case Qconv:
-		r->fid->aux = (void*)readlist((int)r->fid->aux, convlist, r);
-		respond(r, nil);
-		break;
-	}
-}
-
-static void
-fswrite(Req *r)
-{
-	int ret;
-	char err[ERRMAX], *s;
-	int (*strfn)(char*);
-
-	switch((int)r->fid->qid.path){
-	default:
-		respond(r, "fswrite: cannot happen");
-		break;
-	case Qrpc:
-		if(rpcwrite(r->fid->aux, r->ifcall.data, r->ifcall.count) < 0){
-			rerrstr(err, sizeof err);
-			respond(r, err);
-		}else{
-			r->ofcall.count = r->ifcall.count;
-			respond(r, nil);
-		}
-		break;
-	case Qneedkey:
-		strfn = needkeywrite;
-		goto string;
-	case Qctl:
-		strfn = ctlwrite;
-		goto string;
-	case Qconfirm:
-		strfn = confirmwrite;
-	string:
-		s = emalloc(r->ifcall.count+1);
-		memmove(s, r->ifcall.data, r->ifcall.count);
-		s[r->ifcall.count] = '\0';
-		ret = (*strfn)(s);
-		free(s);
-		if(ret < 0){
-			rerrstr(err, sizeof err);
-			respond(r, err);
-		}else{
-			r->ofcall.count = r->ifcall.count;
-			respond(r, nil);
-		}
-		break;
-	}
-}
-
-static void
-fsflush(Req *r)
-{
-	confirmflush(r);
-	logflush(r);
-}
-
-static void
-fsdestroyfid(Fid *fid)
-{
-	if(fid->qid.path == Qrpc && fid->aux){
-		convhangup(fid->aux);
-		convclose(fid->aux);
-	}
-}
-
-static Channel *creq;
-static Channel *cfid, *cfidr;
-
-static void
-fsreqthread(void *v)
-{
-	Req *r;
-
-	USED(v);
-
-	while((r = recvp(creq)) != nil){
-		switch(r->ifcall.type){
-		default:
-			respond(r, "bug in fsreqthread");
-			break;
-		case Topen:
-			fsopen(r);
-			break;
-		case Tread:
-			fsread(r);
-			break;
-		case Twrite:
-			fswrite(r);
-			break;
-		case Tflush:
-			fsflush(r);
-			break;
-		}
-	}
-}
-
-static void
-fsclunkthread(void *v)
-{
-	Fid *f;
-
-	USED(v);
-
-	while((f = recvp(cfid)) != nil){
-		fsdestroyfid(f);
-		sendp(cfidr, 0);
-	}
-}
-
-static void
-fsproc(void *v)
-{
-	USED(v);
-
-	threadcreate(fsreqthread, nil, STACK);
-	threadcreate(fsclunkthread, nil, STACK);
-	threadexits(nil);
-}
-
-static void
-fsattach(Req *r)
-{
-	r->fid->qid = mkqid(QTDIR, qtop);
-	r->ofcall.qid = r->fid->qid;
-	respond(r, nil);
-}
-
-static void
-fssend(Req *r)
-{
-	sendp(creq, r);
-}
-
-static void
-fssendclunk(Fid *f)
-{
-	sendp(cfid, f);
-	recvp(cfidr);
-}
-
-void
-fsstart(Srv *s)
-{
-	USED(s);
-
-	if(extrafactotumdir)
-		qtop = Qroot;
-	else
-		qtop = Qfactotum;
-	creq = chancreate(sizeof(Req*), 0);
-	cfid = chancreate(sizeof(Fid*), 0);
-	cfidr = chancreate(sizeof(Fid*), 0);
-	proccreate(fsproc, nil, STACK);
-}
-
-Srv fs = {
-.attach=	fsattach,
-.walk1=	fswalk1,
-.open=	fssend,
-.read=	fssend,
-.write=	fssend,
-.stat=	fsstat,
-.flush=	fssend,
-.destroyfid=	fssendclunk,
-.start=	fsstart,
-};
-
blob - 7293e54b63e77381e187e4e86d8db5cd28f9d9bd (mode 755)
blob + /dev/null
--- src/cmd/factotum/guide
+++ /dev/null
@@ -1,3 +0,0 @@
-kill 8.out|rc
-unmount /srv/factotum /mnt
-8.out
blob - 72f245d0e3d52b86bc84284a3eb4b088057173fb (mode 644)
blob + /dev/null
--- src/cmd/factotum/guide2
+++ /dev/null
@@ -1,6 +0,0 @@
-kill 8.out|rc
-unmount /mnt/factotum
-8.out -m /mnt/factotum
-cat /mnt/factotum/log &
-unmount /factotum
-bind 8.out /factotum
blob - 9023fed509e1bcd4e560efb778f077c322f35cdd (mode 644)
blob + /dev/null
--- src/cmd/factotum/key.c
+++ /dev/null
@@ -1,190 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-Ring ring;
-
-Key*
-keylookup(char *fmt, ...)
-{
-	int i;
-	Attr *a;
-	Key *k;
-	va_list arg;
-
-	va_start(arg, fmt);
-	a = parseattrfmtv(fmt, arg);
-	va_end(arg);
-
-	for(i=0; i<ring.nkey; i++){
-		k = ring.key[i];
-		if(matchattr(a, k->attr, k->privattr)){
-			k->ref++;
-			freeattr(a);
-			return k;
-		}
-	}
-	freeattr(a);
-	werrstr("no key found");
-	return nil;
-}
-
-Key*
-keyfetch(Conv *c, char *fmt, ...)
-{
-	int i, tag;
-	Attr *a;
-	Key *k;
-	va_list arg;
-
-	va_start(arg, fmt);
-	a = parseattrfmtv(fmt, arg);
-	va_end(arg);
-
-	tag = 0;
-
-	for(i=0; i<ring.nkey; i++){
-		k = ring.key[i];
-		if(tag < k->tag)
-			tag = k->tag;
-		if(matchattr(a, k->attr, k->privattr)){
-			k->ref++;
-			if(strfindattr(k->attr, "confirm") && confirmkey(c, k) != 1){
-				k->ref--;
-				continue;
-			}
-			freeattr(a);
-			return k;
-		}
-	}
-
-	if(needkey(c, a) < 0)
-		convneedkey(c, a);
-
-	for(i=0; i<ring.nkey; i++){
-		k = ring.key[i];
-		if(k->tag <= tag)
-			continue;
-		if(matchattr(a, k->attr, k->privattr)){
-			k->ref++;
-			if(strfindattr(k->attr, "confirm") && confirmkey(c, k) != 1){
-				k->ref--;
-				continue;
-			}
-			freeattr(a);
-			return k;
-		}
-	}
-	freeattr(a);
-	werrstr("no key found");
-	return nil;
-}
-
-static int taggen;
-
-void
-keyadd(Key *k)
-{
-	int i;
-
-	k->ref++;
-	k->tag = ++taggen;
-	for(i=0; i<ring.nkey; i++){
-		if(matchattr(k->attr, ring.key[i]->attr, nil)
-		&& matchattr(ring.key[i]->attr, k->attr, nil)){
-			keyclose(ring.key[i]);
-			ring.key[i] = k;
-			return;
-		}
-	}
-
-	ring.key = erealloc(ring.key, (ring.nkey+1)*sizeof(ring.key[0]));
-	ring.key[ring.nkey++] = k;
-}
-
-void
-keyclose(Key *k)
-{
-	if(k == nil)
-		return;
-
-	if(--k->ref > 0)
-		return;
-
-	if(k->proto->closekey)
-		(*k->proto->closekey)(k);
-
-	freeattr(k->attr);
-	freeattr(k->privattr);
-	free(k);
-}
-
-Key*
-keyreplace(Conv *c, Key *k, char *fmt, ...)
-{
-	Key *kk;
-	char *msg;
-	Attr *a, *b, *bp;
-	va_list arg;
-
-	va_start(arg, fmt);
-	msg = vsmprint(fmt, arg);
-	if(msg == nil)
-		sysfatal("out of memory");
-	va_end(arg);
-
-	/* replace prompted values with prompts */	
-	a = copyattr(k->attr);
-	bp = parseattr(k->proto->keyprompt);
-	for(b=bp; b; b=b->next){
-		a = delattr(a, b->name);
-		a = addattr(a, "%q?", b->name);
-	}
-	freeattr(bp);
-
-	if(badkey(c, k, msg, a) < 0)
-		convbadkey(c, k, msg, a);
-	kk = keylookup("%A", a);
-	freeattr(a);
-	keyclose(k);
-	if(kk == k){
-		keyclose(kk);
-		werrstr("%s", msg);
-		return nil;
-	}
-
-	if(strfindattr(kk->attr, "confirm")){
-		if(confirmkey(c, kk) != 1){
-			werrstr("key use not confirmed");
-			keyclose(kk);
-			return nil;
-		}
-	}
-	return kk;
-}
-
-void
-keyevict(Conv *c, Key *k, char *fmt, ...)
-{
-	char *msg;
-	Attr *a, *b, *bp;
-	va_list arg;
-
-	va_start(arg, fmt);
-	msg = vsmprint(fmt, arg);
-	if(msg == nil)
-		sysfatal("out of memory");
-	va_end(arg);
-
-	/* replace prompted values with prompts */	
-	a = copyattr(k->attr);
-	bp = parseattr(k->proto->keyprompt);
-	for(b=bp; b; b=b->next){
-		a = delattr(a, b->name);
-		a = addattr(a, "%q?", b->name);
-	}
-	freeattr(bp);
-
-	if(badkey(c, k, msg, nil) < 0)
-		convbadkey(c, k, msg, nil);
-	keyclose(k);
-}
blob - 6c2d69ddbf6a5d152737ebbb1ef680f8a42eab2f (mode 644)
blob + /dev/null
--- src/cmd/factotum/log.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-void
-lbkick(Logbuf *lb)
-{
-	char *s;
-	int n;
-	Req *r;
-
-	while(lb->wait && lb->rp != lb->wp){
-		r = lb->wait;
-		lb->wait = r->aux;
-		if(lb->wait == nil)
-			lb->waitlast = &lb->wait;
-		r->aux = nil;
-		if(r->ifcall.count < 5){
-			respond(r, "factotum: read request count too short");
-			continue;
-		}
-		s = lb->msg[lb->rp];
-		lb->msg[lb->rp] = nil;
-		if(++lb->rp == nelem(lb->msg))
-			lb->rp = 0;
-		n = r->ifcall.count;
-		if(n < strlen(s)+1+1){
-			memmove(r->ofcall.data, s, n-5);
-			n -= 5;
-			r->ofcall.data[n] = '\0';
-			/* look for first byte of UTF-8 sequence by skipping continuation bytes */
-			while(n>0 && (r->ofcall.data[--n]&0xC0)==0x80)
-				;
-			strcpy(r->ofcall.data+n, "...\n");
-		}else{
-			strcpy(r->ofcall.data, s);
-			strcat(r->ofcall.data, "\n");
-		}
-		r->ofcall.count = strlen(r->ofcall.data);
-		free(s);
-		respond(r, nil);
-	}
-}
-
-void
-lbread(Logbuf *lb, Req *r)
-{
-	if(lb->waitlast == nil)
-		lb->waitlast = &lb->wait;
-	*(lb->waitlast) = r;
-	lb->waitlast = (Req**)&r->aux;
-	r->aux = nil;
-	lbkick(lb);
-}
-
-void
-lbflush(Logbuf *lb, Req *r)
-{
-	Req **l;
-
-	for(l=&lb->wait; *l; l=(Req**)&(*l)->aux){
-		if(*l == r){
-			*l = r->aux;
-			r->aux = nil;
-			if(*l == nil)
-				lb->waitlast = l;
-			closereq(r);
-			break;
-		}
-	}
-}
-
-void
-lbappend(Logbuf *lb, char *fmt, ...)
-{
-	va_list arg;
-
-	va_start(arg, fmt);
-	lbvappend(lb, fmt, arg);
-	va_end(arg);
-}
-
-void
-lbvappend(Logbuf *lb, char *fmt, va_list arg)
-{
-	char *s;
-
-	s = smprint(fmt, arg);
-	if(s == nil)
-		sysfatal("out of memory");
-	if(lb->msg[lb->wp])
-		free(lb->msg[lb->wp]);
-	lb->msg[lb->wp] = s;
-	if(++lb->wp == nelem(lb->msg))
-		lb->wp = 0;
-	lbkick(lb);
-}
-
-Logbuf logbuf;
-
-void
-logread(Req *r)
-{
-	lbread(&logbuf, r);
-}
-
-void
-logflush(Req *r)
-{
-	lbflush(&logbuf, r);
-}
-
-void
-flog(char *fmt, ...)
-{
-	va_list arg;
-
-	va_start(arg, fmt);
-	lbvappend(&logbuf, fmt, arg);
-	va_end(arg);
-}
-
blob - dbcfa5fe67bd96986dd86fc1798e426e79f09b67 (mode 644)
blob + /dev/null
--- src/cmd/factotum/main.c
+++ /dev/null
@@ -1,185 +0,0 @@
-#include "std.h"
-#include "dat.h"
-#include <9pclient.h>
-
-int extrafactotumdir;
-int debug;
-int trysecstore = 1;
-char *factname = "factotum";
-char *service = "factotum";
-char *owner;
-char *authaddr;
-void gflag(char*);
-
-void
-usage(void)
-{
-	fprint(2, "usage: factotum [-Dd] [-a authaddr] [-m mtpt] [-s service]\n");
-	fprint(2, " or   factotum -g keypattern\n");
-	fprint(2, " or   factotum -g 'badkeyattr\\nmsg\\nkeypattern'\n");
-	threadexitsall("usage");
-}
-
-void
-threadmain(int argc, char *argv[])
-{
-	char *mtpt;
-	char err[ERRMAX];
-
-//	mtpt = "/mnt";
-	mtpt = nil;
-	owner = getuser();
-	quotefmtinstall();
-	fmtinstall('A', attrfmt);
-	fmtinstall('H', encodefmt);
-	fmtinstall('N', attrnamefmt);
-
-	if(argc == 3 && strcmp(argv[1], "-g") == 0){
-		gflag(argv[2]);
-		threadexitsall(nil);
-	}
-
-	ARGBEGIN{
-	default:
-		usage();
-	case 'D':
-		chatty9p++;
-		break;
-	case 'a':
-		authaddr = EARGF(usage());
-		break;
-	case 'g':
-		usage();
-	case 'm':
-		mtpt = EARGF(usage());
-		break;
-	case 's':
-		service = EARGF(usage());
-		break;
-	case 'n':
-		trysecstore = 0;
-		break;
-	case 'x':
-		extrafactotumdir = 1;
-		break;
-	}ARGEND
-
-	if(argc != 0)
-		usage();
-
-	if(trysecstore && havesecstore()){
-		while(secstorefetch() < 0){
-			rerrstr(err, sizeof err);
-			if(strcmp(err, "cancel") == 0)
-				break;
-			fprint(2, "secstorefetch: %r\n");
-			fprint(2, "Enter an empty password to quit.\n");
-		}
-	}
-	
-	threadpostmountsrv(&fs, service, mtpt, MBEFORE);
-	threadexits(nil);
-}
-
-/*
- *  prompt user for a key.  don't care about memory leaks, runs standalone
- */
-static Attr*
-promptforkey(int fd, char *params)
-{
-	char *v;
-	Attr *a, *attr;
-	char *def;
-
-	attr = _parseattr(params);
-	fprint(fd, "!adding key:");
-	for(a=attr; a; a=a->next)
-		if(a->type != AttrQuery && a->name[0] != '!')
-			fprint(fd, " %q=%q", a->name, a->val);
-	fprint(fd, "\n");
-
-	for(a=attr; a; a=a->next){
-		v = a->name;
-		if(a->type != AttrQuery || v[0]=='!')
-			continue;
-		def = nil;
-		if(strcmp(v, "user") == 0)
-			def = getuser();
-		a->val = readcons(v, def, 0);
-		if(a->val == nil)
-			sysfatal("user terminated key input");
-		a->type = AttrNameval;
-	}
-	for(a=attr; a; a=a->next){
-		v = a->name;
-		if(a->type != AttrQuery || v[0]!='!')
-			continue;
-		def = nil;
-		if(strcmp(v+1, "user") == 0)
-			def = getuser();
-		a->val = readcons(v+1, def, 1);
-		if(a->val == nil)
-			sysfatal("user terminated key input");
-		a->type = AttrNameval;
-	}
-	fprint(fd, "!\n");
-	close(fd);
-	return attr;
-}
-
-/*
- *  send a key to the mounted factotum
- */
-static int
-sendkey(Attr *attr)
-{
-	int rv;
-	char buf[1024];
-	CFid *fid;
-	
-	fid = nsopen("factotum", nil, "ctl", OWRITE);
-	if(fid == nil)
-		sysfatal("opening factotum/ctl: %r");
-	snprint(buf, sizeof buf, "key %A\n", attr);
-	rv = fswrite(fid, buf, strlen(buf));
-	fsclose(fid);
-	return rv;
-}
-
-static void
-askuser(int fd, char *params)
-{
-	Attr *attr;
-
-	attr = promptforkey(fd, params);
-	if(attr == nil)
-		sysfatal("no key supplied");
-	if(sendkey(attr) < 0)
-		sysfatal("sending key to factotum: %r");
-}
-
-void
-gflag(char *s)
-{
-	char *f[4];
-	int nf;
-	int fd;
-
-	if((fd = open("/dev/tty", ORDWR)) < 0)
-		sysfatal("open /dev/tty: %r");
-
-	nf = getfields(s, f, nelem(f), 0, "\n");
-	if(nf == 1){	/* needkey or old badkey */
-		fprint(fd, "\n");
-		askuser(fd, s);
-		threadexitsall(nil);
-	}
-	if(nf == 3){	/* new badkey */
-		fprint(fd, "\n");
-		fprint(fd, "!replace: %s\n", f[0]);
-		fprint(fd, "!because: %s\n", f[1]);
-		askuser(fd, f[2]);
-		threadexitsall(nil);
-	}
-	usage();
-}
blob - 1d48e6a4950c021a827d0cea68fca704f4efa975 (mode 644)
blob + /dev/null
--- src/cmd/factotum/mkfile
+++ /dev/null
@@ -1,33 +0,0 @@
-<$PLAN9/src/mkhdr
-
-TARG=factotum
-PROTO=\
-	apop.$O\
-	chap.$O\
-	p9any.$O\
-	p9sk1.$O\
-
-OFILES=\
-	$PROTO\
-	attr.$O\
-	confirm.$O\
-	conv.$O\
-	ctl.$O\
-	fs.$O\
-	key.$O\
-	log.$O\
-	main.$O\
-	plan9.$O\
-	proto.$O\
-	rpc.$O\
-	util.$O\
-	xio.$O\
-	secstore.$O\
-
-HFILES=dat.h
-
-<$PLAN9/src/mkone
-
-$O.test: test.$O
-	$LD -o $target $prereq
-
blob - 0006cad1833979af04d9ef5ff78e594510a881a2 (mode 644)
blob + /dev/null
--- src/cmd/factotum/p9any.c
+++ /dev/null
@@ -1,270 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-/*
- * p9any - protocol negotiator
- *
- * Protocol:
- *	S->C: v.2 proto@dom proto@dom proto@dom... NUL
- *	C->S: proto dom NUL
- *	[negotiated proto continues]
- */
-
-static Proto* okproto[] =
-{
-	&p9sk1,
-	nil,
-};
-
-static int
-rolecall(Role *r, char *name, Conv *c)
-{
-	for(; r->name; r++)
-		if(strcmp(r->name, name) == 0)
-			return (*r->fn)(c);
-	werrstr("unknown role");
-	return -1;
-}
-
-static int
-hasnul(void *v, int n)
-{
-	char *c;
-
-	c = v;
-	if(n > 0 && c[n-1] == '\0')
-		return n;
-	else
-		return AuthRpcMax;
-}
-
-static int
-p9anyserver(Conv *c)
-{
-	char *s, *dom;
-	int i, j, n, m, ret;
-	char *tok[3];
-	Attr *attr;
-	Key *k;
-
-	ret = -1;
-	s = estrdup("v.2");
-	n = 0;
-	attr = delattr(copyattr(c->attr), "proto");
-
-	for(i=0; i<ring.nkey; i++){
-		k = ring.key[i];
-		for(j=0; okproto[j]; j++)
-			if(k->proto == okproto[j]
-			&& (dom = strfindattr(k->attr, "dom")) != nil
-			&& matchattr(attr, k->attr, k->privattr)){
-				s = estrappend(s, " %s@%s", k->proto->name, dom);
-				n++;
-			}
-	}
-
-	if(n == 0){
-		werrstr("no valid keys");
-		goto out;
-	}
-
-	c->state = "write offer";
-	if(convwrite(c, s, strlen(s)+1) < 0)
-		goto out;
-	free(s);
-	s = nil;
-
-	c->state = "read choice";
-	if(convreadfn(c, hasnul, &s) < 0)
-		goto out;
-
-	m = tokenize(s, tok, nelem(tok));
-	if(m != 2){
-		werrstr("bad protocol message");
-		goto out;
-	}
-
-	for(i=0; okproto[i]; i++)
-		if(strcmp(okproto[i]->name, tok[0]) == 0)
-			break;
-	if(!okproto[i]){
-		werrstr("bad chosen protocol %q", tok[0]);
-		goto out;
-	}
-
-	c->state = "write ok";
-	if(convwrite(c, "OK\0", 3) < 0)
-		goto out;
-
-	c->state = "start choice";
-	attr = addattr(attr, "proto=%q dom=%q", tok[0], tok[1]);
-	free(c->attr);
-	c->attr = attr;
-	attr = nil;
-	c->proto = okproto[i];
-
-	if(rolecall(c->proto->roles, "server", c) < 0){
-		werrstr("%s: %r", tok[0]);
-		goto out;
-	}
-
-	ret = 0;
-	
-out:
-	free(s);
-	freeattr(attr);
-	return ret;
-}
-
-static int
-p9anyclient(Conv *c)
-{
-	char *s, **f, *tok[20], ok[3], *q, *user, *dom, *choice;
-	int i, n, ret, version;
-	Key *k;
-	Attr *attr;
-	Proto *p;
-
-	ret = -1;
-	s = nil;
-	k = nil;
-
-	user = strfindattr(c->attr, "user");
-	dom = strfindattr(c->attr, "dom");
-
-	/*
-	 * if the user is the factotum owner, any key will do.
-	 * if not, then if we have a speakfor key,
-	 * we will only vouch for the user's local identity.
-	 *
-	 * this logic is duplicated in p9sk1.c
-	 */
-	attr = delattr(copyattr(c->attr), "role");
-	attr = delattr(attr, "proto");
-	if(strcmp(c->sysuser, owner) == 0)
-		attr = addattr(attr, "role=client");
-	else if(user==nil || strcmp(c->sysuser, user)==0){
-		attr = delattr(attr, "user");
-		attr = addattr(attr, "role=speakfor");
-	}else{
-		werrstr("will not authenticate for %q as %q", c->sysuser, user);
-		goto out;
-	}
-
-	c->state = "read offer";
-	if(convreadfn(c, hasnul, &s) < 0)
-		goto out;
-
-	c->state = "look for keys";
-	n = tokenize(s, tok, nelem(tok));
-	f = tok;
-	version = 1;
-	if(n > 0 && memcmp(f[0], "v.", 2) == 0){
-		version = atoi(f[0]+2);
-		if(version != 2){
-			werrstr("unknown p9any version: %s", f[0]);
-			goto out;
-		}
-		f++;
-		n--;
-	}
-
-	/* look for keys that don't need confirmation */
-	for(i=0; i<n; i++){
-		if((q = strchr(f[i], '@')) == nil)
-			continue;
-		if(dom && strcmp(q+1, dom) != 0)
-			continue;
-		*q++ = '\0';
-		if((k = keylookup("%A proto=%q dom=%q", attr, f[i], q))
-		&& strfindattr(k->attr, "confirm") == nil)
-			goto found;
-		*--q = '@';
-	}
-
-	/* look for any keys at all */
-	for(i=0; i<n; i++){
-		if((q = strchr(f[i], '@')) == nil)
-			continue;
-		if(dom && strcmp(q+1, dom) != 0)
-			continue;
-		*q++ = '\0';
-		if(k = keylookup("%A proto=%q dom=%q", attr, f[i], q))
-			goto found;
-		*--q = '@';
-	}
-
-	/* ask for new keys */
-	c->state = "ask for keys";
-	for(i=0; i<n; i++){
-		if((q = strchr(f[i], '@')) == nil)
-			continue;
-		if(dom && strcmp(q+1, dom) != 0)
-			continue;
-		*q++ = '\0';
-		p = protolookup(f[i]);
-		if(p == nil || p->keyprompt == nil){
-			*--q = '@';
-			continue;
-		}
-		if(k = keyfetch(c, "%A proto=%q dom=%q %s", attr, f[i], q, p->keyprompt))
-			goto found;
-		*--q = '@';
-	}
-
-	/* nothing worked */
-	werrstr("unable to find common key");
-	goto out;
-
-found:
-	/* f[i] is the chosen protocol, q the chosen domain */
-	attr = addattr(attr, "proto=%q dom=%q", f[i], q);
-	c->state = "write choice";
-	
-	/* have a key: go for it */
-	choice = estrappend(nil, "%q %q", f[i], q);
-	if(convwrite(c, choice, strlen(choice)+1) < 0){
-		free(choice);
-		goto out;
-	}
-	free(choice);
-
-	if(version == 2){
-		c->state = "read ok";
-		if(convread(c, ok, 3) < 0 || memcmp(ok, "OK\0", 3) != 0)
-			goto out;
-	}
-
-	c->state = "start choice";
-	c->proto = protolookup(f[i]);
-	freeattr(c->attr);
-	c->attr = attr;
-	attr = nil;
-
-	if(rolecall(c->proto->roles, "client", c) < 0){
-		werrstr("%s: %r", c->proto->name);
-		goto out;
-	}
-
-	ret = 0;
-
-out:
-	keyclose(k);
-	freeattr(attr);
-	free(s);
-	return ret;
-}
-
-static Role
-p9anyroles[] = 
-{
-	"client",	p9anyclient,
-	"server",	p9anyserver,
-	0
-};
-
-Proto p9any = {
-.name=		"p9any",
-.roles=		p9anyroles,
-};
-
blob - 7f53e44782057f8f4aa67ba923ab8530b8490e38 (mode 644)
blob + /dev/null
--- src/cmd/factotum/p9cr.c
+++ /dev/null
@@ -1,545 +0,0 @@
-/*
- * p9cr, vnc - one-sided challenge/response authentication
- *
- * Protocol:
- *
- *	C -> S: user
- *	S -> C: challenge
- *	C -> S: response
- *	S -> C: ok or bad
- *
- * Note that this is the protocol between factotum and the local
- * program, not between the two factotums.  The information 
- * exchanged here is wrapped in other protocols by the local
- * programs.
- */
-
-#include "std.h"
-#include "dat.h"
-
-static int
-p9crcheck(Key *k)
-{
-	if(!strfindattr(k->attr, "user") || !strfindattr(k->privattr, "!password")){
-		werrstr("need user and !password attributes");
-		return -1;
-	}
-	return 0;
-}
-
-static int
-p9crclient(Conv *c)
-{
-	char *chal, *pw, *res, *user;
-	int astype, nchal, npw, ntry, ret;
-	uchar resp[MD5dlen];
-	Attr *attr;
-	DigestState *ds;
-	Key *k;
-	
-	chal = nil;
-	k = nil;
-	res = nil;
-	ret = -1;
-	attr = c->attr;
-
-	if(c->proto == &p9cr){
-		astype = AuthChal;
-		challen = NETCHLEN;
-	}else if(c->proto == &vnc){
-		astype = AuthVnc;
-		challen = MAXCHAL;
-	}else{
-		werrstr("bad proto");
-		goto out;
-	}
-
-	c->state = "find key";
-	k = keyfetch(c, "%A %s", attr, c->proto->keyprompt);
-	if(k == nil)
-		goto out;
-
-	for(ntry=1;; ntry++){
-		if(c->attr != attr)
-			freeattr(c->attr);
-		c->attr = addattrs(copyattr(attr), k->attr);
-		if((pw = strfindattr(k->privattr, "!password")) == nil){
-			werrstr("key has no !password (cannot happen)");
-			goto out;
-		}
-		npw = strlen(pw);
-
-		if((user = strfindattr(k->attr, "user")) == nil){
-			werrstr("key has no user (cannot happen)");
-			goto out;
-		}
-
-		if(convprint(c, "%s", user) < 0)
-			goto out;
-
-		if(convreadm(c, &chal) < 0)
-			goto out;
-
-		if((nresp = (*response)(chal, resp)) < 0)
-			goto out;
-
-		if(convwrite(c, resp, nresp) < 0)
-			goto out;
-
-		if(convreadm(c, &res) < 0)
-			goto out;
-
-		if(strcmp(res, "ok") == 0)
-			break;
-
-		if((k = keyreplace(c, k, "%s", res)) == nil){
-			c->state = "auth failed";
-			werrstr("%s", res);
-			goto out;
-		}
-	}
-
-	werrstr("succeeded");
-	ret = 0;
-
-out:
-	keyclose(k);
-	free(chal);
-	if(c->attr != attr)
-		freeattr(attr);
-	return ret;
-}
-
-static int
-p9crserver(Conv *c)
-{
-	char chal[APOPCHALLEN], *user, *resp;
-	ServerState s;
-	int astype, ret;
-	Attr *a;
-
-	ret = -1;
-	user = nil;
-	resp = nil;
-	memset(&s, 0, sizeof s);
-	s.asfd = -1;
-
-	if(c->proto == &apop)
-		astype = AuthApop;
-	else if(c->proto == &cram)
-		astype = AuthCram;
-	else{
-		werrstr("bad proto");
-		goto out;
-	}
-
-	c->state = "find key";
-	if((s.k = plan9authkey(c->attr)) == nil)
-		goto out;
-
-	a = copyattr(s.k->attr);
-	a = delattr(a, "proto");
-	c->attr = addattrs(c->attr, a);
-	freeattr(a);
-
-	c->state = "authdial";
-	s.hostid = strfindattr(s.k->attr, "user");
-	s.dom = strfindattr(s.k->attr, "dom");
-	if((s.asfd = xioauthdial(nil, s.dom)) < 0){
-		werrstr("authdial %s: %r", s.dom);
-		goto out;
-	}
-
-	c->state = "authchal";
-	if(p9crchal(&s, astype, chal) < 0)
-		goto out;
-
-	c->state = "write challenge";
-	if(convprint(c, "%s", chal) < 0)
-		goto out;
-
-	for(;;){
-		c->state = "read user";
-		if(convreadm(c, &user) < 0)
-			goto out;
-
-		c->state = "read response";
-		if(convreadm(c, &resp) < 0)
-			goto out;
-
-		c->state = "authwrite";
-		switch(apopresp(&s, user, resp)){
-		case -1:
-			goto out;
-		case 0:
-			c->state = "write status";
-			if(convprint(c, "bad authentication failed") < 0)
-				goto out;
-			break;
-		case 1:
-			c->state = "write status";
-			if(convprint(c, "ok") < 0)
-				goto out;
-			goto ok;
-		}
-		free(user);
-		free(resp);
-		user = nil;
-		resp = nil;
-	}
-
-ok:
-	ret = 0;
-	c->attr = addcap(c->attr, c->sysuser, &s.t);
-
-out:
-	keyclose(s.k);
-	free(user);
-	free(resp);
-//	xioclose(s.asfd);
-	return ret;
-}
-
-enum
-{
-	MAXCHAL = 64,
-};
-
-typedef struct State State;
-struct State
-{
-	Key	*key;
-	int	astype;
-	int	asfd;
-	Ticket	t;
-	Ticketreq tr;
-	char	chal[MAXCHAL];
-	int	challen;
-	char	resp[MAXCHAL];
-	int	resplen;
-};
-
-enum
-{
-	CNeedChal,
-	CHaveResp,
-
-	SHaveChal,
-	SNeedResp,
-
-	Maxphase,
-};
-
-static char *phasenames[Maxphase] =
-{
-[CNeedChal]	"CNeedChal",
-[CHaveResp]	"CHaveResp",
-
-[SHaveChal]	"SHaveChal",
-[SNeedResp]	"SNeedResp",
-};
-
-static void
-p9crclose(Fsstate *fss)
-{
-	State *s;
-
-	s = fss->ps;
-	if(s->asfd >= 0){
-		close(s->asfd);
-		s->asfd = -1;
-	}
-	free(s);
-}
-
-static int getchal(State*, Fsstate*);
-
-static int
-p9crinit(Proto *p, Fsstate *fss)
-{
-	int iscli, ret;
-	char *user;
-	State *s;
-	Attr *attr;
-
-	if((iscli = isclient(_str_findattr(fss->attr, "role"))) < 0)
-		return failure(fss, nil);
-	
-	s = emalloc(sizeof(*s));
-	s->asfd = -1;
-	if(p == &p9cr){
-		s->astype = AuthChal;
-		s->challen = NETCHLEN;
-	}else if(p == &vnc){
-		s->astype = AuthVNC;
-		s->challen = Maxchal;
-	}else
-		abort();
-
-	if(iscli){
-		fss->phase = CNeedChal;
-		if(p == &p9cr)
-			attr = setattr(_copyattr(fss->attr), "proto=p9sk1");
-		else
-			attr = nil;
-		ret = findkey(&s->key, fss, Kuser, 0, attr ? attr : fss->attr,
-			"role=client %s", p->keyprompt);
-		_freeattr(attr);
-		if(ret != RpcOk){
-			free(s);
-			return ret;
-		}
-		fss->ps = s;
-	}else{
-		if((ret = findp9authkey(&s->key, fss)) != RpcOk){
-			free(s);
-			return ret;
-		}
-		if((user = _str_findattr(fss->attr, "user")) == nil){
-			free(s);
-			return failure(fss, "no user name specified in start msg");
-		}
-		if(strlen(user) >= sizeof s->tr.uid){
-			free(s);
-			return failure(fss, "user name too long");
-		}
-		fss->ps = s;
-		strcpy(s->tr.uid, user);
-		ret = getchal(s, fss);
-		if(ret != RpcOk){
-			p9crclose(fss);	/* frees s */
-			fss->ps = nil;
-		}
-	}
-	fss->phasename = phasenames;
-	fss->maxphase = Maxphase;
-	return ret;
-}
-
-static int
-p9crread(Fsstate *fss, void *va, uint *n)
-{
-	int m;
-	State *s;
-
-	s = fss->ps;
-	switch(fss->phase){
-	default:
-		return phaseerror(fss, "read");
-
-	case CHaveResp:
-		if(s->resplen < *n)
-			*n = s->resplen;
-		memmove(va, s->resp, *n);
-		fss->phase = Established;
-		return RpcOk;
-
-	case SHaveChal:
-		if(s->astype == AuthChal)
-			m = strlen(s->chal);	/* ascii string */
-		else
-			m = s->challen;		/* fixed length binary */
-		if(m > *n)
-			return toosmall(fss, m);
-		*n = m;
-		memmove(va, s->chal, m);
-		fss->phase = SNeedResp;
-		return RpcOk;
-	}
-}
-
-static int
-p9response(Fsstate *fss, State *s)
-{
-	char key[DESKEYLEN];
-	uchar buf[8];
-	ulong chal;
-	char *pw;
-
-	pw = _str_findattr(s->key->privattr, "!password");
-	if(pw == nil)
-		return failure(fss, "vncresponse cannot happen");
-	passtokey(key, pw);
-	memset(buf, 0, 8);
-	sprint((char*)buf, "%d", atoi(s->chal));
-	if(encrypt(key, buf, 8) < 0)
-		return failure(fss, "can't encrypt response");
-	chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3];
-	s->resplen = snprint(s->resp, sizeof s->resp, "%.8lux", chal);
-	return RpcOk;
-}
-
-static uchar tab[256];
-
-/* VNC reverses the bits of each byte before using as a des key */
-static void
-mktab(void)
-{
-	int i, j, k;
-	static int once;
-
-	if(once)
-		return;
-	once = 1;
-
-	for(i=0; i<256; i++) {
-		j=i;
-		tab[i] = 0;
-		for(k=0; k<8; k++) {
-			tab[i] = (tab[i]<<1) | (j&1);
-			j >>= 1;
-		}
-	}
-}
-
-static int
-vncaddkey(Key *k)
-{
-	uchar *p;
-	char *s;
-
-	k->priv = emalloc(8+1);
-	if(s = _str_findattr(k->privattr, "!password")){
-		mktab();
-		memset(k->priv, 0, 8+1);
-		strncpy((char*)k->priv, s, 8);
-		for(p=k->priv; *p; p++)
-			*p = tab[*p];
-	}else{
-		werrstr("no key data");
-		return -1;
-	}
-	return replacekey(k);
-}
-
-static void
-vncclosekey(Key *k)
-{
-	free(k->priv);
-}
-
-static int
-vncresponse(Fsstate*, State *s)
-{
-	DESstate des;
-
-	memmove(s->resp, s->chal, sizeof s->chal);
-	setupDESstate(&des, s->key->priv, nil);
-	desECBencrypt((uchar*)s->resp, s->challen, &des);
-	s->resplen = s->challen;
-	return RpcOk;
-}
-
-static int
-p9crwrite(Fsstate *fss, void *va, uint n)
-{
-	char tbuf[TICKETLEN+AUTHENTLEN];
-	State *s;
-	char *data = va;
-	Authenticator a;
-	char resp[Maxchal];
-	int ret;
-
-	s = fss->ps;
-	switch(fss->phase){
-	default:
-		return phaseerror(fss, "write");
-
-	case CNeedChal:
-		if(n >= sizeof(s->chal))
-			return failure(fss, Ebadarg);
-		memset(s->chal, 0, sizeof s->chal);
-		memmove(s->chal, data, n);
-		s->challen = n;
-
-		if(s->astype == AuthChal)
-			ret = p9response(fss, s);
-		else
-			ret = vncresponse(fss, s);
-		if(ret != RpcOk)
-			return ret;
-		fss->phase = CHaveResp;
-		return RpcOk;
-
-	case SNeedResp:
-		/* send response to auth server and get ticket */
-		if(n > sizeof(resp))
-			return failure(fss, Ebadarg);
-		memset(resp, 0, sizeof resp);
-		memmove(resp, data, n);
-		if(write(s->asfd, resp, s->challen) != s->challen)
-			return failure(fss, Easproto);
-
-		/* get ticket plus authenticator from auth server */
-		if(_asrdresp(s->asfd, tbuf, TICKETLEN+AUTHENTLEN) < 0)
-			return failure(fss, nil);
-
-		/* check ticket */
-		convM2T(tbuf, &s->t, s->key->priv);
-		if(s->t.num != AuthTs
-		|| memcmp(s->t.chal, s->tr.chal, sizeof(s->t.chal)) != 0)
-			return failure(fss, Easproto);
-		convM2A(tbuf+TICKETLEN, &a, s->t.key);
-		if(a.num != AuthAc
-		|| memcmp(a.chal, s->tr.chal, sizeof(a.chal)) != 0
-		|| a.id != 0)
-			return failure(fss, Easproto);
-
-		fss->haveai = 1;
-		fss->ai.cuid = s->t.cuid;
-		fss->ai.suid = s->t.suid;
-		fss->ai.nsecret = 0;
-		fss->ai.secret = nil;
-		fss->phase = Established;
-		return RpcOk;
-	}
-}
-
-static int
-getchal(State *s, Fsstate *fss)
-{
-	char trbuf[TICKREQLEN];
-	int n;
-
-	safecpy(s->tr.hostid, _str_findattr(s->key->attr, "user"), sizeof(s->tr.hostid));
-	safecpy(s->tr.authdom, _str_findattr(s->key->attr, "dom"), sizeof(s->tr.authdom));
-	s->tr.type = s->astype;
-	convTR2M(&s->tr, trbuf);
-
-	/* get challenge from auth server */
-	s->asfd = _authdial(nil, _str_findattr(s->key->attr, "dom"));
-	if(s->asfd < 0)
-		return failure(fss, Easproto);
-	if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN)
-		return failure(fss, Easproto);
-	n = _asrdresp(s->asfd, s->chal, s->challen);
-	if(n <= 0){
-		if(n == 0)
-			werrstr("_asrdresp short read");
-		return failure(fss, nil);
-	}
-	s->challen = n;
-	fss->phase = SHaveChal;
-	return RpcOk;
-}
-
-Proto p9cr =
-{
-.name=		"p9cr",
-.init=		p9crinit,
-.write=		p9crwrite,
-.read=		p9crread,
-.close=		p9crclose,
-.keyprompt=	"user? !password?",
-};
-
-Proto vnc =
-{
-.name=		"vnc",
-.init=		p9crinit,
-.write=		p9crwrite,
-.read=		p9crread,
-.close=		p9crclose,
-.keyprompt=	"!password?",
-.addkey=	vncaddkey,
-};
blob - 2828e708c879be1d6abcec0c76cc1e047606ef95 (mode 644)
blob + /dev/null
--- src/cmd/factotum/p9sk1.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * p9sk1, p9sk2 - Plan 9 secret (private) key authentication.
- * p9sk2 is an incomplete flawed variant of p9sk1.
- *
- * Client protocol:
- *	write challenge[challen]	(p9sk1 only)
- *	read tickreq[tickreqlen]
- *	write ticket[ticketlen]
- *	read authenticator[authentlen]
- *
- * Server protocol:
- * 	read challenge[challen]	(p9sk1 only)
- *	write tickreq[tickreqlen]
- *	read ticket[ticketlen]
- *	write authenticator[authentlen]
- */
-
-#include "std.h"
-#include "dat.h"
-
-static int gettickets(Ticketreq*, char*, Key*);
-
-#define max(a, b) ((a) > (b) ? (a) : (b))
-enum
-{
-	MAXAUTH = max(TICKREQLEN, TICKETLEN+max(TICKETLEN, AUTHENTLEN))
-};
-
-static int
-p9skclient(Conv *c)
-{
-	char *user;
-	char cchal[CHALLEN];
-	uchar secret[8];
-	char buf[MAXAUTH];
-	int speakfor, ret;
-	Attr *a;
-	Authenticator au;
-	Key *k;
-	Ticket t;
-	Ticketreq tr;
-
-	ret = -1;
-	a = nil;
-	k = nil;
-
-	/* p9sk1: send client challenge */
-	if(c->proto == &p9sk1){
-		c->state = "write challenge";
-		memrandom(cchal, CHALLEN);
-		if(convwrite(c, cchal, CHALLEN) < 0)
-			goto out;
-	}
-
-	/* read ticket request */
-	c->state = "read tickreq";
-	if(convread(c, buf, TICKREQLEN) < 0)
-		goto out;
-	convM2TR(buf, &tr);
-
-	/* p9sk2: use server challenge as client challenge */
-	if(c->proto == &p9sk2)
-		memmove(cchal, tr.chal, CHALLEN);
-
-	/*
-	 * find a key.
-	 *
-	 * if the user is the factotum owner, any key will do.
-	 * if not, then if we have a speakfor key,
-	 * we will only vouch for the user's local identity.
-	 *
-	 * this logic is duplicated in p9any.c
-	 */
-	user = strfindattr(c->attr, "user");
-	a = delattr(copyattr(c->attr), "role");
-	a = addattr(a, "proto=p9sk1");
-
-	if(strcmp(c->sysuser, owner) == 0){
-		speakfor = 0;
-		a = addattr(a, "proto=p9sk1 user? dom=%q", tr.authdom);
-	}else if(user==nil || strcmp(c->sysuser, user)==0){
-		speakfor = 1;
-		a = delattr(a, "user");
-		a = addattr(a, "proto=p9sk1 user? dom=%q role=speakfor", tr.authdom);
-	}else{
-		werrstr("will not authenticate for %q as %q", c->sysuser, user);
-		goto out;
-	}
-
-	for(;;){
-		c->state = "find key";
-		k = keyfetch(c, "%A", a);
-		if(k == nil)
-			goto out;
-		
-		/* relay ticket request to auth server, get tickets */
-		strcpy(tr.hostid, strfindattr(k->attr, "user"));
-		if(speakfor)
-			strcpy(tr.uid, c->sysuser);
-		else
-			strcpy(tr.uid, tr.hostid);
-
-		c->state = "get tickets";
-		if(gettickets(&tr, buf, k) < 0)
-			goto out;
-
-		convM2T(buf, &t, k->priv);
-		if(t.num == AuthTc)
-			break;
-
-		/* we don't agree with the auth server about the key; try again */
-		c->state = "replace key";
-		if((k = keyreplace(c, k, "key mismatch with auth server")) == nil){
-			werrstr("key mismatch with auth server");
-			goto out;
-		}
-	}
-
-	/* send second ticket and authenticator to server */
-	c->state = "write ticket+auth";
-	memmove(buf, buf+TICKETLEN, TICKETLEN);
-	au.num = AuthAc;
-	memmove(au.chal, tr.chal, CHALLEN);
-	au.id = 0;
-	convA2M(&au, buf+TICKETLEN, t.key);
-	if(convwrite(c, buf, TICKETLEN+AUTHENTLEN) < 0)
-		goto out;
-
-	/* read authenticator from server */
-	c->state = "read auth";
-	if(convread(c, buf, AUTHENTLEN) < 0)
-		goto out;
-	convM2A(buf, &au, t.key);
-	if(au.num != AuthAs || memcmp(au.chal, cchal, CHALLEN) != 0 || au.id != 0){
-		werrstr("server lies through his teeth");
-		goto out;
-	}
-
-	/* success */
-	c->attr = addcap(c->attr, c->sysuser, &t);
-	des56to64((uchar*)t.key, secret);
-	c->attr = addattr(c->attr, "secret=%.8H", secret);
-	ret = 0;
-
-out:
-	freeattr(a);
-	keyclose(k);
-	return ret;
-}
-
-static int
-p9skserver(Conv *c)
-{
-	char cchal[CHALLEN], buf[MAXAUTH];
-	uchar secret[8];
-	int ret;
-	Attr *a;
-	Authenticator au;
-	Key *k;
-	Ticketreq tr;
-	Ticket t;
-
-	ret = -1;
-
-	a = addattr(copyattr(c->attr), "user? dom?");
-	a = addattr(a, "user? dom? proto=p9sk1");
-	if((k = keyfetch(c, "%A", a)) == nil)
-		goto out;
-
-	/* p9sk1: read client challenge */
-	if(c->proto == &p9sk1){
-		if(convread(c, cchal, CHALLEN) < 0)
-			goto out;
-	}
-
-	/* send ticket request */
-	memset(&tr, 0, sizeof tr);
-	tr.type = AuthTreq;
-	strcpy(tr.authid, strfindattr(k->attr, "user"));
-	strcpy(tr.authdom, strfindattr(k->attr, "dom"));
-	memrandom(tr.chal, sizeof tr.chal);
-	convTR2M(&tr, buf);
-	if(convwrite(c, buf, TICKREQLEN) < 0)
-		goto out;
-
-	/* p9sk2: use server challenge as client challenge */
-	if(c->proto == &p9sk2)
-		memmove(cchal, tr.chal, sizeof tr.chal);
-
-	/* read ticket+authenticator */
-	if(convread(c, buf, TICKETLEN+AUTHENTLEN) < 0)
-		goto out;
-
-	convM2T(buf, &t, k->priv);
-	if(t.num != AuthTs || memcmp(t.chal, tr.chal, CHALLEN) != 0){
-		/* BUG badkey */
-		werrstr("key mismatch with auth server");
-		goto out;
-	}
-
-	convM2A(buf+TICKETLEN, &au, t.key);
-	if(au.num != AuthAc || memcmp(au.chal, tr.chal, CHALLEN) != 0 || au.id != 0){
-		werrstr("client lies through his teeth");
-		goto out;
-	}
-
-	/* send authenticator */
-	au.num = AuthAs;
-	memmove(au.chal, cchal, CHALLEN);
-	convA2M(&au, buf, t.key);
-	if(convwrite(c, buf, AUTHENTLEN) < 0)
-		goto out;
-
-	/* success */
-	c->attr = addcap(c->attr, c->sysuser, &t);
-	des56to64((uchar*)t.key, secret);
-	c->attr = addattr(c->attr, "secret=%.8H", secret);
-	ret = 0;
-
-out:
-	freeattr(a);
-	keyclose(k);
-	return ret;
-}
-
-int
-_asgetticket(int fd, char *trbuf, char *tbuf)
-{
-	if(write(fd, trbuf, TICKREQLEN) < 0){
-		close(fd);
-		return -1;
-	}
-	return _asrdresp(fd, tbuf, 2*TICKETLEN);
-}
-static int
-getastickets(Ticketreq *tr, char *buf)
-{
-	int asfd;
-	int ret;
-
-	if((asfd = xioauthdial(nil, tr->authdom)) < 0)
-		return -1;
-	convTR2M(tr, buf);
-	ret = xioasgetticket(asfd, buf, buf);
-	xioclose(asfd);
-	return ret;
-}
-
-static int
-mktickets(Ticketreq *tr, char *buf, Key *k)
-{
-	Ticket t;
-
-	if(strcmp(tr->authid, tr->hostid) != 0)
-		return -1;
-
-	memset(&t, 0, sizeof t);
-	memmove(t.chal, tr->chal, CHALLEN);
-	strcpy(t.cuid, tr->uid);
-	strcpy(t.suid, tr->uid);
-	memrandom(t.key, DESKEYLEN);
-	t.num = AuthTc;
-	convT2M(&t, buf, k->priv);
-	t.num = AuthTs;
-	convT2M(&t, buf+TICKETLEN, k->priv);
-	return 0;
-}
-
-static int
-gettickets(Ticketreq *tr, char *buf, Key *k)
-{
-	if(getastickets(tr, buf) == 0)
-		return 0;
-	if(mktickets(tr, buf, k) == 0)
-		return 0;
-	werrstr("gettickets: %r");
-	return -1;
-}
-
-static int
-p9sk1check(Key *k)
-{
-	char *user, *dom, *pass;
-	Ticketreq tr;
-
-	user = strfindattr(k->attr, "user");
-	dom = strfindattr(k->attr, "dom");
-	if(user==nil || dom==nil){
-		werrstr("need user and dom attributes");
-		return -1;
-	}
-	if(strlen(user) >= sizeof tr.authid){
-		werrstr("user name too long");
-		return -1;
-	}
-	if(strlen(dom) >= sizeof tr.authdom){
-		werrstr("auth dom name too long");
-		return -1;
-	}
-
-	k->priv = emalloc(DESKEYLEN);
-	if(pass = strfindattr(k->privattr, "!password"))
-		passtokey(k->priv, pass);
-	else if(pass = strfindattr(k->privattr, "!hex")){
-		if(hexparse(pass, k->priv, 7) < 0){
-			werrstr("malformed !hex key data");
-			return -1;
-		}
-	}else{
-		werrstr("need !password or !hex attribute");
-		return -1;
-	}
-
-	return 0;
-}
-
-static void
-p9sk1close(Key *k)
-{
-	free(k->priv);
-	k->priv = nil;
-}
-
-static Role
-p9sk1roles[] = 
-{
-	"client",	p9skclient,
-	"server",	p9skserver,
-	0
-};
-
-static Role
-p9sk2roles[] = 
-{
-	"client",	p9skclient,
-	"server",	p9skserver,
-	0
-};
-
-Proto p9sk1 = {
-.name=		"p9sk1",
-.roles=		p9sk1roles,
-.checkkey=	p9sk1check,
-.closekey=	p9sk1close,
-.keyprompt=	"user? dom? !password?",
-};
-
-Proto p9sk2 = {
-.name=		"p9sk2",
-.roles=		p9sk2roles,
-};
-
blob - b3d4cb6ad2c87b9b7755d314e63f41bebde4c72a (mode 644)
blob + /dev/null
--- src/cmd/factotum/pass.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * This is just a repository for a password.
- * We don't want to encourage this, there's
- * no server side.
- */
-
-#include "dat.h"
-
-typedef struct State State;
-struct State 
-{
-	Key *key;
-};
-
-enum
-{
-	HavePass,
-	Maxphase,
-};
-
-static char *phasenames[Maxphase] =
-{
-[HavePass]	"HavePass",
-};
-
-static int
-passinit(Proto *p, Fsstate *fss)
-{
-	int ask;
-	Key *k;
-	State *s;
-
-	k = findkey(fss, Kuser, &ask, 0, fss->attr, "%s", p->keyprompt);
-	if(k == nil){
-		if(ask)
-			return RpcNeedkey;
-		return failure(fss, nil);
-	}
-	setattrs(fss->attr, k->attr);
-	s = emalloc(sizeof(*s));
-	s->key = k;
-	fss->ps = s;
-	return RpcOk;
-}
-
-static void
-passclose(Fsstate *fss)
-{
-	State *s;
-
-	s = fss->ps;
-	if(s->key)
-		closekey(s->key);
-	free(s);
-}
-
-static int
-passread(Fsstate *fss, void *va, uint *n)
-{
-	int m;
-	char buf[500];
-	char *pass, *user;
-	State *s;
-
-	s = fss->ps;
-	switch(fss->phase){
-	default:
-		return phaseerror(fss, "read");
-
-	case HavePass:
-		user = strfindattr(s->key->attr, "user");
-		pass = strfindattr(s->key->privattr, "!password");
-		if(user==nil || pass==nil)
-			return failure(fss, "passread cannot happen");
-		snprint(buf, sizeof buf, "%q %q", user, pass);
-		m = strlen(buf);
-		if(m > *n)
-			return toosmall(fss, m);
-		*n = m;
-		memmove(va, buf, m);
-		return RpcOk;
-	}
-}
-
-static int
-passwrite(Fsstate *fss, void*, uint)
-{
-	return phaseerror(fss, "write");
-}
-
-Proto pass =
-{
-.name=		"pass",
-.init=		passinit,
-.write=		passwrite,
-.read=		passread,
-.close=		passclose,
-.addkey=		replacekey,
-.keyprompt=	"user? !password?",
-};
blob - 0b6bb601731289951ac250f8f4c7ff466c78f065 (mode 644)
blob + /dev/null
--- src/cmd/factotum/plan9.c
+++ /dev/null
@@ -1,45 +0,0 @@
-#include "std.h"
-#include "dat.h"
-#include <bio.h>
-
-int
-memrandom(void *p, int n)
-{
-	uchar *cp;
-
-	for(cp = (uchar*)p; n > 0; n--)
-		*cp++ = fastrand();
-	return 0;
-}
-
-Attr*
-addcap(Attr *a, char *from, Ticket *t)
-{
-	return addattr(a, "cuid=%q suid=%q cap=''", t->cuid, t->suid);
-}
-
-int
-_authdial(char *net, char *authdom)
-{
-	return authdial(net, authdom);
-}
-
-Key*
-plan9authkey(Attr *a)
-{
-	char *dom;
-	Key *k;
-
-	/*
-	 * The only important part of a is dom.
-	 * We don't care, for example, about user name.
-	 */
-	dom = strfindattr(a, "dom");
-	if(dom)
-		k = keylookup("proto=p9sk1 role=server user? dom=%q", dom);
-	else
-		k = keylookup("proto=p9sk1 role=server user? dom?");
-	if(k == nil)
-		werrstr("could not find plan 9 auth key dom %q", dom);
-	return k;
-}
blob - e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 (mode 644)
blob + /dev/null
blob - 64bb2e3411fe666d9858d2dd3e9cf2acccb4fe2a (mode 644)
blob + /dev/null
--- src/cmd/factotum/proto.c
+++ /dev/null
@@ -1,22 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-Proto *prototab[] = {
-	&apop,
-	&cram,
-	&p9any,
-	&p9sk1,
-	&p9sk2,
-	nil,
-};
-
-Proto*
-protolookup(char *name)
-{
-	int i;
-
-	for(i=0; prototab[i]; i++)
-		if(strcmp(prototab[i]->name, name) == 0)
-			return prototab[i];
-	return nil;
-}
blob - e9c163aa4eff3753961142f1b20fd319388158fc (mode 644)
blob + /dev/null
--- src/cmd/factotum/rpc.c
+++ /dev/null
@@ -1,315 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-/*
- * Factotum RPC
- *
- * Must be paired write/read cycles on /mnt/factotum/rpc.
- * The format of a request is verb, single space, data.
- * Data format is verb-dependent; in particular, it can be binary.
- * The format of a response is the same.  The write only sets up
- * the RPC.  The read tries to execute it.  If the /mnt/factotum/key
- * file is open, we ask for new keys using that instead of returning
- * an error in the RPC.  This means the read blocks.
- * Textual arguments are parsed with tokenize, so rc-style quoting
- * rules apply.
- *
- * Only authentication protocol messages go here.  Configuration
- * is still via ctl (below).
- *
- * Request RPCs are:
- *	start attrs - initializes protocol for authentication, can fail.
- *		returns "ok read" or "ok write" on success.
- *	read - execute protocol read
- *	write - execute protocol write
- *	authinfo - if the protocol is finished, return the AI if any
- *	attr - return protocol information
- * Return values are:
- *	error message - an error happened.
- *	ok [data] - success, possible data is request dependent.
- *	needkey attrs - request aborted, get me this key and try again
- *	badkey attrs - request aborted, this key might be bad
- *	done [haveai] - authentication is done [haveai: you can get an ai with authinfo]
- */
-
-char *rpcname[] = 
-{
-	"unknown",
-	"authinfo",
-	"attr",
-	"read",
-	"start",
-	"write",
-};
-
-static int
-classify(char *s)
-{
-	int i;
-
-	for(i=1; i<nelem(rpcname); i++)
-		if(strcmp(s, rpcname[i]) == 0)
-			return i;
-	return RpcUnknown;
-}
-
-int
-rpcwrite(Conv *c, void *data, int count)
-{
-	int op;
-	uchar *p;
-
-	if(count >= MaxRpc){
-		werrstr("rpc too large");
-		return -1;
-	}
-
-	/* cancel any current rpc */
-	c->rpc.op = RpcUnknown;
-	c->nreply = 0;
-
-	/* parse new rpc */
-	memmove(c->rpcbuf, data, count);
-	c->rpcbuf[count] = 0;
-	if(p = (uchar*)strchr((char*)c->rpcbuf, ' ')){
-		*p++ = '\0';
-		c->rpc.data = p;
-		c->rpc.count = count - (p - (uchar*)c->rpcbuf);
-	}else{
-		c->rpc.data = "";
-		c->rpc.count = 0;
-	}
-	op = classify(c->rpcbuf);
-	if(op == RpcUnknown){
-		werrstr("bad rpc verb: %s", c->rpcbuf);
-		return -1;
-	}
-
-	c->rpc.op = op;
-	return 0;
-}
-
-void
-convthread(void *v)
-{
-	Conv *c;
-	Attr *a;
-	char *role, *proto;
-	Proto *p;
-	Role *r;
-
-	c = v;
-	a = parseattr(c->rpc.data);
-	if(a == nil){
-		werrstr("empty attr");
-		goto out;
-	}
-	c->attr = a;
-	proto = strfindattr(a, "proto");
-	role = strfindattr(a, "role");
-
-	if(proto == nil){
-		werrstr("no proto in attrs");
-		goto out;
-	}
-	if(role == nil){
-		werrstr("no role in attrs");
-		goto out;
-	}
-
-	p = protolookup(proto);
-	if(p == nil){
-		werrstr("unknown proto %s", proto);
-		goto out;
-	}
-
-	c->proto = p;
-	for(r=p->roles; r->name; r++){
-		if(strcmp(r->name, role) != 0)
-			continue;
-		rpcrespond(c, "ok");
-		c->active = 1;
-		if((*r->fn)(c) == 0){
-			c->done = 1;
-			werrstr("protocol finished");
-		}else
-			werrstr("%s %s %s: %r", p->name, r->name, c->state);
-		goto out;
-	}
-	werrstr("unknown role");
-
-out:
-	c->active = 0;
-	c->state = 0;
-	rerrstr(c->err, sizeof c->err);
-	rpcrespond(c, "error %r");
-	convclose(c);
-}
-
-static uchar* convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex);
-
-void
-rpcexec(Conv *c)
-{
-	uchar *p;
-
-	switch(c->rpc.op){
-	case RpcRead:
-		if(c->rpc.count > 0){
-			rpcrespond(c, "error read takes no parameters");
-			break;
-		}
-		/* fall through */
-	default:
-		if(!c->active){
-			if(c->done)
-				rpcrespond(c, "done");
-			else
-				rpcrespond(c, "error %s", c->err);
-			break;
-		}
-		nbsendp(c->rpcwait, 0);
-		break;
-	case RpcUnknown:
-		break;
-	case RpcAuthinfo:
-		/* deprecated */
-		if(c->active)
-			rpcrespond(c, "error conversation still active");
-		else if(!c->done)
-			rpcrespond(c, "error conversation not successful");
-		else{
-			/* make up an auth info using the attr */
-			p = convAI2M((uchar*)c->reply+3, sizeof c->reply-3, 
-				strfindattr(c->attr, "cuid"),
-				strfindattr(c->attr, "suid"),
-				strfindattr(c->attr, "cap"),
-				strfindattr(c->attr, "secret"));
-			if(p == nil)
-				rpcrespond(c, "error %r");
-			else
-				rpcrespondn(c, "ok", c->reply+3, p-(uchar*)(c->reply+3));
-		}
-		break;
-	case RpcAttr:
-		rpcrespond(c, "ok %A", c->attr);
-		break;
-	case RpcStart:
-		convreset(c);
-		c->ref++;
-		threadcreate(convthread, c, STACK);
-		break;
-	}
-}
-
-void
-rpcrespond(Conv *c, char *fmt, ...)
-{
-	va_list arg;
-
-	if(c->hangup)
-		return;
-
-	if(fmt == nil)
-		fmt = "";
-
-	va_start(arg, fmt);
-	c->nreply = vsnprint(c->reply, sizeof c->reply, fmt, arg);
-	va_end(arg);
-	(*c->kickreply)(c);
-	c->rpc.op = RpcUnknown;
-}
-
-void
-rpcrespondn(Conv *c, char *verb, void *data, int count)
-{
-	char *p;
-
-	if(c->hangup)
-		return;
-
-	if(strlen(verb)+1+count > sizeof c->reply){
-		print("RPC response too large; caller %#lux", getcallerpc(&c));
-		return;
-	}
-
-	strcpy(c->reply, verb);
-	p = c->reply + strlen(c->reply);
-	*p++ = ' ';
-	memmove(p, data, count);
-	c->nreply = count + (p - c->reply);
-	(*c->kickreply)(c);
-	c->rpc.op = RpcUnknown;
-}
-
-/* deprecated */
-static uchar*
-pstring(uchar *p, uchar *e, char *s)
-{
-	uint n;
-
-	if(p == nil)
-		return nil;
-	if(s == nil)
-		s = "";
-	n = strlen(s);
-	if(p+n+BIT16SZ >= e)
-		return nil;
-	PBIT16(p, n);
-	p += BIT16SZ;
-	memmove(p, s, n);
-	p += n;
-	return p;
-}
-
-static uchar*
-pcarray(uchar *p, uchar *e, uchar *s, uint n)
-{
-	if(p == nil)
-		return nil;
-	if(s == nil){
-		if(n > 0)
-			sysfatal("pcarray");
-		s = (uchar*)"";
-	}
-	if(p+n+BIT16SZ >= e)
-		return nil;
-	PBIT16(p, n);
-	p += BIT16SZ;
-	memmove(p, s, n);
-	p += n;
-	return p;
-}
-
-static uchar*
-convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex)
-{
-	uchar *e = p+n;
-	uchar *secret;
-	int nsecret;
-
-	if(cuid == nil)
-		cuid = "";
-	if(suid == nil)
-		suid = "";
-	if(cap == nil)
-		cap = "";
-	if(hex == nil)
-		hex = "";
-	nsecret = strlen(hex)/2;
-	secret = emalloc(nsecret);
-	if(hexparse(hex, secret, nsecret) < 0){
-		werrstr("hexparse %s failed", hex);	/* can't happen */
-		free(secret);
-		return nil;
-	}
-	p = pstring(p, e, cuid);
-	p = pstring(p, e, suid);
-	p = pstring(p, e, cap);
-	p = pcarray(p, e, secret, nsecret);
-	free(secret);
-	if(p == nil)
-		werrstr("authinfo too big");
-	return p;
-}
-
blob - d82d7862a48e8b2692d1e0572a10e3e30f067594 (mode 644)
blob + /dev/null
--- src/cmd/factotum/secstore.c
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * Various files from /sys/src/cmd/auth/secstore, just enough
- * to download a file at boot time.
- */
-
-#include "std.h"
-#include "dat.h"
-#include <ip.h>
-
-enum{ CHK = 16};
-enum{ MAXFILESIZE = 10*1024*1024 };
-
-enum{// PW status bits
-	Enabled 	= (1<<0),
-	STA 		= (1<<1),	// extra SecurID step
-};
-
-static char testmess[] = "__secstore\tPAK\nC=%s\nm=0\n";
-char *secstore;
-
-int
-secdial(void)
-{
-	char *p;
-
-	p = secstore;
-	if(p == nil)	  /* else use the authserver */
-		p = getenv("secstore");
-	if(p == nil)
-		p = getenv("auth");
-	if(p == nil)
-		p = "secstore";
-
-	return dial(netmkaddr(p, "net", "secstore"), 0, 0, 0);
-}
-
-
-int
-havesecstore(void)
-{
-	int m, n, fd;
-	uchar buf[500];
-
-	n = snprint((char*)buf, sizeof buf, testmess, owner);
-	hnputs(buf, 0x8000+n-2);
-
-	fd = secdial();
-	if(fd < 0)
-		return 0;
-	if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2){
-		close(fd);
-		return 0;
-	}
-	n = ((buf[0]&0x7f)<<8) + buf[1];
-	if(n+1 > sizeof buf){
-		werrstr("implausibly large count %d", n);
-		close(fd);
-		return 0;
-	}
-	m = readn(fd, buf, n);
-	close(fd);
-	if(m != n){
-		if(m >= 0)
-			werrstr("short read from secstore");
-		return 0;
-	}
-	buf[n] = 0;
-	if(strcmp((char*)buf, "!account expired") == 0){
-		werrstr("account expired");
-		return 0;
-	}
-	return strcmp((char*)buf, "!account exists") == 0;
-}
-
-// delimited, authenticated, encrypted connection
-enum{ Maxmsg=4096 };	// messages > Maxmsg bytes are truncated
-typedef struct SConn SConn;
-
-extern SConn* newSConn(int);	// arg is open file descriptor
-struct SConn{
-	void *chan;
-	int secretlen;
-	int (*secret)(SConn*, uchar*, int);// 
-	int (*read)(SConn*, uchar*, int); // <0 if error;  errmess in buffer
-	int (*write)(SConn*, uchar*, int);
-	void (*free)(SConn*);		// also closes file descriptor
-};
-// secret(s,b,dir) sets secret for digest, encrypt, using the secretlen
-//		bytes in b to form keys 	for the two directions;
-//	  set dir=0 in client, dir=1 in server
-
-// error convention: write !message in-band
-#define readstr secstore_readstr
-static void writerr(SConn*, char*);
-static int readstr(SConn*, char*);  // call with buf of size Maxmsg+1
-	// returns -1 upon error, with error message in buf
-
-typedef struct ConnState {
-	uchar secret[SHA1dlen];
-	ulong seqno;
-	RC4state rc4;
-} ConnState;
-
-typedef struct SS{
-	int fd;		// file descriptor for read/write of encrypted data
-	int alg;	// if nonzero, "alg sha rc4_128"
-	ConnState in, out;
-} SS;
-
-static int
-SC_secret(SConn *conn, uchar *sigma, int direction)
-{
-	SS *ss = (SS*)(conn->chan);
-	int nsigma = conn->secretlen;
-
-	if(direction != 0){
-		hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->out.secret, nil);
-		hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->in.secret, nil);
-	}else{
-		hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->out.secret, nil);
-		hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->in.secret, nil);
-	}
-	setupRC4state(&ss->in.rc4, ss->in.secret, 16); // restrict to 128 bits
-	setupRC4state(&ss->out.rc4, ss->out.secret, 16);
-	ss->alg = 1;
-	return 0;
-}
-
-static void
-hash(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
-{
-	DigestState sha;
-	uchar seq[4];
-
-	seq[0] = seqno>>24;
-	seq[1] = seqno>>16;
-	seq[2] = seqno>>8;
-	seq[3] = seqno;
-	memset(&sha, 0, sizeof sha);
-	sha1(secret, SHA1dlen, nil, &sha);
-	sha1(data, len, nil, &sha);
-	sha1(seq, 4, d, &sha);
-}
-
-static int
-verify(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
-{
-	DigestState sha;
-	uchar seq[4];
-	uchar digest[SHA1dlen];
-
-	seq[0] = seqno>>24;
-	seq[1] = seqno>>16;
-	seq[2] = seqno>>8;
-	seq[3] = seqno;
-	memset(&sha, 0, sizeof sha);
-	sha1(secret, SHA1dlen, nil, &sha);
-	sha1(data, len, nil, &sha);
-	sha1(seq, 4, digest, &sha);
-	return memcmp(d, digest, SHA1dlen);
-}
-
-static int
-SC_read(SConn *conn, uchar *buf, int n)
-{
-	SS *ss = (SS*)(conn->chan);
-	uchar count[2], digest[SHA1dlen];
-	int len, nr;
-
-	if(read(ss->fd, count, 2) != 2 || count[0]&0x80 == 0){
-		werrstr("!SC_read invalid count");
-		return -1;
-	}
-	len = (count[0]&0x7f)<<8 | count[1];	// SSL-style count; no pad
-	if(ss->alg){
-		len -= SHA1dlen;
-		if(len <= 0 || readn(ss->fd, digest, SHA1dlen) != SHA1dlen){
-			werrstr("!SC_read missing sha1");
-			return -1;
-		}
-		if(len > n || readn(ss->fd, buf, len) != len){
-			werrstr("!SC_read missing data");
-			return -1;
-		}
-		rc4(&ss->in.rc4, digest, SHA1dlen);
-		rc4(&ss->in.rc4, buf, len);
-		if(verify(ss->in.secret, buf, len, ss->in.seqno, digest) != 0){
-			werrstr("!SC_read integrity check failed");
-			return -1;
-		}
-	}else{
-		if(len <= 0 || len > n){
-			werrstr("!SC_read implausible record length");
-			return -1;
-		}
-		if( (nr = readn(ss->fd, buf, len)) != len){
-			werrstr("!SC_read expected %d bytes, but got %d", len, nr);
-			return -1;
-		}
-	}
-	ss->in.seqno++;
-	return len;
-}
-
-static int
-SC_write(SConn *conn, uchar *buf, int n)
-{
-	SS *ss = (SS*)(conn->chan);
-	uchar count[2], digest[SHA1dlen], enc[Maxmsg+1];
-	int len;
-
-	if(n <= 0 || n > Maxmsg+1){
-		werrstr("!SC_write invalid n %d", n);
-		return -1;
-	}
-	len = n;
-	if(ss->alg)
-		len += SHA1dlen;
-	count[0] = 0x80 | len>>8;
-	count[1] = len;
-	if(write(ss->fd, count, 2) != 2){
-		werrstr("!SC_write invalid count");
-		return -1;
-	}
-	if(ss->alg){
-		hash(ss->out.secret, buf, n, ss->out.seqno, digest);
-		rc4(&ss->out.rc4, digest, SHA1dlen);
-		memcpy(enc, buf, n);
-		rc4(&ss->out.rc4, enc, n);
-		if(write(ss->fd, digest, SHA1dlen) != SHA1dlen ||
-				write(ss->fd, enc, n) != n){
-			werrstr("!SC_write error on send");
-			return -1;
-		}
-	}else{
-		if(write(ss->fd, buf, n) != n){
-			werrstr("!SC_write error on send");
-			return -1;
-		}
-	}
-	ss->out.seqno++;
-	return n;
-}
-
-static void
-SC_free(SConn *conn)
-{
-	SS *ss = (SS*)(conn->chan);
-
-	close(ss->fd);
-	free(ss);
-	free(conn);
-}
-
-SConn*
-newSConn(int fd)
-{
-	SS *ss;
-	SConn *conn;
-
-	if(fd < 0)
-		return nil;
-	ss = (SS*)emalloc(sizeof(*ss));
-	conn = (SConn*)emalloc(sizeof(*conn));
-	ss->fd  = fd;
-	ss->alg = 0;
-	conn->chan = (void*)ss;
-	conn->secretlen = SHA1dlen;
-	conn->free = SC_free;
-	conn->secret = SC_secret;
-	conn->read = SC_read;
-	conn->write = SC_write;
-	return conn;
-}
-
-static void
-writerr(SConn *conn, char *s)
-{
-	char buf[Maxmsg];
-
-	snprint(buf, Maxmsg, "!%s", s);
-	conn->write(conn, (uchar*)buf, strlen(buf));
-}
-
-static int
-readstr(SConn *conn, char *s)
-{
-	int n;
-
-	n = conn->read(conn, (uchar*)s, Maxmsg);
-	if(n >= 0){
-		s[n] = 0;
-		if(s[0] == '!'){
-			memmove(s, s+1, n);
-			n = -1;
-		}
-	}else{
-		strcpy(s, "read error");
-	}
-	return n;
-}
-
-static int
-getfile(SConn *conn, uchar *key, int nkey)
-{
-	char *buf;
-	int nbuf, n, nr, len;
-	char s[Maxmsg+1], *gf, *p, *q;
-	uchar skey[SHA1dlen], ib[Maxmsg+CHK], *ibr, *ibw;
-	AESstate aes;
-	DigestState *sha;
-
-	gf = "factotum";
-	memset(&aes, 0, sizeof aes);
-
-	snprint(s, Maxmsg, "GET %s\n", gf);
-	conn->write(conn, (uchar*)s, strlen(s));
-
-	/* get file size */
-	s[0] = '\0';
-	if(readstr(conn, s) < 0){
-		werrstr("secstore: %r");
-		return -1;
-	}
-	if((len = atoi(s)) < 0){
-		werrstr("secstore: remote file %s does not exist", gf);
-		return -1;
-	}else if(len > MAXFILESIZE){//assert
-		werrstr("secstore: implausible file size %d for %s", len, gf);
-		return -1;
-	}
-
-	ibr = ibw = ib;
-	buf = nil;
-	nbuf = 0;
-	for(nr=0; nr < len;){
-		if((n = conn->read(conn, ibw, Maxmsg)) <= 0){
-			werrstr("secstore: empty file chunk n=%d nr=%d len=%d: %r", n, nr, len);
-			return -1;
-		}
-		nr += n;
-		ibw += n;
-		if(!aes.setup){ /* first time, read 16 byte IV */
-			if(n < 16){
-				werrstr("secstore: no IV in file");
-				return -1;
-			}
-			sha = sha1((uchar*)"aescbc file", 11, nil, nil);
-			sha1(key, nkey, skey, sha);
-			setupAESstate(&aes, skey, AESbsize, ibr);
-			memset(skey, 0, sizeof skey);
-			ibr += AESbsize;
-			n -= AESbsize;
-		}
-		aesCBCdecrypt(ibw-n, n, &aes);
-		n = ibw-ibr-CHK;
-		if(n > 0){
-			buf = erealloc(buf, nbuf+n+1);
-			memmove(buf+nbuf, ibr, n);
-			nbuf += n;
-			ibr += n;
-		}
-		memmove(ib, ibr, ibw-ibr);
-		ibw = ib + (ibw-ibr);
-		ibr = ib;
-	}
-	n = ibw-ibr;
-	if((n != CHK) || (memcmp(ib, "XXXXXXXXXXXXXXXX", CHK) != 0)){
-		werrstr("secstore: decrypted file failed to authenticate!");
-		free(buf);
-		return -1;
-	}
-	if(nbuf == 0){
-		werrstr("secstore got empty file");
-		return -1;
-	}
-	buf[nbuf] = '\0';
-	p = buf;
-	n = 0;
-	while(p){
-		if(q = strchr(p, '\n'))
-			*q++ = '\0';
-		n++;
-		if(ctlwrite(p) < 0)
-			fprint(2, "secstore(%s) line %d: %r\n", gf, n);
-		p = q;
-	}
-	free(buf);
-	return 0;
-}
-
-static char VERSION[] = "secstore";
-
-typedef struct PAKparams{
-	mpint *q, *p, *r, *g;
-} PAKparams;
-
-static PAKparams *pak;
-
-// This group was generated by the seed EB7B6E35F7CD37B511D96C67D6688CC4DD440E1E.
-static void
-initPAKparams(void)
-{
-	if(pak)
-		return;
-	pak = (PAKparams*)emalloc(sizeof(*pak));
-	pak->q = strtomp("E0F0EF284E10796C5A2A511E94748BA03C795C13", nil, 16, nil);
-	pak->p = strtomp("C41CFBE4D4846F67A3DF7DE9921A49D3B42DC33728427AB159CEC8CBBD"
-		"B12B5F0C244F1A734AEB9840804EA3C25036AD1B61AFF3ABBC247CD4B384224567A86"
-		"3A6F020E7EE9795554BCD08ABAD7321AF27E1E92E3DB1C6E7E94FAAE590AE9C48F96D9"
-		"3D178E809401ABE8A534A1EC44359733475A36A70C7B425125062B1142D", nil, 16, nil);
-	pak->r = strtomp("DF310F4E54A5FEC5D86D3E14863921E834113E060F90052AD332B3241CEF"
-		"2497EFA0303D6344F7C819691A0F9C4A773815AF8EAECFB7EC1D98F039F17A32A7E887"
-		"D97251A927D093F44A55577F4D70444AEBD06B9B45695EC23962B175F266895C67D21"
-		"C4656848614D888A4", nil, 16, nil);
-	pak->g = strtomp("2F1C308DC46B9A44B52DF7DACCE1208CCEF72F69C743ADD4D2327173444"
-		"ED6E65E074694246E07F9FD4AE26E0FDDD9F54F813C40CB9BCD4338EA6F242AB94CD41"
-		"0E676C290368A16B1A3594877437E516C53A6EEE5493A038A017E955E218E7819734E3E"
-		"2A6E0BAE08B14258F8C03CC1B30E0DDADFCF7CEDF0727684D3D255F1", nil, 16, nil);
-}
-
-// H = (sha(ver,C,sha(passphrase)))^r mod p,
-// a hash function expensive to attack by brute force.
-static void
-longhash(char *ver, char *C, uchar *passwd, mpint *H)
-{
-	uchar *Cp;
-	int i, n, nver, nC;
-	uchar buf[140], key[1];
-
-	nver = strlen(ver);
-	nC = strlen(C);
-	n = nver + nC + SHA1dlen;
-	Cp = (uchar*)emalloc(n);
-	memmove(Cp, ver, nver);
-	memmove(Cp+nver, C, nC);
-	memmove(Cp+nver+nC, passwd, SHA1dlen);
-	for(i = 0; i < 7; i++){
-		key[0] = 'A'+i;
-		hmac_sha1(Cp, n, key, sizeof key, buf+i*SHA1dlen, nil);
-	}
-	memset(Cp, 0, n);
-	free(Cp);
-	betomp(buf, sizeof buf, H);
-	mpmod(H, pak->p, H);
-	mpexp(H, pak->r, pak->p, H);
-}
-
-// Hi = H^-1 mod p
-static char *
-PAK_Hi(char *C, char *passphrase, mpint *H, mpint *Hi)
-{
-	uchar passhash[SHA1dlen];
-
-	sha1((uchar *)passphrase, strlen(passphrase), passhash, nil);
-	initPAKparams();
-	longhash(VERSION, C, passhash, H);
-	mpinvert(H, pak->p, Hi);
-	return mptoa(Hi, 64, nil, 0);
-}
-
-// another, faster, hash function for each party to
-// confirm that the other has the right secrets.
-static void
-shorthash(char *mess, char *C, char *S, char *m, char *mu, char *sigma, char *Hi, uchar *digest)
-{
-	SHA1state *state;
-
-	state = sha1((uchar*)mess, strlen(mess), 0, 0);
-	state = sha1((uchar*)C, strlen(C), 0, state);
-	state = sha1((uchar*)S, strlen(S), 0, state);
-	state = sha1((uchar*)m, strlen(m), 0, state);
-	state = sha1((uchar*)mu, strlen(mu), 0, state);
-	state = sha1((uchar*)sigma, strlen(sigma), 0, state);
-	state = sha1((uchar*)Hi, strlen(Hi), 0, state);
-	state = sha1((uchar*)mess, strlen(mess), 0, state);
-	state = sha1((uchar*)C, strlen(C), 0, state);
-	state = sha1((uchar*)S, strlen(S), 0, state);
-	state = sha1((uchar*)m, strlen(m), 0, state);
-	state = sha1((uchar*)mu, strlen(mu), 0, state);
-	state = sha1((uchar*)sigma, strlen(sigma), 0, state);
-	sha1((uchar*)Hi, strlen(Hi), digest, state);
-}
-
-// On input, conn provides an open channel to the server;
-//	C is the name this client calls itself;
-//	pass is the user's passphrase
-// On output, session secret has been set in conn
-//	(unless return code is negative, which means failure).
-//    If pS is not nil, it is set to the (alloc'd) name the server calls itself.
-static int
-PAKclient(SConn *conn, char *C, char *pass, char **pS)
-{
-	char *mess, *mess2, *eol, *S, *hexmu, *ks, *hexm, *hexsigma = nil, *hexHi;
-	char kc[2*SHA1dlen+1];
-	uchar digest[SHA1dlen];
-	int rc = -1, n;
-	mpint *x, *m = mpnew(0), *mu = mpnew(0), *sigma = mpnew(0);
-	mpint *H = mpnew(0), *Hi = mpnew(0);
-
-	hexHi = PAK_Hi(C, pass, H, Hi);
-
-	// random 1<=x<=q-1; send C, m=g**x H
-	x = mprand(164, genrandom, nil);
-	mpmod(x, pak->q, x);
-	if(mpcmp(x, mpzero) == 0)
-		mpassign(mpone, x);
-	mpexp(pak->g, x, pak->p, m);
-	mpmul(m, H, m);
-	mpmod(m, pak->p, m);
-	hexm = mptoa(m, 64, nil, 0);
-	mess = (char*)emalloc(2*Maxmsg+2);
-	mess2 = mess+Maxmsg+1;
-	snprint(mess, Maxmsg, "%s\tPAK\nC=%s\nm=%s\n", VERSION, C, hexm);
-	conn->write(conn, (uchar*)mess, strlen(mess));
-
-	// recv g**y, S, check hash1(g**xy)
-	if(readstr(conn, mess) < 0){
-		fprint(2, "error: %s\n", mess);
-		writerr(conn, "couldn't read g**y");
-		goto done;
-	}
-	eol = strchr(mess, '\n');
-	if(strncmp("mu=", mess, 3) != 0 || !eol || strncmp("\nk=", eol, 3) != 0){
-		writerr(conn, "verifier syntax error");
-		goto done;
-	}
-	hexmu = mess+3;
-	*eol = 0;
-	ks = eol+3;
-	eol = strchr(ks, '\n');
-	if(!eol || strncmp("\nS=", eol, 3) != 0){
-		writerr(conn, "verifier syntax error for secstore 1.0");
-		goto done;
-	}
-	*eol = 0;
-	S = eol+3;
-	eol = strchr(S, '\n');
-	if(!eol){
-		writerr(conn, "verifier syntax error for secstore 1.0");
-		goto done;
-	}
-	*eol = 0;
-	if(pS)
-		*pS = estrdup(S);
-	strtomp(hexmu, nil, 64, mu);
-	mpexp(mu, x, pak->p, sigma);
-	hexsigma = mptoa(sigma, 64, nil, 0);
-	shorthash("server", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	enc64(kc, sizeof kc, digest, SHA1dlen);
-	if(strcmp(ks, kc) != 0){
-		writerr(conn, "verifier didn't match");
-		goto done;
-	}
-
-	// send hash2(g**xy)
-	shorthash("client", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	enc64(kc, sizeof kc, digest, SHA1dlen);
-	snprint(mess2, Maxmsg, "k'=%s\n", kc);
-	conn->write(conn, (uchar*)mess2, strlen(mess2));
-
-	// set session key
-	shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	memset(hexsigma, 0, strlen(hexsigma));
-	n = conn->secret(conn, digest, 0);
-	memset(digest, 0, SHA1dlen);
-	if(n < 0){//assert
-		writerr(conn, "can't set secret");
-		goto done;
-	}
-
-	rc = 0;
-done:
-	mpfree(x);
-	mpfree(sigma);
-	mpfree(mu);
-	mpfree(m);
-	mpfree(Hi);
-	mpfree(H);
-	free(hexsigma);
-	free(hexHi);
-	free(hexm);
-	free(mess);
-	return rc;
-}
-
-int
-secstorefetch(void)
-{
-	int rv = -1, fd;
-	char s[Maxmsg+1];
-	SConn *conn;
-	char *pass, *sta;
-
-	sta = nil;
-	conn = nil;
-	pass = readcons("secstore password", nil, 1);
-	if(pass==nil || strlen(pass)==0){
-		werrstr("cancel");
-		goto Out;
-	}
-	if((fd = secdial()) < 0)
-		goto Out;
-	if((conn = newSConn(fd)) == nil)
-		goto Out;
-	if(PAKclient(conn, owner, pass, nil) < 0){
-		werrstr("password mistyped?");
-		goto Out;
-	}
-	if(readstr(conn, s) < 0)
-		goto Out;
-	if(strcmp(s, "STA") == 0){
-		sta = readcons("STA PIN+SecureID", nil, 1);
-		if(sta==nil || strlen(sta)==0){
-			werrstr("cancel");
-			goto Out;
-		}
-		if(strlen(sta) >= sizeof s - 3){
-			werrstr("STA response too long");
-			goto Out;
-		}
-		strcpy(s+3, sta);
-		conn->write(conn, (uchar*)s, strlen(s));
-		readstr(conn, s);
-	}
-	if(strcmp(s, "OK") !=0){
-		werrstr("%s", s);
-		goto Out;
-	}
-	if(getfile(conn, (uchar*)pass, strlen(pass)) < 0)
-		goto Out;
-	conn->write(conn, (uchar*)"BYE", 3);
-	rv = 0;
-
-Out:
-	if(conn)
-		conn->free(conn);
-	if(pass)
-		free(pass);
-	if(sta)
-		free(sta);
-	return rv;
-}
-
blob - 4c88bfe655f0f4a62326110184f1a3ff1a1c95a6 (mode 644)
blob + /dev/null
--- src/cmd/factotum/ssh.c
+++ /dev/null
@@ -1,135 +0,0 @@
-#include "dat.h"
-#include <mp.h>
-#include <libsec.h>
-
-typedef struct Sshrsastate Sshrsastate;
-
-enum {
-	CReadpub,
-	CWritechal,
-	CReadresp,
-};
-struct State
-{
-	RSApriv *priv;
-	Key *k;
-	mpint *resp;
-	int phase;
-};
-
-static RSApriv*
-readrsapriv(char *s)
-{
-	RSApriv *priv;
-
-	priv = rsaprivalloc();
-
-	strtoul(s, &s, 10);
-	if((priv->pub.ek=strtomp(s, &s, 16, nil)) == nil)
-		goto Error;
-	if((priv->dk=strtomp(s, &s, 16, nil)) == nil)
-		goto Error;
-	if((priv->pub.n=strtomp(s, &s, 16, nil)) == nil)
-		goto Error;
-	if((priv->p=strtomp(s, &s, 16, nil)) == nil)
-		goto Error;
-	if((priv->q=strtomp(s, &s, 16, nil)) == nil)
-		goto Error;
-	if((priv->kp=strtomp(s, &s, 16, nil)) == nil)
-		goto Error;
-	if((priv->kq=strtomp(s, &s, 16, nil)) == nil)
-		goto Error;
-	if((priv->c2=strtomp(s, &s, 16, nil)) == nil)
-		goto Error;
-
-	return priv;
-
-Error:
-	rsaprivfree(priv);
-	return nil;
-}
-
-int
-sshinit(Fsstate *fss, 
-sshrsaopen(Key *k, char*, int client)
-{
-	Sshrsastate *s;
-
-	fmtinstall('B', mpconv);
-	assert(client);
-	s = emalloc(sizeof *s);
-	s->priv = readrsapriv(s_to_c(k->data));
-	s->k = k;
-	if(s->priv == nil){
-		agentlog("error parsing ssh key %s", k->file);
-		free(s);
-		return nil;
-	}
-	return s;
-}
-
-int
-sshrsaread(void *va, void *buf, int n)
-{
-	Sshrsastate *s;
-
-	s = va;
-	switch(s->phase){
-	case Readpub:
-		s->phase = Done;
-		return snprint(buf, n, "%B", s->priv->pub.n);
-	case Readresp:
-		s->phase = Done;
-		return snprint(buf, n, "%B", s->resp);
-	default:
-		return 0;
-	}
-}
-
-int
-sshrsawrite(void *va, void *vbuf, int n)
-{
-	mpint *m;
-	char *buf;
-	Sshrsastate *s;
-
-	s = va;
-	if((s->k->flags&Fconfirmuse) && confirm("ssh use") < 0)
-		return -1;
-
-	buf = emalloc(n+1);
-	memmove(buf, vbuf, n);
-	buf[n] = '\0';
-	m = strtomp(buf, nil, 16, nil);
-	free(buf);
-	if(m == nil){
-		werrstr("bad bignum");
-		return -1;
-	}
-
-	agentlog("ssh use");
-	m = rsadecrypt(s->priv, m, m);
-	s->resp = m;
-	s->phase = Readresp;
-	return n;
-}
-
-void
-sshrsaclose(void *v)
-{
-	Sshrsastate *s;
-
-	s = v;
-	rsaprivfree(s->priv);
-	mpfree(s->resp);
-	free(s);
-}
-
-Proto sshrsa = {
-.name=	"ssh-rsa",
-.perm=	0666,
-.open=	sshrsaopen,
-.read=	sshrsaread,
-.write=	sshrsawrite,
-.close=	sshrsaclose,
-};
blob - 7227c85566a54cece660b3900a723ec8ab3a92cc (mode 644)
blob + /dev/null
--- src/cmd/factotum/sshrsa.c
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * SSH RSA authentication.
- * 
- * Client protocol:
- *	read public key
- *		if you don't like it, read another, repeat
- *	write challenge
- *	read response
- * all numbers are hexadecimal biginits parsable with strtomp.
- */
-
-#include "dat.h"
-
-enum {
-	CHavePub,
-	CHaveResp,
-
-	Maxphase,
-};
-
-static char *phasenames[] = {
-[CHavePub]	"CHavePub",
-[CHaveResp]	"CHaveResp",
-};
-
-struct State
-{
-	RSApriv *priv;
-	mpint *resp;
-	int off;
-	Key *key;
-};
-
-static RSApriv*
-readrsapriv(Key *k)
-{
-	char *a;
-	RSApriv *priv;
-
-	priv = rsaprivalloc();
-
-	if((a=strfindattr(k->attr, "ek"))==nil || (priv->pub.ek=strtomp(a, nil, 16, nil))==nil)
-		goto Error;
-	if((a=strfindattr(k->attr, "n"))==nil || (priv->pub.n=strtomp(a, nil, 16, nil))==nil)
-		goto Error;
-	if((a=strfindattr(k->privattr, "!p"))==nil || (priv->p=strtomp(a, nil, 16, nil))==nil)
-		goto Error;
-	if((a=strfindattr(k->privattr, "!q"))==nil || (priv->q=strtomp(a, nil, 16, nil))==nil)
-		goto Error;
-	if((a=strfindattr(k->privattr, "!kp"))==nil || (priv->kp=strtomp(a, nil, 16, nil))==nil)
-		goto Error;
-	if((a=strfindattr(k->privattr, "!kq"))==nil || (priv->kq=strtomp(a, nil, 16, nil))==nil)
-		goto Error;
-	if((a=strfindattr(k->privattr, "!c2"))==nil || (priv->c2=strtomp(a, nil, 16, nil))==nil)
-		goto Error;
-	if((a=strfindattr(k->privattr, "!dk"))==nil || (priv->dk=strtomp(a, nil, 16, nil))==nil)
-		goto Error;
-	return priv;
-
-Error:
-	rsaprivfree(priv);
-	return nil;
-}
-
-static int
-sshrsainit(Proto*, Fsstate *fss)
-{
-	int iscli;
-	State *s;
-
-	if((iscli = isclient(strfindattr(fss->attr, "role"))) < 0)
-		return failure(fss, nil);
-	if(iscli==0)
-		return failure(fss, "sshrsa server unimplemented");
-
-	s = emalloc(sizeof *s);
-	fss->phasename = phasenames;
-	fss->maxphase = Maxphase;
-	fss->phase = CHavePub;
-	fss->ps = s;
-	return RpcOk;
-}
-
-static int
-sshrsaread(Fsstate *fss, void *va, uint *n)
-{
-	RSApriv *priv;
-	State *s;
-
-	s = fss->ps;
-	switch(fss->phase){
-	default:
-		return phaseerror(fss, "read");
-	case CHavePub:
-		if(s->key){
-			closekey(s->key);
-			s->key = nil;
-		}
-		if((s->key = findkey(fss, Kuser, nil, s->off, fss->attr, nil)) == nil)
-			return failure(fss, nil);
-		s->off++;
-		priv = s->key->priv;
-		*n = snprint(va, *n, "%B", priv->pub.n);
-		return RpcOk;
-	case CHaveResp:
-		*n = snprint(va, *n, "%B", s->resp);
-		fss->phase = Established;
-		return RpcOk;
-	}
-}
-
-static int
-sshrsawrite(Fsstate *fss, void *va, uint)
-{
-	mpint *m;
-	State *s;
-
-	s = fss->ps;
-	switch(fss->phase){
-	default:
-		return phaseerror(fss, "write");
-	case CHavePub:
-		if(s->key == nil)
-			return failure(fss, "no current key");
-		m = strtomp(va, nil, 16, nil);
-		m = rsadecrypt(s->key->priv, m, m);
-		s->resp = m;
-		fss->phase = CHaveResp;
-		return RpcOk;
-	}
-}
-
-static void
-sshrsaclose(Fsstate *fss)
-{
-	State *s;
-
-	s = fss->ps;
-	if(s->key)
-		closekey(s->key);
-	if(s->resp)
-		mpfree(s->resp);
-	free(s);
-}
-
-static int
-sshrsaaddkey(Key *k)
-{
-	fmtinstall('B', mpconv);
-
-	if((k->priv = readrsapriv(k)) == nil){
-		werrstr("malformed key data");
-		return -1;
-	}
-	return replacekey(k);
-}
-
-static void
-sshrsaclosekey(Key *k)
-{
-	rsaprivfree(k->priv);
-}
-
-Proto sshrsa = {
-.name=	"sshrsa",
-.init=		sshrsainit,
-.write=	sshrsawrite,
-.read=	sshrsaread,
-.close=	sshrsaclose,
-.addkey=	sshrsaaddkey,
-.closekey=	sshrsaclosekey,
-};
blob - 814664e0fb482cf11e5da201fb5f5c63d6b5b17a (mode 644)
blob + /dev/null
--- src/cmd/factotum/std.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-#include <authsrv.h>
-#include <mp.h>
-#include <libsec.h>
-#include <thread.h>
-#include <fcall.h>
-#include <9p.h>
-
blob - b41048980556fe7a81615ffbf1af9b703d5757b0 (mode 644)
blob + /dev/null
--- src/cmd/factotum/test.c
+++ /dev/null
@@ -1,121 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-
-typedef struct Test Test;
-
-struct Test
-{
-	char *name;
-	int (*server)(Test*, AuthRpc*, int);
-	int (*client)(Test*, int);
-};
-
-int
-ai2status(AuthInfo *ai)
-{
-	if(ai == nil)
-		return -1;
-	auth_freeAI(ai);
-	return 0;
-}
-
-int
-proxyserver(Test *t, AuthRpc *rpc, int fd)
-{
-	char buf[1024];
-
-	sprint(buf, "proto=%q role=server", t->name);
-	return ai2status(fauth_proxy(fd, rpc, nil, buf));
-}
-
-int
-proxyclient(Test *t, int fd)
-{
-	return ai2status(auth_proxy(fd, auth_getkey, "proto=%q role=client", t->name));
-}
-
-Test test[] =
-{
-	"apop",		proxyserver,		proxyclient,
-	"cram",		proxyserver,		proxyclient,
-	"p9sk1",		proxyserver,		proxyclient,
-	"p9sk2",		proxyserver,		proxyclient,
-	"p9any",		proxyserver,		proxyclient,
-};
-
-void
-usage(void)
-{
-	fprint(2, "usage: test [name]...\n");
-	exits("usage");
-}
-
-void
-runtest(AuthRpc *srpc, Test *t)
-{
-	int p[2], bad;
-	Waitmsg *w;
-
-	if(pipe(p) < 0)
-		sysfatal("pipe: %r");
-
-	print("%s...", t->name);
-
-	switch(fork()){
-	case -1:
-		sysfatal("fork: %r");
-
-	case 0:
-		close(p[0]);
-		if((*t->server)(t, srpc, p[1]) < 0){
-			print("\n\tserver: %r");
-			_exits("oops");
-		}
-		close(p[1]);
-		_exits(nil);
-	default:
-		close(p[1]);
-		if((*t->client)(t, p[0]) < 0){
-			print("\n\tclient: %r");
-			bad = 1;
-		}
-		close(p[0]);
-		break;
-	}
-	w = wait();
-	if(w->msg[0])
-		bad = 1;
-	print("\n");
-}
-
-void
-main(int argc, char **argv)
-{
-	int i, j;
-	int afd;
-	AuthRpc *srpc;
-
-	ARGBEGIN{
-	default:
-		usage();
-	}ARGEND
-
-	quotefmtinstall();
-	afd = open("/n/kremvax/factotum/rpc", ORDWR);
-	if(afd < 0)
-		sysfatal("open /n/kremvax/factotum/rpc: %r");
-	srpc = auth_allocrpc(afd);
-	if(srpc == nil)
-		sysfatal("auth_allocrpc: %r");
-
-	if(argc == 0)
-		for(i=0; i<nelem(test); i++)
-			runtest(srpc, &test[i]);
-	else
-		for(i=0; i<argc; i++)
-			for(j=0; j<nelem(test); j++)
-				if(strcmp(argv[i], test[j].name) == 0)
-					runtest(srpc, &test[j]);
-	exits(nil);
-}
blob - 2f9f9b1d80dee38976f76647d3257f6ca1ae5ca0 (mode 755)
blob + /dev/null
--- src/cmd/factotum/testsetup
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/rc
-
-slay 8.out|rc
-8.out $* -s fact.s -m /n/kremvax
-8.out $* -s fact.c
-ramfs -m /n/sid >[2]/dev/null
-auth/aescbc -d < /usr/rsc/lib/factotum.aes >/n/sid/all
-read -m /n/sid/all >/n/kremvax/factotum/ctl
-read -m /n/sid/all >/mnt/factotum/ctl
-unmount /n/sid
-
blob - accddddde1c0aa943d3437aa04dad9a03e7658ad (mode 644)
blob + /dev/null
--- src/cmd/factotum/util.c
+++ /dev/null
@@ -1,54 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-static int
-unhex(char c)
-{
-	if('0' <= c && c <= '9')
-		return c-'0';
-	if('a' <= c && c <= 'f')
-		return c-'a'+10;
-	if('A' <= c && c <= 'F')
-		return c-'A'+10;
-	abort();
-	return -1;
-}
-
-int
-hexparse(char *hex, uchar *dat, int ndat)
-{
-	int i, n;
-
-	n = strlen(hex);
-	if(n%2)
-		return -1;
-	n /= 2;
-	if(n > ndat)
-		return -1;
-	if(hex[strspn(hex, "0123456789abcdefABCDEF")] != '\0')
-		return -1;
-	for(i=0; i<n; i++)
-		dat[i] = (unhex(hex[2*i])<<4)|unhex(hex[2*i+1]);
-	return n;
-}
-
-char*
-estrappend(char *s, char *fmt, ...)
-{
-	char *t;
-	int l;
-	va_list arg;
-
-	va_start(arg, fmt);
-	t = vsmprint(fmt, arg);
-	if(t == nil)
-		sysfatal("out of memory");
-	va_end(arg);
-	l = s ? strlen(s) : 0;
-	s = erealloc(s, l+strlen(t)+1);
-	strcpy(s+l, t);
-	free(t);
-	return s;
-}
-
-
blob - 3bedfdd45bc9e8998736da056c57fea47421b402 (mode 644)
blob + /dev/null
--- src/cmd/factotum/x.c
+++ /dev/null
@@ -1,15 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <auth.h>
-
-void
-f(void*)
-{
-}
-
-void
-main(void)
-{
-	f(auth_challenge);
-	f(auth_response);
-}
blob - 2e6b141b0cae8629e25e8d5bb0bb35b907400ca3 (mode 644)
blob + /dev/null
--- src/cmd/factotum/xio.c
+++ /dev/null
@@ -1,165 +0,0 @@
-#include "std.h"
-#include "dat.h"
-
-static Ioproc *cache[5];
-static int ncache;
-
-static Ioproc*
-xioproc(void)
-{
-	Ioproc *c;
-	int i;
-	
-	for(i=0; i<ncache; i++){
-		if(c = cache[i]){
-			cache[i] = nil;
-			return c;
-		}
-	}
-
-	return ioproc();
-}
-
-static void
-closexioproc(Ioproc *io)
-{
-	int i;
-
-	for(i=0; i<ncache; i++)
-		if(cache[i] == nil){
-			cache[i] = io;
-			return;
-		}
-
-	closeioproc(io);
-}
-
-int
-xiodial(char *ds, char *local, char *dir, int *cfdp)
-{
-	int fd;
-	Ioproc *io;
-
-	if((io = xioproc()) == nil)
-		return -1;
-	fd = iodial(io, ds, local, dir, cfdp);
-	closexioproc(io);
-	return fd;
-}
-
-void
-xioclose(int fd)
-{
-	Ioproc *io;
-
-	if((io = xioproc()) == nil){
-		close(fd);
-		return;
-	}
-
-	ioclose(io, fd);
-	closexioproc(io);
-}
-
-int
-xiowrite(int fd, void *v, int n)
-{
-	int m;
-	Ioproc *io;
-
-	if((io = xioproc()) == nil)
-		return -1;
-	m = iowrite(io, fd, v, n);
-	closexioproc(io);
-	if(m != n)
-		return -1;
-	return n;
-}
-
-static long
-_ioauthdial(va_list *arg)
-{
-	char *net;
-	char *dom;
-	int fd;
-
-	net = va_arg(*arg, char*);
-	dom = va_arg(*arg, char*);
-	fd = _authdial(net, dom);
-	if(fd < 0)
-		fprint(2, "authdial: %r\n");
-	return fd;
-}
-
-int
-xioauthdial(char *net, char *dom)
-{
-	int fd;
-	Ioproc *io;
-
-	if((io = xioproc()) == nil)
-		return -1;
-	fd = iocall(io, _ioauthdial, net, dom);
-	closexioproc(io);
-	return fd;
-}
-
-static long
-_ioasrdresp(va_list *arg)
-{
-	int fd;
-	void *a;
-	int n;
-
-	fd = va_arg(*arg, int);
-	a = va_arg(*arg, void*);
-	n = va_arg(*arg, int);
-
-	return _asrdresp(fd, a, n);
-}
-
-int
-xioasrdresp(int fd, void *a, int n)
-{
-	Ioproc *io;
-
-	if((io = xioproc()) == nil)
-		return -1;
-
-	n = iocall(io, _ioasrdresp, fd, a, n);
-	closexioproc(io);
-	return n;
-}
-
-static long
-_ioasgetticket(va_list *arg)
-{
-	int asfd;
-	char *trbuf;
-	char *tbuf;
-
-	asfd = va_arg(*arg, int);
-	trbuf = va_arg(*arg, char*);
-	tbuf = va_arg(*arg, char*);
-
-	return _asgetticket(asfd, trbuf, tbuf);
-}
-
-int
-xioasgetticket(int fd, char *trbuf, char *tbuf)
-{
-	int n;
-	Ioproc *io;
-
-	if((io = xioproc()) == nil)
-		return -1;
-
-	n = iocall(io, _ioasgetticket, fd, trbuf, tbuf);
-	closexioproc(io);
-	if(n != 2*TICKETLEN)
-		n = -1;
-	else
-		n = 0;
-	return n;
-}
-
blob - 7a8654acb3e8f36fbf2d1152c0a10c05ccbaa1cc (mode 644)
blob + /dev/null
--- src/cmd/secstore/SConn.c
+++ /dev/null
@@ -1,213 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-
-extern int verbose;
-
-typedef struct ConnState {
-	uchar secret[SHA1dlen];
-	ulong seqno;
-	RC4state rc4;
-} ConnState;
-
-typedef struct SS{
-	int fd;		// file descriptor for read/write of encrypted data
-	int alg;	// if nonzero, "alg sha rc4_128"
-	ConnState in, out;
-} SS;
-
-static int
-SC_secret(SConn *conn, uchar *sigma, int direction)
-{
-	SS *ss = (SS*)(conn->chan);
-	int nsigma = conn->secretlen;
-
-	if(direction != 0){
-		hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->out.secret, nil);
-		hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->in.secret, nil);
-	}else{
-		hmac_sha1(sigma, nsigma, (uchar*)"two", 3, ss->out.secret, nil);
-		hmac_sha1(sigma, nsigma, (uchar*)"one", 3, ss->in.secret, nil);
-	}
-	setupRC4state(&ss->in.rc4, ss->in.secret, 16); // restrict to 128 bits
-	setupRC4state(&ss->out.rc4, ss->out.secret, 16);
-	ss->alg = 1;
-	return 0;
-}
-
-static void
-hash(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
-{
-	DigestState sha;
-	uchar seq[4];
-
-	seq[0] = seqno>>24;
-	seq[1] = seqno>>16;
-	seq[2] = seqno>>8;
-	seq[3] = seqno;
-	memset(&sha, 0, sizeof sha);
-	sha1(secret, SHA1dlen, nil, &sha);
-	sha1(data, len, nil, &sha);
-	sha1(seq, 4, d, &sha);
-}
-
-static int
-verify(uchar secret[SHA1dlen], uchar *data, int len, int seqno, uchar d[SHA1dlen])
-{
-	DigestState sha;
-	uchar seq[4];
-	uchar digest[SHA1dlen];
-
-	seq[0] = seqno>>24;
-	seq[1] = seqno>>16;
-	seq[2] = seqno>>8;
-	seq[3] = seqno;
-	memset(&sha, 0, sizeof sha);
-	sha1(secret, SHA1dlen, nil, &sha);
-	sha1(data, len, nil, &sha);
-	sha1(seq, 4, digest, &sha);
-	return memcmp(d, digest, SHA1dlen);
-}
-
-static int
-SC_read(SConn *conn, uchar *buf, int n)
-{
-	SS *ss = (SS*)(conn->chan);
-	uchar count[2], digest[SHA1dlen];
-	int len, nr;
-
-	if(read(ss->fd, count, 2) != 2 || (count[0]&0x80) == 0){
-		snprint((char*)buf,n,"!SC_read invalid count");
-		return -1;
-	}
-	len = (count[0]&0x7f)<<8 | count[1];	// SSL-style count; no pad
-	if(ss->alg){
-		len -= SHA1dlen;
-		if(len <= 0 || readn(ss->fd, digest, SHA1dlen) != SHA1dlen){
-			snprint((char*)buf,n,"!SC_read missing sha1");
-			return -1;
-		}
-		if(len > n || readn(ss->fd, buf, len) != len){
-			snprint((char*)buf,n,"!SC_read missing data");
-			return -1;
-		}
-		rc4(&ss->in.rc4, digest, SHA1dlen);
-		rc4(&ss->in.rc4, buf, len);
-		if(verify(ss->in.secret, buf, len, ss->in.seqno, digest) != 0){
-			snprint((char*)buf,n,"!SC_read integrity check failed");
-			return -1;
-		}
-	}else{
-		if(len <= 0 || len > n){
-			snprint((char*)buf,n,"!SC_read implausible record length");
-			return -1;
-		}
-		if( (nr = readn(ss->fd, buf, len)) != len){
-			snprint((char*)buf,n,"!SC_read expected %d bytes, but got %d", len, nr);
-			return -1;
-		}
-	}
-	ss->in.seqno++;
-	return len;
-}
-
-static int
-SC_write(SConn *conn, uchar *buf, int n)
-{
-	SS *ss = (SS*)(conn->chan);
-	uchar count[2], digest[SHA1dlen], enc[Maxmsg+1];
-	int len;
-
-	if(n <= 0 || n > Maxmsg+1){
-		werrstr("!SC_write invalid n %d", n);
-		return -1;
-	}
-	len = n;
-	if(ss->alg)
-		len += SHA1dlen;
-	count[0] = 0x80 | len>>8;
-	count[1] = len;
-	if(write(ss->fd, count, 2) != 2){
-		werrstr("!SC_write invalid count");
-		return -1;
-	}
-	if(ss->alg){
-		hash(ss->out.secret, buf, n, ss->out.seqno, digest);
-		rc4(&ss->out.rc4, digest, SHA1dlen);
-		memcpy(enc, buf, n);
-		rc4(&ss->out.rc4, enc, n);
-		if(write(ss->fd, digest, SHA1dlen) != SHA1dlen ||
-				write(ss->fd, enc, n) != n){
-			werrstr("!SC_write error on send");
-			return -1;
-		}
-	}else{
-		if(write(ss->fd, buf, n) != n){
-			werrstr("!SC_write error on send");
-			return -1;
-		}
-	}
-	ss->out.seqno++;
-	return n;
-}
-
-static void
-SC_free(SConn *conn)
-{
-	SS *ss = (SS*)(conn->chan);
-
-	close(ss->fd);
-	free(ss);
-	free(conn);
-}
-
-SConn*
-newSConn(int fd)
-{
-	SS *ss;
-	SConn *conn;
-
-	if(fd < 0)
-		return nil;
-	ss = (SS*)emalloc(sizeof(*ss));
-	conn = (SConn*)emalloc(sizeof(*conn));
-	ss->fd  = fd;
-	ss->alg = 0;
-	conn->chan = (void*)ss;
-	conn->secretlen = SHA1dlen;
-	conn->free = SC_free;
-	conn->secret = SC_secret;
-	conn->read = SC_read;
-	conn->write = SC_write;
-	return conn;
-}
-
-void
-writerr(SConn *conn, char *s)
-{
-	char buf[Maxmsg];
-
-	snprint(buf, Maxmsg, "!%s", s);
-	conn->write(conn, (uchar*)buf, strlen(buf));
-}
-
-int
-readstr(SConn *conn, char *s)
-{
-	int n;
-
-	n = conn->read(conn, (uchar*)s, Maxmsg);
-	if(n >= 0){
-		s[n] = 0;
-		if(s[0] == '!'){
-			memmove(s, s+1, n);
-			n = -1;
-		}
-	}else{
-		strcpy(s, "read error");
-	}
-	return n;
-}
-
blob - 9a428d833b1ac5aa6b7e8be04252bf562fc5a9fc (mode 644)
blob + /dev/null
--- src/cmd/secstore/SConn.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// delimited, authenticated, encrypted connection
-enum{ Maxmsg=4096 };	// messages > Maxmsg bytes are truncated
-typedef struct SConn SConn;
-
-extern SConn* newSConn(int);	// arg is open file descriptor
-struct SConn{
-	void *chan;
-	int secretlen;
-	int (*secret)(SConn*, uchar*, int);// 
-	int (*read)(SConn*, uchar*, int); // <0 if error;  errmess in buffer
-	int (*write)(SConn*, uchar*, int);
-	void (*free)(SConn*);		// also closes file descriptor
-};
-// secret(s,b,dir) sets secret for digest, encrypt, using the secretlen
-//		bytes in b to form keys 	for the two directions;
-//	  set dir=0 in client, dir=1 in server
-
-// error convention: write !message in-band
-extern void writerr(SConn*, char*);
-extern int readstr(SConn*, char*);  // call with buf of size Maxmsg+1
-	// returns -1 upon error, with error message in buf
-
-extern void *emalloc(ulong); /* dies on failure; clears memory */
-extern void *erealloc(void *, ulong);
-extern char *estrdup(char *);
-
blob - 56aeb00b531f69c7715634f77242d43cb3ba6740 (mode 644)
blob + /dev/null
--- src/cmd/secstore/aescbc.c
+++ /dev/null
@@ -1,156 +0,0 @@
-/* encrypt file by writing
-	v2hdr,
-	16byte initialization vector,
-	AES-CBC(key, random | file),
-    HMAC_SHA1(md5(key), AES-CBC(random | file))
-*/
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mp.h>
-#include <libsec.h>
-
-extern char* getpassm(char*);
-
-enum{ CHK = 16, BUF = 4096 };
-
-uchar v2hdr[AESbsize+1] = "AES CBC SHA1  2\n";
-Biobuf bin;
-Biobuf bout;
-
-void
-safewrite(uchar *buf, int n)
-{
-	int i = Bwrite(&bout, buf, n);
-
-	if(i == n)
-		return;
-	fprint(2, "write error\n");
-	exits("write error");
-}
-
-void
-saferead(uchar *buf, int n)
-{
-	int i = Bread(&bin, buf, n);
-
-	if(i == n)
-		return;
-	fprint(2, "read error\n");
-	exits("read error");
-}
-
-int
-main(int argc, char **argv)
-{
-	int encrypt = 0;  /* 0=decrypt, 1=encrypt */
-	int n, nkey, pass_stdin = 0;
-	char *pass;
-	uchar key[AESmaxkey], key2[SHA1dlen];
-	uchar buf[BUF+SHA1dlen];    /* assumption: CHK <= SHA1dlen */
-	AESstate aes;
-	DigestState *dstate;
-
-	ARGBEGIN{
-	case 'e':
-		encrypt = 1;
-		break;
-	case 'i':
-		pass_stdin = 1;
-		break;
-	}ARGEND;
-	if(argc!=0){
-		fprint(2,"usage: %s -d < cipher.aes > clear.txt\n", argv0);
-		fprint(2,"   or: %s -e < clear.txt > cipher.aes\n", argv0);
-		exits("usage");
-	}
-	Binit(&bin, 0, OREAD);
-	Binit(&bout, 1, OWRITE);
-
-	if(pass_stdin){
-		n = readn(3, buf, (sizeof buf)-1);
-		if(n < 1)
-			exits("usage: echo password |[3=1] auth/aescbc -i ...");
-		buf[n] = 0;
-		while(buf[n-1] == '\n')
-			buf[--n] = 0;
-	}else{
-		pass = readcons("aescbc key", nil, 1);
-		n = strlen(pass);
-		if(n >= BUF)
-			exits("key too long");
-		strcpy((char*)buf, pass);
-		memset(pass, 0, n);
-		free(pass);
-	}
-	if(n <= 0){
-		fprint(2,"no key\n");
-		exits("key");
-	}
-	dstate = sha1((uchar*)"aescbc file", 11, nil, nil);
-	sha1(buf, n, key2, dstate);
-	memcpy(key, key2, 16);
-	nkey = 16;
-	md5(key, nkey, key2, 0);  /* so even if HMAC_SHA1 is broken, encryption key is protected */
-
-	if(encrypt){
-		safewrite(v2hdr, AESbsize);
-		genrandom(buf,2*AESbsize); /* CBC is semantically secure if IV is unpredictable. */
-		setupAESstate(&aes, key, nkey, buf);  /* use first AESbsize bytes as IV */
-		aesCBCencrypt(buf+AESbsize, AESbsize, &aes);  /* use second AESbsize bytes as initial plaintext */
-		safewrite(buf, 2*AESbsize);
-		dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
-		while(1){
-			n = Bread(&bin, buf, BUF);
-			if(n < 0){
-				fprint(2,"read error\n");
-				exits("read error");
-			}
-			aesCBCencrypt(buf, n, &aes);
-			safewrite(buf, n);
-			dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
-			if(n < BUF)
-				break; /* EOF */
-		}
-		hmac_sha1(0, 0, key2, MD5dlen, buf, dstate);
-		safewrite(buf, SHA1dlen);
-	}else{ /* decrypt */
-		saferead(buf, AESbsize);
-		if(memcmp(buf, v2hdr, AESbsize) == 0){
-			saferead(buf, 2*AESbsize);  /* read IV and random initial plaintext */
-			setupAESstate(&aes, key, nkey, buf);
-			dstate = hmac_sha1(buf+AESbsize, AESbsize, key2, MD5dlen, 0, 0);
-			aesCBCdecrypt(buf+AESbsize, AESbsize, &aes);
-			saferead(buf, SHA1dlen);
-			while((n = Bread(&bin, buf+SHA1dlen, BUF)) > 0){
-				dstate = hmac_sha1(buf, n, key2, MD5dlen, 0, dstate);
-				aesCBCdecrypt(buf, n, &aes);
-				safewrite(buf, n);
-				memmove(buf, buf+n, SHA1dlen);  /* these bytes are not yet decrypted */
-			}
-			hmac_sha1(0, 0, key2, MD5dlen, buf+SHA1dlen, dstate);
-			if(memcmp(buf, buf+SHA1dlen, SHA1dlen) != 0){
-				fprint(2,"decrypted file failed to authenticate\n");
-				exits("decrypted file failed to authenticate");
-			}
-		}else{ /* compatibility with past mistake */
-			// if file was encrypted with bad aescbc use this:
-			//         memset(key, 0, AESmaxkey);
-			//    else assume we're decrypting secstore files
-			setupAESstate(&aes, key, AESbsize, buf);
-			saferead(buf, CHK);
-			aesCBCdecrypt(buf, CHK, &aes);
-			while((n = Bread(&bin, buf+CHK, BUF)) > 0){
-				aesCBCdecrypt(buf+CHK, n, &aes);
-				safewrite(buf, n);
-				memmove(buf, buf+n, CHK);
-			}
-			if(memcmp(buf, "XXXXXXXXXXXXXXXX", CHK) != 0){
-				fprint(2,"decrypted file failed to authenticate\n");
-				exits("decrypted file failed to authenticate");
-			}
-		}
-	}
-	exits("");
-	return 1;	/* gcc */
-}
blob - b4479413a8a00ba426432bf72f0ae9b5000eb8f1 (mode 644)
blob + /dev/null
--- src/cmd/secstore/dirls.c
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-
-static long
-ls(char *p, Dir **dirbuf)
-{
-	int fd;
-	long n;
-	Dir *db;
-
-	if((db = dirstat(p)) == nil ||
-		!(db->qid.type & QTDIR) ||
-		(fd = open(p, OREAD)) < 0 )
-		return -1;
-	free(db);
-	n = dirreadall(fd, dirbuf);
-	close(fd);
-	return n;
-}
-
-static uchar*
-sha1file(char *pfx, char *nm)
-{
-	int n, fd, len;
-	char *tmp;
-	uchar buf[8192];
-	static uchar digest[SHA1dlen];
-	DigestState *s;
-
-	len = strlen(pfx)+1+strlen(nm)+1;
-	tmp = emalloc(len);
-	snprint(tmp, len, "%s/%s", pfx, nm);
-	if((fd = open(tmp, OREAD)) < 0){
-		free(tmp);
-		return nil;
-	}
-	free(tmp);
-	s = nil;
-	while((n = read(fd, buf, sizeof buf)) > 0)
-		s = sha1(buf, n, nil, s);
-	close(fd);
-	sha1(nil, 0, digest, s);
-	return digest;
-}
-
-static int
-compare(Dir *a, Dir *b)
-{
-	return strcmp(a->name, b->name);
-}
-
-/* list the (name mtime size sum) of regular, readable files in path */
-char *
-dirls(char *path)
-{
-	char *list, *date, dig[30], buf[128];
-	int m, nmwid, lenwid;
-	long i, n, ndir, len;
-	Dir *dirbuf;
-
-	if(path==nil || (ndir = ls(path, &dirbuf)) < 0)
-		return nil;
-
-	qsort(dirbuf, ndir, sizeof dirbuf[0], (int (*)(const void *, const void *))compare);
-	for(nmwid=lenwid=i=0; i<ndir; i++){
-		if((m = strlen(dirbuf[i].name)) > nmwid)
-			nmwid = m;
-		snprint(buf, sizeof(buf), "%ulld", dirbuf[i].length);
-		if((m = strlen(buf)) > lenwid)
-			lenwid = m;
-	}
-	for(list=nil, len=0, i=0; i<ndir; i++){
-		date = ctime(dirbuf[i].mtime);
-		date[28] = 0;  // trim newline
-		n = snprint(buf, sizeof buf, "%*ulld %s", lenwid, dirbuf[i].length, date+4);
-		n += enc64(dig, sizeof dig, sha1file(path, dirbuf[i].name), SHA1dlen);
-		n += nmwid+3+strlen(dirbuf[i].name);
-		list = erealloc(list, len+n+1);
-		len += snprint(list+len, n+1, "%-*s\t%s %s\n", nmwid, dirbuf[i].name, buf, dig);
-	}
-	free(dirbuf);
-	return list;
-}
-
blob - 72986edd3ad56d1c3be889b3c9fcde8be552285f (mode 644)
blob + /dev/null
--- src/cmd/secstore/mkfile
+++ /dev/null
@@ -1,27 +0,0 @@
-<$PLAN9/src/mkhdr
-
-BIN=$PLAN9/bin
-#CFLAGS=-Fw
-HFILES =\
-	SConn.h\
-	secstore.h\
-
-OFILES =\
-	pak.$O\
-	password.$O\
-	SConn.$O\
-	util.$O\
-
-
-TARG=aescbc secstore secstored secuser
-
-<$PLAN9/src/mkmany
-
-$O.aescbc:	aescbc.$O util.$O
-	$LD -o $target $prereq $LDFLAGS
-
-$O.secstored: secstored.$O dirls.$O secureidcheck.$O $OFILES
-	$LD -o $target $prereq
-
-$O.secuser: secuser.$O $OFILES
-	$LD -o $target $prereq
blob - fb008e0f8e8f1baa7340129679c84974fb9489a1 (mode 644)
blob + /dev/null
--- src/cmd/secstore/pak.c
+++ /dev/null
@@ -1,344 +0,0 @@
-// PAK is an encrypted key exchange protocol designed by Philip MacKenzie et al.
-// It is patented and use outside Plan 9 requires you get a license.
-// (All other EKE protocols are patented as well, by Lucent or others.)
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-#include "secstore.h"
-
-extern int verbose;
-
-char VERSION[] = "secstore";
-static char *feedback[] = {"alpha","bravo","charlie","delta","echo","foxtrot","golf","hotel"};
-
-typedef struct PAKparams{
-	mpint *q, *p, *r, *g;
-} PAKparams;
-
-static PAKparams *pak;
-
-// from seed EB7B6E35F7CD37B511D96C67D6688CC4DD440E1E
-static void
-initPAKparams(void)
-{
-	if(pak)
-		return;
-	pak = (PAKparams*)emalloc(sizeof(*pak));
-	pak->q = strtomp("E0F0EF284E10796C5A2A511E94748BA03C795C13", nil, 16, nil);
-	pak->p = strtomp("C41CFBE4D4846F67A3DF7DE9921A49D3B42DC33728427AB159CEC8CBB"
-		"DB12B5F0C244F1A734AEB9840804EA3C25036AD1B61AFF3ABBC247CD4B384224567A86"
-		"3A6F020E7EE9795554BCD08ABAD7321AF27E1E92E3DB1C6E7E94FAAE590AE9C48F96D9"
-		"3D178E809401ABE8A534A1EC44359733475A36A70C7B425125062B1142D",
-		nil, 16, nil);
-	pak->r = strtomp("DF310F4E54A5FEC5D86D3E14863921E834113E060F90052AD332B3241"
-		"CEF2497EFA0303D6344F7C819691A0F9C4A773815AF8EAECFB7EC1D98F039F17A32A7E"
-		"887D97251A927D093F44A55577F4D70444AEBD06B9B45695EC23962B175F266895C67D"
-		"21C4656848614D888A4", nil, 16, nil);
-	pak->g = strtomp("2F1C308DC46B9A44B52DF7DACCE1208CCEF72F69C743ADD4D23271734"
-		"44ED6E65E074694246E07F9FD4AE26E0FDDD9F54F813C40CB9BCD4338EA6F242AB94CD"
-		"410E676C290368A16B1A3594877437E516C53A6EEE5493A038A017E955E218E7819734"
-		"E3E2A6E0BAE08B14258F8C03CC1B30E0DDADFCF7CEDF0727684D3D255F1",
-		nil, 16, nil);
-}
-
-// H = (sha(ver,C,sha(passphrase)))^r mod p,
-// a hash function expensive to attack by brute force.
-static void
-longhash(char *ver, char *C, uchar *passwd, mpint *H)
-{
-	uchar *Cp;
-	int i, n, nver, nC;
-	uchar buf[140], key[1];
-
-	nver = strlen(ver);
-	nC = strlen(C);
-	n = nver + nC + SHA1dlen;
-	Cp = (uchar*)emalloc(n);
-	memmove(Cp, ver, nver);
-	memmove(Cp+nver, C, nC);
-	memmove(Cp+nver+nC, passwd, SHA1dlen);
-	for(i = 0; i < 7; i++){
-		key[0] = 'A'+i;
-		hmac_sha1(Cp, n, key, sizeof key, buf+i*SHA1dlen, nil);
-	}
-	memset(Cp, 0, n);
-	free(Cp);
-	betomp(buf, sizeof buf, H);
-	mpmod(H, pak->p, H);
-	mpexp(H, pak->r, pak->p, H);
-}
-
-// Hi = H^-1 mod p
-char *
-PAK_Hi(char *C, char *passphrase, mpint *H, mpint *Hi)
-{
-	uchar passhash[SHA1dlen];
-
-	sha1((uchar *)passphrase, strlen(passphrase), passhash, nil);
-	initPAKparams();
-	longhash(VERSION, C, passhash, H);
-	mpinvert(H, pak->p, Hi);
-	return mptoa(Hi, 64, nil, 0);
-}
-
-// another, faster, hash function for each party to
-// confirm that the other has the right secrets.
-static void
-shorthash(char *mess, char *C, char *S, char *m, char *mu, char *sigma, char *Hi, uchar *digest)
-{
-	SHA1state *state;
-
-	state = sha1((uchar*)mess, strlen(mess), 0, 0);
-	state = sha1((uchar*)C, strlen(C), 0, state);
-	state = sha1((uchar*)S, strlen(S), 0, state);
-	state = sha1((uchar*)m, strlen(m), 0, state);
-	state = sha1((uchar*)mu, strlen(mu), 0, state);
-	state = sha1((uchar*)sigma, strlen(sigma), 0, state);
-	state = sha1((uchar*)Hi, strlen(Hi), 0, state);
-	state = sha1((uchar*)mess, strlen(mess), 0, state);
-	state = sha1((uchar*)C, strlen(C), 0, state);
-	state = sha1((uchar*)S, strlen(S), 0, state);
-	state = sha1((uchar*)m, strlen(m), 0, state);
-	state = sha1((uchar*)mu, strlen(mu), 0, state);
-	state = sha1((uchar*)sigma, strlen(sigma), 0, state);
-	sha1((uchar*)Hi, strlen(Hi), digest, state);
-}
-
-// On input, conn provides an open channel to the server;
-//	C is the name this client calls itself;
-//	pass is the user's passphrase
-// On output, session secret has been set in conn
-//	(unless return code is negative, which means failure).
-//    If pS is not nil, it is set to the (alloc'd) name the server calls itself.
-int
-PAKclient(SConn *conn, char *C, char *pass, char **pS)
-{
-	char *mess, *mess2, *eol, *S, *hexmu, *ks, *hexm, *hexsigma = nil, *hexHi;
-	char kc[2*SHA1dlen+1];
-	uchar digest[SHA1dlen];
-	int rc = -1, n;
-	mpint *x, *m = mpnew(0), *mu = mpnew(0), *sigma = mpnew(0);
-	mpint *H = mpnew(0), *Hi = mpnew(0);
-
-	hexHi = PAK_Hi(C, pass, H, Hi);
-	if(verbose)
-		fprint(2,"%s\n", feedback[H->p[0]&0x7]);  // provide a clue to catch typos
-
-	// random 1<=x<=q-1; send C, m=g**x H
-	x = mprand(240, genrandom, nil);
-	mpmod(x, pak->q, x);
-	if(mpcmp(x, mpzero) == 0)
-		mpassign(mpone, x);
-	mpexp(pak->g, x, pak->p, m);
-	mpmul(m, H, m);
-	mpmod(m, pak->p, m);
-	hexm = mptoa(m, 64, nil, 0);
-	mess = (char*)emalloc(2*Maxmsg+2);
-	mess2 = mess+Maxmsg+1;
-	snprint(mess, Maxmsg, "%s\tPAK\nC=%s\nm=%s\n", VERSION, C, hexm);
-	conn->write(conn, (uchar*)mess, strlen(mess));
-
-	// recv g**y, S, check hash1(g**xy)
-	if(readstr(conn, mess) < 0){
-		fprint(2, "error: %s\n", mess);
-		writerr(conn, "couldn't read g**y");
-		goto done;
-	}
-	eol = strchr(mess, '\n');
-	if(strncmp("mu=", mess, 3) != 0 || !eol || strncmp("\nk=", eol, 3) != 0){
-		writerr(conn, "verifier syntax error");
-		goto done;
-	}
-	hexmu = mess+3;
-	*eol = 0;
-	ks = eol+3;
-	eol = strchr(ks, '\n');
-	if(!eol || strncmp("\nS=", eol, 3) != 0){
-		writerr(conn, "verifier syntax error for secstore 1.0");
-		goto done;
-	}
-	*eol = 0;
-	S = eol+3;
-	eol = strchr(S, '\n');
-	if(!eol){
-		writerr(conn, "verifier syntax error for secstore 1.0");
-		goto done;
-	}
-	*eol = 0;
-	if(pS)
-		*pS = estrdup(S);
-	strtomp(hexmu, nil, 64, mu);
-	mpexp(mu, x, pak->p, sigma);
-	hexsigma = mptoa(sigma, 64, nil, 0);
-	shorthash("server", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	enc64(kc, sizeof kc, digest, SHA1dlen);
-	if(strcmp(ks, kc) != 0){
-		writerr(conn, "verifier didn't match");
-		goto done;
-	}
-
-	// send hash2(g**xy)
-	shorthash("client", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	enc64(kc, sizeof kc, digest, SHA1dlen);
-	snprint(mess2, Maxmsg, "k'=%s\n", kc);
-	conn->write(conn, (uchar*)mess2, strlen(mess2));
-
-	// set session key
-	shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	memset(hexsigma, 0, strlen(hexsigma));
-	n = conn->secret(conn, digest, 0);
-	memset(digest, 0, SHA1dlen);
-	if(n < 0){
-		writerr(conn, "can't set secret");
-		goto done;
-	}
-
-	rc = 0;
-done:
-	mpfree(x);
-	mpfree(sigma);
-	mpfree(mu);
-	mpfree(m);
-	mpfree(Hi);
-	mpfree(H);
-	free(hexsigma);
-	free(hexHi);
-	free(hexm);
-	free(mess);
-	return rc;
-}
-
-// On input,
-//	mess contains first message;
-//	name is name this server should call itself.
-// On output, session secret has been set in conn;
-//	if pw!=nil, then *pw points to PW struct for authenticated user.
-//	returns -1 if error
-int
-PAKserver(SConn *conn, char *S, char *mess, PW **pwp)
-{
-	int rc = -1, n;
-	char mess2[Maxmsg+1], *eol;
-	char *C, ks[41], *kc, *hexm, *hexmu = nil, *hexsigma = nil, *hexHi = nil;
-	uchar digest[SHA1dlen];
-	mpint *H = mpnew(0), *Hi = mpnew(0);
-	mpint *y = nil, *m = mpnew(0), *mu = mpnew(0), *sigma = mpnew(0);
-	PW *pw = nil;
-
-	// secstore version and algorithm
-	snprint(mess2,Maxmsg,"%s\tPAK\n", VERSION);
-	n = strlen(mess2);
-	if(strncmp(mess,mess2,n) != 0){
-		writerr(conn, "protocol should start with ver alg");
-		return -1;
-	}
-	mess += n;
-	initPAKparams();
-
-	// parse first message into C, m
-	eol = strchr(mess, '\n');
-	if(strncmp("C=", mess, 2) != 0 || !eol){
-		fprint(2,"mess[1]=%s\n", mess);
-		writerr(conn, "PAK version mismatch");
-		goto done;
-	}
-	C = mess+2;
-	*eol = 0;
-	hexm = eol+3;
-	eol = strchr(hexm, '\n');
-	if(strncmp("m=", hexm-2, 2) != 0 || !eol){
-		writerr(conn, "PAK version mismatch");
-		goto done;
-	}
-	*eol = 0;
-	strtomp(hexm, nil, 64, m);
-	mpmod(m, pak->p, m);
-
-	// lookup client
-	if((pw = getPW(C,0)) == nil) {
-		snprint(mess2, sizeof mess2, "%r");
-		writerr(conn, mess2);
-		goto done;
-	}
-	if(mpcmp(m, mpzero) == 0) {
-		writerr(conn, "account exists");
-		freePW(pw);
-		pw = nil;
-		goto done;
-	}
-	hexHi = mptoa(pw->Hi, 64, nil, 0);
-
-	// random y, mu=g**y, sigma=g**xy
-	y = mprand(240, genrandom, nil);
-	mpmod(y, pak->q, y);
-	if(mpcmp(y, mpzero) == 0){
-		mpassign(mpone, y);
-	}
-	mpexp(pak->g, y, pak->p, mu);
-	mpmul(m, pw->Hi, m);
-	mpmod(m, pak->p, m);
-	mpexp(m, y, pak->p, sigma);
-
-	// send g**y, hash1(g**xy)
-	hexmu = mptoa(mu, 64, nil, 0);
-	hexsigma = mptoa(sigma, 64, nil, 0);
-	shorthash("server", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	enc64(ks, sizeof ks, digest, SHA1dlen);
-	snprint(mess2, sizeof mess2, "mu=%s\nk=%s\nS=%s\n", hexmu, ks, S);
-	conn->write(conn, (uchar*)mess2, strlen(mess2));
-
-	// recv hash2(g**xy)
-	if(readstr(conn, mess2) < 0){
-		writerr(conn, "couldn't read verifier");
-		goto done;
-	}
-	eol = strchr(mess2, '\n');
-	if(strncmp("k'=", mess2, 3) != 0 || !eol){
-		writerr(conn, "verifier syntax error");
-		goto done;
-	}
-	kc = mess2+3;
-	*eol = 0;
-	shorthash("client", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	enc64(ks, sizeof ks, digest, SHA1dlen);
-	if(strcmp(ks, kc) != 0) {
-		rc = -2;
-		goto done;
-	}
-
-	// set session key
-	shorthash("session", C, S, hexm, hexmu, hexsigma, hexHi, digest);
-	n = conn->secret(conn, digest, 1);
-	if(n < 0){
-		writerr(conn, "can't set secret");
-		goto done;
-	}
-
-	rc = 0;
-done:
-	if(rc<0 && pw){
-		pw->failed++;
-		putPW(pw);
-	}
-	if(rc==0 && pw && pw->failed>0){
-		pw->failed = 0;
-		putPW(pw);
-	}
-	if(pwp)
-		*pwp = pw;
-	else
-		freePW(pw);
-	free(hexsigma);
-	free(hexHi);
-	free(hexmu);
-	mpfree(y);
-	mpfree(sigma);
-	mpfree(mu);
-	mpfree(m);
-	mpfree(Hi);
-	mpfree(H);
-	return rc;
-}
-
blob - aacadd9b184dd688aaebfe8296426a75d7893001 (mode 644)
blob + /dev/null
--- src/cmd/secstore/password.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/* password.c */
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-#include "secstore.h"
-
-static Biobuf*
-openPW(char *id, int mode)
-{
-	Biobuf *b;
-	int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
-	char *fn = emalloc(nfn);
-
-	snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
-	b = Bopen(fn, mode);
-	free(fn);
-	return b;
-}
-
-static ulong
-mtimePW(char *id)
-{
-	Dir *d;
-	int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
-	char *fn = emalloc(nfn);
-	ulong mt;
-
-	snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
-	d = dirstat(fn);
-	free(fn);
-	mt = d->mtime;
-	free(d);
-	return mt;
-}
-
-PW *
-getPW(char *id, int dead_or_alive)
-{
-	uint now = time(0);
-	Biobuf *bin;
-	PW *pw;
-	char *f1, *f2; // fields 1, 2 = attribute, value
-
-	if((bin = openPW(id, OREAD)) == 0){
-		id = "FICTITIOUS";
-		if((bin = openPW(id, OREAD)) == 0){
-			werrstr("account does not exist");
-			return nil;
-		}
-	}
-	pw = emalloc(sizeof(*pw));
-	pw->id = estrdup(id);
-	pw->status |= Enabled;
-	while( (f1 = Brdline(bin, '\n')) != 0){
-		f1[Blinelen(bin)-1] = 0;
-		for(f2 = f1; *f2 && (*f2!=' ') && (*f2!='\t'); f2++){}
-		if(*f2)
-			for(*f2++ = 0; *f2 && (*f2==' ' || *f2=='\t'); f2++){}
-		if(strcmp(f1, "exp") == 0){
-			pw->expire = strtoul(f2, 0, 10);
-		}else if(strcmp(f1, "DISABLED") == 0){
-			pw->status &= ~Enabled;
-		}else if(strcmp(f1, "STA") == 0){
-			pw->status |= STA;
-		}else if(strcmp(f1, "failed") == 0){
-			pw->failed = strtoul(f2, 0, 10);
-		}else if(strcmp(f1, "other") == 0){
-			pw->other = estrdup(f2);
-		}else if(strcmp(f1, "PAK-Hi") == 0){
-			pw->Hi = strtomp(f2, nil, 64, nil);
-		}
-	}
-	Bterm(bin);
-	if(dead_or_alive)
-		return pw;  // return PW entry for editing, whether currently valid or not
-	if(pw->expire <= now){
-		werrstr("account expired");
-		freePW(pw);
-		return nil;
-	}
-	if((pw->status & Enabled) == 0){
-		werrstr("account disabled");
-		freePW(pw);
-		return nil;
-	}
-	if(pw->failed < 10)
-		return pw;  // success
-	if(now < mtimePW(id)+300){
-		werrstr("too many failures; try again in five minutes");
-		freePW(pw);
-		return nil;
-	}
-	pw->failed = 0;
-	putPW(pw);  // reset failed-login-counter after five minutes
-	return pw;
-}
-
-int
-putPW(PW *pw)
-{
-	Biobuf *bout;
-	char *hexHi;
-
-	if((bout = openPW(pw->id, OWRITE|OTRUNC)) ==0){
-		werrstr("can't open PW file");
-		return -1;
-	}
-	Bprint(bout, "exp	%lud\n", pw->expire);
-	if(!(pw->status & Enabled))
-		Bprint(bout, "DISABLED\n");
-	if(pw->status & STA)
-		Bprint(bout, "STA\n");
-	if(pw->failed)
-		Bprint(bout, "failed\t%d\n", pw->failed);
-	if(pw->other)
-		Bprint(bout,"other\t%s\n", pw->other);
-	hexHi = mptoa(pw->Hi, 64, nil, 0);
-	Bprint(bout, "PAK-Hi\t%s\n", hexHi);
-	free(hexHi);
-	return 0;
-}
-
-void
-freePW(PW *pw)
-{
-	if(pw == nil)
-		return;
-	free(pw->id);
-	free(pw->other);
-	mpfree(pw->Hi);
-	free(pw);
-}
-
blob - 8d50496e37164560e61fe1703fbc71212ce90555 (mode 644)
blob + /dev/null
--- src/cmd/secstore/portdate
+++ /dev/null
@@ -1,9 +0,0 @@
-SConn.c		2004/1225
-SConn.h		2004/1225
-aescbc.c		2004/1225
-dirls.c		2004/1225
-pak.c		2004/1225
-password.c		2004/1225
-secstore.c		2004/1225
-secstore.h		2004/1225
-util.c		2004/1225
blob - 4390129a1bd5beab28c664d673985630f9dcbf44 (mode 644)
blob + /dev/null
--- src/cmd/secstore/secacct.c
+++ /dev/null
@@ -1,35 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <ip.h>
-
-int verbose = 1;
-static char testmess[] = "__secstore\tPAK\nC=%s\nm=0\n";
-
-void
-main(int argc, char **argv)
-{
-	int n, m, fd;
-	uchar buf[500];
-
-	if(argc != 2)
-		exits("usage: secacct userid");
-
-	n = snprint((char*)buf, sizeof buf, testmess, argv[1]);
-	hnputs(buf, 0x8000+n-2);
-
-	fd = dial("tcp!ruble.cs.bell-labs.com!5356", 0, 0, 0);
-	if(fd < 0)
-		exits("cannot dial ruble");
-	if(write(fd, buf, n) != n || readn(fd, buf, 2) != 2)
-		exits("cannot exchange first round");
-	n = ((buf[0]&0x7f)<<8) + buf[1];
-	if(n+1 > sizeof buf)
-		exits("implausibly large count");
-	m = readn(fd, buf, n);
-	close(fd);
-	if(m != n)
-		fprint(2,"short read from secstore\n");
-	buf[m] = 0;
-	print("%s\n", (char*)buf);
-	exits(0);
-}
blob - 59e26d512ae6dfda4aec0a121c6ae5a7ad5ce2db (mode 644)
blob + /dev/null
--- src/cmd/secstore/secchk.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <ndb.h>
-
-extern char* secureidcheck(char *user, char *response);
-Ndb *db;
-
-void
-main(int argc, char **argv)
-{
-	Ndb *db2;
-
-	if(argc!=2){
-		fprint(2,"usage %s pinsecurid\n", argv[0]);
-		exits("usage");
-	}
-	db = ndbopen("/lib/ndb/auth");
-	if(db == 0)
-		syslog(0, "secstore", "no /lib/ndb/auth");
-	db2 = ndbopen(0);
-	if(db2 == 0)
-		syslog(0, "secstore", "no /lib/ndb/local");
-	db = ndbcat(db, db2);
-	print("user=%s\n", getenv("user"));
-	print("%s\n", secureidcheck(getenv("user"), argv[1]));
-	exits(0);
-}
blob - 864aa88d373b8467e7e1ba060d36a6a86b99ba4f (mode 644)
blob + /dev/null
--- src/cmd/secstore/secstore.c
+++ /dev/null
@@ -1,585 +0,0 @@
-/* network login client */
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include <authsrv.h>
-#include "SConn.h"
-#include "secstore.h"
-enum{ CHK = 16, MAXFILES = 100 };
-
-typedef struct AuthConn{
-	SConn *conn;
-	char pass[64];
-	int passlen;
-} AuthConn;
-
-int verbose;
-Nvrsafe nvr;
-char *SECSTORE_DIR;
-
-void
-usage(void)
-{
-	fprint(2, "usage: secstore [-cin] [-g getfile] [-p putfile] [-r rmfile] [-s tcp!server!5356] [-u user] [-v]\n");
-	exits("usage");
-}
-
-static int
-getfile(SConn *conn, char *gf, uchar **buf, ulong *buflen, uchar *key, int nkey)
-{
-	int fd = -1;
-	int i, n, nr, nw, len;
-	char s[Maxmsg+1];
-	uchar skey[SHA1dlen], ib[Maxmsg+CHK], *ibr, *ibw, *bufw, *bufe;
-	AESstate aes;
-	DigestState *sha;
-
-	if(strchr(gf, '/')){
-		fprint(2, "simple filenames, not paths like %s\n", gf);
-		return -1;
-	}
-	memset(&aes, 0, sizeof aes);
-
-	snprint(s, Maxmsg, "GET %s\n", gf);
-	conn->write(conn, (uchar*)s, strlen(s));
-
-	/* get file size */
-	s[0] = '\0';
-	bufw = bufe = nil;
-	if(readstr(conn, s) < 0){
-		fprint(2, "remote: %s\n", s);
-		return -1;
-	}
-	len = atoi(s);
-	if(len == -1){
-		fprint(2, "remote file %s does not exist\n", gf);
-		return -1;
-	}else if(len == -3){
-		fprint(2, "implausible filesize for %s\n", gf);
-		return -1;
-	}else if(len < 0){
-		fprint(2, "GET refused for %s\n", gf);
-		return -1;
-	}
-	if(buf != nil){
-		*buflen = len - AESbsize - CHK;
-		*buf = bufw = emalloc(len);
-		bufe = bufw + len;
-	}
-
-	/* directory listing */
-	if(strcmp(gf,".")==0){
-		if(buf != nil)
-			*buflen = len;
-		for(i=0; i < len; i += n){
-			if((n = conn->read(conn, (uchar*)s, Maxmsg)) <= 0){
-				fprint(2, "empty file chunk\n");
-				return -1;
-			}
-			if(buf == nil)
-				write(1, s, n);
-			else
-				memmove((*buf)+i, s, n);
-		}
-		return 0;
-	}
-
-	/* conn is already encrypted against wiretappers, 
-		but gf is also encrypted against server breakin. */
-	if(buf == nil && (fd =create(gf, OWRITE, 0600)) < 0){
-		fprint(2, "can't open %s: %r\n", gf);
-		return -1;
-	}
-
-	ibr = ibw = ib;
-	for(nr=0; nr < len;){
-		if((n = conn->read(conn, ibw, Maxmsg)) <= 0){
-			fprint(2, "empty file chunk n=%d nr=%d len=%d: %r\n", n, nr, len);
-			return -1;
-		}
-		nr += n;
-		ibw += n;
-		if(!aes.setup){ /* first time, read 16 byte IV */
-			if(n < AESbsize){
-				fprint(2, "no IV in file\n");
-				return -1;
-			}
-			sha = sha1((uchar*)"aescbc file", 11, nil, nil);
-			sha1(key, nkey, skey, sha);
-			setupAESstate(&aes, skey, AESbsize, ibr);
-			memset(skey, 0, sizeof skey);
-			ibr += AESbsize;
-			n -= AESbsize;
-		}
-		aesCBCdecrypt(ibw-n, n, &aes);
-		n = ibw-ibr-CHK;
-		if(n > 0){
-			if(buf == nil){
-				nw = write(fd, ibr, n);
-				if(nw != n){
-					fprint(2, "write error on %s", gf);
-					return -1;
-				}
-			}else{
-				assert(bufw+n <= bufe);
-				memmove(bufw, ibr, n);
-				bufw += n;
-			}
-			ibr += n;
-		}
-		memmove(ib, ibr, ibw-ibr);
-		ibw = ib + (ibw-ibr);
-		ibr = ib;
-	}
-	if(buf == nil)
-		close(fd);
-	n = ibw-ibr;
-	if((n != CHK) || (memcmp(ib, "XXXXXXXXXXXXXXXX", CHK) != 0)){
-			fprint(2,"decrypted file failed to authenticate!\n");
-			return -1;
-	}
-	return 0;
-}
-
-// This sends a file to the secstore disk that can, in an emergency, be
-// decrypted by the program aescbc.c.
-static int
-putfile(SConn *conn, char *pf, uchar *buf, ulong len, uchar *key, int nkey)
-{
-	int i, n, fd, ivo, bufi, done;
-	char s[Maxmsg];
-	uchar  skey[SHA1dlen], b[CHK+Maxmsg], IV[AESbsize];
-	AESstate aes;
-	DigestState *sha;
-
-	/* create initialization vector */
-	srand(time(0));  /* doesn't need to be unpredictable */
-	for(i=0; i<AESbsize; i++)
-		IV[i] = 0xff & rand();
-	sha = sha1((uchar*)"aescbc file", 11, nil, nil);
-	sha1(key, nkey, skey, sha);
-	setupAESstate(&aes, skey, AESbsize, IV);
-	memset(skey, 0, sizeof skey);
-
-	snprint(s, Maxmsg, "PUT %s\n", pf);
-	conn->write(conn, (uchar*)s, strlen(s));
-
-	if(buf == nil){
-		/* get file size */
-		if((fd = open(pf, OREAD)) < 0){
-			fprint(2, "can't open %s: %r\n", pf);
-			return -1;
-		}
-		len = seek(fd, 0, 2);
-		seek(fd, 0, 0);
-	} else {
-		fd = -1;
-	}
-	if(len > MAXFILESIZE){
-		fprint(2, "implausible filesize %ld for %s\n", len, pf);
-		return -1;
-	}
-
-	/* send file size */
-	snprint(s, Maxmsg, "%ld", len+AESbsize+CHK);
-	conn->write(conn, (uchar*)s, strlen(s));
-
-	/* send IV and file+XXXXX in Maxmsg chunks */
-	ivo = AESbsize;
-	bufi = 0;
-	memcpy(b, IV, ivo);
-	for(done = 0; !done; ){
-		if(buf == nil){
-			n = read(fd, b+ivo, Maxmsg-ivo);
-			if(n < 0){
-				fprint(2, "read error on %s: %r\n", pf);
-				return -1;
-			}
-		}else{
-			if((n = len - bufi) > Maxmsg-ivo)	
-				n = Maxmsg-ivo;
-			memcpy(b+ivo, buf+bufi, n);
-			bufi += n;
-		}
-		n += ivo;
-		ivo = 0;
-		if(n < Maxmsg){ /* EOF on input; append XX... */
-			memset(b+n, 'X', CHK);
-			n += CHK; // might push n>Maxmsg
-			done = 1;
-		}
-		aesCBCencrypt(b, n, &aes);
-		if(n > Maxmsg){
-			assert(done==1);
-			conn->write(conn, b, Maxmsg);
-			n -= Maxmsg;
-			memmove(b, b+Maxmsg, n);
-		}
-		conn->write(conn, b, n);
-	}
-
-	if(buf == nil)
-		close(fd);
-	fprint(2, "saved %ld bytes\n", len);
-
-	return 0;
-}
-
-static int
-removefile(SConn *conn, char *rf)
-{
-	char buf[Maxmsg];
-
-	if(strchr(rf, '/')){
-		fprint(2, "simple filenames, not paths like %s\n", rf);
-		return -1;
-	}
-
-	snprint(buf, Maxmsg, "RM %s\n", rf);
-	conn->write(conn, (uchar*)buf, strlen(buf));
-
-	return 0;
-}
-
-static int
-cmd(AuthConn *c, char **gf, int *Gflag, char **pf, char **rf)
-{
-	ulong len;
-	int rv = -1;
-	uchar *memfile, *memcur, *memnext;
-
-	while(*gf != nil){
-		if(verbose)
-			fprint(2, "get %s\n", *gf);
-		if(getfile(c->conn, *gf, *Gflag ? &memfile : nil, &len, (uchar*)c->pass, c->passlen) < 0)
-			goto Out;
-		if(*Gflag){
-			// write one line at a time, as required by /mnt/factotum/ctl
-			memcur = memfile;
-			while(len>0){
-				memnext = (uchar*)strchr((char*)memcur, '\n');
-				if(memnext){
-					write(1, memcur, memnext-memcur+1);
-					len -= memnext-memcur+1;
-					memcur = memnext+1;
-				}else{
-					write(1, memcur, len);
-					break;
-				}
-			}
-			free(memfile);
-		}
-		gf++;
-		Gflag++;
-	}
-	while(*pf != nil){
-		if(verbose)
-			fprint(2, "put %s\n", *pf);
-		if(putfile(c->conn, *pf, nil, 0, (uchar*)c->pass, c->passlen) < 0)
-			goto Out;
-		pf++;
-	}
-	while(*rf != nil){
-		if(verbose)
-			fprint(2, "rm  %s\n", *rf);
-		if(removefile(c->conn, *rf) < 0)
-			goto Out;
-		rf++;
-	}
-
-	c->conn->write(c->conn, (uchar*)"BYE", 3);
-	rv = 0;
-
-Out:
-	c->conn->free(c->conn);
-	return rv;
-}
-
-static int
-chpasswd(AuthConn *c, char *id)
-{
-	ulong len;
-	int rv = -1, newpasslen = 0;
-	mpint *H, *Hi;
-	uchar *memfile;
-	char *newpass, *passck;
-	char *list, *cur, *next, *hexHi;
-	char *f[8], prompt[128];
-
-	H = mpnew(0);
-	Hi = mpnew(0);
-	// changing our password is vulnerable to connection failure
-	for(;;){
-		snprint(prompt, sizeof(prompt), "new password for %s: ", id);
-		newpass = readcons(prompt, nil, 1);
-		if(newpass == nil)
-			goto Out;
-		if(strlen(newpass) >= 7)
-			break;
-		else if(strlen(newpass) == 0){
-			fprint(2, "!password change aborted\n");
-			goto Out;
-		}
-		print("!password must be at least 7 characters\n");
-	}
-	newpasslen = strlen(newpass);
-	snprint(prompt, sizeof(prompt), "retype password: ");
-	passck = readcons(prompt, nil, 1);
-	if(passck == nil){
-		fprint(2, "readcons failed\n");
-		goto Out;
-	}
-	if(strcmp(passck, newpass) != 0){
-		fprint(2, "passwords didn't match\n");
-		goto Out;
-	}
-
-	c->conn->write(c->conn, (uchar*)"CHPASS", strlen("CHPASS"));
-	hexHi = PAK_Hi(id, newpass, H, Hi);
-	c->conn->write(c->conn, (uchar*)hexHi, strlen(hexHi));
-	free(hexHi);
-	mpfree(H);
-	mpfree(Hi);
-
-	if(getfile(c->conn, ".", (uchar **)(void*)&list, &len, nil, 0) < 0){
-		fprint(2, "directory listing failed.\n");
-		goto Out;
-	}
-
-	/* Loop over files and reencrypt them; try to keep going after error */
-	for(cur=list; (next=strchr(cur, '\n')) != nil; cur=next+1){
-		*next = '\0';
-		if(tokenize(cur, f, nelem(f))< 1)
-			break;
-		fprint(2, "reencrypting '%s'\n", f[0]);
-		if(getfile(c->conn, f[0], &memfile, &len, (uchar*)c->pass, c->passlen) < 0){
-			fprint(2, "getfile of '%s' failed\n", f[0]);
-			continue;
-		}
-		if(putfile(c->conn, f[0], memfile, len, (uchar*)newpass, newpasslen) < 0)
-			fprint(2, "putfile of '%s' failed\n", f[0]);
-		free(memfile);
-	}
-	free(list);
-	c->conn->write(c->conn, (uchar*)"BYE", 3);
-	rv = 0;
-
-Out:
-	if(newpass != nil){
-		memset(newpass, 0, newpasslen);
-		free(newpass);
-	}
-	c->conn->free(c->conn);
-	return rv;
-}
-
-static AuthConn*
-login(char *id, char *dest, int pass_stdin, int pass_nvram)
-{
-	AuthConn *c;
-	int fd, n, ntry = 0;
-	char *S, *PINSTA = nil, *nl, s[Maxmsg+1], *pass;
-
-	if(dest == nil){
-		fprint(2, "tried to login with nil dest\n");
-		exits("nil dest");
-	}
-	c = emalloc(sizeof(*c));
-	if(pass_nvram){
-		/* if(readnvram(&nvr, 0) < 0) */
-			exits("readnvram: %r");
-		strecpy(c->pass, c->pass+sizeof c->pass, nvr.config);
-	}
-	if(pass_stdin){
-		n = readn(0, s, Maxmsg-2);  // so len(PINSTA)<Maxmsg-3
-		if(n < 1)
-			exits("no password on standard input");
-		s[n] = 0;
-		nl = strchr(s, '\n');
-		if(nl){
-			*nl++ = 0;
-			PINSTA = estrdup(nl);
-			nl = strchr(PINSTA, '\n');
-			if(nl)
-				*nl = 0;
-		}
-		strecpy(c->pass, c->pass+sizeof c->pass, s);
-	}
-	while(1){
-		if(verbose)
-			fprint(2, "dialing %s\n", dest);
-		if((fd = dial(dest, nil, nil, nil)) < 0){
-			fprint(2, "can't dial %s\n", dest);
-			free(c);
-			return nil;
-		}
-		if((c->conn = newSConn(fd)) == nil){
-			free(c);
-			return nil;
-		}
-		ntry++;
-		if(!pass_stdin && !pass_nvram){
-			pass = readcons("secstore password", nil, 1);
-			if(pass == nil)
-				pass = estrdup("");
-			if(strlen(pass) >= sizeof c->pass){
-				fprint(2, "password too long, skipping secstore login\n");
-				exits("password too long");
-			}
-			strcpy(c->pass, pass);
-			memset(pass, 0, strlen(pass));
-			free(pass);
-		}
-		if(c->pass[0]==0){
-			fprint(2, "null password, skipping secstore login\n");
-			exits("no password");
-		}
-		if(PAKclient(c->conn, id, c->pass, &S) >= 0)
-			break;
-		c->conn->free(c->conn);
-		if(pass_stdin)
-			exits("invalid password on standard input");
-		if(pass_nvram)
-			exits("invalid password in nvram");
-		// and let user try retyping the password
-		if(ntry==3)
-			fprint(2, "Enter an empty password to quit.\n");
-	}
-	c->passlen = strlen(c->pass);
-	fprint(2, "server: %s\n", S);
-	free(S);
-	if(readstr(c->conn, s) < 0){
-		c->conn->free(c->conn);
-		free(c);
-		return nil;
-	}
-	if(strcmp(s, "STA") == 0){
-		long sn;
-		if(pass_stdin){
-			if(PINSTA)
-				strncpy(s+3, PINSTA, (sizeof s)-3);
-			else
-				exits("missing PIN+SecureID on standard input");
-			free(PINSTA);
-		}else{
-			pass = readcons("STA PIN+SecureID", nil, 1);
-			if(pass == nil)
-				pass = estrdup("");
-			strncpy(s+3, pass, (sizeof s)-4);
-			memset(pass, 0, strlen(pass));
-			free(pass);
-		}
-		sn = strlen(s+3);
-		if(verbose)
-			fprint(2, "%ld\n", sn);
-		c->conn->write(c->conn, (uchar*)s, sn+3);
-		readstr(c->conn, s);
-	}
-	if(strcmp(s, "OK") != 0){
-		fprint(2, "%s\n", s);
-		c->conn->free(c->conn);
-		free(c);
-		return nil;
-	}
-	return c;
-}
-
-int
-main(int argc, char **argv)
-{
-	int chpass = 0, pass_stdin = 0, pass_nvram = 0, rc;
-	int ngfile = 0, npfile = 0, nrfile = 0, Gflag[MAXFILES+1];
-	char *gfile[MAXFILES], *pfile[MAXFILES], *rfile[MAXFILES];
-	char *serve, *tcpserve, *user;
-	AuthConn *c;
-
-	serve = "$auth";
-	user = getuser();
-	memset(Gflag, 0, sizeof Gflag);
-	fmtinstall('B', mpfmt);
-	fmtinstall('H', encodefmt);
-
-	ARGBEGIN{
-	case 'c':
-		chpass = 1;
-		break;
-	case 'G':
-		Gflag[ngfile]++;
-		/* fall through */
-	case 'g':
-		if(ngfile >= MAXFILES)
-			exits("too many gfiles");
-		gfile[ngfile++] = ARGF();
-		if(gfile[ngfile-1] == nil)
-			usage();
-		break;
-	case 'i':
-		pass_stdin = 1;
-		break;
-	case 'n':
-		pass_nvram = 1;
-		break;
-	case 'p':
-		if(npfile >= MAXFILES)
-			exits("too many pfiles");
-		pfile[npfile++] = ARGF();
-		if(pfile[npfile-1] == nil)
-			usage();
-		break;
-	case 'r':
-		if(nrfile >= MAXFILES)
-			exits("too many rfiles");
-		rfile[nrfile++] = ARGF();
-		if(rfile[nrfile-1] == nil)
-			usage();
-		break;
-	case 's':
-		serve = EARGF(usage());
-		break;
-	case 'u':
-		user = EARGF(usage());
-		break;
-	case 'v':
-		verbose++;
-		break;
-	default:
-		usage();
-		break;
-	}ARGEND;
-	gfile[ngfile] = nil;
-	pfile[npfile] = nil;
-	rfile[nrfile] = nil;
-
-	if(argc!=0 || user==nil)
-		usage();
-
-	if(chpass && (ngfile || npfile || nrfile)){
-		fprint(2, "Get, put, and remove invalid with password change.\n");
-		exits("usage");
-	}
-
-	rc = strlen(serve)+sizeof("tcp!!99990");
-	tcpserve = emalloc(rc);
-	if(strchr(serve,'!'))
-		strcpy(tcpserve, serve);
-	else
-		snprint(tcpserve, rc, "tcp!%s!5356", serve);
-	c = login(user, tcpserve, pass_stdin, pass_nvram);
-	free(tcpserve);
-	if(c == nil){
-		fprint(2, "secstore authentication failed\n");
-		exits("secstore authentication failed");
-	}
-	if(chpass)
-		rc = chpasswd(c, user);
-	else
-		rc = cmd(c, gfile, Gflag, pfile, rfile);
-	if(rc < 0){
-		fprint(2, "secstore cmd failed\n");
-		exits("secstore cmd failed");
-	}
-	exits("");
-	return 0;
-}
-
blob - dbd2ec9cfeec4dd3aad3a57c5fd9a602ce10168c (mode 644)
blob + /dev/null
--- src/cmd/secstore/secstore.h
+++ /dev/null
@@ -1,31 +0,0 @@
-enum{ MAXFILESIZE = 10*1024*1024 };
-
-enum{// PW status bits
-	Enabled 	= (1<<0),
-	STA 		= (1<<1),	// extra SecurID step
-};
-
-typedef struct PW {
-	char *id;		// user id
-	ulong expire;	// expiration time (epoch seconds)
-	ushort status;	// Enabled, STA, ...
-	ushort failed;	// number of failed login attempts
-	char *other;	// other information, e.g. sponsor
-	mpint *Hi;  	// H(passphrase)^-1 mod p
-} PW;
-
-PW *getPW(char *, int);
-int putPW(PW *);
-void freePW(PW *);
-
-// *client: SConn, client name, passphrase
-// *server: SConn, (partial) 1st msg, PW entry
-// *setpass: Username, hashed passphrase, PW entry
-int PAKclient(SConn *, char *, char *, char **);
-int PAKserver(SConn *, char *, char *, PW **);
-char *PAK_Hi(char *, char *, mpint *, mpint *);
-
-#define LOG "secstore"
-
-extern	char	*SECSTORE_DIR;
-
blob - 58f7459aec7b6f1783fda5734c1693cffecde193 (mode 644)
blob + /dev/null
--- src/cmd/secstore/secstored.c
+++ /dev/null
@@ -1,420 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <ndb.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-#include "secstore.h"
-
-char *SECSTORE_DIR;
-char* secureidcheck(char *, char *);   // from /sys/src/cmd/auth/
-extern char* dirls(char *path);
-
-int verbose;
-Ndb *db;
-
-static void
-usage(void)
-{
-	fprint(2, "usage: secstored [-R] [-S servername] [-s tcp!*!5356] [-v] [-x netmtpt]\n");
-	exits("usage");
-}
-
-static int
-getdir(SConn *conn, char *id)
-{
-	char *ls, *s; 
-	uchar *msg;
-	int n, len;
-
-	s = emalloc(Maxmsg);
-	snprint(s, Maxmsg, "%s/store/%s", SECSTORE_DIR, id);
-
-	if((ls = dirls(s)) == nil)
-		len = 0;
-	else
-		len = strlen(ls);
-
-	/* send file size */
-	snprint(s, Maxmsg, "%d", len);
-	conn->write(conn, (uchar*)s, strlen(s));
-
-	/* send directory listing in Maxmsg chunks */
-	n = Maxmsg;
-	msg = (uchar*)ls;
-	while(len > 0){
-		if(len < Maxmsg)
-			n = len;
-		conn->write(conn, msg, n);
-		msg += n;
-		len -= n;
-	}
-	free(s);
-	free(ls);
-	return 0;
-}
-
-char *
-validatefile(char *f)
-{
-	char *nl;
-
-	if(f==nil || *f==0)
-		return nil;
-	if(nl = strchr(f, '\n'))
-		*nl = 0;
-	if(strchr(f,'/') != nil || strcmp(f,"..")==0 || strlen(f) >= 300){
-		syslog(0, LOG, "no slashes allowed: %s\n", f);
-		return nil;
-	}
-	return f;
-}
-
-static int
-getfile(SConn *conn, char *id, char *gf)
-{
-	int n, gd, len;
-	ulong mode;
-	char *s;
-	Dir *st;
-
-	if(strcmp(gf,".")==0)
-		return getdir(conn, id);
-
-	/* send file size */
-	s = emalloc(Maxmsg);
-	snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, gf);
-	gd = open(s, OREAD);
-	if(gd < 0){
-		syslog(0, LOG, "can't open %s: %r\n", s);
-		free(s);
-		conn->write(conn, (uchar*)"-1", 2);
-		return -1;
-	}
-	st = dirfstat(gd);
-	if(st == nil){
-		syslog(0, LOG, "can't stat %s: %r\n", s);
-		free(s);
-		conn->write(conn, (uchar*)"-1", 2);
-		return -1;
-	}
-	mode = st->mode;
-	len = st->length;
-	free(st);
-	if(mode & DMDIR) {
-		syslog(0, LOG, "%s should be a plain file, not a directory\n", s);
-		free(s);
-		conn->write(conn, (uchar*)"-1", 2);
-		return -1;
-	}
-	if(len < 0 || len > MAXFILESIZE){
-		syslog(0, LOG, "implausible filesize %d for %s\n", len, gf);
-		free(s);
-		conn->write(conn, (uchar*)"-3", 2);
-		return -1;
-	}
-	snprint(s, Maxmsg, "%d", len);
-	conn->write(conn, (uchar*)s, strlen(s));
-
-	/* send file in Maxmsg chunks */
-	while(len > 0){
-		n = read(gd, s, Maxmsg);
-		if(n <= 0){
-			syslog(0, LOG, "read error on %s: %r\n", gf);
-			free(s);
-			return -1;
-		}
-		conn->write(conn, (uchar*)s, n);
-		len -= n;
-	}
-	close(gd);
-	free(s);
-	return 0;
-}
-
-static int
-putfile(SConn *conn, char *id, char *pf)
-{
-	int n, nw, pd;
-	long len;
-	char s[Maxmsg+1];
-
-	/* get file size */
-	n = readstr(conn, s);
-	if(n < 0){
-		syslog(0, LOG, "remote: %s: %r\n", s);
-		return -1;
-	}
-	len = atoi(s);
-	if(len == -1){
-		syslog(0, LOG, "remote file %s does not exist\n", pf);
-		return -1;
-	}else if(len < 0 || len > MAXFILESIZE){
-		syslog(0, LOG, "implausible filesize %ld for %s\n", len, pf);
-		return -1;
-	}
-
-	/* get file in Maxmsg chunks */
-	if(strchr(pf,'/') != nil || strcmp(pf,"..")==0){
-		syslog(0, LOG, "no slashes allowed: %s\n", pf);
-		return -1;
-	}
-	snprint(s, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, pf);
-	pd = create(s, OWRITE, 0660);
-	if(pd < 0){
-		syslog(0, LOG, "can't open %s: %r\n", s);
-		return -1;
-	}
-	while(len > 0){
-		n = conn->read(conn, (uchar*)s, Maxmsg);
-		if(n <= 0){
-			syslog(0, LOG, "empty file chunk\n");
-			return -1;
-		}
-		nw = write(pd, s, n);
-		if(nw != n){
-			syslog(0, LOG, "write error on %s: %r", pf);
-			return -1;
-		}
-		len -= n;
-	}
-	close(pd);
-	return 0;
-
-}
-
-static int
-removefile(SConn *conn, char *id, char *f)
-{
-	Dir *d;
-	char buf[Maxmsg];
-
-	snprint(buf, Maxmsg, "%s/store/%s/%s", SECSTORE_DIR, id, f);
-
-	if((d = dirstat(buf)) == nil){
-		snprint(buf, sizeof buf, "remove failed: %r");
-		writerr(conn, buf);
-		return -1;
-	}else if(d->mode & DMDIR){
-		snprint(buf, sizeof buf, "can't remove a directory");
-		writerr(conn, buf);
-		free(d);
-		return -1;
-	}
-
-	free(d);
-	if(remove(buf) < 0){
-		snprint(buf, sizeof buf, "remove failed: %r");
-		writerr(conn, buf);
-		return -1;
-	}
-	return 0;
-}
-
-/* given line directory from accept, returns ipaddr!port */
-static char*
-remoteIP(char *ldir)
-{
-	int fd, n;
-	char rp[100], ap[500];
-
-	snprint(rp, sizeof rp, "%s/remote", ldir);
-	fd = open(rp, OREAD);
-	if(fd < 0)
-		return strdup("?!?");
-	n = read(fd, ap, sizeof ap);
-	if(n <= 0 || n == sizeof ap){
-		fprint(2, "error %d reading %s: %r\n", n, rp);
-		return strdup("?!?");
-	}
-	close(fd);
-	ap[n--] = 0;
-	if(ap[n] == '\n')
-		ap[n] = 0;
-	return strdup(ap);
-}
-
-static int
-dologin(int fd, char *S, int forceSTA)
-{
-	int i, n, rv;
-	char *file, *mess;
-	char msg[Maxmsg+1];
-	PW *pw;
-	SConn *conn;
-
-	pw = nil;
-	rv = -1;
-
-	// collect the first message
-	if((conn = newSConn(fd)) == nil)
-		return -1;
-	if(readstr(conn, msg) < 0){
-		fprint(2, "remote: %s: %r\n", msg);
-		writerr(conn, "can't read your first message");
-		goto Out;
-	}
-
-	// authenticate
-	if(PAKserver(conn, S, msg, &pw) < 0){
-		if(pw != nil)
-			syslog(0, LOG, "secstore denied for %s", pw->id);
-		goto Out;
-	}
-	if((forceSTA || pw->status&STA) != 0){
-		conn->write(conn, (uchar*)"STA", 3);
-		if(readstr(conn, msg) < 10 || strncmp(msg, "STA", 3) != 0){
-			syslog(0, LOG, "no STA from %s", pw->id);
-			goto Out;
-		}
-		mess = secureidcheck(pw->id, msg+3);
-		if(mess != nil){
-			syslog(0, LOG, "secureidcheck denied %s because %s", pw->id, mess);
-			goto Out;
-		}
-	}
-	conn->write(conn, (uchar*)"OK", 2);
-	syslog(0, LOG, "AUTH %s", pw->id);
-
-	// perform operations as asked
-	while((n = readstr(conn, msg)) > 0){
-		syslog(0, LOG, "[%s] %s", pw->id, msg);
-
-		if(strncmp(msg, "GET ", 4) == 0){
-			file = validatefile(msg+4);
-			if(file==nil || getfile(conn, pw->id, file) < 0)
-				goto Err;
-
-		}else if(strncmp(msg, "PUT ", 4) == 0){
-			file = validatefile(msg+4);
-			if(file==nil || putfile(conn, pw->id, file) < 0){
-				syslog(0, LOG, "failed PUT %s/%s", pw->id, file);
-				goto Err;
-			}
-
-		}else if(strncmp(msg, "RM ", 3) == 0){
-			file = validatefile(msg+3);
-			if(file==nil || removefile(conn, pw->id, file) < 0){
-				syslog(0, LOG, "failed RM %s/%s", pw->id, file);
-				goto Err;
-			}
-
-		}else if(strncmp(msg, "CHPASS", 6) == 0){
-			if(readstr(conn, msg) < 0){
-				syslog(0, LOG, "protocol botch CHPASS for %s", pw->id);
-				writerr(conn, "protocol botch while setting PAK");
-				goto Out;
-			}
-			pw->Hi = strtomp(msg, nil, 64, pw->Hi);
-			for(i=0; i < 4 && putPW(pw) < 0; i++)
-				syslog(0, LOG, "password change failed for %s (%d): %r", pw->id, i);
-			if(i==4)
-				goto Out;
-
-		}else if(strncmp(msg, "BYE", 3) == 0){
-			rv = 0;
-			break;
-
-		}else{
-			writerr(conn, "unrecognized operation");
-			break;
-		}
-
-	}
-	if(n <= 0)
-		syslog(0, LOG, "%s closed connection without saying goodbye\n", pw->id);
-
-Out:
-	freePW(pw);
-	conn->free(conn);
-	return rv;
-Err:
-	writerr(conn, "operation failed");
-	goto Out;
-}
-
-void
-main(int argc, char **argv)
-{
-	int afd, dfd, lcfd, forceSTA = 0;
-	char adir[40], ldir[40], *remote;
-	char *serve = "tcp!*!5356", *p, aserve[128];
-	char *S = "secstore";
-	char *dbpath;
-	Ndb *db2;
-
-	S = sysname();
-	SECSTORE_DIR = unsharp("#9/secstore");
-//	setnetmtpt(net, sizeof(net), nil);
-	ARGBEGIN{
-	case 'R':
-		forceSTA = 1;
-		break;
-	case 's':
-		serve = EARGF(usage());
-		break;
-	case 'S':
-		S = EARGF(usage());
-		break;
-	case 'x':
-		p = ARGF();
-		if(p == nil)
-			usage();
-		USED(p);
-	//	setnetmtpt(net, sizeof(net), p);
-		break;
-	case 'v':
-		verbose++;
-		break;
-	default:
-		usage();
-	}ARGEND;
-
-	if(!verbose)
-		switch(rfork(RFNOTEG|RFPROC|RFFDG)) {
-		case -1:
-			sysfatal("fork: %r");
-		case 0:
-			break;
-		default:
-			exits(0);
-		}
-
-	snprint(aserve, sizeof aserve, "%s", serve);
-	afd = announce(aserve, adir);
-	if(afd < 0)
-		sysfatal("%s: %r\n", aserve);
-	syslog(0, LOG, "ANNOUNCE %s", aserve);
-	for(;;){
-		if((lcfd = listen(adir, ldir)) < 0)
-			exits("can't listen");
-		switch(fork()){
-		case -1:
-			fprint(2, "secstore forking: %r\n");
-			close(lcfd);
-			break;
-		case 0:
-			// "/lib/ndb/common.radius does not exist" if db set before fork
-			db = ndbopen(dbpath=unsharp("#9/ndb/auth"));
-			if(db == 0)
-				syslog(0, LOG, "no ndb/auth");
-			db2 = ndbopen(0);
-			if(db2 == 0)
-				syslog(0, LOG, "no ndb/local");
-			db = ndbcat(db, db2);
-			if((dfd = accept(lcfd, ldir)) < 0)
-				exits("can't accept");
-			alarm(30*60*1000); 	// 30 min
-			remote = remoteIP(ldir);
-			syslog(0, LOG, "secstore from %s", remote);
-			free(remote);
-			dologin(dfd, S, forceSTA);
-			exits(nil);
-		default:
-			close(lcfd);
-			break;
-		}
-	}
-}
-
blob - 95adb38541c9a7a656957ae28cabd7e2ecefb149 (mode 644)
blob + /dev/null
--- src/cmd/secstore/secureidcheck.c
+++ /dev/null
@@ -1,446 +0,0 @@
-/* RFC2138 */
-#include <u.h>
-#include <libc.h>
-#include <ip.h>
-#include <ctype.h>
-#include <mp.h>
-#include <libsec.h>
-#include <bio.h>
-#include <ndb.h>
-#define AUTHLOG "auth"
-
-enum{	R_AccessRequest=1,	/* Packet code */
-	R_AccessAccept=2,
-	R_AccessReject=3,
-	R_AccessChallenge=11,
-	R_UserName=1,
-	R_UserPassword=2,
-	R_NASIPAddress=4,
-	R_ReplyMessage=18,
-	R_State=24,
-	R_NASIdentifier=32
-};
-
-typedef struct Secret{
-	uchar *s;
-	int len;
-} Secret;
-
-typedef struct Attribute{
-	struct Attribute *next;
-	uchar type;
-	uchar len;	// number of bytes in value
-	uchar val[256];
-} Attribute;
-
-typedef struct Packet{
-	uchar code, ID;
-	uchar authenticator[16];
-	Attribute first;
-} Packet;
-
-// assumes pass is at most 16 chars
-void
-hide(Secret *shared, uchar *auth, Secret *pass, uchar *x)
-{
-	DigestState *M;
-	int i, n = pass->len;
-
-	M = md5(shared->s, shared->len, nil, nil);
-	md5(auth, 16, x, M);
-	if(n > 16)
-		n = 16;
-	for(i = 0; i < n; i++)
-		x[i] ^= (pass->s)[i];
-}
-
-int
-authcmp(Secret *shared, uchar *buf, int m, uchar *auth)
-{
-	DigestState *M;
-	uchar x[16];
-
-	M = md5(buf, 4, nil, nil); // Code+ID+Length
-	M = md5(auth, 16, nil, M); // RequestAuth
-	M = md5(buf+20, m-20, nil, M); // Attributes
-	md5(shared->s, shared->len, x, M);
-	return memcmp(x, buf+4, 16);
-}
-
-Packet*
-newRequest(uchar *auth)
-{
-	static uchar ID = 0;
-	Packet *p;
-
-	p = (Packet*)malloc(sizeof(*p));
-	if(p == nil)
-		return nil;
-	p->code = R_AccessRequest;
-	p->ID = ++ID;
-	memmove(p->authenticator, auth, 16);
-	p->first.next = nil;
-	p->first.type = 0;
-	return p;
-}
-
-void
-freePacket(Packet *p)
-{
-	Attribute *a, *x;
-
-	if(!p)
-		return;
-	a = p->first.next;
-	while(a){
-		x = a;
-		a = a->next;
-		free(x);
-	}
-	free(p);
-}
-
-int
-ding(void *v, char *msg)
-{
-	USED(v);
-/*	syslog(0, AUTHLOG, "ding %s", msg); */
-	if(strstr(msg, "alarm"))
-		return 1;
-	return 0;
-}
-
-Packet *
-rpc(char *dest, Secret *shared, Packet *req)
-{
-	uchar buf[4096], buf2[4096], *b, *e;
-	Packet *resp;
-	Attribute *a;
-	int m, n, fd, try;
-
-	// marshal request
-	e = buf + sizeof buf;
-	buf[0] = req->code;
-	buf[1] = req->ID;
-	memmove(buf+4, req->authenticator, 16);
-	b = buf+20;
-	for(a = &req->first; a; a = a->next){
-		if(b + 2 + a->len > e)
-			return nil;
-		*b++ = a->type;
-		*b++ = 2 + a->len;
-		memmove(b, a->val, a->len);
-		b += a->len;
-	}
-	n = b-buf;
-	buf[2] = n>>8;
-	buf[3] = n;
-
-	// send request, wait for reply
-	fd = dial(dest, 0, 0, 0);
-	if(fd < 0){
-		syslog(0, AUTHLOG, "%s: rpc can't get udp channel", dest);
-		return nil;
-	}
-	atnotify(ding, 1);
-	m = -1;
-	for(try = 0; try < 2; try++){
-		alarm(4000);
-		m = write(fd, buf, n);
-		if(m != n){
-			syslog(0, AUTHLOG, "%s: rpc write err %d %d: %r", dest, m, n);
-			m = -1;
-			break;
-		}
-		m = read(fd, buf2, sizeof buf2);
-		alarm(0);
-		if(m < 0){
-			syslog(0, AUTHLOG, "%s rpc read err %d: %r", dest, m);
-			break; // failure
-		}
-		if(m == 0 || buf2[1] != buf[1]){  // need matching ID
-			syslog(0, AUTHLOG, "%s unmatched reply %d", dest, m);
-			continue;
-		}
-		if(authcmp(shared, buf2, m, buf+4) == 0)
-			break;
-		syslog(0, AUTHLOG, "%s bad rpc chksum", dest);
-	}
-	close(fd);
-	if(m <= 0)
-		return nil;
-
-	// unmarshal reply
-	b = buf2;
-	e = buf2+m;
-	resp = (Packet*)malloc(sizeof(*resp));
-	if(resp == nil)
-		return nil;
-	resp->code = *b++;
-	resp->ID = *b++;
-	n = *b++;
-	n = (n<<8) | *b++;
-	if(m != n){
-		syslog(0, AUTHLOG, "rpc got %d bytes, length said %d", m, n);
-		if(m > n)
-			e = buf2+n;
-	}
-	memmove(resp->authenticator, b, 16);
-	b += 16;
-	a = &resp->first;
-	a->type = 0;
-	while(1){
-		if(b >= e){
-			a->next = nil;
-			break;			// exit loop
-		}
-		a->type = *b++;
-		a->len = (*b++) - 2;
-		if(b + a->len > e){ // corrupt packet
-			a->next = nil;
-			freePacket(resp);
-			return nil;
-		}
-		memmove(a->val, b, a->len);
-		b += a->len;
-		if(b < e){  // any more attributes?
-			a->next = (Attribute*)malloc(sizeof(*a));
-			if(a->next == nil){
-				free(req);
-				return nil;
-			}
-			a = a->next;
-		}
-	}
-	return resp;
-}
-
-int
-setAttribute(Packet *p, uchar type, uchar *s, int n)
-{
-	Attribute *a;
-
-	a = &p->first;
-	if(a->type != 0){
-		a = (Attribute*)malloc(sizeof(*a));
-		if(a == nil)
-			return -1;
-		a->next = p->first.next;
-		p->first.next = a;
-	}
-	a->type = type;
-	a->len = n;
-	if(a->len > 253 )  // RFC2138, section 5
-		a->len = 253;
-	memmove(a->val, s, a->len);
-	return 0;
-}
-
-/* return a reply message attribute string */
-char*
-replymsg(Packet *p)
-{
-	Attribute *a;
-	static char buf[255];
-
-	for(a = &p->first; a; a = a->next){
-		if(a->type == R_ReplyMessage){
-			if(a->len >= sizeof buf)
-				a->len = sizeof(buf)-1;
-			memmove(buf, a->val, a->len);
-			buf[a->len] = 0;
-		}
-	}
-	return buf;
-}
-
-/* for convenience while debugging */
-char *replymess;
-Attribute *stateattr;
-
-void
-logPacket(Packet *p)
-{
-	Attribute *a;
-	char buf[255];
-	char pbuf[4*1024];
-	uchar *au = p->authenticator;
-	int i;
-	char *np, *e;
-
-	e = pbuf + sizeof(pbuf);
-
-	np = seprint(pbuf, e, "Packet ID=%d auth=%x %x %x... ", p->ID, au[0], au[1], au[2]);
-	switch(p->code){
-	case R_AccessRequest:
-		np = seprint(np, e, "request\n");
-		break;
-	case R_AccessAccept:
-		np = seprint(np, e, "accept\n");
-		break;
-	case R_AccessReject:
-		np = seprint(np, e, "reject\n");
-		break;
-	case R_AccessChallenge:
-		np = seprint(np, e, "challenge\n");
-		break;
-	default:
-		np = seprint(np, e, "code=%d\n", p->code);
-		break;
-	}
-	replymess = "0000000";
-	for(a = &p->first; a; a = a->next){
-		if(a->len > 253 )
-			a->len = 253;
-		memmove(buf, a->val, a->len);
-		np = seprint(np, e, " [%d]", a->type);
-		for(i = 0; i<a->len; i++)
-			if(isprint(a->val[i]))
-				np = seprint(np, e, "%c", a->val[i]);
-			else
-				np = seprint(np, e, "\\%o", a->val[i]);
-		np = seprint(np, e, "\n");
-		buf[a->len] = 0;
-		if(a->type == R_ReplyMessage)
-			replymess = strdup(buf);
-		else if(a->type == R_State)
-			stateattr = a;
-	}
-
-	syslog(0, AUTHLOG, "%s", pbuf);
-}
-
-static uchar*
-getipv4addr(void)
-{
-	Ipifc *nifc;
-	Iplifc *lifc;
-	static Ipifc *ifc;
-
-	ifc = readipifc("/net", ifc, -1);
-	for(nifc = ifc; nifc; nifc = nifc->next)
-		for(lifc = nifc->lifc; lifc; lifc = lifc->next)
-			if(ipcmp(lifc->ip, IPnoaddr) != 0 && ipcmp(lifc->ip, v4prefix) != 0)
-				return lifc->ip;
-	return nil;
-}
-
-extern Ndb *db;
-
-/* returns 0 on success, error message on failure */
-char*
-secureidcheck(char *user, char *response)
-{
-	Packet *req = nil, *resp = nil;
-	ulong u[4];
-	uchar x[16];
-	char *radiussecret;
-	char ruser[ 64];
-	char dest[3*IPaddrlen+20];
-	Secret shared, pass;
-	char *rv = "authentication failed";
-	Ndbs s;
-	Ndbtuple *t, *nt, *tt;
-	uchar *ip;
-	static Ndb *netdb;
-
-	if(netdb == nil)
-		netdb = ndbopen(0);
-
-	/* bad responses make them disable the fob, avoid silly checks */
-	if(strlen(response) < 4 || strpbrk(response,"abcdefABCDEF") != nil)
-		goto out;
-
-	/* get radius secret */
-	radiussecret = ndbgetvalue(db, &s, "radius", "lra-radius", "secret", &t);
-	if(radiussecret == nil){
-		syslog(0, AUTHLOG, "secureidcheck: nil radius secret: %r");
-		goto out;
-	}
-
-	/* translate user name if we have to */
-	strcpy(ruser, user);
-	for(nt = t; nt; nt = nt->entry){
-		if(strcmp(nt->attr, "uid") == 0 && strcmp(nt->val, user) == 0)
-			for(tt = nt->line; tt != nt; tt = tt->line)
-				if(strcmp(tt->attr, "rid") == 0){
-					strcpy(ruser, tt->val);
-					break;
-				}
-	}
-	ndbfree(t);
-
-	u[0] = fastrand();
-	u[1] = fastrand();
-	u[2] = fastrand();
-	u[3] = fastrand();
-	req = newRequest((uchar*)u);
-	if(req == nil)
-		goto out;
-	shared.s = (uchar*)radiussecret;
-	shared.len = strlen(radiussecret);
-	ip = getipv4addr();
-	if(ip == nil){
-		syslog(0, AUTHLOG, "no interfaces: %r\n");
-		goto out;
-	}
-	if(setAttribute(req, R_NASIPAddress, ip + IPv4off, 4) < 0)
-		goto out;
-
-	if(setAttribute(req, R_UserName, (uchar*)ruser, strlen(ruser)) < 0)
-		goto out;
-	pass.s = (uchar*)response;
-	pass.len = strlen(response);
-	hide(&shared, req->authenticator, &pass, x);
-	if(setAttribute(req, R_UserPassword, x, 16) < 0)
-		goto out;
-
-	t = ndbsearch(netdb, &s, "sys", "lra-radius");
-	if(t == nil){
-		syslog(0, AUTHLOG, "secureidcheck: nil radius sys search: %r\n");
-		goto out;
-	}
-	for(nt = t; nt; nt = nt->entry){
-		if(strcmp(nt->attr, "ip") != 0)
-			continue;
-
-		snprint(dest,sizeof dest,"udp!%s!oradius", nt->val);
-		resp = rpc(dest, &shared, req);
-		if(resp == nil){
-			syslog(0, AUTHLOG, "%s nil response", dest);
-			continue;
-		}
-		if(resp->ID != req->ID){
-			syslog(0, AUTHLOG, "%s mismatched ID  req=%d resp=%d",
-				dest, req->ID, resp->ID);
-			freePacket(resp);
-			resp = nil;
-			continue;
-		}
-	
-		switch(resp->code){
-		case R_AccessAccept:
-			syslog(0, AUTHLOG, "%s accepted ruser=%s", dest, ruser);
-			rv = nil;
-			break;
-		case R_AccessReject:
-			syslog(0, AUTHLOG, "%s rejected ruser=%s %s", dest, ruser, replymsg(resp));
-			rv = "secureid failed";
-			break;
-		case R_AccessChallenge:
-			syslog(0, AUTHLOG, "%s challenge ruser=%s %s", dest, ruser, replymsg(resp));
-			rv = "secureid out of sync";
-			break;
-		default:
-			syslog(0, AUTHLOG, "%s code=%d ruser=%s %s", dest, resp->code, ruser, replymsg(resp));
-			break;
-		}
-		break; // we have a proper reply, no need to ask again
-	}
-	ndbfree(t);
-	free(radiussecret);
-out:
-	freePacket(req);
-	freePacket(resp);
-	return rv;
-}
blob - 31ba184bb5d680aa3f18d666e44481814ce7cbd6 (mode 644)
blob + /dev/null
--- src/cmd/secstore/secuser.c
+++ /dev/null
@@ -1,244 +0,0 @@
-#include <u.h>
-#include <libc.h>
-#include <mp.h>
-#include <libsec.h>
-#include "SConn.h"
-#include "secstore.h"
-
-int verbose;
-
-static void userinput(char *, int);
-char *SECSTORE_DIR;
-
-static void
-ensure_exists(char *f, ulong perm)
-{
-	int fd;
-
-	if(access(f, AEXIST) >= 0)
-		return;
-	if(verbose)
-		fprint(2,"first time setup for secstore: create %s %lo\n", f, perm);
-	fd = create(f, OREAD, perm);
-	if(fd < 0){
-		fprint(2, "unable to create %s\n", f);
-		exits("secstored directories");
-	}
-	close(fd);
-}
-
-
-int
-main(int argc, char **argv)
-{
-	int isnew;
-	char *id, buf[Maxmsg], home[Maxmsg], prompt[100], *hexHi;
-	char *pass, *passck;
-	long expsecs;
-	mpint *H = mpnew(0), *Hi = mpnew(0);
-	PW *pw;
-	Tm *tm;
-
-	SECSTORE_DIR = unsharp("#9/secstore");
-
-	ARGBEGIN{
-	case 'v':
-		verbose++;
-		break;
-	}ARGEND;
-	if(argc!=1){
-		print("usage: secuser [-v] <user>\n");
-		exits("usage");
-	}
-
-	ensure_exists(SECSTORE_DIR, DMDIR|0755L);
-	snprint(home, sizeof(home), "%s/who", SECSTORE_DIR);
-	ensure_exists(home, DMDIR|0755L);
-	snprint(home, sizeof(home), "%s/store", SECSTORE_DIR);
-	ensure_exists(home, DMDIR|0700L);
-
-	id = argv[0];
-	if(verbose)
-		fprint(2,"secuser %s\n", id);
-	if((pw = getPW(id,1)) == nil){
-		isnew = 1;
-		print("new account (because %s/%s %r)\n", SECSTORE_DIR, id);
-		pw = emalloc(sizeof(*pw));
-		pw->id = estrdup(id);
-		snprint(home, sizeof(home), "%s/store/%s", SECSTORE_DIR, id);
-		if(access(home, AEXIST) == 0){
-			print("new user, but directory %s already exists\n", home);
-			exits(home);
-		}
-	}else{
-		isnew = 0;
-	}
-
-	/* get main password for id */
-	for(;;){
-		if(isnew)
-			snprint(prompt, sizeof(prompt), "%s password", id);
-		else
-			snprint(prompt, sizeof(prompt), "%s password [default = don't change]", id);
-		pass = readcons(prompt, nil, 1);
-		if(pass == nil){
-			print("getpass failed\n");
-			exits("getpass failed");
-		}
-		if(verbose)
-			print("%ld characters\n", strlen(pass));
-		if(pass[0] == '\0' && isnew == 0)
-			break;
-		if(strlen(pass) >= 7)
-			break;
-		print("password must be at least 7 characters\n");
-	}
-
-	if(pass[0] != '\0'){
-		snprint(prompt, sizeof(prompt), "retype password");
-		if(verbose)
-			print("confirming...\n");
-		passck = readcons(prompt, nil, 1);
-		if(passck == nil){
-			print("getpass failed\n");
-			exits("getpass failed");
-		}
-		if(strcmp(pass, passck) != 0){
-			print("passwords didn't match\n");
-			exits("no match");
-		}
-		memset(passck, 0, strlen(passck));
-		free(passck);
-		hexHi = PAK_Hi(id, pass, H, Hi);
-		memset(pass, 0, strlen(pass));
-		free(pass);
-		free(hexHi);
-		mpfree(H);
-		pw->Hi = Hi;
-	}
-
-	/* get expiration time (midnight of date specified) */
-	if(isnew)
-		expsecs = time(0) + 365*24*60*60;
-	else
-		expsecs = pw->expire;
-
-	for(;;){
-		tm = localtime(expsecs);
-		print("expires [DDMMYYYY, default = %2.2d%2.2d%4.4d]: ",
-				tm->mday, tm->mon, tm->year+1900);
-		userinput(buf, sizeof(buf));
-		if(strlen(buf) == 0)
-			break;
-		if(strlen(buf) != 8){
-			print("!bad date format: %s\n", buf);
-			continue;
-		}
-		tm->mday = (buf[0]-'0')*10 + (buf[1]-'0');
-		if(tm->mday > 31 || tm->mday < 1){
-			print("!bad day of month: %d\n", tm->mday);
-			continue;
-		}
-		tm->mon = (buf[2]-'0')*10 + (buf[3]-'0') - 1;
-		if(tm->mon > 11 || tm->mday < 0){
-			print("!bad month: %d\n", tm->mon + 1);
-			continue;
-		}
-		tm->year = atoi(buf+4) - 1900;
-		if(tm->year < 70){
-			print("!bad year: %d\n", tm->year + 1900);
-			continue;
-		}
-		tm->sec = 59;
-		tm->min = 59;
-		tm->hour = 23;
-		tm->yday = 0;
-		expsecs = tm2sec(tm);
-		break;
-	}
-	pw->expire = expsecs;
-
-	/* failed logins */
-	if(pw->failed != 0 )
-		print("clearing %d failed login attempts\n", pw->failed);
-	pw->failed = 0;
-
-	/* status bits */
-	if(isnew)
-		pw->status = Enabled;
-	for(;;){
-		print("Enabled or Disabled [default %s]: ",
-			(pw->status & Enabled) ? "Enabled" : "Disabled" );
-		userinput(buf, sizeof(buf));
-		if(strlen(buf) == 0)
-			break;
-		if(buf[0]=='E' || buf[0]=='e'){
-			pw->status |= Enabled;
-			break;
-		}
-		if(buf[0]=='D' || buf[0]=='d'){
-			pw->status = pw->status & ~Enabled;
-			break;
-		}
-	}
-	for(;;){
-		print("require STA? [default %s]: ",
-			(pw->status & STA) ? "yes" : "no" );
-		userinput(buf, sizeof(buf));
-		if(strlen(buf) == 0)
-			break;
-		if(buf[0]=='Y' || buf[0]=='y'){
-			pw->status |= STA;
-			break;
-		}
-		if(buf[0]=='N' || buf[0]=='n'){
-			pw->status = pw->status & ~STA;
-			break;
-		}
-	}
-
-	/* free form field */
-	if(isnew)
-		pw->other = nil;
-	print("comments [default = %s]: ", (pw->other == nil) ? "" : pw->other);
-	userinput(buf, 72);  /* 72 comes from password.h */
-	if(buf[0])
-		if((pw->other = strdup(buf)) == nil)
-			sysfatal("strdup");
-
-	syslog(0, LOG, "CHANGELOGIN for '%s'", pw->id);
-	if(putPW(pw) < 0){
-		print("error writing entry: %r\n");
-		exits("can't write password file");
-	}else{
-		print("change written\n");
-		if(isnew && create(home, OREAD, DMDIR | 0775L) < 0){
-			print("unable to create %s: %r\n", home);
-			exits(home);
-		}
-	}
-
-	exits("");
-	return 1;  /* keep  other compilers happy */
-}
-
-
-static void
-userinput(char *buf, int blen)
-{
-	int n;
-
-	while(1){
-		n = read(0, buf, blen);
-		if(n<=0)
-			exits("read error");
-		if(buf[n-1]=='\n'){
-			buf[n-1] = '\0';
-			return;
-		}
-		buf += n;  blen -= n;
-		if(blen<=0)
-			exits("input too large");
-	}
-}
-
blob - ebbb12df8745f412311704ab7ad1fcecc0be741e (mode 644)
blob + /dev/null
--- src/cmd/secstore/util.c
+++ /dev/null
@@ -1,28 +0,0 @@
-#include <u.h>
-#include <libc.h>
-
-void *
-emalloc(ulong n)
-{
-	void *p = malloc(n);
-	if(p == nil)
-		sysfatal("emalloc");
-	memset(p, 0, n);
-	return p;
-}
-
-void *
-erealloc(void *p, ulong n)
-{
-	if ((p = realloc(p, n)) == nil)
-		sysfatal("erealloc");
-	return p;
-}
-
-char *
-estrdup(char *s)
-{
-	if ((s = strdup(s)) == nil)
-		sysfatal("estrdup");
-	return s;
-}