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
passinit(Proto * p,Fsstate * fss)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
passclose(Fsstate * fss)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
passread(Fsstate * fss,void * va,uint * n)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
passwrite(Fsstate * fss,void *,uint)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