Blob


1 #include "std.h"
2 #include "dat.h"
3 #include <9pclient.h>
5 int extrafactotumdir;
6 int debug;
7 int trysecstore = 1;
8 char *factname = "factotum";
9 char *service = "factotum";
10 char *owner;
11 char *authaddr;
12 void gflag(char*);
14 void
15 usage(void)
16 {
17 fprint(2, "usage: factotum [-Dd] [-a authaddr] [-m mtpt] [-s service]\n");
18 fprint(2, " or factotum -g keypattern\n");
19 fprint(2, " or factotum -g 'badkeyattr\\nmsg\\nkeypattern'\n");
20 threadexitsall("usage");
21 }
23 void
24 threadmain(int argc, char *argv[])
25 {
26 char *mtpt;
27 char err[ERRMAX];
29 /* mtpt = "/mnt"; */
30 mtpt = nil;
31 owner = getuser();
32 quotefmtinstall();
33 fmtinstall('A', attrfmt);
34 fmtinstall('H', encodefmt);
35 fmtinstall('N', attrnamefmt);
37 if(argc == 3 && strcmp(argv[1], "-g") == 0){
38 gflag(argv[2]);
39 threadexitsall(nil);
40 }
42 ARGBEGIN{
43 default:
44 usage();
45 case 'D':
46 chatty9p++;
47 break;
48 case 'a':
49 authaddr = EARGF(usage());
50 break;
51 case 'd':
52 debug = 1;
53 break;
54 case 'g':
55 usage();
56 case 'm':
57 mtpt = EARGF(usage());
58 break;
59 case 's':
60 service = EARGF(usage());
61 break;
62 case 'n':
63 trysecstore = 0;
64 break;
65 case 'x':
66 extrafactotumdir = 1;
67 break;
68 }ARGEND
70 if(argc != 0)
71 usage();
73 if(trysecstore && havesecstore()){
74 while(secstorefetch() < 0){
75 rerrstr(err, sizeof err);
76 if(strcmp(err, "cancel") == 0)
77 break;
78 fprint(2, "secstorefetch: %r\n");
79 fprint(2, "Enter an empty password to quit.\n");
80 }
81 }
83 fsinit0();
84 threadpostmountsrv(&fs, service, mtpt, MBEFORE);
85 threadexits(nil);
86 }
88 /*
89 * prompt user for a key. don't care about memory leaks, runs standalone
90 */
91 static Attr*
92 promptforkey(int fd, char *params)
93 {
94 char *v;
95 Attr *a, *attr;
96 char *def;
98 attr = _parseattr(params);
99 fprint(fd, "!adding key:");
100 for(a=attr; a; a=a->next)
101 if(a->type != AttrQuery && a->name[0] != '!')
102 fprint(fd, " %q=%q", a->name, a->val);
103 fprint(fd, "\n");
105 for(a=attr; a; a=a->next){
106 v = a->name;
107 if(a->type != AttrQuery || v[0]=='!')
108 continue;
109 def = nil;
110 if(strcmp(v, "user") == 0)
111 def = getuser();
112 a->val = readcons(v, def, 0);
113 if(a->val == nil)
114 sysfatal("user terminated key input");
115 a->type = AttrNameval;
117 for(a=attr; a; a=a->next){
118 v = a->name;
119 if(a->type != AttrQuery || v[0]!='!')
120 continue;
121 def = nil;
122 if(strcmp(v+1, "user") == 0)
123 def = getuser();
124 a->val = readcons(v+1, def, 1);
125 if(a->val == nil)
126 sysfatal("user terminated key input");
127 a->type = AttrNameval;
129 fprint(fd, "!\n");
130 close(fd);
131 return attr;
134 /*
135 * send a key to the mounted factotum
136 */
137 static int
138 sendkey(Attr *attr)
140 int rv;
141 char buf[8192];
142 CFid *fid;
144 fid = nsopen("factotum", nil, "ctl", OWRITE);
145 if(fid == nil)
146 sysfatal("opening factotum/ctl: %r");
147 snprint(buf, sizeof buf, "key %A\n", attr);
148 rv = fswrite(fid, buf, strlen(buf));
149 fsclose(fid);
150 return rv;
153 static void
154 askuser(int fd, char *params)
156 Attr *attr;
158 attr = promptforkey(fd, params);
159 if(attr == nil)
160 sysfatal("no key supplied");
161 if(sendkey(attr) < 0)
162 sysfatal("sending key to factotum: %r");
165 void
166 gflag(char *s)
168 char *f[4];
169 int nf;
170 int fd;
172 if((fd = open("/dev/tty", ORDWR)) < 0)
173 sysfatal("open /dev/tty: %r");
175 nf = getfields(s, f, nelem(f), 0, "\n");
176 if(nf == 1){ /* needkey or old badkey */
177 fprint(fd, "\n");
178 askuser(fd, s);
179 threadexitsall(nil);
181 if(nf == 3){ /* new badkey */
182 fprint(fd, "\n");
183 fprint(fd, "!replace: %s\n", f[0]);
184 fprint(fd, "!because: %s\n", f[1]);
185 askuser(fd, f[2]);
186 threadexitsall(nil);
188 usage();