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