| /* |
| * This is just a repository for a password. |
| * We don't want to encourage this, there's |
| * no server side. |
| */ |
| |
| #include "dat.h" |
| |
| typedef struct State State; |
| struct State |
| { |
| Key *key; |
| }; |
| |
| enum |
| { |
| HavePass, |
| Maxphase, |
| }; |
| |
| static char *phasenames[Maxphase] = |
| { |
| [HavePass] "HavePass", |
| }; |
| |
| static int |
| passinit(Proto *p, Fsstate *fss) |
| { |
| int ask; |
| Key *k; |
| State *s; |
| |
| k = findkey(fss, Kuser, &ask, 0, fss->attr, "%s", p->keyprompt); |
| if(k == nil){ |
| if(ask) |
| return RpcNeedkey; |
| return failure(fss, nil); |
| } |
| setattrs(fss->attr, k->attr); |
| s = emalloc(sizeof(*s)); |
| s->key = k; |
| fss->ps = s; |
| return RpcOk; |
| } |
| |
| static void |
| passclose(Fsstate *fss) |
| { |
| State *s; |
| |
| s = fss->ps; |
| if(s->key) |
| closekey(s->key); |
| free(s); |
| } |
| |
| static int |
| passread(Fsstate *fss, void *va, uint *n) |
| { |
| int m; |
| char buf[500]; |
| char *pass, *user; |
| State *s; |
| |
| s = fss->ps; |
| switch(fss->phase){ |
| default: |
| return phaseerror(fss, "read"); |
| |
| case HavePass: |
| user = strfindattr(s->key->attr, "user"); |
| pass = strfindattr(s->key->privattr, "!password"); |
| if(user==nil || pass==nil) |
| return failure(fss, "passread cannot happen"); |
| snprint(buf, sizeof buf, "%q %q", user, pass); |
| m = strlen(buf); |
| if(m > *n) |
| return toosmall(fss, m); |
| *n = m; |
| memmove(va, buf, m); |
| return RpcOk; |
| } |
| } |
| |
| static int |
| passwrite(Fsstate *fss, void*, uint) |
| { |
| return phaseerror(fss, "write"); |
| } |
| |
| Proto pass = |
| { |
| .name= "pass", |
| .init= passinit, |
| .write= passwrite, |
| .read= passread, |
| .close= passclose, |
| .addkey= replacekey, |
| .keyprompt= "user? !password?", |
| }; |