/*
 * Present factotum in ssh agent clothing.
 */
#include <u.h>
#include <libc.h>
#include <mp.h>
#include <libsec.h>
#include <auth.h>
#include <thread.h>
#include <9pclient.h>

enum
{
	STACK = 65536
};
enum		/* agent protocol packet types */
{
	SSH_AGENTC_NONE = 0,
	SSH_AGENTC_REQUEST_RSA_IDENTITIES,
	SSH_AGENT_RSA_IDENTITIES_ANSWER,
	SSH_AGENTC_RSA_CHALLENGE,
	SSH_AGENT_RSA_RESPONSE,
	SSH_AGENT_FAILURE,
	SSH_AGENT_SUCCESS,
	SSH_AGENTC_ADD_RSA_IDENTITY,
	SSH_AGENTC_REMOVE_RSA_IDENTITY,
	SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES,
	
	SSH2_AGENTC_REQUEST_IDENTITIES = 11,
	SSH2_AGENT_IDENTITIES_ANSWER,
	SSH2_AGENTC_SIGN_REQUEST,
	SSH2_AGENT_SIGN_RESPONSE,

	SSH2_AGENTC_ADD_IDENTITY = 17,
	SSH2_AGENTC_REMOVE_IDENTITY,
	SSH2_AGENTC_REMOVE_ALL_IDENTITIES,
	SSH2_AGENTC_ADD_SMARTCARD_KEY,
	SSH2_AGENTC_REMOVE_SMARTCARD_KEY,

	SSH_AGENTC_LOCK,
	SSH_AGENTC_UNLOCK,
	SSH_AGENTC_ADD_RSA_ID_CONSTRAINED,
	SSH2_AGENTC_ADD_ID_CONSTRAINED,
	SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED,
	
	SSH_AGENT_CONSTRAIN_LIFETIME = 1,
	SSH_AGENT_CONSTRAIN_CONFIRM = 2,

	SSH2_AGENT_FAILURE = 30,
	
	SSH_COM_AGENT2_FAILURE = 102,
	SSH_AGENT_OLD_SIGNATURE = 0x01,
};

typedef struct Aconn Aconn;
struct Aconn
{
	uchar *data;
	uint ndata;
	int ctl;
	int fd;
	char dir[40];
};

typedef struct Msg Msg;
struct Msg
{
	uchar *bp;
	uchar *p;
	uchar *ep;
	int bpalloc;
};

char adir[40];
int afd;
int chatty;
char *factotum = "factotum";

void		agentproc(void *v);
void*	emalloc(int n);
void*	erealloc(void *v, int n);
void		listenproc(void *v);
int		runmsg(Aconn *a);
void		listkeystext(void);

void
usage(void)
{
	fprint(2, "usage: 9 ssh-agent [-D] [factotum]\n");
	threadexitsall("usage");
}

void
threadmain(int argc, char **argv)
{
	int fd, pid, export, dotextlist;
	char dir[100], *ns;
	char sock[200], addr[200];
	uvlong x;

	export = 0;
	dotextlist = 0;
	pid = getpid();
	fmtinstall('B', mpfmt);
	fmtinstall('H', encodefmt);
	fmtinstall('[', encodefmt);

	ARGBEGIN{
	case '9':
		chatty9pclient++;
		break;
	case 'D':
		chatty++;
		break;
	case 'e':
		export = 1;
		break;
	case 'l':
		dotextlist = 1;
		break;
	default:
		usage();
	}ARGEND
	
	if(argc > 1)
		usage();
	if(argc == 1)
		factotum = argv[0];
		
	if(dotextlist)
		listkeystext();

	ns = getns();
	snprint(sock, sizeof sock, "%s/ssh-agent.socket", ns);
	if(0){
		x = ((uvlong)fastrand()<<32) | fastrand();
		x ^= ((uvlong)fastrand()<<32) | fastrand();
		snprint(dir, sizeof dir, "/tmp/ssh-%llux", x);
		if((fd = create(dir, OREAD, DMDIR|0700)) < 0)
			sysfatal("mkdir %s: %r", dir);
		close(fd);
		snprint(sock, sizeof sock, "%s/agent.%d", dir, pid);
	}
	snprint(addr, sizeof addr, "unix!%s", sock);

	if((afd = announce(addr, adir)) < 0)
		sysfatal("announce %s: %r", addr);
	
	print("SSH_AUTH_SOCK=%s;\n", sock);
	if(export)
		print("export SSH_AUTH_SOCK;\n");
	print("SSH_AGENT_PID=%d;\n", pid);
	if(export)
		print("export SSH_AGENT_PID;\n");
	close(1);
	rfork(RFNOTEG);
	proccreate(listenproc, nil, STACK);
	threadexits(0);
}

