URI:
       tpasswd.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tpasswd.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 }