tmain.c - plan9port - [fork] Plan 9 from user space
HTML git clone git://src.adamsgaard.dk/plan9port
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
tmain.c (3534B)
---
1 #include "std.h"
2 #include "dat.h"
3 #include <9pclient.h>
4
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*);
13
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 }
22
23 int
24 threadmaybackground(void)
25 {
26 return 1;
27 }
28
29 void
30 threadmain(int argc, char *argv[])
31 {
32 char *mtpt;
33 char err[ERRMAX];
34
35 /* mtpt = "/mnt"; */
36 mtpt = nil;
37 owner = getuser();
38 quotefmtinstall();
39 fmtinstall('A', attrfmt);
40 fmtinstall('H', encodefmt);
41 fmtinstall('N', attrnamefmt);
42
43 if(argc == 3 && strcmp(argv[1], "-g") == 0){
44 gflag(argv[2]);
45 threadexitsall(nil);
46 }
47
48 ARGBEGIN{
49 default:
50 usage();
51 case 'D':
52 chatty9p++;
53 break;
54 case 'a':
55 authaddr = EARGF(usage());
56 break;
57 case 'd':
58 debug = 1;
59 break;
60 case 'g':
61 usage();
62 case 'm':
63 mtpt = EARGF(usage());
64 break;
65 case 's':
66 service = EARGF(usage());
67 break;
68 case 'n':
69 trysecstore = 0;
70 break;
71 case 'x':
72 extrafactotumdir = 1;
73 break;
74 }ARGEND
75
76 if(argc != 0)
77 usage();
78
79 if(trysecstore && havesecstore()){
80 while(secstorefetch() < 0){
81 rerrstr(err, sizeof err);
82 if(strcmp(err, "cancel") == 0)
83 break;
84 fprint(2, "secstorefetch: %r\n");
85 fprint(2, "Enter an empty password to quit.\n");
86 }
87 }
88
89 rfork(RFNOTEG);
90
91 fsinit0();
92 threadpostmountsrv(&fs, service, mtpt, MBEFORE);
93 threadexits(nil);
94 }
95
96 /*
97 * prompt user for a key. don't care about memory leaks, runs standalone
98 */
99 static Attr*
100 promptforkey(int fd, char *params)
101 {
102 char *v;
103 Attr *a, *attr;
104 char *def;
105
106 attr = _parseattr(params);
107 fprint(fd, "!adding key:");
108 for(a=attr; a; a=a->next)
109 if(a->type != AttrQuery && a->name[0] != '!')
110 fprint(fd, " %q=%q", a->name, a->val);
111 fprint(fd, "\n");
112
113 for(a=attr; a; a=a->next){
114 v = a->name;
115 if(a->type != AttrQuery || v[0]=='!')
116 continue;
117 def = nil;
118 if(strcmp(v, "user") == 0)
119 def = getuser();
120 a->val = readcons(v, def, 0);
121 if(a->val == nil)
122 sysfatal("user terminated key input");
123 a->type = AttrNameval;
124 }
125 for(a=attr; a; a=a->next){
126 v = a->name;
127 if(a->type != AttrQuery || v[0]!='!')
128 continue;
129 def = nil;
130 if(strcmp(v+1, "user") == 0)
131 def = getuser();
132 a->val = readcons(v+1, def, 1);
133 if(a->val == nil)
134 sysfatal("user terminated key input");
135 a->type = AttrNameval;
136 }
137 fprint(fd, "!\n");
138 close(fd);
139 return attr;
140 }
141
142 /*
143 * send a key to the mounted factotum
144 */
145 static int
146 sendkey(Attr *attr)
147 {
148 int rv;
149 char buf[8192];
150 CFid *fid;
151
152 fid = nsopen("factotum", nil, "ctl", OWRITE);
153 if(fid == nil)
154 sysfatal("opening factotum/ctl: %r");
155 snprint(buf, sizeof buf, "key %A\n", attr);
156 rv = fswrite(fid, buf, strlen(buf));
157 fsclose(fid);
158 return rv;
159 }
160
161 static void
162 askuser(int fd, char *params)
163 {
164 Attr *attr;
165
166 attr = promptforkey(fd, params);
167 if(attr == nil)
168 sysfatal("no key supplied");
169 if(sendkey(attr) < 0)
170 sysfatal("sending key to factotum: %r");
171 }
172
173 void
174 gflag(char *s)
175 {
176 char *f[4];
177 int nf;
178 int fd;
179
180 if((fd = open("/dev/tty", ORDWR)) < 0)
181 sysfatal("open /dev/tty: %r");
182
183 nf = getfields(s, f, nelem(f), 0, "\n");
184 if(nf == 1){ /* needkey or old badkey */
185 fprint(fd, "\n");
186 askuser(fd, s);
187 threadexitsall(nil);
188 }
189 if(nf == 3){ /* new badkey */
190 fprint(fd, "\n");
191 fprint(fd, "!replace: %s\n", f[0]);
192 fprint(fd, "!because: %s\n", f[1]);
193 askuser(fd, f[2]);
194 threadexitsall(nil);
195 }
196 usage();
197 }