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 ce94dbe6 2005-02-13 devnull char dir[100];
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 ce94dbe6 2005-02-13 devnull x = ((uvlong)fastrand()<<32) | fastrand();
133 ce94dbe6 2005-02-13 devnull x ^= ((uvlong)fastrand()<<32) | fastrand();
134 ce94dbe6 2005-02-13 devnull snprint(dir, sizeof dir, "/tmp/ssh-%llux", x);
135 ce94dbe6 2005-02-13 devnull if((fd = create(dir, OREAD, DMDIR|0700)) < 0)
136 ce94dbe6 2005-02-13 devnull sysfatal("mkdir %s: %r", dir);
137 ce94dbe6 2005-02-13 devnull close(fd);
138 ce94dbe6 2005-02-13 devnull snprint(sock, sizeof sock, "%s/agent.%d", dir, pid);
139 ce94dbe6 2005-02-13 devnull snprint(addr, sizeof addr, "unix!%s", sock);
141 ce94dbe6 2005-02-13 devnull if((afd = announce(addr, adir)) < 0)
142 ce94dbe6 2005-02-13 devnull sysfatal("announce %s: %r", addr);
144 ce94dbe6 2005-02-13 devnull print("SSH_AUTH_SOCK=%s;\n", sock);
145 ce94dbe6 2005-02-13 devnull if(export)
146 ce94dbe6 2005-02-13 devnull print("export SSH_AUTH_SOCK;\n");
147 ce94dbe6 2005-02-13 devnull print("SSH_AGENT_PID=%d;\n", pid);
148 ce94dbe6 2005-02-13 devnull if(export)
149 ce94dbe6 2005-02-13 devnull print("export SSH_AGENT_PID;\n");
150 ce94dbe6 2005-02-13 devnull close(1);
151 e1a22963 2005-02-13 devnull rfork(RFNOTEG);
152 e1a22963 2005-02-13 devnull proccreate(listenproc, nil, STACK);
153 ce94dbe6 2005-02-13 devnull threadexits(0);
157 ce94dbe6 2005-02-13 devnull listenproc(void *v)
159 ce94dbe6 2005-02-13 devnull Aconn *a;
161 ce94dbe6 2005-02-13 devnull USED(v);
162 ce94dbe6 2005-02-13 devnull for(;;){
163 ce94dbe6 2005-02-13 devnull a = emalloc(sizeof *a);
164 ce94dbe6 2005-02-13 devnull a->ctl = listen(adir, a->dir);
165 ce94dbe6 2005-02-13 devnull if(a->ctl < 0)
166 ce94dbe6 2005-02-13 devnull sysfatal("listen: %r");
167 ce94dbe6 2005-02-13 devnull proccreate(agentproc, a, STACK);
172 ce94dbe6 2005-02-13 devnull agentproc(void *v)
174 ce94dbe6 2005-02-13 devnull Aconn *a;
178 ce94dbe6 2005-02-13 devnull a->fd = accept(a->ctl, a->dir);
179 ce94dbe6 2005-02-13 devnull close(a->ctl);
180 ce94dbe6 2005-02-13 devnull a->ctl = -1;
181 ce94dbe6 2005-02-13 devnull for(;;){
182 ce94dbe6 2005-02-13 devnull a->data = erealloc(a->data, a->ndata+1024);
183 ce94dbe6 2005-02-13 devnull n = read(a->fd, a->data+a->ndata, 1024);
184 ce94dbe6 2005-02-13 devnull if(n <= 0)
186 ce94dbe6 2005-02-13 devnull a->ndata += n;
187 ce94dbe6 2005-02-13 devnull while(runmsg(a))
190 ce94dbe6 2005-02-13 devnull close(a->fd);
191 ce94dbe6 2005-02-13 devnull free(a);
192 ce94dbe6 2005-02-13 devnull threadexits(nil);
196 ce94dbe6 2005-02-13 devnull get1(Msg *m)
198 ce94dbe6 2005-02-13 devnull if(m->p >= m->ep)
199 ce94dbe6 2005-02-13 devnull return 0;
200 ce94dbe6 2005-02-13 devnull return *m->p++;
204 ce94dbe6 2005-02-13 devnull get2(Msg *m)
208 ce94dbe6 2005-02-13 devnull if(m->p+2 > m->ep)
209 ce94dbe6 2005-02-13 devnull return 0;
210 ce94dbe6 2005-02-13 devnull x = (m->p[0]<<8)|m->p[1];
211 ce94dbe6 2005-02-13 devnull m->p += 2;
212 ce94dbe6 2005-02-13 devnull return x;
216 ce94dbe6 2005-02-13 devnull get4(Msg *m)
219 ce94dbe6 2005-02-13 devnull if(m->p+4 > m->ep)
220 ce94dbe6 2005-02-13 devnull return 0;
221 ce94dbe6 2005-02-13 devnull x = (m->p[0]<<24)|(m->p[1]<<16)|(m->p[2]<<8)|m->p[3];
222 ce94dbe6 2005-02-13 devnull m->p += 4;
223 ce94dbe6 2005-02-13 devnull return x;
227 ce94dbe6 2005-02-13 devnull getn(Msg *m, uint n)
229 ce94dbe6 2005-02-13 devnull uchar *p;
231 ce94dbe6 2005-02-13 devnull if(m->p+n > m->ep)
232 ce94dbe6 2005-02-13 devnull return nil;
233 ce94dbe6 2005-02-13 devnull p = m->p;
234 ce94dbe6 2005-02-13 devnull m->p += n;
235 ce94dbe6 2005-02-13 devnull return p;
239 ce94dbe6 2005-02-13 devnull getstr(Msg *m)
242 ce94dbe6 2005-02-13 devnull uchar *p;
244 ce94dbe6 2005-02-13 devnull n = get4(m);
245 ce94dbe6 2005-02-13 devnull p = getn(m, n);
246 ce94dbe6 2005-02-13 devnull if(p == nil)
247 ce94dbe6 2005-02-13 devnull return nil;
249 ce94dbe6 2005-02-13 devnull memmove(p, p+1, n);
250 ce94dbe6 2005-02-13 devnull p[n] = 0;
251 ce94dbe6 2005-02-13 devnull return p;
255 ce94dbe6 2005-02-13 devnull getmp(Msg *m)
258 ce94dbe6 2005-02-13 devnull uchar *p;
260 ce94dbe6 2005-02-13 devnull n = (get2(m)+7)/8;
261 ce94dbe6 2005-02-13 devnull if((p=getn(m, n)) == nil)
262 ce94dbe6 2005-02-13 devnull return nil;
263 ce94dbe6 2005-02-13 devnull return betomp(p, n, nil);
267 ce94dbe6 2005-02-13 devnull getmp2(Msg *m)
270 ce94dbe6 2005-02-13 devnull uchar *p;
272 ce94dbe6 2005-02-13 devnull n = get4(m);
273 ce94dbe6 2005-02-13 devnull if((p = getn(m, n)) == nil)
274 ce94dbe6 2005-02-13 devnull return nil;
275 ce94dbe6 2005-02-13 devnull return betomp(p, n, nil);
279 ce94dbe6 2005-02-13 devnull getm(Msg *m, Msg *mm)
282 ce94dbe6 2005-02-13 devnull uchar *p;
284 ce94dbe6 2005-02-13 devnull n = get4(m);
285 ce94dbe6 2005-02-13 devnull if((p = getn(m, n)) == nil)
286 ce94dbe6 2005-02-13 devnull return nil;
287 ce94dbe6 2005-02-13 devnull mm->bp = p;
288 ce94dbe6 2005-02-13 devnull mm->p = p;
289 ce94dbe6 2005-02-13 devnull mm->ep = p+n;
290 ce94dbe6 2005-02-13 devnull return mm;
294 ce94dbe6 2005-02-13 devnull ensure(Msg *m, int n)
296 ce94dbe6 2005-02-13 devnull int len, plen;
297 ce94dbe6 2005-02-13 devnull uchar *p;
299 ce94dbe6 2005-02-13 devnull len = m->ep - m->bp;
300 ce94dbe6 2005-02-13 devnull if(m->p+n > m->ep){
301 ce94dbe6 2005-02-13 devnull plen = m->p - m->bp;
302 ce94dbe6 2005-02-13 devnull m->bp = erealloc(m->bp, len+n+1024);
303 ce94dbe6 2005-02-13 devnull m->p = m->bp+plen;
304 ce94dbe6 2005-02-13 devnull m->ep = m->bp+len+n+1024;
306 ce94dbe6 2005-02-13 devnull p = m->p;
307 ce94dbe6 2005-02-13 devnull m->p += n;
308 ce94dbe6 2005-02-13 devnull return p;
312 ce94dbe6 2005-02-13 devnull put4(Msg *m, uint n)
314 ce94dbe6 2005-02-13 devnull uchar *p;
316 ce94dbe6 2005-02-13 devnull p = ensure(m, 4);
317 ce94dbe6 2005-02-13 devnull p[0] = (n>>24)&0xFF;
318 ce94dbe6 2005-02-13 devnull p[1] = (n>>16)&0xFF;
319 ce94dbe6 2005-02-13 devnull p[2] = (n>>8)&0xFF;
320 ce94dbe6 2005-02-13 devnull p[3] = n&0xFF;
324 ce94dbe6 2005-02-13 devnull put2(Msg *m, uint n)
326 ce94dbe6 2005-02-13 devnull uchar *p;
328 ce94dbe6 2005-02-13 devnull p = ensure(m, 2);
329 ce94dbe6 2005-02-13 devnull p[0] = (n>>8)&0xFF;
330 ce94dbe6 2005-02-13 devnull p[1] = n&0xFF;
334 ce94dbe6 2005-02-13 devnull put1(Msg *m, uint n)
336 ce94dbe6 2005-02-13 devnull uchar *p;
338 ce94dbe6 2005-02-13 devnull p = ensure(m, 1);
339 ce94dbe6 2005-02-13 devnull p[0] = n&0xFF;
343 ce94dbe6 2005-02-13 devnull putn(Msg *m, void *a, uint n)
345 ce94dbe6 2005-02-13 devnull uchar *p;
347 ce94dbe6 2005-02-13 devnull p = ensure(m, n);
348 ce94dbe6 2005-02-13 devnull memmove(p, a, n);
352 ce94dbe6 2005-02-13 devnull putmp(Msg *m, mpint *b)
354 ce94dbe6 2005-02-13 devnull int bits, n;
355 ce94dbe6 2005-02-13 devnull uchar *p;
357 ce94dbe6 2005-02-13 devnull bits = mpsignif(b);
358 ce94dbe6 2005-02-13 devnull put2(m, bits);
359 ce94dbe6 2005-02-13 devnull n = (bits+7)/8;
360 ce94dbe6 2005-02-13 devnull p = ensure(m, n);
361 ce94dbe6 2005-02-13 devnull mptobe(b, p, n, nil);
365 ce94dbe6 2005-02-13 devnull putmp2(Msg *m, mpint *b)
367 ce94dbe6 2005-02-13 devnull int bits, n;
368 ce94dbe6 2005-02-13 devnull uchar *p;
370 ce94dbe6 2005-02-13 devnull if(mpcmp(b, mpzero) == 0){
371 ce94dbe6 2005-02-13 devnull put4(m, 0);
374 ce94dbe6 2005-02-13 devnull bits = mpsignif(b);
375 ce94dbe6 2005-02-13 devnull n = (bits+7)/8;
376 ce94dbe6 2005-02-13 devnull if(bits%8 == 0){
377 ce94dbe6 2005-02-13 devnull put4(m, n+1);
378 ce94dbe6 2005-02-13 devnull put1(m, 0);
380 ce94dbe6 2005-02-13 devnull put4(m, n);
381 ce94dbe6 2005-02-13 devnull p = ensure(m, n);
382 ce94dbe6 2005-02-13 devnull mptobe(b, p, n, nil);
386 ce94dbe6 2005-02-13 devnull putstr(Msg *m, char *s)
390 ce94dbe6 2005-02-13 devnull n = strlen(s);
391 ce94dbe6 2005-02-13 devnull put4(m, n);
392 ce94dbe6 2005-02-13 devnull putn(m, s, n);
396 ce94dbe6 2005-02-13 devnull putm(Msg *m, Msg *mm)
400 ce94dbe6 2005-02-13 devnull n = mm->p - mm->bp;
401 ce94dbe6 2005-02-13 devnull put4(m, n);
402 ce94dbe6 2005-02-13 devnull putn(m, mm->bp, n);
406 ce94dbe6 2005-02-13 devnull newmsg(Msg *m)
408 ce94dbe6 2005-02-13 devnull memset(m, 0, sizeof *m);
412 ce94dbe6 2005-02-13 devnull newreply(Msg *m, int type)
414 ce94dbe6 2005-02-13 devnull memset(m, 0, sizeof *m);
415 ce94dbe6 2005-02-13 devnull put4(m, 0);
416 ce94dbe6 2005-02-13 devnull put1(m, type);
420 ce94dbe6 2005-02-13 devnull reply(Aconn *a, Msg *m)
423 ce94dbe6 2005-02-13 devnull uchar *p;
425 ce94dbe6 2005-02-13 devnull n = (m->p - m->bp) - 4;
426 ce94dbe6 2005-02-13 devnull p = m->bp;
427 ce94dbe6 2005-02-13 devnull p[0] = (n>>24)&0xFF;
428 ce94dbe6 2005-02-13 devnull p[1] = (n>>16)&0xFF;
429 ce94dbe6 2005-02-13 devnull p[2] = (n>>8)&0xFF;
430 ce94dbe6 2005-02-13 devnull p[3] = n&0xFF;
431 ce94dbe6 2005-02-13 devnull if(chatty)
432 ce94dbe6 2005-02-13 devnull fprint(2, "respond %d: %.*H\n", p[4], n, m->bp+4);
433 ce94dbe6 2005-02-13 devnull write(a->fd, p, n+4);
434 ce94dbe6 2005-02-13 devnull free(p);
435 ce94dbe6 2005-02-13 devnull memset(m, 0, sizeof *m);
438 ce94dbe6 2005-02-13 devnull typedef struct Key Key;
439 ce94dbe6 2005-02-13 devnull struct Key
441 ce94dbe6 2005-02-13 devnull mpint *mod;
442 ce94dbe6 2005-02-13 devnull mpint *ek;
443 ce94dbe6 2005-02-13 devnull char *comment;
446 ce94dbe6 2005-02-13 devnull static char*
447 ce94dbe6 2005-02-13 devnull find(char **f, int nf, char *k)
449 ce94dbe6 2005-02-13 devnull int i, len;
451 ce94dbe6 2005-02-13 devnull len = strlen(k);
452 ce94dbe6 2005-02-13 devnull for(i=1; i<nf; i++) /* i=1: f[0] is "key" */
453 ce94dbe6 2005-02-13 devnull if(strncmp(f[i], k, len) == 0 && f[i][len] == '=')
454 ce94dbe6 2005-02-13 devnull return f[i]+len+1;
455 ce94dbe6 2005-02-13 devnull return nil;
458 ce94dbe6 2005-02-13 devnull static int
459 ce94dbe6 2005-02-13 devnull putrsa1(Msg *m, char **f, int nf)
461 ce94dbe6 2005-02-13 devnull char *p;
462 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
464 ce94dbe6 2005-02-13 devnull p = find(f, nf, "n");
465 ce94dbe6 2005-02-13 devnull if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
466 ce94dbe6 2005-02-13 devnull return -1;
467 ce94dbe6 2005-02-13 devnull p = find(f, nf, "ek");
468 ce94dbe6 2005-02-13 devnull if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
469 ce94dbe6 2005-02-13 devnull mpfree(mod);
470 ce94dbe6 2005-02-13 devnull return -1;
472 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
473 ce94dbe6 2005-02-13 devnull if(p == nil)
475 ce94dbe6 2005-02-13 devnull put4(m, mpsignif(mod));
476 ce94dbe6 2005-02-13 devnull putmp(m, ek);
477 ce94dbe6 2005-02-13 devnull putmp(m, mod);
478 ce94dbe6 2005-02-13 devnull putstr(m, p);
479 ce94dbe6 2005-02-13 devnull mpfree(mod);
480 ce94dbe6 2005-02-13 devnull mpfree(ek);
481 ce94dbe6 2005-02-13 devnull return 0;
485 ce94dbe6 2005-02-13 devnull printattr(char **f, int nf)
489 ce94dbe6 2005-02-13 devnull print("#");
490 ce94dbe6 2005-02-13 devnull for(i=0; i<nf; i++)
491 ce94dbe6 2005-02-13 devnull print(" %s", f[i]);
492 ce94dbe6 2005-02-13 devnull print("\n");
496 ce94dbe6 2005-02-13 devnull printrsa1(char **f, int nf)
498 ce94dbe6 2005-02-13 devnull char *p;
499 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
501 ce94dbe6 2005-02-13 devnull p = find(f, nf, "n");
502 ce94dbe6 2005-02-13 devnull if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
504 ce94dbe6 2005-02-13 devnull p = find(f, nf, "ek");
505 ce94dbe6 2005-02-13 devnull if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
506 ce94dbe6 2005-02-13 devnull mpfree(mod);
509 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
510 ce94dbe6 2005-02-13 devnull if(p == nil)
513 ce94dbe6 2005-02-13 devnull if(chatty)
514 ce94dbe6 2005-02-13 devnull printattr(f, nf);
515 ce94dbe6 2005-02-13 devnull print("%d %.10B %.10B %s\n", mpsignif(mod), ek, mod, p);
516 ce94dbe6 2005-02-13 devnull mpfree(ek);
517 ce94dbe6 2005-02-13 devnull mpfree(mod);
520 ce94dbe6 2005-02-13 devnull static int
521 ce94dbe6 2005-02-13 devnull putrsa(Msg *m, char **f, int nf)
523 ce94dbe6 2005-02-13 devnull char *p;
524 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
526 ce94dbe6 2005-02-13 devnull p = find(f, nf, "n");
527 ce94dbe6 2005-02-13 devnull if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
528 ce94dbe6 2005-02-13 devnull return -1;
529 ce94dbe6 2005-02-13 devnull p = find(f, nf, "ek");
530 ce94dbe6 2005-02-13 devnull if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
531 ce94dbe6 2005-02-13 devnull mpfree(mod);
532 ce94dbe6 2005-02-13 devnull return -1;
534 ce94dbe6 2005-02-13 devnull putstr(m, "ssh-rsa");
535 ce94dbe6 2005-02-13 devnull putmp2(m, ek);
536 ce94dbe6 2005-02-13 devnull putmp2(m, mod);
537 ce94dbe6 2005-02-13 devnull mpfree(ek);
538 ce94dbe6 2005-02-13 devnull mpfree(mod);
539 ce94dbe6 2005-02-13 devnull return 0;
543 ce94dbe6 2005-02-13 devnull getrsapub(Msg *m)
545 ce94dbe6 2005-02-13 devnull RSApub *k;
547 ce94dbe6 2005-02-13 devnull k = rsapuballoc();
548 ce94dbe6 2005-02-13 devnull if(k == nil)
549 ce94dbe6 2005-02-13 devnull return nil;
550 ce94dbe6 2005-02-13 devnull k->ek = getmp2(m);
551 ce94dbe6 2005-02-13 devnull k->n = getmp2(m);
552 ce94dbe6 2005-02-13 devnull if(k->ek == nil || k->n == nil){
553 ce94dbe6 2005-02-13 devnull rsapubfree(k);
554 ce94dbe6 2005-02-13 devnull return nil;
556 ce94dbe6 2005-02-13 devnull return k;
559 ce94dbe6 2005-02-13 devnull static int
560 ce94dbe6 2005-02-13 devnull putdsa(Msg *m, char **f, int nf)
562 ce94dbe6 2005-02-13 devnull char *p;
563 ce94dbe6 2005-02-13 devnull int ret;
564 ce94dbe6 2005-02-13 devnull mpint *dp, *dq, *dalpha, *dkey;
566 ce94dbe6 2005-02-13 devnull ret = -1;
567 ce94dbe6 2005-02-13 devnull dp = dq = dalpha = dkey = nil;
568 ce94dbe6 2005-02-13 devnull p = find(f, nf, "p");
569 ce94dbe6 2005-02-13 devnull if(p == nil || (dp = strtomp(p, nil, 16, nil)) == nil)
570 ce94dbe6 2005-02-13 devnull goto out;
571 ce94dbe6 2005-02-13 devnull p = find(f, nf, "q");
572 ce94dbe6 2005-02-13 devnull if(p == nil || (dq = strtomp(p, nil, 16, nil)) == nil)
573 ce94dbe6 2005-02-13 devnull goto out;
574 ce94dbe6 2005-02-13 devnull p = find(f, nf, "alpha");
575 ce94dbe6 2005-02-13 devnull if(p == nil || (dalpha = strtomp(p, nil, 16, nil)) == nil)
576 ce94dbe6 2005-02-13 devnull goto out;
577 ce94dbe6 2005-02-13 devnull p = find(f, nf, "key");
578 ce94dbe6 2005-02-13 devnull if(p == nil || (dkey = strtomp(p, nil, 16, nil)) == nil)
579 ce94dbe6 2005-02-13 devnull goto out;
580 ce94dbe6 2005-02-13 devnull putstr(m, "ssh-dss");
581 ce94dbe6 2005-02-13 devnull putmp2(m, dp);
582 ce94dbe6 2005-02-13 devnull putmp2(m, dq);
583 ce94dbe6 2005-02-13 devnull putmp2(m, dalpha);
584 ce94dbe6 2005-02-13 devnull putmp2(m, dkey);
585 ce94dbe6 2005-02-13 devnull ret = 0;
587 ce94dbe6 2005-02-13 devnull mpfree(dp);
588 ce94dbe6 2005-02-13 devnull mpfree(dq);
589 ce94dbe6 2005-02-13 devnull mpfree(dalpha);
590 ce94dbe6 2005-02-13 devnull mpfree(dkey);
591 ce94dbe6 2005-02-13 devnull return ret;
594 ce94dbe6 2005-02-13 devnull static int
595 ce94dbe6 2005-02-13 devnull putkey2(Msg *m, int (*put)(Msg*,char**,int), char **f, int nf)
597 ce94dbe6 2005-02-13 devnull char *p;
600 ce94dbe6 2005-02-13 devnull newmsg(&mm);
601 ce94dbe6 2005-02-13 devnull if(put(&mm, f, nf) < 0)
602 ce94dbe6 2005-02-13 devnull return -1;
603 ce94dbe6 2005-02-13 devnull putm(m, &mm);
604 ce94dbe6 2005-02-13 devnull free(mm.bp);
605 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
606 ce94dbe6 2005-02-13 devnull if(p == nil)
608 ce94dbe6 2005-02-13 devnull putstr(m, p);
609 ce94dbe6 2005-02-13 devnull return 0;
612 ce94dbe6 2005-02-13 devnull static int
613 ce94dbe6 2005-02-13 devnull printkey(char *type, int (*put)(Msg*,char**,int), char **f, int nf)
616 ce94dbe6 2005-02-13 devnull char *p;
618 ce94dbe6 2005-02-13 devnull newmsg(&m);
619 ce94dbe6 2005-02-13 devnull if(put(&m, f, nf) < 0)
620 ce94dbe6 2005-02-13 devnull return -1;
621 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
622 ce94dbe6 2005-02-13 devnull if(p == nil)
624 ce94dbe6 2005-02-13 devnull if(chatty)
625 ce94dbe6 2005-02-13 devnull printattr(f, nf);
626 ce94dbe6 2005-02-13 devnull print("%s %.*[ %s\n", type, m.p-m.bp, m.bp, p);
627 ce94dbe6 2005-02-13 devnull free(m.bp);
628 ce94dbe6 2005-02-13 devnull return 0;
632 ce94dbe6 2005-02-13 devnull getdsapub(Msg *m)
634 ce94dbe6 2005-02-13 devnull DSApub *k;
636 ce94dbe6 2005-02-13 devnull k = dsapuballoc();
637 ce94dbe6 2005-02-13 devnull if(k == nil)
638 ce94dbe6 2005-02-13 devnull return nil;
639 ce94dbe6 2005-02-13 devnull k->p = getmp2(m);
640 ce94dbe6 2005-02-13 devnull k->q = getmp2(m);
641 ce94dbe6 2005-02-13 devnull k->alpha = getmp2(m);
642 ce94dbe6 2005-02-13 devnull k->key = getmp2(m);
643 ce94dbe6 2005-02-13 devnull if(!k->p || !k->q || !k->alpha || !k->key){
644 ce94dbe6 2005-02-13 devnull dsapubfree(k);
645 ce94dbe6 2005-02-13 devnull return nil;
647 ce94dbe6 2005-02-13 devnull return k;
650 ce94dbe6 2005-02-13 devnull static int
651 ce94dbe6 2005-02-13 devnull listkeys(Msg *m, int version)
653 ce94dbe6 2005-02-13 devnull char buf[8192+1], *line[100], *f[20], *p, *s;
654 ce94dbe6 2005-02-13 devnull uchar *pnk;
655 ce94dbe6 2005-02-13 devnull int i, n, nl, nf, nk;
656 ce94dbe6 2005-02-13 devnull CFid *fid;
659 ce94dbe6 2005-02-13 devnull pnk = m->p;
660 ce94dbe6 2005-02-13 devnull put4(m, 0);
661 e1a22963 2005-02-13 devnull if((fid = nsopen(factotum, nil, "ctl", OREAD)) == nil){
662 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: open factotum: %r\n");
663 ce94dbe6 2005-02-13 devnull return -1;
665 ce94dbe6 2005-02-13 devnull for(;;){
666 ce94dbe6 2005-02-13 devnull if((n = fsread(fid, buf, sizeof buf-1)) <= 0)
668 ce94dbe6 2005-02-13 devnull buf[n] = 0;
669 ce94dbe6 2005-02-13 devnull nl = getfields(buf, line, nelem(line), 1, "\n");
670 ce94dbe6 2005-02-13 devnull for(i=0; i<nl; i++){
671 ce94dbe6 2005-02-13 devnull nf = tokenize(line[i], f, nelem(f));
672 ce94dbe6 2005-02-13 devnull if(nf == 0 || strcmp(f[0], "key") != 0)
673 ce94dbe6 2005-02-13 devnull continue;
674 ce94dbe6 2005-02-13 devnull p = find(f, nf, "proto");
675 ce94dbe6 2005-02-13 devnull if(p == nil)
676 ce94dbe6 2005-02-13 devnull continue;
677 ce94dbe6 2005-02-13 devnull s = find(f, nf, "service");
678 ce94dbe6 2005-02-13 devnull if(s == nil)
679 ce94dbe6 2005-02-13 devnull continue;
681 ce94dbe6 2005-02-13 devnull if(version == 1 && strcmp(p, "rsa") == 0 && strcmp(s, "ssh") == 0)
682 ce94dbe6 2005-02-13 devnull if(putrsa1(m, f, nf) >= 0)
684 ce94dbe6 2005-02-13 devnull if(version == 2 && strcmp(p, "rsa") == 0 && strcmp(s, "ssh-rsa") == 0)
685 ce94dbe6 2005-02-13 devnull if(putkey2(m, putrsa, f, nf) >= 0)
687 ce94dbe6 2005-02-13 devnull if(version == 2 && strcmp(p, "dsa") == 0 && strcmp(s, "ssh-dss") == 0)
688 ce94dbe6 2005-02-13 devnull if(putkey2(m, putdsa, f, nf) >= 0)
692 ce94dbe6 2005-02-13 devnull fsclose(fid);
693 ce94dbe6 2005-02-13 devnull pnk[0] = (nk>>24)&0xFF;
694 ce94dbe6 2005-02-13 devnull pnk[1] = (nk>>16)&0xFF;
695 ce94dbe6 2005-02-13 devnull pnk[2] = (nk>>8)&0xFF;
696 ce94dbe6 2005-02-13 devnull pnk[3] = nk&0xFF;
697 ce94dbe6 2005-02-13 devnull return nk;
701 ce94dbe6 2005-02-13 devnull listkeystext(void)
703 ce94dbe6 2005-02-13 devnull char buf[4096+1], *line[100], *f[20], *p, *s;
704 ce94dbe6 2005-02-13 devnull int i, n, nl, nf;
705 ce94dbe6 2005-02-13 devnull CFid *fid;
707 ce94dbe6 2005-02-13 devnull if((fid = nsopen(factotum, nil, "ctl", OREAD)) == nil){
708 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: open factotum: %r\n");
711 ce94dbe6 2005-02-13 devnull for(;;){
712 ce94dbe6 2005-02-13 devnull if((n = fsread(fid, buf, sizeof buf-1)) <= 0)
714 ce94dbe6 2005-02-13 devnull buf[n] = 0;
715 ce94dbe6 2005-02-13 devnull nl = getfields(buf, line, nelem(line), 1, "\n");
716 ce94dbe6 2005-02-13 devnull for(i=0; i<nl; i++){
717 ce94dbe6 2005-02-13 devnull nf = tokenize(line[i], f, nelem(f));
718 ce94dbe6 2005-02-13 devnull if(nf == 0 || strcmp(f[0], "key") != 0)
719 ce94dbe6 2005-02-13 devnull continue;
720 ce94dbe6 2005-02-13 devnull p = find(f, nf, "proto");
721 ce94dbe6 2005-02-13 devnull if(p == nil)
722 ce94dbe6 2005-02-13 devnull continue;
723 ce94dbe6 2005-02-13 devnull s = find(f, nf, "service");
724 ce94dbe6 2005-02-13 devnull if(s == nil)
725 ce94dbe6 2005-02-13 devnull continue;
727 ce94dbe6 2005-02-13 devnull if(strcmp(p, "rsa") == 0 && strcmp(s, "ssh") == 0)
728 ce94dbe6 2005-02-13 devnull printrsa1(f, nf);
729 ce94dbe6 2005-02-13 devnull if(strcmp(p, "rsa") == 0 && strcmp(s, "ssh-rsa") == 0)
730 ce94dbe6 2005-02-13 devnull printkey("ssh-rsa", putrsa, f, nf);
731 ce94dbe6 2005-02-13 devnull if(strcmp(p, "dsa") == 0 && strcmp(s, "ssh-dss") == 0)
732 ce94dbe6 2005-02-13 devnull printkey("ssh-dss", putdsa, f, nf);
735 ce94dbe6 2005-02-13 devnull fsclose(fid);
736 ce94dbe6 2005-02-13 devnull threadexitsall(nil);
740 ce94dbe6 2005-02-13 devnull rsaunpad(mpint *b)
742 ce94dbe6 2005-02-13 devnull int i, n;
743 ce94dbe6 2005-02-13 devnull uchar buf[2560];
745 ce94dbe6 2005-02-13 devnull n = (mpsignif(b)+7)/8;
746 ce94dbe6 2005-02-13 devnull if(n > sizeof buf){
747 ce94dbe6 2005-02-13 devnull werrstr("rsaunpad: too big");
748 ce94dbe6 2005-02-13 devnull return nil;
750 ce94dbe6 2005-02-13 devnull mptobe(b, buf, n, nil);
752 ce94dbe6 2005-02-13 devnull /* the initial zero has been eaten by the betomp -> mptobe sequence */
753 ce94dbe6 2005-02-13 devnull if(buf[0] != 2){
754 ce94dbe6 2005-02-13 devnull werrstr("rsaunpad: expected leading 2");
755 ce94dbe6 2005-02-13 devnull return nil;
757 ce94dbe6 2005-02-13 devnull for(i=1; i<n; i++)
758 ce94dbe6 2005-02-13 devnull if(buf[i]==0)
760 ce94dbe6 2005-02-13 devnull return betomp(buf+i, n-i, nil);
764 ce94dbe6 2005-02-13 devnull mptoberjust(mpint *b, uchar *buf, int len)
768 ce94dbe6 2005-02-13 devnull n = mptobe(b, buf, len, nil);
769 ce94dbe6 2005-02-13 devnull assert(n >= 0);
770 ce94dbe6 2005-02-13 devnull if(n < len){
771 ce94dbe6 2005-02-13 devnull len -= n;
772 ce94dbe6 2005-02-13 devnull memmove(buf+len, buf, n);
773 ce94dbe6 2005-02-13 devnull memset(buf, 0, len);
777 ce94dbe6 2005-02-13 devnull static int
778 ce94dbe6 2005-02-13 devnull dorsa(Aconn *a, mpint *mod, mpint *exp, mpint *chal, uchar chalbuf[32])
780 ce94dbe6 2005-02-13 devnull AuthRpc *rpc;
781 ce94dbe6 2005-02-13 devnull char buf[4096], *p;
782 ce94dbe6 2005-02-13 devnull mpint *decr, *unpad;
784 ce94dbe6 2005-02-13 devnull USED(exp);
785 ce94dbe6 2005-02-13 devnull if((rpc = auth_allocrpc()) == nil){
786 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth_allocrpc: %r\n");
787 ce94dbe6 2005-02-13 devnull return -1;
789 e1a22963 2005-02-13 devnull snprint(buf, sizeof buf, "proto=rsa service=ssh role=decrypt n=%lB ek=%lB", mod, exp);
790 ce94dbe6 2005-02-13 devnull if(chatty)
791 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: start %s\n", buf);
792 ce94dbe6 2005-02-13 devnull if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
793 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth 'start' failed: %r\n");
795 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
796 ce94dbe6 2005-02-13 devnull return -1;
799 ce94dbe6 2005-02-13 devnull p = mptoa(chal, 16, nil, 0);
800 ce94dbe6 2005-02-13 devnull if(p == nil){
801 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: mptoa: %r\n");
802 ce94dbe6 2005-02-13 devnull goto Die;
804 ce94dbe6 2005-02-13 devnull if(chatty)
805 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: challenge %B => %s\n", chal, p);
806 e1a22963 2005-02-13 devnull if(auth_rpc(rpc, "writehex", p, strlen(p)) != ARok){
807 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: auth 'write': %r\n");
808 ce94dbe6 2005-02-13 devnull free(p);
809 ce94dbe6 2005-02-13 devnull goto Die;
811 ce94dbe6 2005-02-13 devnull free(p);
812 e1a22963 2005-02-13 devnull if(auth_rpc(rpc, "readhex", nil, 0) != ARok){
813 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: auth 'read': %r\n");
814 ce94dbe6 2005-02-13 devnull goto Die;
816 ce94dbe6 2005-02-13 devnull decr = strtomp(rpc->arg, nil, 16, nil);
817 ce94dbe6 2005-02-13 devnull if(chatty)
818 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: response %s => %B\n", rpc->arg, decr);
819 ce94dbe6 2005-02-13 devnull if(decr == nil){
820 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: strtomp: %r\n");
821 ce94dbe6 2005-02-13 devnull goto Die;
823 ce94dbe6 2005-02-13 devnull unpad = rsaunpad(decr);
824 ce94dbe6 2005-02-13 devnull if(chatty)
825 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: unpad %B => %B\n", decr, unpad);
826 ce94dbe6 2005-02-13 devnull if(unpad == nil){
827 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: dorsa: rsaunpad: %r\n");
828 ce94dbe6 2005-02-13 devnull mpfree(decr);
829 ce94dbe6 2005-02-13 devnull goto Die;
831 ce94dbe6 2005-02-13 devnull mpfree(decr);
832 ce94dbe6 2005-02-13 devnull mptoberjust(unpad, chalbuf, 32);
833 ce94dbe6 2005-02-13 devnull mpfree(unpad);
834 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
835 ce94dbe6 2005-02-13 devnull return 0;
839 ce94dbe6 2005-02-13 devnull keysign(Msg *mkey, Msg *mdata, Msg *msig)
841 ce94dbe6 2005-02-13 devnull char *s;
842 ce94dbe6 2005-02-13 devnull AuthRpc *rpc;
843 ce94dbe6 2005-02-13 devnull RSApub *rsa;
844 ce94dbe6 2005-02-13 devnull DSApub *dsa;
845 ce94dbe6 2005-02-13 devnull char buf[4096];
846 ce94dbe6 2005-02-13 devnull uchar digest[SHA1dlen];
848 ce94dbe6 2005-02-13 devnull s = getstr(mkey);
849 ce94dbe6 2005-02-13 devnull if(strcmp(s, "ssh-rsa") == 0){
850 ce94dbe6 2005-02-13 devnull rsa = getrsapub(mkey);
851 ce94dbe6 2005-02-13 devnull if(rsa == nil)
852 ce94dbe6 2005-02-13 devnull return -1;
853 ce94dbe6 2005-02-13 devnull snprint(buf, sizeof buf, "proto=rsa service=ssh-rsa role=sign n=%lB ek=%lB",
854 ce94dbe6 2005-02-13 devnull rsa->n, rsa->ek);
855 ce94dbe6 2005-02-13 devnull rsapubfree(rsa);
856 ce94dbe6 2005-02-13 devnull }else if(strcmp(s, "ssh-dss") == 0){
857 ce94dbe6 2005-02-13 devnull dsa = getdsapub(mkey);
858 ce94dbe6 2005-02-13 devnull if(dsa == nil)
859 ce94dbe6 2005-02-13 devnull return -1;
860 ce94dbe6 2005-02-13 devnull snprint(buf, sizeof buf, "proto=dsa service=ssh-dss role=sign p=%lB q=%lB alpha=%lB key=%lB",
861 ce94dbe6 2005-02-13 devnull dsa->p, dsa->q, dsa->alpha, dsa->key);
862 ce94dbe6 2005-02-13 devnull dsapubfree(dsa);
864 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: cannot sign key type %s\n", s);
865 ce94dbe6 2005-02-13 devnull werrstr("unknown key type %s", s);
866 ce94dbe6 2005-02-13 devnull return -1;
869 ce94dbe6 2005-02-13 devnull if((rpc = auth_allocrpc()) == nil){
870 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth_allocrpc: %r\n");
871 ce94dbe6 2005-02-13 devnull return -1;
873 ce94dbe6 2005-02-13 devnull if(chatty)
874 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: start %s\n", buf);
875 ce94dbe6 2005-02-13 devnull if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
876 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth 'start' failed: %r\n");
878 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
879 ce94dbe6 2005-02-13 devnull return -1;
881 ce94dbe6 2005-02-13 devnull sha1(mdata->bp, mdata->ep-mdata->bp, digest, nil);
882 ce94dbe6 2005-02-13 devnull if(auth_rpc(rpc, "write", digest, SHA1dlen) != ARok){
883 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth 'write in sign failed: %r\n");
884 ce94dbe6 2005-02-13 devnull goto Die;
886 ce94dbe6 2005-02-13 devnull if(auth_rpc(rpc, "read", nil, 0) != ARok){
887 ce94dbe6 2005-02-13 devnull fprint(2, "ssh-agent: auth 'read' failed: %r\n");
888 ce94dbe6 2005-02-13 devnull goto Die;
890 ce94dbe6 2005-02-13 devnull newmsg(msig);
891 ce94dbe6 2005-02-13 devnull putstr(msig, s);
892 ce94dbe6 2005-02-13 devnull put4(msig, rpc->narg);
893 ce94dbe6 2005-02-13 devnull putn(msig, rpc->arg, rpc->narg);
894 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
895 ce94dbe6 2005-02-13 devnull return 0;
899 ce94dbe6 2005-02-13 devnull runmsg(Aconn *a)
901 ce94dbe6 2005-02-13 devnull char *p;
902 ce94dbe6 2005-02-13 devnull int n, nk, type, rt, vers;
903 ce94dbe6 2005-02-13 devnull mpint *ek, *mod, *chal;
904 ce94dbe6 2005-02-13 devnull uchar sessid[16], chalbuf[32], digest[MD5dlen];
905 ce94dbe6 2005-02-13 devnull uint len, flags;
906 ce94dbe6 2005-02-13 devnull DigestState *s;
907 ce94dbe6 2005-02-13 devnull Msg m, mkey, mdata, msig;
909 ce94dbe6 2005-02-13 devnull if(a->ndata < 4)
910 ce94dbe6 2005-02-13 devnull return 0;
911 ce94dbe6 2005-02-13 devnull len = (a->data[0]<<24)|(a->data[1]<<16)|(a->data[2]<<8)|a->data[3];
912 ce94dbe6 2005-02-13 devnull if(a->ndata < 4+len)
913 ce94dbe6 2005-02-13 devnull return 0;
914 ce94dbe6 2005-02-13 devnull m.p = a->data+4;
915 ce94dbe6 2005-02-13 devnull m.ep = m.p+len;
916 ce94dbe6 2005-02-13 devnull type = get1(&m);
917 ce94dbe6 2005-02-13 devnull if(chatty)
918 ce94dbe6 2005-02-13 devnull fprint(2, "msg %d: %.*H\n", type, len, m.p);
919 ce94dbe6 2005-02-13 devnull switch(type){
920 ce94dbe6 2005-02-13 devnull default:
921 ce94dbe6 2005-02-13 devnull Failure:
922 ce94dbe6 2005-02-13 devnull newreply(&m, SSH_AGENT_FAILURE);
923 ce94dbe6 2005-02-13 devnull reply(a, &m);
926 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
927 ce94dbe6 2005-02-13 devnull vers = 1;
928 ce94dbe6 2005-02-13 devnull newreply(&m, SSH_AGENT_RSA_IDENTITIES_ANSWER);
929 ce94dbe6 2005-02-13 devnull goto Identities;
930 ce94dbe6 2005-02-13 devnull case SSH2_AGENTC_REQUEST_IDENTITIES:
931 ce94dbe6 2005-02-13 devnull vers = 2;
932 ce94dbe6 2005-02-13 devnull newreply(&m, SSH2_AGENT_IDENTITIES_ANSWER);
933 ce94dbe6 2005-02-13 devnull Identities:
934 ce94dbe6 2005-02-13 devnull nk = listkeys(&m, vers);
935 ce94dbe6 2005-02-13 devnull if(nk < 0){
936 ce94dbe6 2005-02-13 devnull free(m.bp);
937 ce94dbe6 2005-02-13 devnull goto Failure;
939 ce94dbe6 2005-02-13 devnull if(chatty)
940 ce94dbe6 2005-02-13 devnull fprint(2, "request identities\n", nk);
941 ce94dbe6 2005-02-13 devnull reply(a, &m);
944 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_RSA_CHALLENGE:
945 ce94dbe6 2005-02-13 devnull n = get4(&m);
946 ce94dbe6 2005-02-13 devnull ek = getmp(&m);
947 ce94dbe6 2005-02-13 devnull mod = getmp(&m);
948 ce94dbe6 2005-02-13 devnull chal = getmp(&m);
949 ce94dbe6 2005-02-13 devnull if((p = getn(&m, 16)) == nil){
950 ce94dbe6 2005-02-13 devnull Failchal:
951 ce94dbe6 2005-02-13 devnull mpfree(ek);
952 ce94dbe6 2005-02-13 devnull mpfree(mod);
953 ce94dbe6 2005-02-13 devnull mpfree(chal);
954 ce94dbe6 2005-02-13 devnull goto Failure;
956 ce94dbe6 2005-02-13 devnull memmove(sessid, p, 16);
957 ce94dbe6 2005-02-13 devnull rt = get4(&m);
958 ce94dbe6 2005-02-13 devnull if(rt != 1 || dorsa(a, mod, ek, chal, chalbuf) < 0)
959 ce94dbe6 2005-02-13 devnull goto Failchal;
960 ce94dbe6 2005-02-13 devnull s = md5(chalbuf, 32, nil, nil);
961 ce94dbe6 2005-02-13 devnull if(s == nil)
962 ce94dbe6 2005-02-13 devnull goto Failchal;
963 ce94dbe6 2005-02-13 devnull md5(sessid, 16, digest, s);
964 e1a22963 2005-02-13 devnull print("md5 %.*H %.*H => %.*H\n", 32, chalbuf, 16, sessid, MD5dlen, digest);
966 ce94dbe6 2005-02-13 devnull newreply(&m, SSH_AGENT_RSA_RESPONSE);
967 ce94dbe6 2005-02-13 devnull putn(&m, digest, 16);
968 ce94dbe6 2005-02-13 devnull reply(a, &m);
970 ce94dbe6 2005-02-13 devnull mpfree(ek);
971 ce94dbe6 2005-02-13 devnull mpfree(mod);
972 ce94dbe6 2005-02-13 devnull mpfree(chal);
975 ce94dbe6 2005-02-13 devnull case SSH2_AGENTC_SIGN_REQUEST:
976 ce94dbe6 2005-02-13 devnull if(getm(&m, &mkey) < 0
977 ce94dbe6 2005-02-13 devnull || getm(&m, &mdata) < 0)
978 ce94dbe6 2005-02-13 devnull goto Failure;
979 ce94dbe6 2005-02-13 devnull flags = get4(&m);
980 ce94dbe6 2005-02-13 devnull if(flags & SSH_AGENT_OLD_SIGNATURE)
981 ce94dbe6 2005-02-13 devnull goto Failure;
982 ce94dbe6 2005-02-13 devnull if(keysign(&mkey, &mdata, &msig) < 0)
983 ce94dbe6 2005-02-13 devnull goto Failure;
984 ce94dbe6 2005-02-13 devnull if(chatty)
985 ce94dbe6 2005-02-13 devnull fprint(2, "signature: %.*H\n",
986 ce94dbe6 2005-02-13 devnull msig.p-msig.bp, msig.bp);
987 ce94dbe6 2005-02-13 devnull newreply(&m, SSH2_AGENT_SIGN_RESPONSE);
988 ce94dbe6 2005-02-13 devnull putm(&m, &msig);
989 ce94dbe6 2005-02-13 devnull free(msig.bp);
990 ce94dbe6 2005-02-13 devnull reply(a, &m);
993 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_ADD_RSA_IDENTITY:
995 ce94dbe6 2005-02-13 devnull msg: n[4] mod[mp] pubexp[exp] privexp[mp]
996 ce94dbe6 2005-02-13 devnull p^-1 mod q[mp] p[mp] q[mp] comment[str]
998 ce94dbe6 2005-02-13 devnull goto Failure;
1000 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_REMOVE_RSA_IDENTITY:
1002 ce94dbe6 2005-02-13 devnull msg: n[4] mod[mp] pubexp[mp]
1004 ce94dbe6 2005-02-13 devnull goto Failure;
1008 ce94dbe6 2005-02-13 devnull a->ndata -= 4+len;
1009 ce94dbe6 2005-02-13 devnull memmove(a->data, a->data+4+len, a->ndata);
1010 ce94dbe6 2005-02-13 devnull return 1;
1014 ce94dbe6 2005-02-13 devnull emalloc(int n)
1016 ce94dbe6 2005-02-13 devnull void *v;
1018 ce94dbe6 2005-02-13 devnull v = mallocz(n, 1);
1019 ce94dbe6 2005-02-13 devnull if(v == nil){
1020 ce94dbe6 2005-02-13 devnull abort();
1021 ce94dbe6 2005-02-13 devnull sysfatal("out of memory allocating %d", n);
1023 ce94dbe6 2005-02-13 devnull return v;
1027 ce94dbe6 2005-02-13 devnull erealloc(void *v, int n)
1029 ce94dbe6 2005-02-13 devnull v = realloc(v, n);
1030 ce94dbe6 2005-02-13 devnull if(v == nil){
1031 ce94dbe6 2005-02-13 devnull abort();
1032 ce94dbe6 2005-02-13 devnull sysfatal("out of memory reallocating %d", n);
1034 ce94dbe6 2005-02-13 devnull return v;