2 ce94dbe6 2005-02-13 devnull * Present factotum in ssh agent clothing.
4 ce94dbe6 2005-02-13 devnull #include <u.h>
5 ce94dbe6 2005-02-13 devnull #include <libc.h>
6 ce94dbe6 2005-02-13 devnull #include <mp.h>
7 ce94dbe6 2005-02-13 devnull #include <libsec.h>
8 ce94dbe6 2005-02-13 devnull #include <auth.h>
9 ce94dbe6 2005-02-13 devnull #include <thread.h>
10 ce94dbe6 2005-02-13 devnull #include <9pclient.h>
14 ce94dbe6 2005-02-13 devnull STACK = 65536
16 ce94dbe6 2005-02-13 devnull enum /* agent protocol packet types */
18 ce94dbe6 2005-02-13 devnull SSH_AGENTC_NONE = 0,
19 ce94dbe6 2005-02-13 devnull SSH_AGENTC_REQUEST_RSA_IDENTITIES,
20 ce94dbe6 2005-02-13 devnull SSH_AGENT_RSA_IDENTITIES_ANSWER,
21 ce94dbe6 2005-02-13 devnull SSH_AGENTC_RSA_CHALLENGE,
22 ce94dbe6 2005-02-13 devnull SSH_AGENT_RSA_RESPONSE,
23 ce94dbe6 2005-02-13 devnull SSH_AGENT_FAILURE,
24 ce94dbe6 2005-02-13 devnull SSH_AGENT_SUCCESS,
25 ce94dbe6 2005-02-13 devnull SSH_AGENTC_ADD_RSA_IDENTITY,
26 ce94dbe6 2005-02-13 devnull SSH_AGENTC_REMOVE_RSA_IDENTITY,
27 ce94dbe6 2005-02-13 devnull SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES,
29 ce94dbe6 2005-02-13 devnull SSH2_AGENTC_REQUEST_IDENTITIES = 11,
30 ce94dbe6 2005-02-13 devnull SSH2_AGENT_IDENTITIES_ANSWER,
31 ce94dbe6 2005-02-13 devnull SSH2_AGENTC_SIGN_REQUEST,
32 ce94dbe6 2005-02-13 devnull SSH2_AGENT_SIGN_RESPONSE,
34 ce94dbe6 2005-02-13 devnull SSH2_AGENTC_ADD_IDENTITY = 17,
35 ce94dbe6 2005-02-13 devnull SSH2_AGENTC_REMOVE_IDENTITY,
36 ce94dbe6 2005-02-13 devnull SSH2_AGENTC_REMOVE_ALL_IDENTITIES,
37 ce94dbe6 2005-02-13 devnull SSH2_AGENTC_ADD_SMARTCARD_KEY,
38 ce94dbe6 2005-02-13 devnull SSH2_AGENTC_REMOVE_SMARTCARD_KEY,
40 ce94dbe6 2005-02-13 devnull SSH_AGENTC_LOCK,
41 ce94dbe6 2005-02-13 devnull SSH_AGENTC_UNLOCK,
42 ce94dbe6 2005-02-13 devnull SSH_AGENTC_ADD_RSA_ID_CONSTRAINED,
43 ce94dbe6 2005-02-13 devnull SSH2_AGENTC_ADD_ID_CONSTRAINED,
44 ce94dbe6 2005-02-13 devnull SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED,
46 ce94dbe6 2005-02-13 devnull SSH_AGENT_CONSTRAIN_LIFETIME = 1,
47 ce94dbe6 2005-02-13 devnull SSH_AGENT_CONSTRAIN_CONFIRM = 2,
49 ce94dbe6 2005-02-13 devnull SSH2_AGENT_FAILURE = 30,
51 ce94dbe6 2005-02-13 devnull SSH_COM_AGENT2_FAILURE = 102,
52 ce94dbe6 2005-02-13 devnull SSH_AGENT_OLD_SIGNATURE = 0x01,
55 ce94dbe6 2005-02-13 devnull typedef struct Aconn Aconn;
56 ce94dbe6 2005-02-13 devnull struct Aconn
58 ce94dbe6 2005-02-13 devnull uchar *data;
59 ce94dbe6 2005-02-13 devnull uint ndata;
62 ce94dbe6 2005-02-13 devnull char dir[40];
65 ce94dbe6 2005-02-13 devnull typedef struct Msg Msg;
66 ce94dbe6 2005-02-13 devnull struct Msg
68 ce94dbe6 2005-02-13 devnull uchar *bp;
69 ce94dbe6 2005-02-13 devnull uchar *p;
70 ce94dbe6 2005-02-13 devnull uchar *ep;
73 ce94dbe6 2005-02-13 devnull char adir[40];
75 ce94dbe6 2005-02-13 devnull int chatty;
76 ce94dbe6 2005-02-13 devnull char *factotum = "factotum";
78 ce94dbe6 2005-02-13 devnull void agentproc(void *v);
79 ce94dbe6 2005-02-13 devnull void* emalloc(int n);
80 ce94dbe6 2005-02-13 devnull void* erealloc(void *v, int n);
81 ce94dbe6 2005-02-13 devnull void listenproc(void *v);
82 ce94dbe6 2005-02-13 devnull int runmsg(Aconn *a);
83 ce94dbe6 2005-02-13 devnull void listkeystext(void);
86 ce94dbe6 2005-02-13 devnull usage(void)
88 ce94dbe6 2005-02-13 devnull fprint(2, "usage: 9 ssh-agent [-D] [factotum]\n");
89 ce94dbe6 2005-02-13 devnull threadexitsall("usage");
93 ce94dbe6 2005-02-13 devnull threadmain(int argc, char **argv)
95 ce94dbe6 2005-02-13 devnull int fd, pid, export, dotextlist;
96 e3331bf2 2005-03-18 devnull char dir[100], *ns;
97 ce94dbe6 2005-02-13 devnull char sock[200], addr[200];
98 ce94dbe6 2005-02-13 devnull uvlong x;
100 ce94dbe6 2005-02-13 devnull export = 0;
101 ce94dbe6 2005-02-13 devnull dotextlist = 0;
102 ce94dbe6 2005-02-13 devnull pid = getpid();
103 ce94dbe6 2005-02-13 devnull fmtinstall('B', mpfmt);
104 ce94dbe6 2005-02-13 devnull fmtinstall('H', encodefmt);
105 ce94dbe6 2005-02-13 devnull fmtinstall('[', encodefmt);
107 ce94dbe6 2005-02-13 devnull ARGBEGIN{
108 e1a22963 2005-02-13 devnull case '9':
109 e1a22963 2005-02-13 devnull chatty9pclient++;
111 ce94dbe6 2005-02-13 devnull case 'D':
112 ce94dbe6 2005-02-13 devnull chatty++;
114 ce94dbe6 2005-02-13 devnull case 'e':
115 ce94dbe6 2005-02-13 devnull export = 1;
117 ce94dbe6 2005-02-13 devnull case 'l':
118 ce94dbe6 2005-02-13 devnull dotextlist = 1;
120 ce94dbe6 2005-02-13 devnull default:
121 ce94dbe6 2005-02-13 devnull usage();
124 ce94dbe6 2005-02-13 devnull if(argc > 1)
125 ce94dbe6 2005-02-13 devnull usage();
126 ce94dbe6 2005-02-13 devnull if(argc == 1)
127 ce94dbe6 2005-02-13 devnull factotum = argv[0];
129 ce94dbe6 2005-02-13 devnull if(dotextlist)
130 ce94dbe6 2005-02-13 devnull listkeystext();
132 e3331bf2 2005-03-18 devnull ns = getns();
133 e3331bf2 2005-03-18 devnull snprint(sock, sizeof sock, "%s/ssh-agent.socket", ns);
135 e3331bf2 2005-03-18 devnull x = ((uvlong)fastrand()<<32) | fastrand();
136 e3331bf2 2005-03-18 devnull x ^= ((uvlong)fastrand()<<32) | fastrand();
137 e3331bf2 2005-03-18 devnull snprint(dir, sizeof dir, "/tmp/ssh-%llux", x);
138 e3331bf2 2005-03-18 devnull if((fd = create(dir, OREAD, DMDIR|0700)) < 0)
139 e3331bf2 2005-03-18 devnull sysfatal("mkdir %s: %r", dir);
140 e3331bf2 2005-03-18 devnull close(fd);
141 e3331bf2 2005-03-18 devnull snprint(sock, sizeof sock, "%s/agent.%d", dir, pid);
143 ce94dbe6 2005-02-13 devnull snprint(addr, sizeof addr, "unix!%s", sock);
145 ce94dbe6 2005-02-13 devnull if((afd = announce(addr, adir)) < 0)
146 ce94dbe6 2005-02-13 devnull sysfatal("announce %s: %r", addr);
148 ce94dbe6 2005-02-13 devnull print("SSH_AUTH_SOCK=%s;\n", sock);
149 ce94dbe6 2005-02-13 devnull if(export)
150 ce94dbe6 2005-02-13 devnull print("export SSH_AUTH_SOCK;\n");
151 ce94dbe6 2005-02-13 devnull print("SSH_AGENT_PID=%d;\n", pid);
152 ce94dbe6 2005-02-13 devnull if(export)
153 ce94dbe6 2005-02-13 devnull print("export SSH_AGENT_PID;\n");
154 ce94dbe6 2005-02-13 devnull close(1);
155 e1a22963 2005-02-13 devnull rfork(RFNOTEG);
156 e1a22963 2005-02-13 devnull proccreate(listenproc, nil, STACK);
157 ce94dbe6 2005-02-13 devnull threadexits(0);
161 ce94dbe6 2005-02-13 devnull listenproc(void *v)
163 ce94dbe6 2005-02-13 devnull Aconn *a;
165 ce94dbe6 2005-02-13 devnull USED(v);
166 ce94dbe6 2005-02-13 devnull for(;;){
167 ce94dbe6 2005-02-13 devnull a = emalloc(sizeof *a);
168 ce94dbe6 2005-02-13 devnull a->ctl = listen(adir, a->dir);
169 ce94dbe6 2005-02-13 devnull if(a->ctl < 0)
170 ce94dbe6 2005-02-13 devnull sysfatal("listen: %r");
171 ce94dbe6 2005-02-13 devnull proccreate(agentproc, a, STACK);
176 ce94dbe6 2005-02-13 devnull agentproc(void *v)
178 ce94dbe6 2005-02-13 devnull Aconn *a;
182 ce94dbe6 2005-02-13 devnull a->fd = accept(a->ctl, a->dir);
183 ce94dbe6 2005-02-13 devnull close(a->ctl);
184 ce94dbe6 2005-02-13 devnull a->ctl = -1;
185 ce94dbe6 2005-02-13 devnull for(;;){
186 ce94dbe6 2005-02-13 devnull a->data = erealloc(a->data, a->ndata+1024);
187 ce94dbe6 2005-02-13 devnull n = read(a->fd, a->data+a->ndata, 1024);
188 ce94dbe6 2005-02-13 devnull if(n <= 0)
190 ce94dbe6 2005-02-13 devnull a->ndata += n;
191 ce94dbe6 2005-02-13 devnull while(runmsg(a))
194 ce94dbe6 2005-02-13 devnull close(a->fd);
195 ce94dbe6 2005-02-13 devnull free(a);
196 ce94dbe6 2005-02-13 devnull threadexits(nil);
200 ce94dbe6 2005-02-13 devnull get1(Msg *m)
202 ce94dbe6 2005-02-13 devnull if(m->p >= m->ep)
203 ce94dbe6 2005-02-13 devnull return 0;
204 ce94dbe6 2005-02-13 devnull return *m->p++;
208 ce94dbe6 2005-02-13 devnull get2(Msg *m)
212 ce94dbe6 2005-02-13 devnull if(m->p+2 > m->ep)
213 ce94dbe6 2005-02-13 devnull return 0;
214 ce94dbe6 2005-02-13 devnull x = (m->p[0]<<8)|m->p[1];
215 ce94dbe6 2005-02-13 devnull m->p += 2;
216 ce94dbe6 2005-02-13 devnull return x;
220 ce94dbe6 2005-02-13 devnull get4(Msg *m)
223 ce94dbe6 2005-02-13 devnull if(m->p+4 > m->ep)
224 ce94dbe6 2005-02-13 devnull return 0;
225 ce94dbe6 2005-02-13 devnull x = (m->p[0]<<24)|(m->p[1]<<16)|(m->p[2]<<8)|m->p[3];
226 ce94dbe6 2005-02-13 devnull m->p += 4;
227 ce94dbe6 2005-02-13 devnull return x;
231 ce94dbe6 2005-02-13 devnull getn(Msg *m, uint n)
233 ce94dbe6 2005-02-13 devnull uchar *p;
235 ce94dbe6 2005-02-13 devnull if(m->p+n > m->ep)
236 ce94dbe6 2005-02-13 devnull return nil;
237 ce94dbe6 2005-02-13 devnull p = m->p;
238 ce94dbe6 2005-02-13 devnull m->p += n;
239 ce94dbe6 2005-02-13 devnull return p;
243 ce94dbe6 2005-02-13 devnull getstr(Msg *m)
246 ce94dbe6 2005-02-13 devnull uchar *p;
248 ce94dbe6 2005-02-13 devnull n = get4(m);
249 ce94dbe6 2005-02-13 devnull p = getn(m, n);
250 ce94dbe6 2005-02-13 devnull if(p == nil)
251 ce94dbe6 2005-02-13 devnull return nil;
253 ce94dbe6 2005-02-13 devnull memmove(p, p+1, n);
254 ce94dbe6 2005-02-13 devnull p[n] = 0;
255 1cab7105 2005-07-13 devnull return (char*)p;
259 ce94dbe6 2005-02-13 devnull getmp(Msg *m)
262 ce94dbe6 2005-02-13 devnull uchar *p;
264 ce94dbe6 2005-02-13 devnull n = (get2(m)+7)/8;
265 ce94dbe6 2005-02-13 devnull if((p=getn(m, n)) == nil)
266 ce94dbe6 2005-02-13 devnull return nil;
267 ce94dbe6 2005-02-13 devnull return betomp(p, n, nil);
271 ce94dbe6 2005-02-13 devnull getmp2(Msg *m)
274 ce94dbe6 2005-02-13 devnull uchar *p;
276 ce94dbe6 2005-02-13 devnull n = get4(m);
277 ce94dbe6 2005-02-13 devnull if((p = getn(m, n)) == nil)
278 ce94dbe6 2005-02-13 devnull return nil;
279 ce94dbe6 2005-02-13 devnull return betomp(p, n, nil);
283 ce94dbe6 2005-02-13 devnull getm(Msg *m, Msg *mm)
286 ce94dbe6 2005-02-13 devnull uchar *p;
288 ce94dbe6 2005-02-13 devnull n = get4(m);
289 ce94dbe6 2005-02-13 devnull if((p = getn(m, n)) == nil)
290 ce94dbe6 2005-02-13 devnull return nil;
291 ce94dbe6 2005-02-13 devnull mm->bp = p;
292 ce94dbe6 2005-02-13 devnull mm->p = p;
293 ce94dbe6 2005-02-13 devnull mm->ep = p+n;
294 ce94dbe6 2005-02-13 devnull return mm;
298 ce94dbe6 2005-02-13 devnull ensure(Msg *m, int n)
300 ce94dbe6 2005-02-13 devnull int len, plen;
301 ce94dbe6 2005-02-13 devnull uchar *p;
303 ce94dbe6 2005-02-13 devnull len = m->ep - m->bp;
304 ce94dbe6 2005-02-13 devnull if(m->p+n > m->ep){
305 ce94dbe6 2005-02-13 devnull plen = m->p - m->bp;
306 ce94dbe6 2005-02-13 devnull m->bp = erealloc(m->bp, len+n+1024);
307 ce94dbe6 2005-02-13 devnull m->p = m->bp+plen;
308 ce94dbe6 2005-02-13 devnull m->ep = m->bp+len+n+1024;
310 ce94dbe6 2005-02-13 devnull p = m->p;
311 ce94dbe6 2005-02-13 devnull m->p += n;
312 ce94dbe6 2005-02-13 devnull return p;
316 ce94dbe6 2005-02-13 devnull put4(Msg *m, uint n)
318 ce94dbe6 2005-02-13 devnull uchar *p;
320 ce94dbe6 2005-02-13 devnull p = ensure(m, 4);
321 ce94dbe6 2005-02-13 devnull p[0] = (n>>24)&0xFF;
322 ce94dbe6 2005-02-13 devnull p[1] = (n>>16)&0xFF;
323 ce94dbe6 2005-02-13 devnull p[2] = (n>>8)&0xFF;
324 ce94dbe6 2005-02-13 devnull p[3] = n&0xFF;
328 ce94dbe6 2005-02-13 devnull put2(Msg *m, uint n)
330 ce94dbe6 2005-02-13 devnull uchar *p;
332 ce94dbe6 2005-02-13 devnull p = ensure(m, 2);
333 ce94dbe6 2005-02-13 devnull p[0] = (n>>8)&0xFF;
334 ce94dbe6 2005-02-13 devnull p[1] = n&0xFF;
338 ce94dbe6 2005-02-13 devnull put1(Msg *m, uint n)
340 ce94dbe6 2005-02-13 devnull uchar *p;
342 ce94dbe6 2005-02-13 devnull p = ensure(m, 1);
343 ce94dbe6 2005-02-13 devnull p[0] = n&0xFF;
347 ce94dbe6 2005-02-13 devnull putn(Msg *m, void *a, uint n)
349 ce94dbe6 2005-02-13 devnull uchar *p;
351 ce94dbe6 2005-02-13 devnull p = ensure(m, n);
352 ce94dbe6 2005-02-13 devnull memmove(p, a, n);
356 ce94dbe6 2005-02-13 devnull putmp(Msg *m, mpint *b)
358 ce94dbe6 2005-02-13 devnull int bits, n;
359 ce94dbe6 2005-02-13 devnull uchar *p;
361 ce94dbe6 2005-02-13 devnull bits = mpsignif(b);
362 ce94dbe6 2005-02-13 devnull put2(m, bits);
363 ce94dbe6 2005-02-13 devnull n = (bits+7)/8;
364 ce94dbe6 2005-02-13 devnull p = ensure(m, n);
365 ce94dbe6 2005-02-13 devnull mptobe(b, p, n, nil);
369 ce94dbe6 2005-02-13 devnull putmp2(Msg *m, mpint *b)
371 ce94dbe6 2005-02-13 devnull int bits, n;
372 ce94dbe6 2005-02-13 devnull uchar *p;
374 ce94dbe6 2005-02-13 devnull if(mpcmp(b, mpzero) == 0){
375 ce94dbe6 2005-02-13 devnull put4(m, 0);
378 ce94dbe6 2005-02-13 devnull bits = mpsignif(b);
379 ce94dbe6 2005-02-13 devnull n = (bits+7)/8;
380 ce94dbe6 2005-02-13 devnull if(bits%8 == 0){
381 ce94dbe6 2005-02-13 devnull put4(m, n+1);
382 ce94dbe6 2005-02-13 devnull put1(m, 0);
384 ce94dbe6 2005-02-13 devnull put4(m, n);
385 ce94dbe6 2005-02-13 devnull p = ensure(m, n);
386 ce94dbe6 2005-02-13 devnull mptobe(b, p, n, nil);
390 ce94dbe6 2005-02-13 devnull putstr(Msg *m, char *s)
394 ce94dbe6 2005-02-13 devnull n = strlen(s);
395 ce94dbe6 2005-02-13 devnull put4(m, n);
396 ce94dbe6 2005-02-13 devnull putn(m, s, n);
400 ce94dbe6 2005-02-13 devnull putm(Msg *m, Msg *mm)
404 ce94dbe6 2005-02-13 devnull n = mm->p - mm->bp;
405 ce94dbe6 2005-02-13 devnull put4(m, n);
406 ce94dbe6 2005-02-13 devnull putn(m, mm->bp, n);
410 ce94dbe6 2005-02-13 devnull newmsg(Msg *m)
412 ce94dbe6 2005-02-13 devnull memset(m, 0, sizeof *m);
416 ce94dbe6 2005-02-13 devnull newreply(Msg *m, int type)
418 ce94dbe6 2005-02-13 devnull memset(m, 0, sizeof *m);
419 ce94dbe6 2005-02-13 devnull put4(m, 0);
420 ce94dbe6 2005-02-13 devnull put1(m, type);
424 ce94dbe6 2005-02-13 devnull reply(Aconn *a, Msg *m)
427 ce94dbe6 2005-02-13 devnull uchar *p;
429 ce94dbe6 2005-02-13 devnull n = (m->p - m->bp) - 4;
430 ce94dbe6 2005-02-13 devnull p = m->bp;
431 ce94dbe6 2005-02-13 devnull p[0] = (n>>24)&0xFF;
432 ce94dbe6 2005-02-13 devnull p[1] = (n>>16)&0xFF;
433 ce94dbe6 2005-02-13 devnull p[2] = (n>>8)&0xFF;
434 ce94dbe6 2005-02-13 devnull p[3] = n&0xFF;
435 ce94dbe6 2005-02-13 devnull if(chatty)
436 ce94dbe6 2005-02-13 devnull fprint(2, "respond %d: %.*H\n", p[4], n, m->bp+4);
437 ce94dbe6 2005-02-13 devnull write(a->fd, p, n+4);
438 ce94dbe6 2005-02-13 devnull free(p);
439 ce94dbe6 2005-02-13 devnull memset(m, 0, sizeof *m);
442 ce94dbe6 2005-02-13 devnull typedef struct Key Key;
443 ce94dbe6 2005-02-13 devnull struct Key
445 ce94dbe6 2005-02-13 devnull mpint *mod;
446 ce94dbe6 2005-02-13 devnull mpint *ek;
447 ce94dbe6 2005-02-13 devnull char *comment;
450 ce94dbe6 2005-02-13 devnull static char*
451 ce94dbe6 2005-02-13 devnull find(char **f, int nf, char *k)
453 ce94dbe6 2005-02-13 devnull int i, len;
455 ce94dbe6 2005-02-13 devnull len = strlen(k);
456 ce94dbe6 2005-02-13 devnull for(i=1; i<nf; i++) /* i=1: f[0] is "key" */
457 ce94dbe6 2005-02-13 devnull if(strncmp(f[i], k, len) == 0 && f[i][len] == '=')
458 ce94dbe6 2005-02-13 devnull return f[i]+len+1;
459 ce94dbe6 2005-02-13 devnull return nil;
462 ce94dbe6 2005-02-13 devnull static int
463 ce94dbe6 2005-02-13 devnull putrsa1(Msg *m, char **f, int nf)
465 ce94dbe6 2005-02-13 devnull char *p;
466 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
468 ce94dbe6 2005-02-13 devnull p = find(f, nf, "n");
469 ce94dbe6 2005-02-13 devnull if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
470 ce94dbe6 2005-02-13 devnull return -1;
471 ce94dbe6 2005-02-13 devnull p = find(f, nf, "ek");
472 ce94dbe6 2005-02-13 devnull if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
473 ce94dbe6 2005-02-13 devnull mpfree(mod);
474 ce94dbe6 2005-02-13 devnull return -1;
476 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
477 ce94dbe6 2005-02-13 devnull if(p == nil)
479 ce94dbe6 2005-02-13 devnull put4(m, mpsignif(mod));
480 ce94dbe6 2005-02-13 devnull putmp(m, ek);
481 ce94dbe6 2005-02-13 devnull putmp(m, mod);
482 ce94dbe6 2005-02-13 devnull putstr(m, p);
483 ce94dbe6 2005-02-13 devnull mpfree(mod);
484 ce94dbe6 2005-02-13 devnull mpfree(ek);
485 ce94dbe6 2005-02-13 devnull return 0;
489 ce94dbe6 2005-02-13 devnull printattr(char **f, int nf)
493 ce94dbe6 2005-02-13 devnull print("#");
494 ce94dbe6 2005-02-13 devnull for(i=0; i<nf; i++)
495 ce94dbe6 2005-02-13 devnull print(" %s", f[i]);
496 ce94dbe6 2005-02-13 devnull print("\n");
500 ce94dbe6 2005-02-13 devnull printrsa1(char **f, int nf)
502 ce94dbe6 2005-02-13 devnull char *p;
503 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
505 ce94dbe6 2005-02-13 devnull p = find(f, nf, "n");
506 ce94dbe6 2005-02-13 devnull if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
508 ce94dbe6 2005-02-13 devnull p = find(f, nf, "ek");
509 ce94dbe6 2005-02-13 devnull if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
510 ce94dbe6 2005-02-13 devnull mpfree(mod);
513 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
514 ce94dbe6 2005-02-13 devnull if(p == nil)
517 ce94dbe6 2005-02-13 devnull if(chatty)
518 ce94dbe6 2005-02-13 devnull printattr(f, nf);
519 ce94dbe6 2005-02-13 devnull print("%d %.10B %.10B %s\n", mpsignif(mod), ek, mod, p);
520 ce94dbe6 2005-02-13 devnull mpfree(ek);
521 ce94dbe6 2005-02-13 devnull mpfree(mod);
524 ce94dbe6 2005-02-13 devnull static int
525 ce94dbe6 2005-02-13 devnull putrsa(Msg *m, char **f, int nf)
527 ce94dbe6 2005-02-13 devnull char *p;
528 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
530 ce94dbe6 2005-02-13 devnull p = find(f, nf, "n");
531 ce94dbe6 2005-02-13 devnull if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
532 ce94dbe6 2005-02-13 devnull return -1;
533 ce94dbe6 2005-02-13 devnull p = find(f, nf, "ek");
534 ce94dbe6 2005-02-13 devnull if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
535 ce94dbe6 2005-02-13 devnull mpfree(mod);
536 ce94dbe6 2005-02-13 devnull return -1;
538 ce94dbe6 2005-02-13 devnull putstr(m, "ssh-rsa");
539 ce94dbe6 2005-02-13 devnull putmp2(m, ek);
540 ce94dbe6 2005-02-13 devnull putmp2(m, mod);
541 ce94dbe6 2005-02-13 devnull mpfree(ek);
542 ce94dbe6 2005-02-13 devnull mpfree(mod);
543 ce94dbe6 2005-02-13 devnull return 0;
547 ce94dbe6 2005-02-13 devnull getrsapub(Msg *m)
549 ce94dbe6 2005-02-13 devnull RSApub *k;
551 ce94dbe6 2005-02-13 devnull k = rsapuballoc();
552 ce94dbe6 2005-02-13 devnull if(k == nil)
553 ce94dbe6 2005-02-13 devnull return nil;
554 ce94dbe6 2005-02-13 devnull k->ek = getmp2(m);
555 ce94dbe6 2005-02-13 devnull k->n = getmp2(m);
556 ce94dbe6 2005-02-13 devnull if(k->ek == nil || k->n == nil){
557 ce94dbe6 2005-02-13 devnull rsapubfree(k);
558 ce94dbe6 2005-02-13 devnull return nil;
560 ce94dbe6 2005-02-13 devnull return k;
563 ce94dbe6 2005-02-13 devnull static int
564 ce94dbe6 2005-02-13 devnull putdsa(Msg *m, char **f, int nf)
566 ce94dbe6 2005-02-13 devnull char *p;
567 ce94dbe6 2005-02-13 devnull int ret;
568 ce94dbe6 2005-02-13 devnull mpint *dp, *dq, *dalpha, *dkey;
570 ce94dbe6 2005-02-13 devnull ret = -1;
571 ce94dbe6 2005-02-13 devnull dp = dq = dalpha = dkey = nil;
572 ce94dbe6 2005-02-13 devnull p = find(f, nf, "p");
573 ce94dbe6 2005-02-13 devnull if(p == nil || (dp = strtomp(p, nil, 16, nil)) == nil)
574 ce94dbe6 2005-02-13 devnull goto out;
575 ce94dbe6 2005-02-13 devnull p = find(f, nf, "q");
576 ce94dbe6 2005-02-13 devnull if(p == nil || (dq = strtomp(p, nil, 16, nil)) == nil)
577 ce94dbe6 2005-02-13 devnull goto out;
578 ce94dbe6 2005-02-13 devnull p = find(f, nf, "alpha");
579 ce94dbe6 2005-02-13 devnull if(p == nil || (dalpha = strtomp(p, nil, 16, nil)) == nil)
580 ce94dbe6 2005-02-13 devnull goto out;
581 ce94dbe6 2005-02-13 devnull p = find(f, nf, "key");
582 ce94dbe6 2005-02-13 devnull if(p == nil || (dkey = strtomp(p, nil, 16, nil)) == nil)
583 ce94dbe6 2005-02-13 devnull goto out;
584 ce94dbe6 2005-02-13 devnull putstr(m, "ssh-dss");
585 ce94dbe6 2005-02-13 devnull putmp2(m, dp);
586 ce94dbe6 2005-02-13 devnull putmp2(m, dq);
587 ce94dbe6 2005-02-13 devnull putmp2(m, dalpha);
588 ce94dbe6 2005-02-13 devnull putmp2(m, dkey);
589 ce94dbe6 2005-02-13 devnull ret = 0;
591 ce94dbe6 2005-02-13 devnull mpfree(dp);
592 ce94dbe6 2005-02-13 devnull mpfree(dq);
593 ce94dbe6 2005-02-13 devnull mpfree(dalpha);
594 ce94dbe6 2005-02-13 devnull mpfree(dkey);
595 ce94dbe6 2005-02-13 devnull return ret;
598 ce94dbe6 2005-02-13 devnull static int
599 ce94dbe6 2005-02-13 devnull putkey2(Msg *m, int (*put)(Msg*,char**,int), char **f, int nf)
601 ce94dbe6 2005-02-13 devnull char *p;
604 ce94dbe6 2005-02-13 devnull newmsg(&mm);
605 ce94dbe6 2005-02-13 devnull if(put(&mm, f, nf) < 0)
606 ce94dbe6 2005-02-13 devnull return -1;
607 ce94dbe6 2005-02-13 devnull putm(m, &mm);
608 ce94dbe6 2005-02-13 devnull free(mm.bp);
609 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
610 ce94dbe6 2005-02-13 devnull if(p == nil)
612 ce94dbe6 2005-02-13 devnull putstr(m, p);
613 ce94dbe6 2005-02-13 devnull return 0;
616 ce94dbe6 2005-02-13 devnull static int
617 ce94dbe6 2005-02-13 devnull printkey(char *type, int (*put)(Msg*,char**,int), char **f, int nf)
620 ce94dbe6 2005-02-13 devnull char *p;
622 ce94dbe6 2005-02-13 devnull newmsg(&m);
623 ce94dbe6 2005-02-13 devnull if(put(&m, f, nf) < 0)
624 ce94dbe6 2005-02-13 devnull return -1;
625 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
626 ce94dbe6 2005-02-13 devnull if(p == nil)
628 ce94dbe6 2005-02-13 devnull if(chatty)
629 ce94dbe6 2005-02-13 devnull printattr(f, nf);
630 ce94dbe6 2005-02-13 devnull print("%s %.*[ %s\n", type, m.p-m.bp, m.bp, p);
631 ce94dbe6 2005-02-13 devnull free(m.bp);
632 ce94dbe6 2005-02-13 devnull return 0;
636 ce94dbe6 2005-02-13 devnull getdsapub(Msg *m)
638 ce94dbe6 2005-02-13 devnull DSApub *k;
640 ce94dbe6 2005-02-13 devnull k = dsapuballoc();
641 ce94dbe6 2005-02-13 devnull if(k == nil)
642 ce94dbe6 2005-02-13 devnull return nil;
643 ce94dbe6 2005-02-13 devnull k->p = getmp2(m);
644 ce94dbe6 2005-02-13 devnull k->q = getmp2(m);
645 ce94dbe6 2005-02-13 devnull k->alpha = getmp2(m);
646 ce94dbe6 2005-02-13 devnull k->key = getmp2(m);
647 ce94dbe6 2005-02-13 devnull if(!k->p || !k->q || !k->alpha || !k->key){
648 ce94dbe6 2005-02-13 devnull dsapubfree(k);
649 ce94dbe6 2005-02-13 devnull return nil;
651 ce94dbe6 2005-02-13 devnull return k;
654 ce94dbe6 2005-02-13 devnull static int
655 ce94dbe6 2005-02-13 devnull listkeys(Msg *m, int version)
657 ce94dbe6 2005-02-13 devnull char buf[8192+1], *line[100], *f[20], *p, *s;
658 ce94dbe6 2005-02-13 devnull uchar *pnk;
659 ce94dbe6 2005-02-13 devnull int i, n, nl, nf, nk;
660 ce94dbe6 2005-02-13 devnull CFid *fid;
663 ce94dbe6 2005-02-13 devnull pnk = m->p;
664 ce94dbe6 2005-02-13 devnull put4(m, 0);
665 e1a22963 2005-02-13 devnull if((fid = nsopen(factotum, nil, "ctl", OREAD)) == nil){
666 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: open factotum: %r\n");
667 ce94dbe6 2005-02-13 devnull return -1;
669 ce94dbe6 2005-02-13 devnull for(;;){
670 ce94dbe6 2005-02-13 devnull if((n = fsread(fid, buf, sizeof buf-1)) <= 0)
672 ce94dbe6 2005-02-13 devnull buf[n] = 0;
673 ce94dbe6 2005-02-13 devnull nl = getfields(buf, line, nelem(line), 1, "\n");
674 ce94dbe6 2005-02-13 devnull for(i=0; i<nl; i++){
675 ce94dbe6 2005-02-13 devnull nf = tokenize(line[i], f, nelem(f));
676 ce94dbe6 2005-02-13 devnull if(nf == 0 || strcmp(f[0], "key") != 0)
677 ce94dbe6 2005-02-13 devnull continue;
678 ce94dbe6 2005-02-13 devnull p = find(f, nf, "proto");
679 ce94dbe6 2005-02-13 devnull if(p == nil)
680 ce94dbe6 2005-02-13 devnull continue;
681 ce94dbe6 2005-02-13 devnull s = find(f, nf, "service");
682 ce94dbe6 2005-02-13 devnull if(s == nil)
683 ce94dbe6 2005-02-13 devnull continue;
685 ce94dbe6 2005-02-13 devnull if(version == 1 && strcmp(p, "rsa") == 0 && strcmp(s, "ssh") == 0)
686 ce94dbe6 2005-02-13 devnull if(putrsa1(m, f, nf) >= 0)
688 ce94dbe6 2005-02-13 devnull if(version == 2 && strcmp(p, "rsa") == 0 && strcmp(s, "ssh-rsa") == 0)
689 ce94dbe6 2005-02-13 devnull if(putkey2(m, putrsa, f, nf) >= 0)
691 ce94dbe6 2005-02-13 devnull if(version == 2 && strcmp(p, "dsa") == 0 && strcmp(s, "ssh-dss") == 0)
692 ce94dbe6 2005-02-13 devnull if(putkey2(m, putdsa, f, nf) >= 0)
696 ce94dbe6 2005-02-13 devnull fsclose(fid);
697 ce94dbe6 2005-02-13 devnull pnk[0] = (nk>>24)&0xFF;
698 ce94dbe6 2005-02-13 devnull pnk[1] = (nk>>16)&0xFF;
699 ce94dbe6 2005-02-13 devnull pnk[2] = (nk>>8)&0xFF;
700 ce94dbe6 2005-02-13 devnull pnk[3] = nk&0xFF;
701 ce94dbe6 2005-02-13 devnull return nk;
705 ce94dbe6 2005-02-13 devnull listkeystext(void)
707 ce94dbe6 2005-02-13 devnull char buf[4096+1], *line[100], *f[20], *p, *s;
708 ce94dbe6 2005-02-13 devnull int i, n, nl, nf;
709 ce94dbe6 2005-02-13 devnull CFid *fid;
711 ce94dbe6 2005-02-13 devnull if((fid = nsopen(factotum, nil, "ctl", OREAD)) == nil){
712 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: open factotum: %r\n");
715 ce94dbe6 2005-02-13 devnull for(;;){
716 ce94dbe6 2005-02-13 devnull if((n = fsread(fid, buf, sizeof buf-1)) <= 0)
718 ce94dbe6 2005-02-13 devnull buf[n] = 0;
719 ce94dbe6 2005-02-13 devnull nl = getfields(buf, line, nelem(line), 1, "\n");
720 ce94dbe6 2005-02-13 devnull for(i=0; i<nl; i++){
721 ce94dbe6 2005-02-13 devnull nf = tokenize(line[i], f, nelem(f));
722 ce94dbe6 2005-02-13 devnull if(nf == 0 || strcmp(f[0], "key") != 0)
723 ce94dbe6 2005-02-13 devnull continue;
724 ce94dbe6 2005-02-13 devnull p = find(f, nf, "proto");
725 ce94dbe6 2005-02-13 devnull if(p == nil)
726 ce94dbe6 2005-02-13 devnull continue;
727 ce94dbe6 2005-02-13 devnull s = find(f, nf, "service");
728 ce94dbe6 2005-02-13 devnull if(s == nil)
729 ce94dbe6 2005-02-13 devnull continue;
731 ce94dbe6 2005-02-13 devnull if(strcmp(p, "rsa") == 0 && strcmp(s, "ssh") == 0)
732 ce94dbe6 2005-02-13 devnull printrsa1(f, nf);
733 ce94dbe6 2005-02-13 devnull if(strcmp(p, "rsa") == 0 && strcmp(s, "ssh-rsa") == 0)
734 ce94dbe6 2005-02-13 devnull printkey("ssh-rsa", putrsa, f, nf);
735 ce94dbe6 2005-02-13 devnull if(strcmp(p, "dsa") == 0 && strcmp(s, "ssh-dss") == 0)
736 ce94dbe6 2005-02-13 devnull printkey("ssh-dss", putdsa, f, nf);
739 ce94dbe6 2005-02-13 devnull fsclose(fid);
740 ce94dbe6 2005-02-13 devnull threadexitsall(nil);
744 ce94dbe6 2005-02-13 devnull rsaunpad(mpint *b)
746 ce94dbe6 2005-02-13 devnull int i, n;
747 ce94dbe6 2005-02-13 devnull uchar buf[2560];
749 ce94dbe6 2005-02-13 devnull n = (mpsignif(b)+7)/8;
750 ce94dbe6 2005-02-13 devnull if(n > sizeof buf){
751 ce94dbe6 2005-02-13 devnull werrstr("rsaunpad: too big");
752 ce94dbe6 2005-02-13 devnull return nil;
754 ce94dbe6 2005-02-13 devnull mptobe(b, buf, n, nil);
756 ce94dbe6 2005-02-13 devnull /* the initial zero has been eaten by the betomp -> mptobe sequence */
757 ce94dbe6 2005-02-13 devnull if(buf[0] != 2){
758 ce94dbe6 2005-02-13 devnull werrstr("rsaunpad: expected leading 2");
759 ce94dbe6 2005-02-13 devnull return nil;
761 ce94dbe6 2005-02-13 devnull for(i=1; i<n; i++)
762 ce94dbe6 2005-02-13 devnull if(buf[i]==0)
764 ce94dbe6 2005-02-13 devnull return betomp(buf+i, n-i, nil);
768 ce94dbe6 2005-02-13 devnull mptoberjust(mpint *b, uchar *buf, int len)
772 ce94dbe6 2005-02-13 devnull n = mptobe(b, buf, len, nil);
773 ce94dbe6 2005-02-13 devnull assert(n >= 0);
774 ce94dbe6 2005-02-13 devnull if(n < len){
775 ce94dbe6 2005-02-13 devnull len -= n;
776 ce94dbe6 2005-02-13 devnull memmove(buf+len, buf, n);
777 ce94dbe6 2005-02-13 devnull memset(buf, 0, len);
781 ce94dbe6 2005-02-13 devnull static int
782 ce94dbe6 2005-02-13 devnull dorsa(Aconn *a, mpint *mod, mpint *exp, mpint *chal, uchar chalbuf[32])
784 ce94dbe6 2005-02-13 devnull AuthRpc *rpc;
785 ce94dbe6 2005-02-13 devnull char buf[4096], *p;
786 ce94dbe6 2005-02-13 devnull mpint *decr, *unpad;
788 ce94dbe6 2005-02-13 devnull USED(exp);
789 ce94dbe6 2005-02-13 devnull if((rpc = auth_allocrpc()) == nil){
790 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth_allocrpc: %r\n");
791 ce94dbe6 2005-02-13 devnull return -1;
793 e1a22963 2005-02-13 devnull snprint(buf, sizeof buf, "proto=rsa service=ssh role=decrypt n=%lB ek=%lB", mod, exp);
794 ce94dbe6 2005-02-13 devnull if(chatty)
795 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: start %s\n", buf);
796 ce94dbe6 2005-02-13 devnull if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
797 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth 'start' failed: %r\n");
799 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
800 ce94dbe6 2005-02-13 devnull return -1;
803 ce94dbe6 2005-02-13 devnull p = mptoa(chal, 16, nil, 0);
804 ce94dbe6 2005-02-13 devnull if(p == nil){
805 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: mptoa: %r\n");
806 ce94dbe6 2005-02-13 devnull goto Die;
808 ce94dbe6 2005-02-13 devnull if(chatty)
809 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: challenge %B => %s\n", chal, p);
810 e1a22963 2005-02-13 devnull if(auth_rpc(rpc, "writehex", p, strlen(p)) != ARok){
811 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: auth 'write': %r\n");
812 ce94dbe6 2005-02-13 devnull free(p);
813 ce94dbe6 2005-02-13 devnull goto Die;
815 ce94dbe6 2005-02-13 devnull free(p);
816 e1a22963 2005-02-13 devnull if(auth_rpc(rpc, "readhex", nil, 0) != ARok){
817 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: auth 'read': %r\n");
818 ce94dbe6 2005-02-13 devnull goto Die;
820 ce94dbe6 2005-02-13 devnull decr = strtomp(rpc->arg, nil, 16, nil);
821 ce94dbe6 2005-02-13 devnull if(chatty)
822 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: response %s => %B\n", rpc->arg, decr);
823 ce94dbe6 2005-02-13 devnull if(decr == nil){
824 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: strtomp: %r\n");
825 ce94dbe6 2005-02-13 devnull goto Die;
827 ce94dbe6 2005-02-13 devnull unpad = rsaunpad(decr);
828 ce94dbe6 2005-02-13 devnull if(chatty)
829 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: unpad %B => %B\n", decr, unpad);
830 ce94dbe6 2005-02-13 devnull if(unpad == nil){
831 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: rsaunpad: %r\n");
832 ce94dbe6 2005-02-13 devnull mpfree(decr);
833 ce94dbe6 2005-02-13 devnull goto Die;
835 ce94dbe6 2005-02-13 devnull mpfree(decr);
836 ce94dbe6 2005-02-13 devnull mptoberjust(unpad, chalbuf, 32);
837 ce94dbe6 2005-02-13 devnull mpfree(unpad);
838 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
839 ce94dbe6 2005-02-13 devnull return 0;
843 ce94dbe6 2005-02-13 devnull keysign(Msg *mkey, Msg *mdata, Msg *msig)
845 ce94dbe6 2005-02-13 devnull char *s;
846 ce94dbe6 2005-02-13 devnull AuthRpc *rpc;
847 ce94dbe6 2005-02-13 devnull RSApub *rsa;
848 ce94dbe6 2005-02-13 devnull DSApub *dsa;
849 ce94dbe6 2005-02-13 devnull char buf[4096];
850 ce94dbe6 2005-02-13 devnull uchar digest[SHA1dlen];
852 ce94dbe6 2005-02-13 devnull s = getstr(mkey);
853 ce94dbe6 2005-02-13 devnull if(strcmp(s, "ssh-rsa") == 0){
854 ce94dbe6 2005-02-13 devnull rsa = getrsapub(mkey);
855 ce94dbe6 2005-02-13 devnull if(rsa == nil)
856 ce94dbe6 2005-02-13 devnull return -1;
857 ce94dbe6 2005-02-13 devnull snprint(buf, sizeof buf, "proto=rsa service=ssh-rsa role=sign n=%lB ek=%lB",
858 ce94dbe6 2005-02-13 devnull rsa->n, rsa->ek);
859 ce94dbe6 2005-02-13 devnull rsapubfree(rsa);
860 ce94dbe6 2005-02-13 devnull }else if(strcmp(s, "ssh-dss") == 0){
861 ce94dbe6 2005-02-13 devnull dsa = getdsapub(mkey);
862 ce94dbe6 2005-02-13 devnull if(dsa == nil)
863 ce94dbe6 2005-02-13 devnull return -1;
864 ce94dbe6 2005-02-13 devnull snprint(buf, sizeof buf, "proto=dsa service=ssh-dss role=sign p=%lB q=%lB alpha=%lB key=%lB",
865 ce94dbe6 2005-02-13 devnull dsa->p, dsa->q, dsa->alpha, dsa->key);
866 ce94dbe6 2005-02-13 devnull dsapubfree(dsa);
868 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: cannot sign key type %s\n", s);
869 ce94dbe6 2005-02-13 devnull werrstr("unknown key type %s", s);
870 ce94dbe6 2005-02-13 devnull return -1;
873 ce94dbe6 2005-02-13 devnull if((rpc = auth_allocrpc()) == nil){
874 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth_allocrpc: %r\n");
875 ce94dbe6 2005-02-13 devnull return -1;
877 ce94dbe6 2005-02-13 devnull if(chatty)
878 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: start %s\n", buf);
879 ce94dbe6 2005-02-13 devnull if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
880 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth 'start' failed: %r\n");
882 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
883 ce94dbe6 2005-02-13 devnull return -1;
885 ce94dbe6 2005-02-13 devnull sha1(mdata->bp, mdata->ep-mdata->bp, digest, nil);
886 ce94dbe6 2005-02-13 devnull if(auth_rpc(rpc, "write", digest, SHA1dlen) != ARok){
887 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth 'write in sign failed: %r\n");
888 ce94dbe6 2005-02-13 devnull goto Die;
890 ce94dbe6 2005-02-13 devnull if(auth_rpc(rpc, "read", nil, 0) != ARok){
891 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth 'read' failed: %r\n");
892 ce94dbe6 2005-02-13 devnull goto Die;
894 ce94dbe6 2005-02-13 devnull newmsg(msig);
895 ce94dbe6 2005-02-13 devnull putstr(msig, s);
896 ce94dbe6 2005-02-13 devnull put4(msig, rpc->narg);
897 ce94dbe6 2005-02-13 devnull putn(msig, rpc->arg, rpc->narg);
898 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
899 ce94dbe6 2005-02-13 devnull return 0;
903 ce94dbe6 2005-02-13 devnull runmsg(Aconn *a)
905 ce94dbe6 2005-02-13 devnull char *p;
906 ce94dbe6 2005-02-13 devnull int n, nk, type, rt, vers;
907 ce94dbe6 2005-02-13 devnull mpint *ek, *mod, *chal;
908 ce94dbe6 2005-02-13 devnull uchar sessid[16], chalbuf[32], digest[MD5dlen];
909 ce94dbe6 2005-02-13 devnull uint len, flags;
910 ce94dbe6 2005-02-13 devnull DigestState *s;
911 ce94dbe6 2005-02-13 devnull Msg m, mkey, mdata, msig;
913 ce94dbe6 2005-02-13 devnull if(a->ndata < 4)
914 ce94dbe6 2005-02-13 devnull return 0;
915 ce94dbe6 2005-02-13 devnull len = (a->data[0]<<24)|(a->data[1]<<16)|(a->data[2]<<8)|a->data[3];
916 ce94dbe6 2005-02-13 devnull if(a->ndata < 4+len)
917 ce94dbe6 2005-02-13 devnull return 0;
918 ce94dbe6 2005-02-13 devnull m.p = a->data+4;
919 ce94dbe6 2005-02-13 devnull m.ep = m.p+len;
920 ce94dbe6 2005-02-13 devnull type = get1(&m);
921 ce94dbe6 2005-02-13 devnull if(chatty)
922 ce94dbe6 2005-02-13 devnull fprint(2, "msg %d: %.*H\n", type, len, m.p);
923 ce94dbe6 2005-02-13 devnull switch(type){
924 ce94dbe6 2005-02-13 devnull default:
925 ce94dbe6 2005-02-13 devnull Failure:
926 ce94dbe6 2005-02-13 devnull newreply(&m, SSH_AGENT_FAILURE);
927 ce94dbe6 2005-02-13 devnull reply(a, &m);
930 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
931 ce94dbe6 2005-02-13 devnull vers = 1;
932 ce94dbe6 2005-02-13 devnull newreply(&m, SSH_AGENT_RSA_IDENTITIES_ANSWER);
933 ce94dbe6 2005-02-13 devnull goto Identities;
934 ce94dbe6 2005-02-13 devnull case SSH2_AGENTC_REQUEST_IDENTITIES:
935 ce94dbe6 2005-02-13 devnull vers = 2;
936 ce94dbe6 2005-02-13 devnull newreply(&m, SSH2_AGENT_IDENTITIES_ANSWER);
937 ce94dbe6 2005-02-13 devnull Identities:
938 ce94dbe6 2005-02-13 devnull nk = listkeys(&m, vers);
939 ce94dbe6 2005-02-13 devnull if(nk < 0){
940 ce94dbe6 2005-02-13 devnull free(m.bp);
941 ce94dbe6 2005-02-13 devnull goto Failure;
943 ce94dbe6 2005-02-13 devnull if(chatty)
944 ce94dbe6 2005-02-13 devnull fprint(2, "request identities\n", nk);
945 ce94dbe6 2005-02-13 devnull reply(a, &m);
948 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_RSA_CHALLENGE:
949 ce94dbe6 2005-02-13 devnull n = get4(&m);
950 ce94dbe6 2005-02-13 devnull ek = getmp(&m);
951 ce94dbe6 2005-02-13 devnull mod = getmp(&m);
952 ce94dbe6 2005-02-13 devnull chal = getmp(&m);
953 2b604081 2005-05-07 devnull if((p = (char*)getn(&m, 16)) == nil){
954 ce94dbe6 2005-02-13 devnull Failchal:
955 ce94dbe6 2005-02-13 devnull mpfree(ek);
956 ce94dbe6 2005-02-13 devnull mpfree(mod);
957 ce94dbe6 2005-02-13 devnull mpfree(chal);
958 ce94dbe6 2005-02-13 devnull goto Failure;
960 ce94dbe6 2005-02-13 devnull memmove(sessid, p, 16);
961 ce94dbe6 2005-02-13 devnull rt = get4(&m);
962 ce94dbe6 2005-02-13 devnull if(rt != 1 || dorsa(a, mod, ek, chal, chalbuf) < 0)
963 ce94dbe6 2005-02-13 devnull goto Failchal;
964 ce94dbe6 2005-02-13 devnull s = md5(chalbuf, 32, nil, nil);
965 ce94dbe6 2005-02-13 devnull if(s == nil)
966 ce94dbe6 2005-02-13 devnull goto Failchal;
967 ce94dbe6 2005-02-13 devnull md5(sessid, 16, digest, s);
968 e1a22963 2005-02-13 devnull print("md5 %.*H %.*H => %.*H\n", 32, chalbuf, 16, sessid, MD5dlen, digest);
970 ce94dbe6 2005-02-13 devnull newreply(&m, SSH_AGENT_RSA_RESPONSE);
971 ce94dbe6 2005-02-13 devnull putn(&m, digest, 16);
972 ce94dbe6 2005-02-13 devnull reply(a, &m);
974 ce94dbe6 2005-02-13 devnull mpfree(ek);
975 ce94dbe6 2005-02-13 devnull mpfree(mod);
976 ce94dbe6 2005-02-13 devnull mpfree(chal);
979 ce94dbe6 2005-02-13 devnull case SSH2_AGENTC_SIGN_REQUEST:
980 2b604081 2005-05-07 devnull if(getm(&m, &mkey) == nil
981 2b604081 2005-05-07 devnull || getm(&m, &mdata) == nil)
982 ce94dbe6 2005-02-13 devnull goto Failure;
983 ce94dbe6 2005-02-13 devnull flags = get4(&m);
984 ce94dbe6 2005-02-13 devnull if(flags & SSH_AGENT_OLD_SIGNATURE)
985 ce94dbe6 2005-02-13 devnull goto Failure;
986 ce94dbe6 2005-02-13 devnull if(keysign(&mkey, &mdata, &msig) < 0)
987 ce94dbe6 2005-02-13 devnull goto Failure;
988 ce94dbe6 2005-02-13 devnull if(chatty)
989 ce94dbe6 2005-02-13 devnull fprint(2, "signature: %.*H\n",
990 ce94dbe6 2005-02-13 devnull msig.p-msig.bp, msig.bp);
991 ce94dbe6 2005-02-13 devnull newreply(&m, SSH2_AGENT_SIGN_RESPONSE);
992 ce94dbe6 2005-02-13 devnull putm(&m, &msig);
993 ce94dbe6 2005-02-13 devnull free(msig.bp);
994 ce94dbe6 2005-02-13 devnull reply(a, &m);
997 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_ADD_RSA_IDENTITY:
999 ce94dbe6 2005-02-13 devnull msg: n[4] mod[mp] pubexp[exp] privexp[mp]
1000 ce94dbe6 2005-02-13 devnull p^-1 mod q[mp] p[mp] q[mp] comment[str]
1002 ce94dbe6 2005-02-13 devnull goto Failure;
1004 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_REMOVE_RSA_IDENTITY:
1006 ce94dbe6 2005-02-13 devnull msg: n[4] mod[mp] pubexp[mp]
1008 ce94dbe6 2005-02-13 devnull goto Failure;
1012 ce94dbe6 2005-02-13 devnull a->ndata -= 4+len;
1013 ce94dbe6 2005-02-13 devnull memmove(a->data, a->data+4+len, a->ndata);
1014 ce94dbe6 2005-02-13 devnull return 1;
1018 ce94dbe6 2005-02-13 devnull emalloc(int n)
1020 ce94dbe6 2005-02-13 devnull void *v;
1022 ce94dbe6 2005-02-13 devnull v = mallocz(n, 1);
1023 ce94dbe6 2005-02-13 devnull if(v == nil){
1024 ce94dbe6 2005-02-13 devnull abort();
1025 ce94dbe6 2005-02-13 devnull sysfatal("out of memory allocating %d", n);
1027 ce94dbe6 2005-02-13 devnull return v;
1031 ce94dbe6 2005-02-13 devnull erealloc(void *v, int n)
1033 ce94dbe6 2005-02-13 devnull v = realloc(v, n);
1034 ce94dbe6 2005-02-13 devnull if(v == nil){
1035 ce94dbe6 2005-02-13 devnull abort();
1036 ce94dbe6 2005-02-13 devnull sysfatal("out of memory reallocating %d", n);
1038 ce94dbe6 2005-02-13 devnull return v;