void
listenproc(void *v)
{
	Aconn *a;

	USED(v);
	for(;;){
		a = emalloc(sizeof *a);
		a->ctl = listen(adir, a->dir);
		if(a->ctl < 0)
			sysfatal("listen: %r");
		proccreate(agentproc, a, STACK);
	}
}

void
agentproc(void *v)
{
	Aconn *a;
	int n;
	
	a = v;
	a->fd = accept(a->ctl, a->dir);
	close(a->ctl);
	a->ctl = -1;
	for(;;){
		a->data = erealloc(a->data, a->ndata+1024);
		n = read(a->fd, a->data+a->ndata, 1024);
		if(n <= 0)
			break;
		a->ndata += n;
		while(runmsg(a))
			;
	}
	close(a->fd);
	free(a);
	threadexits(nil);
}

int
get1(Msg *m)
{
	if(m->p >= m->ep)
		return 0;
	return *m->p++;
}

int
get2(Msg *m)
{
	uint x;
	
	if(m->p+2 > m->ep)
		return 0;
	x = (m->p[0]<<8)|m->p[1];
	m->p += 2;
	return x;
}

int
get4(Msg *m)
{
	uint x;
	if(m->p+4 > m->ep)
		return 0;
	x = (m->p[0]<<24)|(m->p[1]<<16)|(m->p[2]<<8)|m->p[3];
	m->p += 4;
	return x;
}

uchar*
getn(Msg *m, uint n)
{
	uchar *p;
	
	if(m->p+n > m->ep)
		return nil;
	p = m->p;
	m->p += n;
	return p;
}

char*
getstr(Msg *m)
{
	uint n;
	uchar *p;

	n = get4(m);
	p = getn(m, n);
	if(p == nil)
		return nil;
	p--;
	memmove(p, p+1, n);
	p[n] = 0;
	return (char*)p;
}

mpint*
getmp(Msg *m)
{
	int n;
	uchar *p;
	
	n = (get2(m)+7)/8;
	if((p=getn(m, n)) == nil)
		return nil;
	return betomp(p, n, nil);
}

mpint*
getmp2(Msg *m)
{
	int n;
	uchar *p;
	
	n = get4(m);
	if((p = getn(m, n)) == nil)
		return nil;
	return betomp(p, n, nil);
}

void
newmsg(Msg *m)
{
	memset(m, 0, sizeof *m);
}

void
mreset(Msg *m)
{
	if(m->bpalloc){
		memset(m->bp, 0, m->ep-m->bp);
		free(m->bp);
	}
	memset(m, 0, sizeof *m);
}

Msg*
getm(Msg *m, Msg *mm)
{
	uint n;
	uchar *p;
	
	n = get4(m);
	if((p = getn(m, n)) == nil)
		return nil;
	mm->bp = p;
	mm->p = p;
	mm->ep = p+n;
	mm->bpalloc = 0;
	return mm;
}

uchar*
ensure(Msg *m, int n)
{
	int len;
	uchar *p;
	uchar *obp;

	if(m->bp == nil)
		m->bpalloc = 1;
	if(!m->bpalloc){
		p = emalloc(m->ep - m->bp);
		memmove(p, m->bp, m->ep - m->bp);
		obp = m->bp;
		m->bp = p;
		m->ep += m->bp - obp;
		m->p += m->bp - obp;
		m->bpalloc = 1;
	}
	len = m->ep - m->bp;
	if(m->p+n > m->ep){
		obp = m->bp;
		m->bp = erealloc(m->bp, len+n+1024);
		m->p += m->bp - obp;
		m->ep += m->bp - obp;
		m->ep += n+1024;
	}
	p = m->p;
	m->p += n;
	return p;
}

