1 /* 2 * This is just a repository for a password. 3 * We don't want to encourage this, there's 4 * no server side. 5 */ 6 7 #include "dat.h" 8 9 typedef struct State State; 10 struct State 11 { 12 Key *key; 13 }; 14 15 enum 16 { 17 HavePass, 18 Maxphase, 19 }; 20 21 static char *phasenames[Maxphase] = 22 { 23 [HavePass] "HavePass", 24 }; 25 26 static int 27 passinit(Proto *p, Fsstate *fss) 28 { 29 int ret; 30 Key *k; 31 Keyinfo ki; 32 State *s; 33 34 ret = findkey(&k, mkkeyinfo(&ki, fss, nil), "%s", p->keyprompt); 35 if(ret != RpcOk) 36 return ret; 37 setattrs(fss->attr, k->attr); 38 s = emalloc(sizeof(*s)); 39 s->key = k; 40 fss->ps = s; 41 fss->phase = HavePass; 42 return RpcOk; 43 } 44 45 static void 46 passclose(Fsstate *fss) 47 { 48 State *s; 49 50 s = fss->ps; 51 if(s->key) 52 closekey(s->key); 53 free(s); 54 } 55 56 static int 57 passread(Fsstate *fss, void *va, uint *n) 58 { 59 int m; 60 char buf[500]; 61 char *pass, *user; 62 State *s; 63 64 s = fss->ps; 65 switch(fss->phase){ 66 default: 67 return phaseerror(fss, "read"); 68 69 case HavePass: 70 user = _strfindattr(s->key->attr, "user"); 71 pass = _strfindattr(s->key->privattr, "!password"); 72 if(user==nil || pass==nil) 73 return failure(fss, "passread cannot happen"); 74 snprint(buf, sizeof buf, "%q %q", user, pass); 75 m = strlen(buf); 76 if(m > *n) 77 return toosmall(fss, m); 78 *n = m; 79 memmove(va, buf, m); 80 return RpcOk; 81 } 82 } 83 84 static int 85 passwrite(Fsstate *fss, void*, uint) 86 { 87 return phaseerror(fss, "write"); 88 } 89 90 Proto pass = 91 { 92 .name= "pass", 93 .init= passinit, 94 .write= passwrite, 95 .read= passread, 96 .close= passclose, 97 .addkey= replacekey, 98 .keyprompt= "user? !password?", 99 }; 100