plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

password.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 }