Beispiel #1
0
int
auth_respond(void *chal, uint nchal, char *user, uint nuser, void *resp, uint nresp, AuthGetkey *getkey, char *fmt, ...)
{
	char *p, *s;
	va_list arg;
	int afd;
	AuthRpc *rpc;
	Attr *a;

	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
		return -1;
	
	if((rpc = auth_allocrpc(afd)) == nil){
		close(afd);
		return -1;
	}

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

	if(p==nil
	|| dorpc(rpc, "start", p, strlen(p), getkey) != ARok
	|| dorpc(rpc, "write", chal, nchal, getkey) != ARok
	|| dorpc(rpc, "read", nil, 0, getkey) != ARok){
		free(p);
		close(afd);
		auth_freerpc(rpc);
		return -1;
	}
	free(p);

	if(rpc->narg < nresp)
		nresp = rpc->narg;
	memmove(resp, rpc->arg, nresp);

	if((a = auth_attr(rpc)) != nil
	&& (s = _strfindattr(a, "user")) != nil && strlen(s) < nuser)
		strcpy(user, s);
	else if(nuser > 0)
		user[0] = '\0';

	_freeattr(a);
	close(afd);
	auth_freerpc(rpc);
	return nresp;	
}
Beispiel #2
0
AuthInfo*
auth_proxy(int fd, AuthGetkey *getkey, char *fmt, ...)
{
	int afd;
	char *p;
	va_list arg;
	AuthInfo *ai;
	AuthRpc *rpc;

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

	afd = open("/mnt/factotum/rpc", ORDWR);
	if(afd < 0){
		werrstr("opening /mnt/factotum/rpc: %r");
		free(p);
		return nil;
	}

	rpc = auth_allocrpc(afd);
	if(rpc == nil){
		free(p);
		return nil;
	}

	ai = fauth_proxy(fd, rpc, getkey, p);
	free(p);
	auth_freerpc(rpc);
	close(afd);
	return ai;
}
Beispiel #3
0
AuthInfo*
auth_proxy(FFid *f, AuthGetkey *getkey, char *fmt, ...)
{
	int afd;
	char *p, *ftm, *rpcpath;
	va_list arg;
	AuthInfo *ai;
	AuthRpc *rpc;

	va_start(arg, fmt);
	vasprintf(&p, fmt, arg);
	va_end(arg);

	ai = nil;
	ftm = getenv("FACTOTUM");
	asprintf(&rpcpath, "%s/rpc", ftm);
	afd = open(rpcpath, ORDWR);
	if(afd < 0){
		free(p);
		free(rpcpath);
		return nil;
	}

	rpc = auth_allocrpc(afd);
	if(rpc){
		ai = fauth_proxy(f, rpc, getkey, p);
		auth_freerpc(rpc);
	}
	close(afd);
	free(p);
	free(rpcpath);
	return ai;
}
Beispiel #4
0
static int
freecloserpc(AuthRpc *rpc)
{
	if(rpc){
		close(rpc->afd);
		auth_freerpc(rpc);
	}
	return -1;
}
Beispiel #5
0
void
auth_freechal(Chalstate *c)
{
	if(c == nil)
		return;
	if(c->rpc != nil)
		auth_freerpc(c->rpc);
	memset(c, 0xBB, sizeof(*c));
	free(c);
}
Beispiel #6
0
void
authfree(void *auth)
{
	AuthRpc *rpc;

	if(rpc = auth){
		close(rpc->afd);
		auth_freerpc(rpc);
	}
}
Beispiel #7
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;
}
UserPasswd*
auth_getuserpasswd(AuthGetkey *getkey, char *fmt, ...)
{
	AuthRpc *rpc;
	char *f[3], *p, *params;
	int fd;
	va_list arg;
	UserPasswd *up;

	up = nil;
	rpc = nil;
	params = nil;

	fd = open("/mnt/factotum/rpc", ORDWR);
	if(fd < 0)
		goto out;
	rpc = auth_allocrpc(fd);
	if(rpc == nil)
		goto out;
	quotefmtinstall();	/* just in case */
	va_start(arg, fmt);
	params = vsmprint(fmt, arg);
	va_end(arg);
	if(params == nil)
		goto out;

	if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok
	|| dorpc(rpc, "read", nil, 0, getkey) != ARok)
		goto out;

	rpc->arg[rpc->narg] = '\0';
	if(tokenize(rpc->arg, f, 2) != 2){
		werrstr("bad answer from factotum");
		goto out;
	}
	up = malloc(sizeof(*up)+rpc->narg+1);
	if(up == nil)
		goto out;
	p = (char*)&up[1];
	strcpy(p, f[0]);
	up->user = p;
	p += strlen(p)+1;
	strcpy(p, f[1]);
	up->passwd = p;