void
put4(Msg *m, uint n)
{
	uchar *p;
	
	p = ensure(m, 4);
	p[0] = (n>>24)&0xFF;
	p[1] = (n>>16)&0xFF;
	p[2] = (n>>8)&0xFF;
	p[3] = n&0xFF;
}

void
put2(Msg *m, uint n)
{
	uchar *p;
	
	p = ensure(m, 2);
	p[0] = (n>>8)&0xFF;
	p[1] = n&0xFF;
}

void
put1(Msg *m, uint n)
{
	uchar *p;
	
	p = ensure(m, 1);
	p[0] = n&0xFF;
}

void
putn(Msg *m, void *a, uint n)
{
	uchar *p;
	
	p = ensure(m, n);
	memmove(p, a, n);
}

void
putmp(Msg *m, mpint *b)
{
	int bits, n;
	uchar *p;
	
	bits = mpsignif(b);
	put2(m, bits);
	n = (bits+7)/8;
	p = ensure(m, n);
	mptobe(b, p, n, nil);
}

void
putmp2(Msg *m, mpint *b)
{
	int bits, n;
	uchar *p;
	
	if(mpcmp(b, mpzero) == 0){
		put4(m, 0);
		return;
	}
	bits = mpsignif(b);
	n = (bits+7)/8;
	if(bits%8 == 0){
		put4(m, n+1);
		put1(m, 0);
	}else
		put4(m, n);
	p = ensure(m, n);
	mptobe(b, p, n, nil);
}

void
putstr(Msg *m, char *s)
{
	int n;
	
	n = strlen(s);
	put4(m, n);
	putn(m, s, n);
}

void
putm(Msg *m, Msg *mm)
{
	uint n;
	
	n = mm->p - mm->bp;
	put4(m, n);
	putn(m, mm->bp, n);
}

void
newreply(Msg *m, int type)
{
	memset(m, 0, sizeof *m);
	put4(m, 0);
	put1(m, type);
}

void
reply(Aconn *a, Msg *m)
{
	uint n;
	uchar *p;
	
	n = (m->p - m->bp) - 4;
	p = m->bp;
	p[0] = (n>>24)&0xFF;
	p[1] = (n>>16)&0xFF;
	p[2] = (n>>8)&0xFF;
	p[3] = n&0xFF;
	if(chatty)
		fprint(2, "respond %d t=%d: %.*H\n", n, p[4], n, m->bp+4);
	write(a->fd, p, n+4);
	mreset(m);
}

typedef struct Key Key;
struct Key
{
	mpint *mod;
	mpint *ek;
	char *comment;
};

static char*
find(char **f, int nf, char *k)
{
	int i, len;

	len = strlen(k);
	for(i=1; i<nf; i++)	/* i=1: f[0] is "key" */
		if(strncmp(f[i], k, len) == 0 && f[i][len] == '=')
			return f[i]+len+1;
	return nil;
}

static int
putrsa1(Msg *m, char **f, int nf)
{
	char *p;
	mpint *mod, *ek;

	p = find(f, nf, "n");
	if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
		return -1;
	p = find(f, nf, "ek");
	if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
		mpfree(mod);
		return -1;
	}
	p = find(f, nf, "comment");
	if(p == nil)
		p = "";
	put4(m, mpsignif(mod));
	putmp(m, ek);
	putmp(m, mod);
	putstr(m, p);
	mpfree(mod);
	mpfree(ek);
	return 0;
}

void
printattr(char **f, int nf)
{
	int i;
	
	print("#");
	for(i=0; i<nf; i++)
		print(" %s", f[i]);
	print("\n");
}

