Пример #1
0
/*
 *  reply with ticket and authenticator
 */
int
tickauthreply(Ticketreq *tr, char *hkey)
{
	Ticket t;
	Authenticator a;
	char buf[TICKETLEN+AUTHENTLEN+1];

	memset(&t, 0, sizeof(t));
	memmove(t.chal, tr->chal, CHALLEN);
	safecpy(t.cuid, tr->uid, sizeof t.cuid);
	safecpy(t.suid, tr->uid, sizeof t.suid);
	mkkey(t.key);
	buf[0] = AuthOK;
	t.num = AuthTs;
	convT2M(&t, buf+1, hkey);
	memmove(a.chal, t.chal, CHALLEN);
	a.num = AuthAc;
	a.id = 0;
	convA2M(&a, buf+TICKETLEN+1, t.key);
	if(write(1, buf, TICKETLEN+AUTHENTLEN+1) < 0)
		return -1;
	return 0;
}
Пример #2
0
int
authorize(Chan *cp, Oldfcall *in, Oldfcall *ou)
{
	Ticket t;
	Authenticator a;
	int x;
	uint32_t bit;

	if (cp == cons.srvchan)               /* local channel already safe */
		return 1;

	if(wstatallow)		/* set to allow entry during boot */
		return 1;

	if(strcmp(in->uname, "none") == 0)
		return allownone || cp->authed;

	if(in->type == Toattach9p1)
		return 0;

	if(!didread)
		return 0;

	/* decrypt and unpack ticket */
	convM2T(in->ticket, &t, nvr.machkey);
	if(t.num != AuthTs){
print("bad AuthTs num\n");
		return 0;
	}

	/* decrypt and unpack authenticator */
	convM2A(in->auth, &a, t.key);
	if(a.num != AuthAc){
print("bad AuthAc num\n");
		return 0;
	}

	/* challenges must match */
	if(memcmp(a.chal, cp->chal, sizeof(a.chal)) != 0){
print("bad challenge\n");
		return 0;
	}

	/*
	 *  the id must be in a valid range.  the range is specified by a
	 *  lower bount (idoffset) and a bit vector (idvec) where a
	 *  bit set to 1 means unusable
	 */
	lock(&cp->idlock);
	x = a.id - cp->idoffset;
	bit = 1<<x;
	if(x < 0 || x > 31 || (bit&cp->idvec)){
		unlock(&cp->idlock);
		return 0;
	}
	cp->idvec |= bit;

	/* normalize the vector */
	while(cp->idvec&0xffff0001){
		cp->idvec >>= 1;
		cp->idoffset++;
	}
	unlock(&cp->idlock);

	/* ticket name and attach name must match */
	if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){
print("names don't match\n");
		return 0;
	}

	/* copy translated name into input record */
	memmove(in->uname, t.suid, sizeof(in->uname));

	/* craft a reply */
	a.num = AuthAs;
	memmove(a.chal, cp->rchal, CHALLEN);
	convA2M(&a, ou->rauth, t.key);

	cp->authed = 1;
	return 1;
}
Пример #3
0
AuthInfo*
p9any(int fd)
{
	char buf[1024], buf2[1024], cchal[CHALLEN], *bbuf, *p, *dom, *u;
	char *pass;
	char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN];
	char authkey[DESKEYLEN];
	Authenticator auth;
	int afd, i, n, v2;
	Ticketreq tr;
	Ticket t;
	AuthInfo *ai;

	if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0)
		return p9anyfactotum(fd, afd);

	if(readstr(fd, buf, sizeof buf) < 0)
		fatal(1, "cannot read p9any negotiation");
	bbuf = buf;
	v2 = 0;
	if(strncmp(buf, "v.2 ", 4) == 0){
		v2 = 1;
		bbuf += 4;
	}
	if((p = strchr(bbuf, ' ')))
		*p = 0;
	p = bbuf;
	if((dom = strchr(p, '@')) == nil)
		fatal(1, "bad p9any domain");
	*dom++ = 0;
	if(strcmp(p, "p9sk1") != 0)
		fatal(1, "server did not offer p9sk1");

	sprint(buf2, "%s %s", p, dom);
	if(write(fd, buf2, strlen(buf2)+1) != strlen(buf2)+1)
		fatal(1, "cannot write user/domain choice in p9any");
	if(v2){
		if(readstr(fd, buf, sizeof buf) != 3)
			fatal(1, "cannot read OK in p9any");
		if(memcmp(buf, "OK\0", 3) != 0)
			fatal(1, "did not get OK in p9any");
	}
	for(i=0; i<CHALLEN; i++)
		cchal[i] = fastrand();
	if(write(fd, cchal, 8) != 8)
		fatal(1, "cannot write p9sk1 challenge");

	if(readn(fd, trbuf, TICKREQLEN) != TICKREQLEN)
		fatal(1, "cannot read ticket request in p9sk1");


	convM2TR(trbuf, &tr);
	u = user;
	pass = findkey(&u, tr.authdom);
	if(pass == nil)
	again:
		pass = getkey(u, tr.authdom);
	if(pass == nil)
		fatal(1, "no password");

	passtokey(authkey, pass);
	memset(pass, 0, strlen(pass));

	tr.type = AuthTreq;
	strecpy(tr.hostid, tr.hostid+sizeof tr.hostid, u);
	strecpy(tr.uid, tr.uid+sizeof tr.uid, u);
	convTR2M(&tr, trbuf);

	if(gettickets(&tr, authkey, trbuf, tbuf) < 0)
		fatal(1, "cannot get auth tickets in p9sk1");

	convM2T(tbuf, &t, authkey);
	if(t.num != AuthTc){
		print("?password mismatch with auth server\n");
		goto again;
	}
	memmove(tbuf, tbuf+TICKETLEN, TICKETLEN);

	auth.num = AuthAc;
	memmove(auth.chal, tr.chal, CHALLEN);
	auth.id = 0;
	convA2M(&auth, tbuf+TICKETLEN, t.key);

	if(write(fd, tbuf, TICKETLEN+AUTHENTLEN) != TICKETLEN+AUTHENTLEN)
		fatal(1, "cannot send ticket and authenticator back in p9sk1");

	if((n=readn(fd, tbuf, AUTHENTLEN)) != AUTHENTLEN ||
			memcmp(tbuf, "cpu:", 4) == 0){
		if(n <= 4)
			fatal(1, "cannot read authenticator in p9sk1");

		/*
		 * didn't send back authenticator:
		 * sent back fatal error message.
		 */
		memmove(buf, tbuf, n);
		i = readn(fd, buf+n, sizeof buf-n-1);
		if(i > 0)
			n += i;
		buf[n] = 0;
		werrstr("");
		fatal(0, "server says: %s", buf);
	}
	
	convM2A(tbuf, &auth, t.key);
	if(auth.num != AuthAs
	|| memcmp(auth.chal, cchal, CHALLEN) != 0
	|| auth.id != 0){
		print("?you and auth server agree about password.\n");
		print("?server is confused.\n");
		fatal(0, "server lies got %llux.%d want %llux.%d",
		      *(int64_t*)auth.chal, auth.id, *(int64_t*)cchal, 0);
	}
	//print("i am %s there.\n", t.suid);
	ai = mallocz(sizeof(AuthInfo), 1);
	ai->secret = mallocz(8, 1);
	des56to64((uint8_t*)t.key, ai->secret);
	ai->nsecret = 8;
	ai->suid = strdup(t.suid);
	ai->cuid = strdup(t.cuid);
	memset(authkey, 0, sizeof authkey);
	return ai;
}