Example #1
0
AuthInfo*
auth_response(Chalstate *c)
{
	int ret;
	AuthInfo *ai;

	ai = nil;
	if(c->afd < 0){
		werrstr("auth_response: connection not open");
		return nil;
	}
	if(c->resp == nil){
		werrstr("auth_response: nil response");
		return nil;
	}
	if(c->nresp == 0){
		werrstr("auth_response: unspecified response length");
		return nil;
	}

	if(c->user){
		if(auth_rpc(c->rpc, "write", c->user, strlen(c->user)) != ARok){
			/*
			 * if this fails we're out of phase with factotum.
			 * give up.
			 */
			goto Out;
		}
	}

	if(auth_rpc(c->rpc, "write", c->resp, c->nresp) != ARok){
		/*
		 * don't close the connection -- maybe we'll try again.
		 */
		return nil;
	}

	switch(ret = auth_rpc(c->rpc, "read", nil, 0)){
	case ARok:
	default:
		werrstr("factotum protocol botch %d %s", ret, c->rpc->ibuf);
		break;
	case ARdone:
		ai = auth_getinfo(c->rpc);
		break;
	}

Out:
	close(c->afd);
	auth_freerpc(c->rpc);
	c->afd = -1;
	c->rpc = nil;
	return ai;
}
Example #2
0
static int
_authread(Afid *afid, void *data, int count)
{
	AuthInfo *ai;
	
	switch(auth_rpc(afid->rpc, "read", nil, 0)){
	case ARdone:
		ai = auth_getinfo(afid->rpc);
		if(ai == nil)
			return -1;
		auth_freeAI(ai);
		if(chatty9p)
			fprint(2, "authenticate %s/%s: ok\n", afid->uname, afid->aname);
		afid->authok = 1;
		return 0;

	case ARok:
		if(count < afid->rpc->narg){
			werrstr("authread count too small");
			return -1;
		}
		count = afid->rpc->narg;
		memmove(data, afid->rpc->arg, count);
		return count;
	
	case ARphase:
	default:
		werrstr("authrpc botch");
		return -1;
	}
}
Example #3
0
static mpint*
rpcdecrypt(AuthRpc *rpc, mpint *b)
{
	mpint *a;
	char *p;

	p = mptoa(b, 16, nil, 0);
	if(auth_rpc(rpc, "write", p, strlen(p)) != ARok)
		sysfatal("factotum rsa write: %r");
	free(p);
	if(auth_rpc(rpc, "read", nil, 0) != ARok)
		sysfatal("factotum rsa read: %r");
	a = strtomp(rpc->arg, nil, 16, nil);
	mpfree(b);
	return a;
}
Example #4
0
Attr*
auth_attr(AuthRpc *rpc)
{
	if(auth_rpc(rpc, "attr", nil, 0) != ARok)
		return nil;
	return _parseattr(rpc->arg);
}
Example #5
0
int
authWrite(Fid* afid, void* data, int count)
{
	assert(afid->rpc != nil);
	if(auth_rpc(afid->rpc, "write", data, count) != ARok)
		return -1;
	return count;
}
Example #6
0
/*
 *  make factotum add wep keys to an 802.11 device
 */