void
printrsa1(char **f, int nf)
{
	char *p;
	mpint *mod, *ek;

	p = find(f, nf, "n");
	if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
		return;
	p = find(f, nf, "ek");
	if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
		mpfree(mod);
		return;
	}
	p = find(f, nf, "comment");
	if(p == nil)
		p = "";

	if(chatty)
		printattr(f, nf);
	print("%d %.10B %.10B %s\n", mpsignif(mod), ek, mod, p);
	mpfree(ek);
	mpfree(mod);
}

static int
putrsa(Msg *m, char **f, int nf)
{
	char *p;
	mpint *mod, *ek;

	p = find(f, nf, "n");
	if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
		return -1;
	p = find(f, nf, "ek");
	if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
		mpfree(mod);
		return -1;
	}
	putstr(m, "ssh-rsa");
	putmp2(m, ek);
	putmp2(m, mod);
	mpfree(ek);
	mpfree(mod);
	return 0;
}

RSApub*
getrsapub(Msg *m)
{
	RSApub *k;
	
	k = rsapuballoc();
	if(k == nil)
		return nil;
	k->ek = getmp2(m);
	k->n = getmp2(m);
	if(k->ek == nil || k->n == nil){
		rsapubfree(k);
		return nil;
	}
	return k;
}

static int
putdsa(Msg *m, char **f, int nf)
{
	char *p;
	int ret;
	mpint *dp, *dq, *dalpha, *dkey;

	ret = -1;
	dp = dq = dalpha = dkey = nil;
	p = find(f, nf, "p");
	if(p == nil || (dp = strtomp(p, nil, 16, nil)) == nil)
		goto out;
	p = find(f, nf, "q");
	if(p == nil || (dq = strtomp(p, nil, 16, nil)) == nil)
		goto out;
	p = find(f, nf, "alpha");
	if(p == nil || (dalpha = strtomp(p, nil, 16, nil)) == nil)
		goto out;
	p = find(f, nf, "key");
	if(p == nil || (dkey = strtomp(p, nil, 16, nil)) == nil)
		goto out;
	putstr(m, "ssh-dss");
	putmp2(m, dp);
	putmp2(m, dq);
	putmp2(m, dalpha);
	putmp2(m, dkey);
	ret = 0;
out:
	mpfree(dp);
	mpfree(dq);
	mpfree(dalpha);
	mpfree(dkey);
	return ret;
}

static int
putkey2(Msg *m, int (*put)(Msg*,char**,int), char **f, int nf)
{
	char *p;
	Msg mm;
	
	newmsg(&mm);
	if(put(&mm, f, nf) < 0)
		return -1;
	putm(m, &mm);
	mreset(&mm);
	p = find(f, nf, "comment");
	if(p == nil)
		p = "";
	putstr(m, p);
	return 0;
}

static int
printkey(char *type, int (*put)(Msg*,char**,int), char **f, int nf)
{
	Msg m;
	char *p;
	
	newmsg(&m);
	if(put(&m, f, nf) < 0)
		return -1;
	p = find(f, nf, "comment");
	if(p == nil)
		p = "";
	if(chatty)
		printattr(f, nf);
	print("%s %.*[ %s\n", type, m.p-m.bp, m.bp, p);
	mreset(&m);
	return 0;
}

DSApub*
getdsapub(Msg *m)
{
	DSApub *k;
	
	k = dsapuballoc();
	if(k == nil)
		return nil;
	k->p = getmp2(m);
	k->q = getmp2(m);
	k->alpha = getmp2(m);
	k->key = getmp2(m);
	if(!k->p || !k->q || !k->alpha || !k->key){
		dsapubfree(k);
		return nil;
	}
	return k;
}

