Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <libsec.h>
4 #include <authsrv.h>
6 static char *pbmsg = "AS protocol botch";
8 int
9 asrdresp(int fd, char *buf, int len)
10 {
11 char error[AERRLEN];
13 if(read(fd, buf, 1) != 1){
14 werrstr(pbmsg);
15 return -1;
16 }
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 }
40 void
41 readln(char *prompt, char *buf, int nbuf, int secret)
42 {
43 char *p;
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 }
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;
67 user = getuser();
69 ARGBEGIN{
70 }ARGEND
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 }
82 fd = authdial(nil, s);
83 if(fd < 0)
84 sysfatal("protocol botch: %r");
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);
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");
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;
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;
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");
150 close(fd);
152 exits(0);