Пример #1
0
static int
wepwrite(Fsstate *fss, void *va, uint n)
{
	char *data = va;
	State *s;
	char dev[64];
	int fd, cfd;
	int rv;
	char *p;

	/* get the device */
	if(n > sizeof(dev)-5){
		werrstr("device too long");
		return RpcErrstr;
	}
	memmove(dev, data, n);
	dev[n] = 0;
	s = fss->ps;

	/* legal? */
	if(dev[0] != '#' || dev[1] != 'l'){
		werrstr("%s not an ether device", dev);
		return RpcErrstr;
	}
	strcat(dev, "!0");
	fd = dial(dev, 0, 0, &cfd);
	if(fd < 0)
		return RpcErrstr;

	/* flavor it with passwords, essid, and turn on wep */
	rv = RpcErrstr;
	p = _strfindattr(s->key->privattr, "!key1");
	if(p != nil)
		if(fprint(cfd, "key1 %s", p) < 0)
			goto out;
	p = _strfindattr(s->key->privattr, "!key2");
	if(p != nil)
		if(fprint(cfd, "key2 %s", p) < 0)
			goto out;
	p = _strfindattr(s->key->privattr, "!key3");
	if(p != nil)
		if(fprint(cfd, "key3 %s", p) < 0)
			goto out;
	p = _strfindattr(fss->attr, "essid");
	if(p != nil)
		if(fprint(cfd, "essid %s", p) < 0)
			goto out;
	if(fprint(cfd, "crypt on") < 0)
		goto out;
	rv = RpcOk;
out:
	close(fd);
	close(cfd);
	return rv;
}
Пример #2
0
int
confirmwrite(char *s)
{
	char *t, *ans;
	int allow, tagoff;
	ulong tag;
	Attr *a;
	Fsstate *fss;
	Req *r, **l;

	a = _parseattr(s);
	if(a == nil){
		werrstr("empty write");
		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;
	}
	r = nil;
	tagoff = -1;
	for(l=&cusewait; *l; l=&(*l)->aux){
		r = *l;
		if(hastag(r->fid->aux, tag, &tagoff)){
			*l = r->aux;
			if(r->aux == nil)
				cuselast = l;
			break;
		}
	}
	if(r == nil || tagoff == -1){
		werrstr("tag not found");
		return -1;
	}
	fss = r->fid->aux;
	fss->conf[tagoff].canuse = allow;
	rpcread(r);
	return 0;
}
Пример #3
0
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;
}
Пример #4
0
int
needkeywrite(char *s)
{
	char *t;
	ulong tag;
	Attr *a;
	Req *r, **l;

	a = _parseattr(s);
	if(a == nil){
		werrstr("empty write");
		return -1;
	}
	if((t = _strfindattr(a, "tag")) == nil){
		werrstr("no tag");
		return -1;
	}
	tag = strtoul(t, 0, 0);
	r = nil;
	for(l=&needwait; *l; l=&(*l)->aux){
		r = *l;
		if(r->tag == tag){
			*l = r->aux;
			if(r->aux == nil)
				needlast = l;
			break;
		}
	}
	if(r == nil){
		werrstr("tag not found");
		return -1;
	}
	rpcread(r);
	return 0;
}
Пример #5
0
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){
		flog("bad confirm write: no tag");
		werrstr("no tag");
		return -1;
	}
	tag = strtoul(t, 0, 0);
	if((ans = _strfindattr(a, "answer")) == nil){
		flog("bad confirm write: no answer");
		werrstr("no answer");
		return -1;
	}
	if(strcmp(ans, "yes") == 0)
		allow = 1;
	else if(strcmp(ans, "no") == 0)
		allow = 0;
	else{
		flog("bad confirm write: bad answer");
		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;
}
Пример #6
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;	
}
Пример #7
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);
}
Пример #8
0
RSApriv*
getkey(int argc, char **argv, int needprivate, Attr **pa)
{
    char *file, *s, *p;
    int sz;
    RSApriv *key;
    Biobuf *b;
    int regen;
    Attr *a;

    if(argc == 0)
        file = "#d/0";
    else
        file = argv[0];

    key = mallocz(sizeof(RSApriv), 1);
    if(key == nil)
        return nil;

    if((b = Bopen(file, OREAD)) == nil) {
        werrstr("open %s: %r", file);
        return nil;
    }
    s = Brdstr(b, '\n', 1);
    if(s == nil) {
        werrstr("read %s: %r", file);
        return nil;
    }
    if(strncmp(s, "key ", 4) != 0) {
        werrstr("bad key format");
        return nil;
    }

    regen = 0;
    a = _parseattr(s+4);
    if(a == nil) {
        werrstr("empty key");
        return nil;
    }
    if((p = _strfindattr(a, "proto")) == nil) {
        werrstr("no proto");
        return nil;
    }
    if(strcmp(p, "rsa") != 0) {
        werrstr("proto not rsa");
        return nil;
    }
    if((p = _strfindattr(a, "ek")) == nil) {
        werrstr("no ek");
        return nil;
    }
    if((key->pub.ek = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad ek");
        return nil;
    }
    if((p = _strfindattr(a, "n")) == nil) {
        werrstr("no n");
        return nil;
    }
    if((key->pub.n = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad n");
        return nil;
    }
    if((p = _strfindattr(a, "size")) == nil)
        fprint(2, "warning: missing size; will add\n");
    else if((sz = strtol(p, &p, 10)) == 0 || *p != 0)
        fprint(2, "warning: bad size; will correct\n");
    else if(sz != mpsignif(key->pub.n))
        fprint(2, "warning: wrong size (got %d, expected %d); will correct\n",
               sz, mpsignif(key->pub.n));
    if(!needprivate)
        goto call;
    if((p = _strfindattr(a, "!dk")) == nil) {
        werrstr("no !dk");
        return nil;
    }
    if((key->dk = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !dk");
        return nil;
    }
    if((p = _strfindattr(a, "!p")) == nil) {
        werrstr("no !p");
        return nil;
    }
    if((key->p = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !p");
        return nil;
    }
    if((p = _strfindattr(a, "!q")) == nil) {
        werrstr("no !q");
        return nil;
    }
    if((key->q = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !q");
        return nil;
    }
    if((p = _strfindattr(a, "!kp")) == nil) {
        fprint(2, "warning: no !kp\n");
        regen = 1;
        goto regen;
    }
    if((key->kp = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !kp\n");
        regen = 1;
        goto regen;
    }
    if((p = _strfindattr(a, "!kq")) == nil) {
        fprint(2, "warning: no !kq\n");
        regen = 1;
        goto regen;
    }
    if((key->kq = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !kq\n");
        regen = 1;
        goto regen;
    }
    if((p = _strfindattr(a, "!c2")) == nil) {
        fprint(2, "warning: no !c2\n");
        regen = 1;
        goto regen;
    }
    if((key->c2 = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !c2\n");
        regen = 1;
        goto regen;
    }
regen:
    if(regen) {
        RSApriv *k2;

        k2 = rsafill(key->pub.n, key->pub.ek, key->dk, key->p, key->q);
        if(k2 == nil) {
            werrstr("regenerating chinese-remainder parts failed: %r");
            return nil;
        }
        key = k2;
    }
call:
    a = _delattr(a, "ek");
    a = _delattr(a, "n");
    a = _delattr(a, "size");
    a = _delattr(a, "!dk");
    a = _delattr(a, "!p");
    a = _delattr(a, "!q");
    a = _delattr(a, "!c2");
    a = _delattr(a, "!kp");
    a = _delattr(a, "!kq");
    if(pa)
        *pa = a;
    return key;
}
Пример #9
0
DSApriv*
getdsakey(int argc, char **argv, int needprivate, Attr **pa)
{
    char *file, *s, *p;
    DSApriv *key;
    Biobuf *b;
    Attr *a;

    if(argc == 0)
        file = "#d/0";
    else
        file = argv[0];

    key = mallocz(sizeof(RSApriv), 1);
    if(key == nil)
        return nil;

    if((b = Bopen(file, OREAD)) == nil) {
        werrstr("open %s: %r", file);
        return nil;
    }
    s = Brdstr(b, '\n', 1);
    if(s == nil) {
        werrstr("read %s: %r", file);
        return nil;
    }
    if(strncmp(s, "key ", 4) != 0) {
        werrstr("bad key format");
        return nil;
    }

    a = _parseattr(s+4);
    if(a == nil) {
        werrstr("empty key");
        return nil;
    }
    if((p = _strfindattr(a, "proto")) == nil) {
        werrstr("no proto");
        return nil;
    }
    if(strcmp(p, "dsa") != 0) {
        werrstr("proto not dsa");
        return nil;
    }
    if((p = _strfindattr(a, "p")) == nil) {
        werrstr("no p");
        return nil;
    }
    if((key->pub.p = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad p");
        return nil;
    }
    if((p = _strfindattr(a, "q")) == nil) {
        werrstr("no q");
        return nil;
    }
    if((key->pub.q = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad q");
        return nil;
    }
    if((p = _strfindattr(a, "alpha")) == nil) {
        werrstr("no alpha");
        return nil;
    }
    if((key->pub.alpha = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad alpha");
        return nil;
    }
    if((p = _strfindattr(a, "key")) == nil) {
        werrstr("no key=");
        return nil;
    }
    if((key->pub.key = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad key=");
        return nil;
    }
    if(!needprivate)
        goto call;
    if((p = _strfindattr(a, "!secret")) == nil) {
        werrstr("no !secret");
        return nil;
    }
    if((key->secret = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !secret");
        return nil;
    }
call:
    a = _delattr(a, "p");
    a = _delattr(a, "q");
    a = _delattr(a, "alpha");
    a = _delattr(a, "key");
    a = _delattr(a, "!secret");
    if(pa)
        *pa = a;
    return key;
}
Пример #10
0
void
rpcread(Req *r)
{
	Attr *attr;
	char *p;
	int ophase, ret;
	uint8_t *e;
	uint count;
	Fsstate *fss;
	Proto *proto;

	if(r->ifcall.count < 64){
		respond(r, "rpc read too small");
		return;
	}
	fss = r->fid->aux;
	if(!fss->pending){
		respond(r, "no rpc pending");
		return;
	}
	switch(fss->rpc.iverb){
	default:
	case Vunknown:
		retstring(r, fss, "error unknown verb");
		break;

	case Vstart:
		if(fss->phase != Notstarted){
			flog("%d: implicit close due to second start; old attr '%A'", fss->seqnum, fss->attr);
			if(fss->proto && fss->ps)
				(*fss->proto->close)(fss);
			fss->ps = nil;
			fss->proto = nil;
			_freeattr(fss->attr);
			fss->attr = nil;
			fss->phase = Notstarted;
		}
		attr = _parseattr(fss->rpc.arg);
		if((p = _strfindattr(attr, "proto")) == nil){
			retstring(r, fss, "error did not specify proto");
			_freeattr(attr);
			break;
		}
		if((proto = findproto(p)) == nil){
			snprint(fss->rpc.buf, Maxrpc, "error unknown protocol %q", p);
			retstring(r, fss, fss->rpc.buf);
			_freeattr(attr);
			break;
		}
		fss->attr = attr;
		fss->proto = proto;
		fss->seqnum = ++seqnum;
		ret = (*proto->init)(proto, fss);
		rpcstartlog(attr, fss, ret);
		if(ret != RpcOk){
			_freeattr(fss->attr);
			fss->attr = nil;
			fss->phase = Notstarted;
		}
		retrpc(r, ret, fss);
		break;

	case Vread:
		if(fss->rpc.arg && fss->rpc.arg[0]){
			retstring(r, fss, "error read needs no parameters");
			break;
		}
		if(rdwrcheck(r, fss) < 0)
			break;
		count = r->ifcall.count - 3;
		ophase = fss->phase;
		ret = fss->proto->read(fss, (uint8_t*)r->ofcall.data+3,
				       &count);
		rpcrdwrlog(fss, "read", count, ophase, ret);
		if(ret == RpcOk){
			memmove(r->ofcall.data, "ok ", 3);
			if(count == 0)
				r->ofcall.count = 2;
			else
				r->ofcall.count = 3+count;
			fss->pending = 0;
			respond(r, nil);
		}else
			retrpc(r, ret, fss);
		break;

	case Vwrite:
		if(rdwrcheck(r, fss) < 0)
			break;
		ophase = fss->phase;
		ret = fss->proto->write(fss, fss->rpc.arg, fss->rpc.narg);
		rpcrdwrlog(fss, "write", fss->rpc.narg, ophase, ret);
		retrpc(r, ret, fss);
		break;

	case Vauthinfo:
		if(fss->phase != Established){
			retstring(r, fss, "error authentication unfinished");
			break;
		}
		if(!fss->haveai){
			retstring(r, fss, "error no authinfo available");
			break;
		}
		memmove(r->ofcall.data, "ok ", 3);
		fss->ai.cap = mkcap(r->fid->uid, fss->ai.suid);
		e = convAI2M(&fss->ai, (uint8_t*)r->ofcall.data+3,
			     r->ifcall.count-3);
		free(fss->ai.cap);
		fss->ai.cap = nil;
		if(e == nil){
			retstring(r, fss, "error read too small");
			break;
		}
		r->ofcall.count = e - (uint8_t*)r->ofcall.data;
		fss->pending = 0;
		respond(r, nil);
		break;

	case Vattr:
		snprint(fss->rpc.buf, Maxrpc, "ok %A", fss->attr);
		retstring(r, fss, fss->rpc.buf);
		break;
	}
}