static int
listkeys(Msg *m, int version)
{
	char buf[8192+1], *line[100], *f[20], *p, *s;
	int pnk;
	int i, n, nl, nf, nk;
	CFid *fid;

	nk = 0;
	pnk = m->p - m->bp;
	put4(m, 0);
	if((fid = nsopen(factotum, nil, "ctl", OREAD)) == nil){
		fprint(2, "ssh-agent: open factotum: %r\n");
		return -1;
	}
	for(;;){
		if((n = fsread(fid, buf, sizeof buf-1)) <= 0)
			break;
		buf[n] = 0;
		nl = getfields(buf, line, nelem(line), 1, "\n");
		for(i=0; i<nl; i++){
			nf = tokenize(line[i], f, nelem(f));
			if(nf == 0 || strcmp(f[0], "key") != 0)
				continue;
			p = find(f, nf, "proto");
			if(p == nil)
				continue;
			s = find(f, nf, "service");
			if(s == nil)
				continue;

			if(version == 1 && strcmp(p, "rsa") == 0 && strcmp(s, "ssh") == 0)
				if(putrsa1(m, f, nf) >= 0)
					nk++;
			if(version == 2 && strcmp(p, "rsa") == 0 && strcmp(s, "ssh-rsa") == 0)
				if(putkey2(m, putrsa, f, nf) >= 0)
					nk++;
			if(version == 2 && strcmp(p, "dsa") == 0 && strcmp(s, "ssh-dss") == 0)
				if(putkey2(m, putdsa, f, nf) >= 0)
					nk++;
		}
	}
	if(chatty)
		fprint(2, "sending %d keys\n", nk);
	fsclose(fid);
	m->bp[pnk+0] = (nk>>24)&0xFF;
	m->bp[pnk+1] = (nk>>16)&0xFF;
	m->bp[pnk+2] = (nk>>8)&0xFF;
	m->bp[pnk+3] = nk&0xFF;
	return nk;
}

void
listkeystext(void)
{
	char buf[8192+1], *line[100], *f[20], *p, *s;
	int i, n, nl, nf;
	CFid *fid;

	if((fid = nsopen(factotum, nil, "ctl", OREAD)) == nil){
		fprint(2, "ssh-agent: open factotum: %r\n");
		return;
	}
	for(;;){
		if((n = fsread(fid, buf, sizeof buf-1)) <= 0)
			break;
		buf[n] = 0;
		nl = getfields(buf, line, nelem(line), 1, "\n");
		for(i=0; i<nl; i++){
			nf = tokenize(line[i], f, nelem(f));
			if(nf == 0 || strcmp(f[0], "key") != 0)
				continue;
			p = find(f, nf, "proto");
			if(p == nil)
				continue;
			s = find(f, nf, "service");
			if(s == nil)
				continue;

			if(strcmp(p, "rsa") == 0 && strcmp(s, "ssh") == 0)
				printrsa1(f, nf);
			if(strcmp(p, "rsa") == 0 && strcmp(s, "ssh-rsa") == 0)
				printkey("ssh-rsa", putrsa, f, nf);
			if(strcmp(p, "dsa") == 0 && strcmp(s, "ssh-dss") == 0)
				printkey("ssh-dss", putdsa, f, nf);
		}
	}
	fsclose(fid);
	threadexitsall(nil);
}

mpint*
rsaunpad(mpint *b)
{
	int i, n;
	uchar buf[2560];

	n = (mpsignif(b)+7)/8;
	if(n > sizeof buf){
		werrstr("rsaunpad: too big");
		return nil;
	}
	mptobe(b, buf, n, nil);

	/* the initial zero has been eaten by the betomp -> mptobe sequence */
	if(buf[0] != 2){
		werrstr("rsaunpad: expected leading 2");
		return nil;
	}
	for(i=1; i<n; i++)
		if(buf[i]==0)
			break;
	return betomp(buf+i, n-i, nil);
}

void
mptoberjust(mpint *b, uchar *buf, int len)
{
	int n;

	n = mptobe(b, buf, len, nil);
	assert(n >= 0);
	if(n < len){
		len -= n;
		memmove(buf+len, buf, n);
		memset(buf, 0, len);
	}
}

