plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

passwd.c (3021B)


      1 #include <u.h>
      2 #include <libc.h>
      3 #include <libsec.h>
      4 #include <authsrv.h>
      5 
      6 static char *pbmsg = "AS protocol botch";
      7 
      8 int
      9 asrdresp(int fd, char *buf, int len)
     10 {
     11 	char error[AERRLEN];
     12 
     13 	if(read(fd, buf, 1) != 1){
     14 		werrstr(pbmsg);
     15 		return -1;
     16 	}
     17 
     18 	switch(buf[0]){
     19 	case AuthOK:
     20 		if(readn(fd, buf, len) < 0){
     21 			werrstr(pbmsg);
     22 			return -1;
     23 		}
     24 		break;
     25 	case AuthErr:
     26 		if(readn(fd, error, AERRLEN) < 0){
     27 			werrstr(pbmsg);
     28 			return -1;
     29 		}
     30 		error[AERRLEN-1] = 0;
     31 		werrstr(error);
     32 		return -1;
     33 	default:
     34 		werrstr(pbmsg);
     35 		return -1;
     36 	}
     37 	return 0;
     38 }
     39 
     40 void
     41 readln(char *prompt, char *buf, int nbuf, int secret)
     42 {
     43 	char *p;
     44 
     45 	p = readcons(prompt, nil, secret);
     46 	if(p == nil)
     47 		sysfatal("user terminated input");
     48 	if(strlen(p) >= nbuf)
     49 		sysfatal("too long");
     50 	strcpy(buf, p);
     51 	memset(p, 0, strlen(p));
     52 	free(p);
     53 }
     54 
     55 void
     56 main(int argc, char **argv)
     57 {
     58 	int fd;
     59 	Ticketreq tr;
     60 	Ticket t;
     61 	Passwordreq pr;
     62 	char tbuf[TICKETLEN];
     63 	char key[DESKEYLEN];
     64 	char buf[512];
     65 	char *s, *user;
     66 
     67 	user = getuser();
     68 
     69 	ARGBEGIN{
     70 	}ARGEND
     71 
     72 	s = nil;
     73 	if(argc > 0){
     74 		user = argv[0];
     75 		s = strchr(user, '@');
     76 		if(s != nil)
     77 			*s++ = 0;
     78 		if(*user == 0)
     79 			user = getuser();
     80 	}
     81 
     82 	fd = authdial(nil, s);
     83 	if(fd < 0)
     84 		sysfatal("protocol botch: %r");
     85 
     86 	/* send ticket request to AS */
     87 	memset(&tr, 0, sizeof(tr));
     88 	strcpy(tr.uid, user);
     89 	tr.type = AuthPass;
     90 	convTR2M(&tr, buf);
     91 	if(write(fd, buf, TICKREQLEN) != TICKREQLEN)
     92 		sysfatal("protocol botch: %r");
     93 	if(asrdresp(fd, buf, TICKETLEN) < 0)
     94 		sysfatal("%r");
     95 	memmove(tbuf, buf, TICKETLEN);
     96 
     97 	/*
     98 	 *  get a password from the user and try to decrypt the
     99 	 *  ticket.  If it doesn't work we've got a bad password,
    100 	 *  give up.
    101 	 */
    102 	readln("Plan 9 Password", pr.old, sizeof pr.old, 1);
    103 	passtokey(key, pr.old);
    104 	convM2T(tbuf, &t, key);
    105 	if(t.num != AuthTp || strcmp(t.cuid, tr.uid))
    106 		sysfatal("bad password");
    107 
    108 	/* loop trying new passwords */
    109 	for(;;){
    110 		pr.changesecret = 0;
    111 		*pr.new = 0;
    112 		readln("change Plan 9 Password? (y/n)", buf, sizeof buf, 0);
    113 		if(*buf == 'y' || *buf == 'Y'){
    114 			readln("Password(8 to 31 characters)", pr.new,
    115 				sizeof pr.new, 1);
    116 			readln("Confirm", buf, sizeof buf, 1);
    117 			if(strcmp(pr.new, buf)){
    118 				print("!mismatch\n");
    119 				continue;
    120 			}
    121 		}
    122 		readln("change Inferno/POP password? (y/n)", buf, sizeof buf, 0);
    123 		if(*buf == 'y' || *buf == 'Y'){
    124 			pr.changesecret = 1;
    125 			readln("make it the same as your plan 9 password? (y/n)",
    126 				buf, sizeof buf, 0);
    127 			if(*buf == 'y' || *buf == 'Y'){
    128 				if(*pr.new == 0)
    129 					strcpy(pr.secret, pr.old);
    130 				else
    131 					strcpy(pr.secret, pr.new);
    132 			} else {
    133 				readln("Secret(0 to 256 characters)", pr.secret,
    134 					sizeof pr.secret, 1);
    135 				readln("Confirm", buf, sizeof buf, 1);
    136 				if(strcmp(pr.secret, buf)){
    137 					print("!mismatch\n");
    138 					continue;
    139 				}
    140 			}
    141 		}
    142 		pr.num = AuthPass;
    143 		convPR2M(&pr, buf, t.key);
    144 		if(write(fd, buf, PASSREQLEN) != PASSREQLEN)
    145 			sysfatal("AS protocol botch: %r");
    146 		if(asrdresp(fd, buf, 0) == 0)
    147 			break;
    148 		fprint(2, "refused: %r\n");
    149 	}
    150 	close(fd);
    151 
    152 	exits(0);
    153 }