148 lines · 3.1 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <authsrv.h>#include <bio.h>#include "authcmdlib.h" static char *pbmsg = "AS protocol botch"; intasrdresp(int fd, char *buf, int len){	char error[AERRLEN]; 	if(read(fd, buf, 1) != 1){		werrstr(pbmsg);		return -1;	} 	switch(buf[0]){	case AuthOK:		if(readn(fd, buf, len) < 0){			werrstr(pbmsg);			return -1;		}		break;	case AuthErr:		if(readn(fd, error, AERRLEN) < 0){			werrstr(pbmsg);			return -1;		}		error[AERRLEN-1] = 0;		werrstr(error);		return -1;	default:		werrstr(pbmsg);		return -1;	}	return 0;} voidmain(int argc, char **argv){	int fd;	Ticketreq tr;	Ticket t;	Passwordreq pr;	char tbuf[TICKETLEN];	char key[DESKEYLEN];	char buf[512];	char *s, *user; 	user = getuser(); 	ARGBEGIN{	}ARGEND 	s = nil;	if(argc > 0){		user = argv[0];		s = strchr(user, '@');		if(s != nil)			*s++ = 0;		if(*user == 0)			user = getuser();	} 	fd = authdial(nil, s);	if(fd < 0)		error("protocol botch: %r"); 	/* send ticket request to AS */	memset(&tr, 0, sizeof(tr));	strcpy(tr.uid, user);	tr.type = AuthPass;	convTR2M(&tr, buf);	if(write(fd, buf, TICKREQLEN) != TICKREQLEN)		error("protocol botch: %r");	if(asrdresp(fd, buf, TICKETLEN) < 0)		error("%r");	memmove(tbuf, buf, TICKETLEN); 	/*	 *  get a password from the user and try to decrypt the	 *  ticket.  If it doesn't work we've got a bad password,	 *  give up.	 */	readln("Plan 9 Password: ", pr.old, sizeof pr.old, 1);	passtokey(key, pr.old);	convM2T(tbuf, &t, key);	if(t.num != AuthTp || strcmp(t.cuid, tr.uid))		error("bad password"); 	/* loop trying new passwords */	for(;;){		pr.changesecret = 0;		*pr.new = 0;		readln("change Plan 9 Password? (y/n) ", buf, sizeof buf, 0);		if(*buf == 'y' || *buf == 'Y'){			readln("Password(8 to 31 characters): ", pr.new,				sizeof pr.new, 1);			readln("Confirm: ", buf, sizeof buf, 1);			if(strcmp(pr.new, buf)){				print("!mismatch\n");				continue;			}		}		readln("change Inferno/POP password? (y/n) ", buf, sizeof buf, 0);		if(*buf == 'y' || *buf == 'Y'){			pr.changesecret = 1;			readln("make it the same as your plan 9 password? (y/n) ",				buf, sizeof buf, 0);			if(*buf == 'y' || *buf == 'Y'){				if(*pr.new == 0)					strcpy(pr.secret, pr.old);				else					strcpy(pr.secret, pr.new);			} else {				readln("Secret(0 to 256 characters): ", pr.secret,					sizeof pr.secret, 1);				readln("Confirm: ", buf, sizeof buf, 1);				if(strcmp(pr.secret, buf)){					print("!mismatch\n");					continue;				}			}		}		pr.num = AuthPass;		convPR2M(&pr, buf, t.key);		if(write(fd, buf, PASSREQLEN) != PASSREQLEN)			error("AS protocol botch: %r");		if(asrdresp(fd, buf, 0) == 0)			break;		fprint(2, "passwd: refused: %r\n");	}	close(fd); 	exits(0);}