static int
dorsa(Aconn *a, mpint *mod, mpint *exp, mpint *chal, uchar chalbuf[32])
{
	AuthRpc *rpc;
	char buf[4096], *p;
	mpint *decr, *unpad;

	USED(exp);
	if((rpc = auth_allocrpc()) == nil){
		fprint(2, "ssh-agent: auth_allocrpc: %r\n");
		return -1;
	}
	snprint(buf, sizeof buf, "proto=rsa service=ssh role=decrypt n=%lB ek=%lB", mod, exp);
	if(chatty)
		fprint(2, "ssh-agent: start %s\n", buf);
	if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
		fprint(2, "ssh-agent: auth 'start' failed: %r\n");
	Die:
		auth_freerpc(rpc);
		return -1;
	}
	
	p = mptoa(chal, 16, nil, 0);
	if(p == nil){
		fprint(2, "ssh-agent: dorsa: mptoa: %r\n");
		goto Die;
	}
	if(chatty)
		fprint(2, "ssh-agent: challenge %B => %s\n", chal, p);
	if(auth_rpc(rpc, "writehex", p, strlen(p)) != ARok){
		fprint(2, "ssh-agent: dorsa: auth 'write': %r\n");
		free(p);
		goto Die;
	}
	free(p);
	if(auth_rpc(rpc, "readhex", nil, 0) != ARok){
		fprint(2, "ssh-agent: dorsa: auth 'read': %r\n");
		goto Die;
	}
	decr = strtomp(rpc->arg, nil, 16, nil);
	if(chatty)
		fprint(2, "ssh-agent: response %s => %B\n", rpc->arg, decr);
	if(decr == nil){
		fprint(2, "ssh-agent: dorsa: strtomp: %r\n");
		goto Die;
	}
	unpad = rsaunpad(decr);
	if(chatty)
		fprint(2, "ssh-agent: unpad %B => %B\n", decr, unpad);
	if(unpad == nil){
		fprint(2, "ssh-agent: dorsa: rsaunpad: %r\n");
		mpfree(decr);
		goto Die;
	}
	mpfree(decr);
	mptoberjust(unpad, chalbuf, 32);
	mpfree(unpad);
	auth_freerpc(rpc);
	return 0;
}

int
keysign(Msg *mkey, Msg *mdata, Msg *msig)
{
	char *s;
	AuthRpc *rpc;
	RSApub *rsa;
	DSApub *dsa;
	char buf[4096];
	uchar digest[SHA1dlen];
	
	s = getstr(mkey);
	if(strcmp(s, "ssh-rsa") == 0){
		rsa = getrsapub(mkey);
		if(rsa == nil)
			return -1;
		snprint(buf, sizeof buf, "proto=rsa service=ssh-rsa role=sign n=%lB ek=%lB",
			rsa->n, rsa->ek);
		rsapubfree(rsa);
	}else if(strcmp(s, "ssh-dss") == 0){
		dsa = getdsapub(mkey);
		if(dsa == nil)
			return -1;
		snprint(buf, sizeof buf, "proto=dsa service=ssh-dss role=sign p=%lB q=%lB alpha=%lB key=%lB",
			dsa->p, dsa->q, dsa->alpha, dsa->key);
		dsapubfree(dsa);
	}else{
		fprint(2, "ssh-agent: cannot sign key type %s\n", s);
		werrstr("unknown key type %s", s);
		return -1;
	}

	if((rpc = auth_allocrpc()) == nil){
		fprint(2, "ssh-agent: auth_allocrpc: %r\n");
		return -1;
	}
	if(chatty)
		fprint(2, "ssh-agent: start %s\n", buf);
	if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
		fprint(2, "ssh-agent: auth 'start' failed: %r\n");
	Die:
		auth_freerpc(rpc);
		return -1;
	}
	sha1(mdata->bp, mdata->ep-mdata->bp, digest, nil);
	if(auth_rpc(rpc, "write", digest, SHA1dlen) != ARok){
		fprint(2, "ssh-agent: auth 'write in sign failed: %r\n");
		goto Die;
	}
	if(auth_rpc(rpc, "read", nil, 0) != ARok){
		fprint(2, "ssh-agent: auth 'read' failed: %r\n");
		goto Die;
	}
	newmsg(msig);
	putstr(msig, s);
	put4(msig, rpc->narg);
	putn(msig, rpc->arg, rpc->narg);
	auth_freerpc(rpc);
	return 0;
}

