Blob


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"
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);
17 snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
18 b = Bopen(fn, mode);
19 free(fn);
20 return b;
21 }
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;
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 }
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 */
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 }
101 int
102 putPW(PW *pw)
104 Biobuf *bout;
105 char *hexHi;
107 if((bout = openPW(pw->id, OWRITE|OTRUNC)) ==0){
108 werrstr("can't open PW file");
109 return -1;
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;
126 void
127 freePW(PW *pw)
129 if(pw == nil)
130 return;
131 free(pw->id);
132 free(pw->other);
133 mpfree(pw->Hi);
134 free(pw);