123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- /* password.c */
- #include <u.h>
- #include <libc.h>
- #include <bio.h>
- #include <mp.h>
- #include <libsec.h>
- #include "SConn.h"
- #include "secstore.h"
- static Biobuf*
- openPW(char *id, int mode)
- {
- Biobuf *b;
- int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
- char *fn;
- if(validatefile(id) == nil || strcmp(id,".") == 0)
- return nil;
- fn = emalloc(nfn);
- snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
- b = Bopen(fn, mode);
- free(fn);
- return b;
- }
- static ulong
- mtimePW(char *id)
- {
- Dir *d;
- int nfn = strlen(SECSTORE_DIR)+strlen(id)+20;
- char *fn = emalloc(nfn);
- ulong mt;
- snprint(fn, nfn, "%s/who/%s", SECSTORE_DIR, id);
- d = dirstat(fn);
- free(fn);
- mt = d->mtime;
- free(d);
- return mt;
- }
- PW *
- getPW(char *id, int dead_or_alive)
- {
- uint now = time(0);
- Biobuf *bin;
- PW *pw;
- char *f1, *f2; // fields 1, 2 = attribute, value
- if((bin = openPW(id, OREAD)) == 0){
- id = "FICTITIOUS";
- if((bin = openPW(id, OREAD)) == 0){
- werrstr("account does not exist");
- return nil;
- }
- }
- pw = emalloc(sizeof(*pw));
- pw->id = estrdup(id);
- pw->status |= Enabled;
- while( (f1 = Brdline(bin, '\n')) != 0){
- f1[Blinelen(bin)-1] = 0;
- for(f2 = f1; *f2 && (*f2!=' ') && (*f2!='\t'); f2++){}
- if(*f2)
- for(*f2++ = 0; *f2 && (*f2==' ' || *f2=='\t'); f2++){}
- if(strcmp(f1, "exp") == 0){
- pw->expire = strtoul(f2, 0, 10);
- }else if(strcmp(f1, "DISABLED") == 0){
- pw->status &= ~Enabled;
- }else if(strcmp(f1, "STA") == 0){
- pw->status |= STA;
- }else if(strcmp(f1, "failed") == 0){
- pw->failed = strtoul(f2, 0, 10);
- }else if(strcmp(f1, "other") == 0){
- pw->other = estrdup(f2);
- }else if(strcmp(f1, "PAK-Hi") == 0){
- pw->Hi = strtomp(f2, nil, 64, nil);
- }
- }
- Bterm(bin);
- if(pw->Hi == nil){
- werrstr("corrupted account file");
- freePW(pw);
- return nil;
- }
- if(dead_or_alive)
- return pw; // return PW entry for editing, whether currently valid or not
- if(pw->expire <= now){
- werrstr("account expired");
- freePW(pw);
- return nil;
- }
- if((pw->status & Enabled) == 0){
- werrstr("account disabled");
- freePW(pw);
- return nil;
- }
- if(pw->failed < 10)
- return pw; // success
- if(now < mtimePW(id)+300){
- werrstr("too many failures; try again in five minutes");
- freePW(pw);
- return nil;
- }
- pw->failed = 0;
- putPW(pw); // reset failed-login-counter after five minutes
- return pw;
- }
- int
- putPW(PW *pw)
- {
- Biobuf *bout;
- char *hexHi;
- if((bout = openPW(pw->id, OWRITE|OTRUNC)) ==0){
- werrstr("can't open PW file");
- return -1;
- }
- Bprint(bout, "exp %lud\n", pw->expire);
- if(!(pw->status & Enabled))
- Bprint(bout, "DISABLED\n");
- if(pw->status & STA)
- Bprint(bout, "STA\n");
- if(pw->failed)
- Bprint(bout, "failed\t%d\n", pw->failed);
- if(pw->other)
- Bprint(bout,"other\t%s\n", pw->other);
- hexHi = mptoa(pw->Hi, 64, nil, 0);
- Bprint(bout, "PAK-Hi\t%s\n", hexHi);
- free(hexHi);
- return 0;
- }
- void
- freePW(PW *pw)
- {
- if(pw == nil)
- return;
- free(pw->id);
- free(pw->other);
- mpfree(pw->Hi);
- free(pw);
- }
|