int
runmsg(Aconn *a)
{
	char *p;
	int n, nk, type, rt, vers;
	mpint *ek, *mod, *chal;
	uchar sessid[16], chalbuf[32], digest[MD5dlen];
	uint len, flags;
	DigestState *s;
	Msg m, mkey, mdata, msig;
	
	if(a->ndata < 4)
		return 0;
	len = (a->data[0]<<24)|(a->data[1]<<16)|(a->data[2]<<8)|a->data[3];
	if(a->ndata < 4+len)
		return 0;
	m.p = a->data+4;
	m.ep = m.p+len;
	type = get1(&m);
	if(chatty)
		fprint(2, "msg %d: %.*H\n", type, len, m.p);
	switch(type){
	default:
	Failure:
		newreply(&m, SSH_AGENT_FAILURE);
		reply(a, &m);
		break;

	case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
		vers = 1;
		newreply(&m, SSH_AGENT_RSA_IDENTITIES_ANSWER);
		goto Identities;
	case SSH2_AGENTC_REQUEST_IDENTITIES:
		vers = 2;
		newreply(&m, SSH2_AGENT_IDENTITIES_ANSWER);
	Identities:
		nk = listkeys(&m, vers);
		if(nk < 0){
			mreset(&m);
			goto Failure;
		}
		if(chatty)
			fprint(2, "request identities\n", nk);
		reply(a, &m);
		break;

	case SSH_AGENTC_RSA_CHALLENGE:
		n = get4(&m);
		ek = getmp(&m);
		mod = getmp(&m);
		chal = getmp(&m);
		if((p = (char*)getn(&m, 16)) == nil){
		Failchal:
			mpfree(ek);
			mpfree(mod);
			mpfree(chal);
			goto Failure;
		}
		memmove(sessid, p, 16);
		rt = get4(&m);
		if(rt != 1 || dorsa(a, mod, ek, chal, chalbuf) < 0)
			goto Failchal;
		s = md5(chalbuf, 32, nil, nil);
		if(s == nil)
			goto Failchal;
		md5(sessid, 16, digest, s);
		print("md5 %.*H %.*H => %.*H\n", 32, chalbuf, 16, sessid, MD5dlen, digest);
		
		newreply(&m, SSH_AGENT_RSA_RESPONSE);
		putn(&m, digest, 16);
		reply(a, &m);

		mpfree(ek);
		mpfree(mod);
		mpfree(chal);
		break;

	case SSH2_AGENTC_SIGN_REQUEST:
		if(getm(&m, &mkey) == nil
		|| getm(&m, &mdata) == nil)
			goto Failure;
		flags = get4(&m);
		if(flags & SSH_AGENT_OLD_SIGNATURE)
			goto Failure;
		if(keysign(&mkey, &mdata, &msig) < 0)
			goto Failure;
		if(chatty)
			fprint(2, "signature: %.*H\n",
				msig.p-msig.bp, msig.bp);
		newreply(&m, SSH2_AGENT_SIGN_RESPONSE);
		putm(&m, &msig);
		mreset(&msig);
		reply(a, &m);
		break;
		
	case SSH_AGENTC_ADD_RSA_IDENTITY:
		/*
			msg: n[4] mod[mp] pubexp[exp] privexp[mp]
				p^-1 mod q[mp] p[mp] q[mp] comment[str]
		 */
		goto Failure;
		
	case SSH_AGENTC_REMOVE_RSA_IDENTITY:
		/*
			msg: n[4] mod[mp] pubexp[mp]
		 */
		goto Failure;
		
	}
	
	a->ndata -= 4+len;
	memmove(a->data, a->data+4+len, a->ndata);
	return 1;
}

void*
emalloc(int n)
{
	void *v;

	v = mallocz(n, 1);
	if(v == nil){
		abort();
		sysfatal("out of memory allocating %d", n);
	}
	return v;
}

void*
erealloc(void *v, int n)
{
	v = realloc(v, n);
	if(v == nil){
		abort();
		sysfatal("out of memory reallocating %d", n);
	}
	return v;
}

