URI:
       tpassword.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
       ---
       tpassword.c (2781B)
       ---
            1 /* password.c */
            2 #include <u.h>
            3 #include <libc.h>
            4 #include <bio.h>
            5 #include <mp.h>
            6 #include <libsec.h>
            7 #include "SConn.h"
            8 #include "secstore.h"
            9 
           10 static Biobuf*
           11 openPW(char *id, int mode)
           12 {
           13         Biobuf *b;
           14         int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
           15         char *fn = emalloc(nfn);
           16 
           17         snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
           18         b = Bopen(fn, mode);
           19         free(fn);
           20         return b;
           21 }
           22 
           23 static ulong
           24 mtimePW(char *id)
           25 {
           26         Dir *d;
           27         int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
           28         char *fn = emalloc(nfn);
           29         ulong mt;
           30 
           31         snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
           32         d = dirstat(fn);
           33         free(fn);
           34         mt = d->mtime;
           35         free(d);
           36         return mt;
           37 }
           38 
           39 PW *
           40 getPW(char *id, int dead_or_alive)
           41 {
           42         uint now = time(0);
           43         Biobuf *bin;
           44         PW *pw;
           45         char *f1, *f2; /* fields 1, 2 = attribute, value */
           46 
           47         if((bin = openPW(id, OREAD)) == 0){
           48                 id = "FICTITIOUS";
           49                 if((bin = openPW(id, OREAD)) == 0){
           50                         werrstr("account does not exist");
           51                         return nil;
           52                 }
           53         }
           54         pw = emalloc(sizeof(*pw));
           55         pw->id = estrdup(id);
           56         pw->status |= Enabled;
           57         while( (f1 = Brdline(bin, '\n')) != 0){
           58                 f1[Blinelen(bin)-1] = 0;
           59                 for(f2 = f1; *f2 && (*f2!=' ') && (*f2!='\t'); f2++){}
           60                 if(*f2)
           61                         for(*f2++ = 0; *f2 && (*f2==' ' || *f2=='\t'); f2++){}
           62                 if(strcmp(f1, "exp") == 0){
           63                         pw->expire = strtoul(f2, 0, 10);
           64                 }else if(strcmp(f1, "DISABLED") == 0){
           65                         pw->status &= ~Enabled;
           66                 }else if(strcmp(f1, "STA") == 0){
           67                         pw->status |= STA;
           68                 }else if(strcmp(f1, "failed") == 0){
           69                         pw->failed = strtoul(f2, 0, 10);
           70                 }else if(strcmp(f1, "other") == 0){
           71                         pw->other = estrdup(f2);
           72                 }else if(strcmp(f1, "PAK-Hi") == 0){
           73                         pw->Hi = strtomp(f2, nil, 64, nil);
           74                 }
           75         }
           76         Bterm(bin);
           77         if(dead_or_alive)
           78                 return pw;  /* return PW entry for editing, whether currently valid or not */
           79         if(pw->expire <= now){
           80                 werrstr("account expired");
           81                 freePW(pw);
           82                 return nil;
           83         }
           84         if((pw->status & Enabled) == 0){
           85                 werrstr("account disabled");
           86                 freePW(pw);
           87                 return nil;
           88         }
           89         if(pw->failed < 10)
           90                 return pw;  /* success */
           91         if(now < mtimePW(id)+300){
           92                 werrstr("too many failures; try again in five minutes");
           93                 freePW(pw);
           94                 return nil;
           95         }
           96         pw->failed = 0;
           97         putPW(pw);  /* reset failed-login-counter after five minutes */
           98         return pw;
           99 }
          100 
          101 int
          102 putPW(PW *pw)
          103 {
          104         Biobuf *bout;
          105         char *hexHi;
          106 
          107         if((bout = openPW(pw->id, OWRITE|OTRUNC)) ==0){
          108                 werrstr("can't open PW file");
          109                 return -1;
          110         }
          111         Bprint(bout, "exp        %lud\n", pw->expire);
          112         if(!(pw->status & Enabled))
          113                 Bprint(bout, "DISABLED\n");
          114         if(pw->status & STA)
          115                 Bprint(bout, "STA\n");
          116         if(pw->failed)
          117                 Bprint(bout, "failed\t%d\n", pw->failed);
          118         if(pw->other)
          119                 Bprint(bout,"other\t%s\n", pw->other);
          120         hexHi = mptoa(pw->Hi, 64, nil, 0);
          121         Bprint(bout, "PAK-Hi\t%s\n", hexHi);
          122         free(hexHi);
          123         return 0;
          124 }
          125 
          126 void
          127 freePW(PW *pw)
          128 {
          129         if(pw == nil)
          130                 return;
          131         free(pw->id);
          132         free(pw->other);
          133         mpfree(pw->Hi);
          134         free(pw);
          135 }