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 }