out:
	free(params);
	auth_freerpc(rpc);
	close(fd);
	return up;
}
Beispiel #9
0
static void
fidFree(Fid* fid)
{
	if(fid->file != nil){
		fileDecRef(fid->file);
		fid->file = nil;
	}
	if(fid->db != nil){
		dirBufFree(fid->db);
		fid->db = nil;
	}
	fidUnlock(fid);

	if(fid->uid != nil){
		vtMemFree(fid->uid);
		fid->uid = nil;
	}
	if(fid->uname != nil){
		vtMemFree(fid->uname);
		fid->uname = nil;
	}
	if(fid->excl != nil)
		exclFree(fid);
	if(fid->rpc != nil){
		close(fid->rpc->afd);
		auth_freerpc(fid->rpc);
		fid->rpc = nil;
	}
	if(fid->fsys != nil){
		fsysPut(fid->fsys);
		fid->fsys = nil;
	}
	if(fid->cuname != nil){
		vtMemFree(fid->cuname);
		fid->cuname = nil;
	}

	vtLock(fbox.lock);
	fbox.inuse--;
	if(fbox.nfree < 10){
		fid->hash = fbox.free;
		fbox.free = fid;
		fbox.nfree++;
	}
	else{
		vtLockFree(fid->alock);
		vtLockFree(fid->lock);
		vtMemFree(fid);
	}
	vtUnlock(fbox.lock);
}
Beispiel #10
0
void
authdestroy(Fid *fid)
{
	Afid *afid;
	
	if((fid->qid.type & QTAUTH) && (afid = fid->aux) != nil){
		if(afid->rpc)
			auth_freerpc(afid->rpc);
		close(afid->afd);
		free(afid->uname);
		free(afid->aname);
		free(afid);
		fid->aux = nil;
	}
}
Beispiel #11
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);
}
Beispiel #12
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;
}
Beispiel #13
0
AuthInfo*
fsauth_proxy(CFid *fid, AuthGetkey *getkey, char *fmt, ...)
{
	char *p;
	va_list arg;
	AuthInfo *ai;
	AuthRpc *rpc;

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

	rpc = auth_allocrpc();
	if(rpc == nil){
		free(p);
		return nil;
	}

	ai = fsfauth_proxy(fid, rpc, getkey, p);
	free(p);
	auth_freerpc(rpc);
	return ai;
}
Beispiel #14
0
/* returns 0 if auth succeeded (or unneeded), -1 otherwise */
int
authhostowner(Session *s)
{
	Fid *af, *f;
	int rv = -1;
	int afd;
	AuthInfo *ai;
	AuthRpc *rpc;

	/* get a fid to authenticate over */
	f = nil;
	af = newfid(s);
	s->f.afid = af - s->fids;
	s->f.uname = getuser();
	s->f.aname = s->spec;
	if(xmesg(s, Tauth)){
		/* not needed */
		rv = 0;
		goto out;
	}

	quotefmtinstall();	/* just in case */

	afd = open("/mnt/factotum/rpc", ORDWR);
	if(afd < 0){
		werrstr("opening /mnt/factotum/rpc: %r");
		goto out;
	}

	rpc = auth_allocrpc(afd);
	if(rpc == nil)
		goto out;

	ai = authproto(s, af, rpc, auth_getkey, "proto=p9any role=client");
	if(ai != nil){
		rv = 0;
		auth_freeAI(ai);
	}
	auth_freerpc(rpc);
	close(afd);

	/* try attaching with the afid */
	chat("attaching as hostowner...");
	f = newfid(s);
	s->f.fid = f - s->fids;
	s->f.afid = af - s->fids;;
	s->f.uname = getuser();
	s->f.aname = s->spec;
	if(xmesg(s, Tattach) == 0)
		rv = 0;
out:
	if(af != nil){
		putfid(s, af);
		s->f.fid = af - s->fids;
		xmesg(s, Tclunk);
	}
	if(f != nil){
		putfid(s, f);
		s->f.fid = f - s->fids;
		xmesg(s, Tclunk);
	}

	return rv;
}
Beispiel #15
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;
}
Beispiel #16
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;
}
Beispiel #17
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);
}