int
auth_wep(char *dev, char *fmt, ...)
{
	AuthRpc *rpc;
	char *params, *p;
	int fd;
	va_list arg;
	int rv;

	rv = -1;

	if(dev == nil){
		werrstr("no device specified");
		return rv;
	}

	fd = open("/mnt/factotum/rpc", ORDWR);
	if(fd < 0)
		return rv;

	rpc = auth_allocrpc(fd);
	if(rpc != nil){
		quotefmtinstall();	/* just in case */
		va_start(arg, fmt);
		params = vsmprint(fmt, arg);
		va_end(arg);
		if(params != nil){
			p = smprint("proto=wep %s", params);
			if(p != nil){
				if(auth_rpc(rpc, "start", p, strlen(p)) == ARok
				&& auth_rpc(rpc, "write", dev, strlen(dev)) == ARok)
					rv = 0;
				free(p);
			}
			free(params);
		}
		auth_freerpc(rpc);
	}
	close(fd);
		
	return rv;
}
Example #7
0
Chalstate*
auth_challenge(char *fmt, ...)
{
	char *p;
	va_list arg;
	Chalstate *c;

	quotefmtinstall();	/* just in case */
	va_start(arg, fmt);
	p = vsmprint(fmt, arg);
	va_end(arg);
	if(p == nil)
		return nil;

	c = mallocz(sizeof(*c), 1);
	if(c == nil){
		free(p);
		return nil;
	}

	if((c->afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
	Error:
		auth_freechal(c);
		free(p);
		return nil;
	}

	if((c->rpc=auth_allocrpc(c->afd)) == nil
	|| auth_rpc(c->rpc, "start", p, strlen(p)) != ARok
	|| auth_rpc(c->rpc, "read", nil, 0) != ARok)
		goto Error;

	if(c->rpc->narg > sizeof(c->chal)-1){
		werrstr("buffer too small for challenge");
		goto Error;
	}
	memmove(c->chal, c->rpc->arg, c->rpc->narg);
	c->nchal = c->rpc->narg;
	free(p);
	return c;
}
Example #8
0
AuthInfo*
auth_getinfo(AuthRpc *rpc)
{
	AuthInfo *a;

	if(auth_rpc(rpc, "authinfo", nil, 0) != ARok)
		return nil;
	if(convM2AI((uchar*)rpc->arg, rpc->narg, &a) == nil){
		return nil;
	}
	return a;
}
Example #9
0
static int
dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey)
{
	int ret;

	for(;;){
		if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey)
			return ret;
		if(getkey == nil)
			return ARgiveup;	/* don't know how */
		if((*getkey)(rpc->arg) < 0)
			return ARgiveup;	/* user punted */
	}
}
Example #10
0
AuthInfo*
auth_getinfo(AuthRpc *rpc)
{
	AuthInfo *a;

	if(auth_rpc(rpc, "authinfo", nil, 0) != ARok)
		return nil;
	a = nil;
	if(convM2AI((uchar*)rpc->arg, rpc->narg, &a) == nil){
		werrstr("bad auth info from factotum");
		return nil;
	}
	return a;
}
Example #11
0
int
authRead(Fid* afid, void* data, int count)
{
	AuthInfo *ai;
	AuthRpc *rpc;

	if((rpc = afid->rpc) == nil){
		werrstr("not an auth fid");
		return -1;
	}

	switch(auth_rpc(rpc, "read", nil, 0)){
	default:
		werrstr("fossil authRead: auth protocol not finished");
		return -1;
	case ARdone:
		if((ai = auth_getinfo(rpc)) == nil){
			werrstr("%r");
			break;
		}
		if(ai->cuid == nil || *ai->cuid == '\0'){
			werrstr("auth with no cuid");
			auth_freeAI(ai);
			break;
		}
		assert(afid->cuname == nil);
		afid->cuname = vtstrdup(ai->cuid);
		auth_freeAI(ai);
		if(Dflag)
			fprint(2, "authRead cuname %s\n", afid->cuname);
		assert(afid->uid == nil);
		if((afid->uid = uidByUname(afid->cuname)) == nil){
			werrstr("unknown user %#q", afid->cuname);
			break;
		}
		return 0;
	case ARok:
		if(count < rpc->narg){
			werrstr("not enough data in auth read");
			break;
		}
		memmove(data, rpc->arg, rpc->narg);
		return rpc->narg;
	case ARphase:
		werrstr("%r");
		break;
	}
	return -1;
}
Example #12
0
void
auth9p(Req *r)
{
	char *spec;
	Afid *afid;
	
	afid = emalloc9p(sizeof(Afid));
	afid->afd = open("/mnt/factotum/rpc", ORDWR);
	if(afid->afd < 0)
		goto error;

	if((afid->rpc = auth_allocrpc(afid->afd)) == nil)
		goto error;

	if(r->ifcall.uname[0] == 0)
		goto error;
	afid->uname = estrdup9p(r->ifcall.uname);
	afid->aname = estrdup9p(r->ifcall.aname);

	spec = r->srv->keyspec;
	if(spec == nil)
		spec = "proto=p9any role=server";

	if(auth_rpc(afid->rpc, "start", spec, strlen(spec)) != ARok)
		goto error;

	r->afid->qid.type = QTAUTH;
	r->afid->qid.path = ++authgen;
	r->afid->qid.vers = 0;
	r->afid->omode = ORDWR;
	r->ofcall.qid = r->afid->qid;
	r->afid->aux = afid;
	respond(r, nil);
	return;

error:
	if(afid->rpc)
		auth_freerpc(afid->rpc);
	if(afid->uname)
		free(afid->uname);
	if(afid->aname)
		free(afid->aname);
	if(afid->afd >= 0)
		close(afid->afd);
	free(afid);
	responderror(r);
}
Example #13
0
int
authread(File *file, uchar *data, int count)
{
	AuthInfo *ai;
	AuthRpc *rpc;
	Chan *chan;

	chan = file->cp;
	if((rpc = file->auth) == nil){
		snprint(chan->err, sizeof(chan->err),
			"not an auth fid");
		return -1;
	}

	switch(auth_rpc(rpc, "read", nil, 0)){
	default:
		snprint(chan->err, sizeof(chan->err),
			"authread: auth protocol not finished");
		return -1;
	case ARdone:
		if((ai = auth_getinfo(rpc)) == nil)
			goto Phase;
		file->uid = strtouid(ai->cuid);
		if(file->uid < 0){
			snprint(chan->err, sizeof(chan->err),
				"unknown user '%s'", ai->cuid);
			auth_freeAI(ai);
			return -1;
		}
		auth_freeAI(ai);
		return 0;
	case ARok:
		if(count < rpc->narg){
			snprint(chan->err, sizeof(chan->err),
				"not enough data in auth read");
			return -1;
		}
		memmove(data, rpc->arg, rpc->narg);
		return rpc->narg;
	case ARphase:
	Phase:
		rerrstr(chan->err, sizeof(chan->err));
		return -1;
	}
}
Example #14
0
int
authwrite(File *file, uchar *data, int count)
{
	AuthRpc *rpc;
	Chan *chan;

	chan = file->cp;
	if((rpc = file->auth) == nil){
		snprint(chan->err, sizeof(chan->err),
			"not an auth fid");
		return -1;
	}
	if(auth_rpc(rpc, "write", data, count) != ARok){
		rerrstr(chan->err, sizeof(chan->err));
		return -1;
	}
	return count;
}
Example #15
0
void
authwrite(Req *r)
{
	Afid *afid;
	Fid *fid;
	
	fid = r->fid;
	afid = fid->aux;
	if(afid == nil || r->fid->qid.type != QTAUTH){
		respond(r, "not an auth fid");
		return;
	}
	if(auth_rpc(afid->rpc, "write", r->ifcall.data, r->ifcall.count) != ARok){
		responderror(r);
		return;
	}
	r->ofcall.count = r->ifcall.count;
	respond(r, nil);
}
Example #16
0
void*
authnew(void)
{
	AuthRpc *rpc;
	int fd;

	if(access("/mnt/factotum", 0) < 0)
		if((fd = open("/srv/factotum", ORDWR)) >= 0)
			mount(fd, -1, "/mnt", MBEFORE, "");
	if((fd = open("/mnt/factotum/rpc", ORDWR)) < 0)
		return nil;
	if((rpc = auth_allocrpc(fd)) == nil){
		close(fd);
		return nil;
	}
	if(auth_rpc(rpc, "start", keyspec, strlen(keyspec)) != ARok){
		authfree(rpc);
		return nil;
	}
	return rpc;
}
Example #17
0
static int
authrsafn(Conn *c)
{
	uint8_t chalbuf[32+SESSIDLEN], response[MD5dlen];
	char *s, *p;
	int afd, ret;
	AuthRpc *rpc;
	Msg *m;
	mpint *chal, *decr, *unpad, *mod;

	debug(DBG_AUTH, "rsa!\n");

	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
		debug(DBG_AUTH, "open /mnt/factotum/rpc: %r\n");
		return -1;
	}
	if((rpc = auth_allocrpc(afd)) == nil){
		debug(DBG_AUTH, "auth_allocrpc: %r\n");
		close(afd);
		return -1;
	}
	s = "proto=rsa role=client";
	if(auth_rpc(rpc, "start", s, strlen(s)) != ARok){
		debug(DBG_AUTH, "auth_rpc start %s failed: %r\n", s);
		auth_freerpc(rpc);
		close(afd);
		return -1;
	}

	ret = -1;
	debug(DBG_AUTH, "trying factotum rsa keys\n");
	while(auth_rpc(rpc, "read", nil, 0) == ARok){
		debug(DBG_AUTH, "try %s\n", (char*)rpc->arg);
		mod = strtomp(rpc->arg, nil, 16, nil);
		m = allocmsg(c, SSH_CMSG_AUTH_RSA, 16+(mpsignif(mod)+7/8));
		putmpint(m, mod);
		sendmsg(m);
		mpfree(mod);
		m = recvmsg(c, -1);
		switch(m->type){
		case SSH_SMSG_FAILURE:
			debug(DBG_AUTH, "\tnot accepted %s\n",
			      (char*)rpc->arg);
			free(m);
			continue;
		default:
			badmsg(m, 0);
		case SSH_SMSG_AUTH_RSA_CHALLENGE:
			break;
		}
		chal = getmpint(m);
		debug(DBG_AUTH, "\tgot challenge %B\n", chal);
		free(m);
		p = mptoa(chal, 16, nil, 0);
		mpfree(chal);
		if(p == nil){
			debug(DBG_AUTH, "\tmptoa failed: %r\n");
			unpad = mpnew(0);
			goto Keepgoing;
		}
		if(auth_rpc(rpc, "write", p, strlen(p)) != ARok){
			debug(DBG_AUTH, "\tauth_rpc write failed: %r\n");
			free(p);
			unpad = mpnew(0);	/* it will fail, we'll go round again */
			goto Keepgoing;
		}
		free(p);
		if(auth_rpc(rpc, "read", nil, 0) != ARok){
			debug(DBG_AUTH, "\tauth_rpc read failed: %r\n");
			unpad = mpnew(0);
			goto Keepgoing;
		}
		decr = strtomp(rpc->arg, nil, 16, nil);
		debug(DBG_AUTH, "\tdecrypted %B\n", decr);
		unpad = rsaunpad(decr);
		debug(DBG_AUTH, "\tunpadded %B\n", unpad);
		mpfree(decr);
	Keepgoing:
		mptoberjust(unpad, chalbuf, 32);
		mpfree(unpad);
		debug(DBG_AUTH, "\trjusted %.*H\n", 32, chalbuf);
		memmove(chalbuf+32, c->sessid, SESSIDLEN);
		debug(DBG_AUTH, "\tappend sesskey %.*H\n", 32, chalbuf);
		md5(chalbuf, 32+SESSIDLEN, response, nil);
		m = allocmsg(c, SSH_CMSG_AUTH_RSA_RESPONSE, MD5dlen);
		putbytes(m, response, MD5dlen);
		sendmsg(m);

		m = recvmsg(c, -1);
		switch(m->type){
		case SSH_SMSG_FAILURE:
			free(m);
			continue;
		default:
			badmsg(m, 0);
		case SSH_SMSG_SUCCESS:
			break;
		}
		ret = 0;
		break;
	}
	auth_freerpc(rpc);
	close(afd);
	return ret;
}
Example #18
0
static int
dorsa(mpint *mod, mpint *exp, mpint *chal, uint8_t chalbuf[32])
{
	int afd;
	AuthRpc *rpc;
	mpint *m;
	char buf[4096], *p;
	mpint *decr, *unpad;

	USED(exp);

	snprint(buf, sizeof buf, "proto=rsa service=ssh role=client");
	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
		debug(DBG_AUTH, "open /mnt/factotum/rpc: %r\n");
		return -1;
	}
	if((rpc = auth_allocrpc(afd)) == nil){
		debug(DBG_AUTH, "auth_allocrpc: %r\n");
		close(afd);
		return -1;
	}
	if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
		debug(DBG_AUTH, "auth_rpc start failed: %r\n");
	Die:
		auth_freerpc(rpc);
		close(afd);
		return -1;
	}
	m = nil;
	debug(DBG_AUTH, "trying factotum rsa keys\n");
	while(auth_rpc(rpc, "read", nil, 0) == ARok){
		debug(DBG_AUTH, "try %s\n", (char*)rpc->arg);
		m = strtomp(rpc->arg, nil, 16, nil);
		if(mpcmp(m, mod) == 0)
			break;
		mpfree(m);
		m = nil;
	}
	if(m == nil)
		goto Die;
	mpfree(m);
	
	p = mptoa(chal, 16, nil, 0);
	if(p == nil){
		debug(DBG_AUTH, "\tmptoa failed: %r\n");
		goto Die;
	}
	if(auth_rpc(rpc, "write", p, strlen(p)) != ARok){
		debug(DBG_AUTH, "\tauth_rpc write failed: %r\n");
		free(p);
		goto Die;
	}
	free(p);
	if(auth_rpc(rpc, "read", nil, 0) != ARok){
		debug(DBG_AUTH, "\tauth_rpc read failed: %r\n");
		goto Die;
	}
	decr = strtomp(rpc->arg, nil, 16, nil);
	if(decr == nil){
		debug(DBG_AUTH, "\tdecr %s failed\n", rpc->arg);
		goto Die;
	}
	debug(DBG_AUTH, "\tdecrypted %B\n", decr);
	unpad = rsaunpad(decr);
	if(unpad == nil){
		debug(DBG_AUTH, "\tunpad %B failed\n", decr);
		mpfree(decr);
		goto Die;
	}
	debug(DBG_AUTH, "\tunpadded %B\n", unpad);
	mpfree(decr);
	mptoberjust(unpad, chalbuf, 32);
	mpfree(unpad);
	auth_freerpc(rpc);
	close(afd);
	return 0;
}
Example #19
0
void
sshserverhandshake(Conn *c)
{
	char *p, buf[128];
	Biobuf *b;
	Attr *a;
	int i, afd;
	mpint *m;
	AuthRpc *rpc;
	RSApub *key;

	/*
	 * BUG: should use `attr' to get the key attributes
	 * after the read, but that's not implemented yet.
	 */
	if((b = Bopen("/mnt/factotum/ctl", OREAD)) == nil)
		sysfatal("open /mnt/factotum/ctl: %r");
	while((p = Brdline(b, '\n')) != nil){
		p[Blinelen(b)-1] = '\0';
		if(strstr(p, " proto=rsa ") && strstr(p, " service=sshserve "))
			break;
	}
	if(p == nil)
		sysfatal("no sshserve keys found in /mnt/factotum/ctl");
	a = _parseattr(p);
	Bterm(b);
	key = emalloc(sizeof(*key));
	if((p = _strfindattr(a, "n")) == nil)
		sysfatal("no n in sshserve key");
	if((key->n = strtomp(p, &p, 16, nil)) == nil || *p != 0)
		sysfatal("bad n in sshserve key");
	if((p = _strfindattr(a, "ek")) == nil)
		sysfatal("no ek in sshserve key");
	if((key->ek = strtomp(p, &p, 16, nil)) == nil || *p != 0)
		sysfatal("bad ek in sshserve key");
	_freeattr(a);

	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
		sysfatal("open /mnt/factotum/rpc: %r");
	if((rpc = auth_allocrpc(afd)) == nil)
		sysfatal("auth_allocrpc: %r");
	p = "proto=rsa role=client service=sshserve";
	if(auth_rpc(rpc, "start", p, strlen(p)) != ARok)
		sysfatal("auth_rpc start %s: %r", p);
	if(auth_rpc(rpc, "read", nil, 0) != ARok)
		sysfatal("auth_rpc read: %r");
	m = strtomp(rpc->arg, nil, 16, nil);
	if(mpcmp(m, key->n) != 0)
		sysfatal("key in /mnt/factotum/ctl does not match rpc key");
	mpfree(m);
	c->hostkey = key;

	/* send id string */
	fprint(c->fd[0], "SSH-1.5-Plan9\n");

	/* receive id string */
	if(readstrnl(c->fd[0], buf, sizeof buf) < 0)
		sysfatal("reading server version: %r");

	/* id string is "SSH-m.n-comment".  We need m=1, n>=5. */
	if(strncmp(buf, "SSH-", 4) != 0
	|| strtol(buf+4, &p, 10) != 1
	|| *p != '.'
	|| strtol(p+1, &p, 10) < 5
	|| *p != '-')
		sysfatal("protocol mismatch; got %s, need SSH-1.x for x>=5", buf);

	for(i=0; i<COOKIELEN; i++)
		c->cookie[i] = fastrand();
	calcsessid(c);
	send_ssh_smsg_public_key(c);
	recv_ssh_cmsg_session_key(c, rpc);
	auth_freerpc(rpc);
	close(afd);

	c->cstate = (*c->cipher->init)(c, 1);		/* turns on encryption */
	sendmsg(allocmsg(c, SSH_SMSG_SUCCESS, 0));

	authsrvuser(c);
}