1 #include <u.h> 2 #include <libc.h> 3 #include <auth.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[ERRLEN]; 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, ERRLEN) < 0){ 27 werrstr(pbmsg); 28 return -1; 29 } 30 error[ERRLEN-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 main(int argc, char **argv) 42 { 43 int n, fd; 44 Ticketreq tr; 45 Ticket t; 46 Passwordreq pr; 47 char tbuf[TICKETLEN]; 48 char key[DESKEYLEN]; 49 char buf[512]; 50 char *s; 51 52 ARGBEGIN{ 53 }ARGEND 54 55 s = getenv("service"); 56 if(s && strcmp(s, "cpu") == 0){ 57 fprint(2, "passwd must not be run on the cpu server\n"); 58 exits("boofhead"); 59 } 60 61 if(argc > 1) 62 error("usage: passwd [user]"); 63 64 fd = authdial(); 65 if(fd < 0) 66 error("protocol botch: %r"); 67 68 /* send ticket request to AS */ 69 memset(&tr, 0, sizeof(tr)); 70 if(argc == 0) 71 strcpy(tr.uid, getuser()); 72 else 73 strcpy(tr.uid, argv[0]); 74 tr.type = AuthPass; 75 convTR2M(&tr, buf); 76 if(write(fd, buf, TICKREQLEN) != TICKREQLEN) 77 error("protocol botch: %r"); 78 if(asrdresp(fd, buf, TICKETLEN) < 0) 79 error("%r"); 80 memmove(tbuf, buf, TICKETLEN); 81 82 /* 83 * get a password from the user and try to decrypt the 84 * ticket. If it doesn't work we've got a bad password, 85 * give up. 86 */ 87 readln("Password: ", pr.old, sizeof pr.old, 1); 88 passtokey(key, pr.old); 89 convM2T(tbuf, &t, key); 90 if(t.num != AuthTc || strcmp(t.cuid, tr.uid)) 91 error("bad password"); 92 93 /* loop trying new passwords */ 94 for(;;){ 95 readln("New password: ", pr.new, sizeof pr.new, 1); 96 readln("Confirm: ", buf, sizeof buf, 1); 97 if(strcmp(pr.new, buf)) 98 continue; 99 pr.num = AuthPass; 100 convPR2M(&pr, buf, t.key); 101 if(write(fd, buf, PASSREQLEN) != PASSREQLEN) 102 error("AS protocol botch: %r"); 103 if(asrdresp(fd, buf, 0) == 0) 104 break; 105 fprint(2, "refused: %r\n"); 106 } 107 close(fd); 108 109 /* if this is the hostowner's key, try to change the key in the kernel */ 110 n = readfile("/dev/hostowner", buf, sizeof(buf)-1); 111 if(n > 0){ 112 buf[n] = 0; 113 if(strcmp(buf, tr.uid) == 0){ 114 passtokey(key, pr.new); 115 writefile("/dev/key", key, DESKEYLEN); 116 } 117 } 118 exits(0); 119 } 120