]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/auth/passwd.c
merge
[plan9front.git] / sys / src / cmd / auth / passwd.c
1 #include <u.h>
2 #include <libc.h>
3 #include <bio.h>
4 #include <authsrv.h>
5 #include "authcmdlib.h"
6
7 void
8 main(int argc, char **argv)
9 {
10         int fd, n, try;
11         Ticketreq tr;
12         Ticket t;
13         Passwordreq pr;
14         Authkey key;
15         char buf[512];
16         char *s, *user;
17
18         ARGBEGIN{
19         }ARGEND
20
21         argv0 = "passwd";
22         user = getuser();
23         private();
24
25         s = nil;
26         if(argc > 0){
27                 user = argv[0];
28                 s = strchr(user, '@');
29                 if(s != nil)
30                         *s++ = 0;
31                 if(*user == 0)
32                         user = getuser();
33         }
34
35         fd = authdial(nil, s);
36         if(fd < 0)
37                 error("authdial: %r");
38
39         memset(&tr, 0, sizeof(tr));
40         strncpy(tr.uid, user, sizeof(tr.uid)-1);
41         tr.type = AuthPass;
42
43         /*
44          *  get a password from the user and try to decrypt the
45          *  ticket.  If it doesn't work we've got a bad password,
46          *  give up.
47          */
48         memset(&pr, 0, sizeof(pr));
49         getpass(&key, pr.old, 0, 0);
50
51         /*
52          *  negotiate PAK key. we need to retry in case the AS does
53          *  not support the AuthPAK request or when the user has
54          *  not yet setup a new key and the AS made one up.
55          */
56         try = 0;
57         authpak_hash(&key, tr.uid);
58         if(_asgetpakkey(fd, &tr, &key) < 0){
59 Retry:
60                 try++;
61                 close(fd);
62                 fd = authdial(nil, s);
63                 if(fd < 0)
64                         error("authdial: %r");
65         }
66         /* send ticket request to AS */
67         if(_asrequest(fd, &tr) < 0)
68                 error("%r");
69         if(_asgetresp(fd, &t, nil, &key) < 0)
70                 error("%r");
71         if(t.num != AuthTp || strcmp(t.cuid, tr.uid) != 0){
72                 if(try == 0)
73                         goto Retry;
74                 error("bad password");
75         }
76
77         /* loop trying new passwords */
78         for(;;){
79                 memset(pr.new, 0, sizeof(pr.new));
80                 if(answer("change Plan 9 Password?"))
81                         getpass(nil, pr.new, 0, 1);
82                 pr.changesecret = answer("change Inferno/POP secret?");
83                 if(pr.changesecret){
84                         if(answer("make it the same as your plan 9 password?")){
85                                 if(*pr.new)
86                                         strcpy(pr.secret, pr.new);
87                                 else
88                                         strcpy(pr.secret, pr.old);
89                         } else {
90                                 getpass(nil, pr.secret, 0, 1);
91                         }
92                 }
93                 pr.num = AuthPass;
94                 n = convPR2M(&pr, buf, sizeof(buf), &t);
95                 if(write(fd, buf, n) != n)
96                         error("AS protocol botch: %r");
97                 if(_asrdresp(fd, buf, 0) == 0)
98                         break;
99                 fprint(2, "passwd: refused: %r\n");
100         }
101         close(fd);
102
103         exits(0);
104 }