Blame


1 ce94dbe6 2005-02-13 devnull /*
2 ce94dbe6 2005-02-13 devnull * Present factotum in ssh agent clothing.
3 ce94dbe6 2005-02-13 devnull */
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>
11 ce94dbe6 2005-02-13 devnull
12 ce94dbe6 2005-02-13 devnull enum
13 ce94dbe6 2005-02-13 devnull {
14 ce94dbe6 2005-02-13 devnull STACK = 65536
15 ce94dbe6 2005-02-13 devnull };
16 ce94dbe6 2005-02-13 devnull enum /* agent protocol packet types */
17 ce94dbe6 2005-02-13 devnull {
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,
28 ce94dbe6 2005-02-13 devnull
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,
33 ce94dbe6 2005-02-13 devnull
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,
39 ce94dbe6 2005-02-13 devnull
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,
45 ce94dbe6 2005-02-13 devnull
46 ce94dbe6 2005-02-13 devnull SSH_AGENT_CONSTRAIN_LIFETIME = 1,
47 ce94dbe6 2005-02-13 devnull SSH_AGENT_CONSTRAIN_CONFIRM = 2,
48 ce94dbe6 2005-02-13 devnull
49 ce94dbe6 2005-02-13 devnull SSH2_AGENT_FAILURE = 30,
50 ce94dbe6 2005-02-13 devnull
51 ce94dbe6 2005-02-13 devnull SSH_COM_AGENT2_FAILURE = 102,
52 ce94dbe6 2005-02-13 devnull SSH_AGENT_OLD_SIGNATURE = 0x01,
53 ce94dbe6 2005-02-13 devnull };
54 ce94dbe6 2005-02-13 devnull
55 ce94dbe6 2005-02-13 devnull typedef struct Aconn Aconn;
56 ce94dbe6 2005-02-13 devnull struct Aconn
57 ce94dbe6 2005-02-13 devnull {
58 ce94dbe6 2005-02-13 devnull uchar *data;
59 ce94dbe6 2005-02-13 devnull uint ndata;
60 ce94dbe6 2005-02-13 devnull int ctl;
61 ce94dbe6 2005-02-13 devnull int fd;
62 ce94dbe6 2005-02-13 devnull char dir[40];
63 ce94dbe6 2005-02-13 devnull };
64 ce94dbe6 2005-02-13 devnull
65 ce94dbe6 2005-02-13 devnull typedef struct Msg Msg;
66 ce94dbe6 2005-02-13 devnull struct Msg
67 ce94dbe6 2005-02-13 devnull {
68 ce94dbe6 2005-02-13 devnull uchar *bp;
69 ce94dbe6 2005-02-13 devnull uchar *p;
70 ce94dbe6 2005-02-13 devnull uchar *ep;
71 ce94dbe6 2005-02-13 devnull };
72 ce94dbe6 2005-02-13 devnull
73 ce94dbe6 2005-02-13 devnull char adir[40];
74 ce94dbe6 2005-02-13 devnull int afd;
75 ce94dbe6 2005-02-13 devnull int chatty;
76 ce94dbe6 2005-02-13 devnull char *factotum = "factotum";
77 ce94dbe6 2005-02-13 devnull
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);
84 ce94dbe6 2005-02-13 devnull
85 ce94dbe6 2005-02-13 devnull void
86 ce94dbe6 2005-02-13 devnull usage(void)
87 ce94dbe6 2005-02-13 devnull {
88 ce94dbe6 2005-02-13 devnull fprint(2, "usage: 9 ssh-agent [-D] [factotum]\n");
89 ce94dbe6 2005-02-13 devnull threadexitsall("usage");
90 ce94dbe6 2005-02-13 devnull }
91 ce94dbe6 2005-02-13 devnull
92 ce94dbe6 2005-02-13 devnull void
93 ce94dbe6 2005-02-13 devnull threadmain(int argc, char **argv)
94 ce94dbe6 2005-02-13 devnull {
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;
99 ce94dbe6 2005-02-13 devnull
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);
106 e1a22963 2005-02-13 devnull
107 ce94dbe6 2005-02-13 devnull ARGBEGIN{
108 e1a22963 2005-02-13 devnull case '9':
109 e1a22963 2005-02-13 devnull chatty9pclient++;
110 e1a22963 2005-02-13 devnull break;
111 ce94dbe6 2005-02-13 devnull case 'D':
112 ce94dbe6 2005-02-13 devnull chatty++;
113 ce94dbe6 2005-02-13 devnull break;
114 ce94dbe6 2005-02-13 devnull case 'e':
115 ce94dbe6 2005-02-13 devnull export = 1;
116 ce94dbe6 2005-02-13 devnull break;
117 ce94dbe6 2005-02-13 devnull case 'l':
118 ce94dbe6 2005-02-13 devnull dotextlist = 1;
119 ce94dbe6 2005-02-13 devnull break;
120 ce94dbe6 2005-02-13 devnull default:
121 ce94dbe6 2005-02-13 devnull usage();
122 ce94dbe6 2005-02-13 devnull }ARGEND
123 ce94dbe6 2005-02-13 devnull
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];
128 ce94dbe6 2005-02-13 devnull
129 ce94dbe6 2005-02-13 devnull if(dotextlist)
130 ce94dbe6 2005-02-13 devnull listkeystext();
131 ce94dbe6 2005-02-13 devnull
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);
140 ce94dbe6 2005-02-13 devnull
141 ce94dbe6 2005-02-13 devnull if((afd = announce(addr, adir)) < 0)
142 ce94dbe6 2005-02-13 devnull sysfatal("announce %s: %r", addr);
143 ce94dbe6 2005-02-13 devnull
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);
154 ce94dbe6 2005-02-13 devnull }
155 ce94dbe6 2005-02-13 devnull
156 ce94dbe6 2005-02-13 devnull void
157 ce94dbe6 2005-02-13 devnull listenproc(void *v)
158 ce94dbe6 2005-02-13 devnull {
159 ce94dbe6 2005-02-13 devnull Aconn *a;
160 ce94dbe6 2005-02-13 devnull
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);
168 ce94dbe6 2005-02-13 devnull }
169 ce94dbe6 2005-02-13 devnull }
170 ce94dbe6 2005-02-13 devnull
171 ce94dbe6 2005-02-13 devnull void
172 ce94dbe6 2005-02-13 devnull agentproc(void *v)
173 ce94dbe6 2005-02-13 devnull {
174 ce94dbe6 2005-02-13 devnull Aconn *a;
175 ce94dbe6 2005-02-13 devnull int n;
176 ce94dbe6 2005-02-13 devnull
177 ce94dbe6 2005-02-13 devnull a = v;
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)
185 ce94dbe6 2005-02-13 devnull break;
186 ce94dbe6 2005-02-13 devnull a->ndata += n;
187 ce94dbe6 2005-02-13 devnull while(runmsg(a))
188 ce94dbe6 2005-02-13 devnull ;
189 ce94dbe6 2005-02-13 devnull }
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);
193 ce94dbe6 2005-02-13 devnull }
194 ce94dbe6 2005-02-13 devnull
195 ce94dbe6 2005-02-13 devnull int
196 ce94dbe6 2005-02-13 devnull get1(Msg *m)
197 ce94dbe6 2005-02-13 devnull {
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++;
201 ce94dbe6 2005-02-13 devnull }
202 ce94dbe6 2005-02-13 devnull
203 ce94dbe6 2005-02-13 devnull int
204 ce94dbe6 2005-02-13 devnull get2(Msg *m)
205 ce94dbe6 2005-02-13 devnull {
206 ce94dbe6 2005-02-13 devnull uint x;
207 ce94dbe6 2005-02-13 devnull
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;
213 ce94dbe6 2005-02-13 devnull }
214 ce94dbe6 2005-02-13 devnull
215 ce94dbe6 2005-02-13 devnull int
216 ce94dbe6 2005-02-13 devnull get4(Msg *m)
217 ce94dbe6 2005-02-13 devnull {
218 ce94dbe6 2005-02-13 devnull uint x;
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;
224 ce94dbe6 2005-02-13 devnull }
225 ce94dbe6 2005-02-13 devnull
226 ce94dbe6 2005-02-13 devnull uchar*
227 ce94dbe6 2005-02-13 devnull getn(Msg *m, uint n)
228 ce94dbe6 2005-02-13 devnull {
229 ce94dbe6 2005-02-13 devnull uchar *p;
230 ce94dbe6 2005-02-13 devnull
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;
236 ce94dbe6 2005-02-13 devnull }
237 ce94dbe6 2005-02-13 devnull
238 ce94dbe6 2005-02-13 devnull char*
239 ce94dbe6 2005-02-13 devnull getstr(Msg *m)
240 ce94dbe6 2005-02-13 devnull {
241 ce94dbe6 2005-02-13 devnull uint n;
242 ce94dbe6 2005-02-13 devnull uchar *p;
243 ce94dbe6 2005-02-13 devnull
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;
248 ce94dbe6 2005-02-13 devnull p--;
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;
252 ce94dbe6 2005-02-13 devnull }
253 ce94dbe6 2005-02-13 devnull
254 ce94dbe6 2005-02-13 devnull mpint*
255 ce94dbe6 2005-02-13 devnull getmp(Msg *m)
256 ce94dbe6 2005-02-13 devnull {
257 ce94dbe6 2005-02-13 devnull int n;
258 ce94dbe6 2005-02-13 devnull uchar *p;
259 ce94dbe6 2005-02-13 devnull
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);
264 ce94dbe6 2005-02-13 devnull }
265 ce94dbe6 2005-02-13 devnull
266 ce94dbe6 2005-02-13 devnull mpint*
267 ce94dbe6 2005-02-13 devnull getmp2(Msg *m)
268 ce94dbe6 2005-02-13 devnull {
269 ce94dbe6 2005-02-13 devnull int n;
270 ce94dbe6 2005-02-13 devnull uchar *p;
271 ce94dbe6 2005-02-13 devnull
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);
276 ce94dbe6 2005-02-13 devnull }
277 ce94dbe6 2005-02-13 devnull
278 ce94dbe6 2005-02-13 devnull Msg*
279 ce94dbe6 2005-02-13 devnull getm(Msg *m, Msg *mm)
280 ce94dbe6 2005-02-13 devnull {
281 ce94dbe6 2005-02-13 devnull uint n;
282 ce94dbe6 2005-02-13 devnull uchar *p;
283 ce94dbe6 2005-02-13 devnull
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;
291 ce94dbe6 2005-02-13 devnull }
292 ce94dbe6 2005-02-13 devnull
293 ce94dbe6 2005-02-13 devnull uchar*
294 ce94dbe6 2005-02-13 devnull ensure(Msg *m, int n)
295 ce94dbe6 2005-02-13 devnull {
296 ce94dbe6 2005-02-13 devnull int len, plen;
297 ce94dbe6 2005-02-13 devnull uchar *p;
298 ce94dbe6 2005-02-13 devnull
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;
305 ce94dbe6 2005-02-13 devnull }
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;
309 ce94dbe6 2005-02-13 devnull }
310 ce94dbe6 2005-02-13 devnull
311 ce94dbe6 2005-02-13 devnull void
312 ce94dbe6 2005-02-13 devnull put4(Msg *m, uint n)
313 ce94dbe6 2005-02-13 devnull {
314 ce94dbe6 2005-02-13 devnull uchar *p;
315 ce94dbe6 2005-02-13 devnull
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;
321 ce94dbe6 2005-02-13 devnull }
322 ce94dbe6 2005-02-13 devnull
323 ce94dbe6 2005-02-13 devnull void
324 ce94dbe6 2005-02-13 devnull put2(Msg *m, uint n)
325 ce94dbe6 2005-02-13 devnull {
326 ce94dbe6 2005-02-13 devnull uchar *p;
327 ce94dbe6 2005-02-13 devnull
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;
331 ce94dbe6 2005-02-13 devnull }
332 ce94dbe6 2005-02-13 devnull
333 ce94dbe6 2005-02-13 devnull void
334 ce94dbe6 2005-02-13 devnull put1(Msg *m, uint n)
335 ce94dbe6 2005-02-13 devnull {
336 ce94dbe6 2005-02-13 devnull uchar *p;
337 ce94dbe6 2005-02-13 devnull
338 ce94dbe6 2005-02-13 devnull p = ensure(m, 1);
339 ce94dbe6 2005-02-13 devnull p[0] = n&0xFF;
340 ce94dbe6 2005-02-13 devnull }
341 ce94dbe6 2005-02-13 devnull
342 ce94dbe6 2005-02-13 devnull void
343 ce94dbe6 2005-02-13 devnull putn(Msg *m, void *a, uint n)
344 ce94dbe6 2005-02-13 devnull {
345 ce94dbe6 2005-02-13 devnull uchar *p;
346 ce94dbe6 2005-02-13 devnull
347 ce94dbe6 2005-02-13 devnull p = ensure(m, n);
348 ce94dbe6 2005-02-13 devnull memmove(p, a, n);
349 ce94dbe6 2005-02-13 devnull }
350 ce94dbe6 2005-02-13 devnull
351 ce94dbe6 2005-02-13 devnull void
352 ce94dbe6 2005-02-13 devnull putmp(Msg *m, mpint *b)
353 ce94dbe6 2005-02-13 devnull {
354 ce94dbe6 2005-02-13 devnull int bits, n;
355 ce94dbe6 2005-02-13 devnull uchar *p;
356 ce94dbe6 2005-02-13 devnull
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);
362 ce94dbe6 2005-02-13 devnull }
363 ce94dbe6 2005-02-13 devnull
364 ce94dbe6 2005-02-13 devnull void
365 ce94dbe6 2005-02-13 devnull putmp2(Msg *m, mpint *b)
366 ce94dbe6 2005-02-13 devnull {
367 ce94dbe6 2005-02-13 devnull int bits, n;
368 ce94dbe6 2005-02-13 devnull uchar *p;
369 ce94dbe6 2005-02-13 devnull
370 ce94dbe6 2005-02-13 devnull if(mpcmp(b, mpzero) == 0){
371 ce94dbe6 2005-02-13 devnull put4(m, 0);
372 ce94dbe6 2005-02-13 devnull return;
373 ce94dbe6 2005-02-13 devnull }
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);
379 ce94dbe6 2005-02-13 devnull }else
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);
383 ce94dbe6 2005-02-13 devnull }
384 ce94dbe6 2005-02-13 devnull
385 ce94dbe6 2005-02-13 devnull void
386 ce94dbe6 2005-02-13 devnull putstr(Msg *m, char *s)
387 ce94dbe6 2005-02-13 devnull {
388 ce94dbe6 2005-02-13 devnull int n;
389 ce94dbe6 2005-02-13 devnull
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);
393 ce94dbe6 2005-02-13 devnull }
394 ce94dbe6 2005-02-13 devnull
395 ce94dbe6 2005-02-13 devnull void
396 ce94dbe6 2005-02-13 devnull putm(Msg *m, Msg *mm)
397 ce94dbe6 2005-02-13 devnull {
398 ce94dbe6 2005-02-13 devnull uint n;
399 ce94dbe6 2005-02-13 devnull
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);
403 ce94dbe6 2005-02-13 devnull }
404 ce94dbe6 2005-02-13 devnull
405 ce94dbe6 2005-02-13 devnull void
406 ce94dbe6 2005-02-13 devnull newmsg(Msg *m)
407 ce94dbe6 2005-02-13 devnull {
408 ce94dbe6 2005-02-13 devnull memset(m, 0, sizeof *m);
409 ce94dbe6 2005-02-13 devnull }
410 ce94dbe6 2005-02-13 devnull
411 ce94dbe6 2005-02-13 devnull void
412 ce94dbe6 2005-02-13 devnull newreply(Msg *m, int type)
413 ce94dbe6 2005-02-13 devnull {
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);
417 ce94dbe6 2005-02-13 devnull }
418 ce94dbe6 2005-02-13 devnull
419 ce94dbe6 2005-02-13 devnull void
420 ce94dbe6 2005-02-13 devnull reply(Aconn *a, Msg *m)
421 ce94dbe6 2005-02-13 devnull {
422 ce94dbe6 2005-02-13 devnull uint n;
423 ce94dbe6 2005-02-13 devnull uchar *p;
424 ce94dbe6 2005-02-13 devnull
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);
436 ce94dbe6 2005-02-13 devnull }
437 ce94dbe6 2005-02-13 devnull
438 ce94dbe6 2005-02-13 devnull typedef struct Key Key;
439 ce94dbe6 2005-02-13 devnull struct Key
440 ce94dbe6 2005-02-13 devnull {
441 ce94dbe6 2005-02-13 devnull mpint *mod;
442 ce94dbe6 2005-02-13 devnull mpint *ek;
443 ce94dbe6 2005-02-13 devnull char *comment;
444 ce94dbe6 2005-02-13 devnull };
445 ce94dbe6 2005-02-13 devnull
446 ce94dbe6 2005-02-13 devnull static char*
447 ce94dbe6 2005-02-13 devnull find(char **f, int nf, char *k)
448 ce94dbe6 2005-02-13 devnull {
449 ce94dbe6 2005-02-13 devnull int i, len;
450 ce94dbe6 2005-02-13 devnull
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;
456 ce94dbe6 2005-02-13 devnull }
457 ce94dbe6 2005-02-13 devnull
458 ce94dbe6 2005-02-13 devnull static int
459 ce94dbe6 2005-02-13 devnull putrsa1(Msg *m, char **f, int nf)
460 ce94dbe6 2005-02-13 devnull {
461 ce94dbe6 2005-02-13 devnull char *p;
462 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
463 ce94dbe6 2005-02-13 devnull
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;
471 ce94dbe6 2005-02-13 devnull }
472 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
473 ce94dbe6 2005-02-13 devnull if(p == nil)
474 ce94dbe6 2005-02-13 devnull p = "";
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;
482 ce94dbe6 2005-02-13 devnull }
483 ce94dbe6 2005-02-13 devnull
484 ce94dbe6 2005-02-13 devnull void
485 ce94dbe6 2005-02-13 devnull printattr(char **f, int nf)
486 ce94dbe6 2005-02-13 devnull {
487 ce94dbe6 2005-02-13 devnull int i;
488 ce94dbe6 2005-02-13 devnull
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");
493 ce94dbe6 2005-02-13 devnull }
494 ce94dbe6 2005-02-13 devnull
495 ce94dbe6 2005-02-13 devnull void
496 ce94dbe6 2005-02-13 devnull printrsa1(char **f, int nf)
497 ce94dbe6 2005-02-13 devnull {
498 ce94dbe6 2005-02-13 devnull char *p;
499 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
500 ce94dbe6 2005-02-13 devnull
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)
503 ce94dbe6 2005-02-13 devnull return;
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);
507 ce94dbe6 2005-02-13 devnull return;
508 ce94dbe6 2005-02-13 devnull }
509 ce94dbe6 2005-02-13 devnull p = find(f, nf, "comment");
510 ce94dbe6 2005-02-13 devnull if(p == nil)
511 ce94dbe6 2005-02-13 devnull p = "";
512 ce94dbe6 2005-02-13 devnull
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);
518 ce94dbe6 2005-02-13 devnull }
519 ce94dbe6 2005-02-13 devnull
520 ce94dbe6 2005-02-13 devnull static int
521 ce94dbe6 2005-02-13 devnull putrsa(Msg *m, char **f, int nf)
522 ce94dbe6 2005-02-13 devnull {
523 ce94dbe6 2005-02-13 devnull char *p;
524 ce94dbe6 2005-02-13 devnull mpint *mod, *ek;
525 ce94dbe6 2005-02-13 devnull
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;
533 ce94dbe6 2005-02-13 devnull }
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;
540 ce94dbe6 2005-02-13 devnull }
541 ce94dbe6 2005-02-13 devnull
542 ce94dbe6 2005-02-13 devnull RSApub*
543 ce94dbe6 2005-02-13 devnull getrsapub(Msg *m)
544 ce94dbe6 2005-02-13 devnull {
545 ce94dbe6 2005-02-13 devnull RSApub *k;
546 ce94dbe6 2005-02-13 devnull
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;
555 ce94dbe6 2005-02-13 devnull }
556 ce94dbe6 2005-02-13 devnull return k;
557 ce94dbe6 2005-02-13 devnull }
558 ce94dbe6 2005-02-13 devnull
559 ce94dbe6 2005-02-13 devnull static int
560 ce94dbe6 2005-02-13 devnull putdsa(Msg *m, char **f, int nf)
561 ce94dbe6 2005-02-13 devnull {
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;
565 ce94dbe6 2005-02-13 devnull
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;
586 ce94dbe6 2005-02-13 devnull out:
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;
592 ce94dbe6 2005-02-13 devnull }
593 ce94dbe6 2005-02-13 devnull
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)
596 ce94dbe6 2005-02-13 devnull {
597 ce94dbe6 2005-02-13 devnull char *p;
598 ce94dbe6 2005-02-13 devnull Msg mm;
599 ce94dbe6 2005-02-13 devnull
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)
607 ce94dbe6 2005-02-13 devnull p = "";
608 ce94dbe6 2005-02-13 devnull putstr(m, p);
609 ce94dbe6 2005-02-13 devnull return 0;
610 ce94dbe6 2005-02-13 devnull }
611 ce94dbe6 2005-02-13 devnull
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)
614 ce94dbe6 2005-02-13 devnull {
615 ce94dbe6 2005-02-13 devnull Msg m;
616 ce94dbe6 2005-02-13 devnull char *p;
617 ce94dbe6 2005-02-13 devnull
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)
623 ce94dbe6 2005-02-13 devnull p = "";
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;
629 ce94dbe6 2005-02-13 devnull }
630 ce94dbe6 2005-02-13 devnull
631 ce94dbe6 2005-02-13 devnull DSApub*
632 ce94dbe6 2005-02-13 devnull getdsapub(Msg *m)
633 ce94dbe6 2005-02-13 devnull {
634 ce94dbe6 2005-02-13 devnull DSApub *k;
635 ce94dbe6 2005-02-13 devnull
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;
646 ce94dbe6 2005-02-13 devnull }
647 ce94dbe6 2005-02-13 devnull return k;
648 ce94dbe6 2005-02-13 devnull }
649 ce94dbe6 2005-02-13 devnull
650 ce94dbe6 2005-02-13 devnull static int
651 ce94dbe6 2005-02-13 devnull listkeys(Msg *m, int version)
652 ce94dbe6 2005-02-13 devnull {
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;
657 ce94dbe6 2005-02-13 devnull
658 ce94dbe6 2005-02-13 devnull nk = 0;
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;
664 ce94dbe6 2005-02-13 devnull }
665 ce94dbe6 2005-02-13 devnull for(;;){
666 ce94dbe6 2005-02-13 devnull if((n = fsread(fid, buf, sizeof buf-1)) <= 0)
667 ce94dbe6 2005-02-13 devnull break;
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;
680 ce94dbe6 2005-02-13 devnull
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)
683 ce94dbe6 2005-02-13 devnull nk++;
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)
686 ce94dbe6 2005-02-13 devnull nk++;
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)
689 ce94dbe6 2005-02-13 devnull nk++;
690 ce94dbe6 2005-02-13 devnull }
691 ce94dbe6 2005-02-13 devnull }
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;
698 ce94dbe6 2005-02-13 devnull }
699 ce94dbe6 2005-02-13 devnull
700 ce94dbe6 2005-02-13 devnull void
701 ce94dbe6 2005-02-13 devnull listkeystext(void)
702 ce94dbe6 2005-02-13 devnull {
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;
706 ce94dbe6 2005-02-13 devnull
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");
709 ce94dbe6 2005-02-13 devnull return;
710 ce94dbe6 2005-02-13 devnull }
711 ce94dbe6 2005-02-13 devnull for(;;){
712 ce94dbe6 2005-02-13 devnull if((n = fsread(fid, buf, sizeof buf-1)) <= 0)
713 ce94dbe6 2005-02-13 devnull break;
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;
726 ce94dbe6 2005-02-13 devnull
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);
733 ce94dbe6 2005-02-13 devnull }
734 ce94dbe6 2005-02-13 devnull }
735 ce94dbe6 2005-02-13 devnull fsclose(fid);
736 ce94dbe6 2005-02-13 devnull threadexitsall(nil);
737 ce94dbe6 2005-02-13 devnull }
738 ce94dbe6 2005-02-13 devnull
739 ce94dbe6 2005-02-13 devnull mpint*
740 ce94dbe6 2005-02-13 devnull rsaunpad(mpint *b)
741 ce94dbe6 2005-02-13 devnull {
742 ce94dbe6 2005-02-13 devnull int i, n;
743 ce94dbe6 2005-02-13 devnull uchar buf[2560];
744 ce94dbe6 2005-02-13 devnull
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;
749 ce94dbe6 2005-02-13 devnull }
750 ce94dbe6 2005-02-13 devnull mptobe(b, buf, n, nil);
751 ce94dbe6 2005-02-13 devnull
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;
756 ce94dbe6 2005-02-13 devnull }
757 ce94dbe6 2005-02-13 devnull for(i=1; i<n; i++)
758 ce94dbe6 2005-02-13 devnull if(buf[i]==0)
759 ce94dbe6 2005-02-13 devnull break;
760 ce94dbe6 2005-02-13 devnull return betomp(buf+i, n-i, nil);
761 ce94dbe6 2005-02-13 devnull }
762 ce94dbe6 2005-02-13 devnull
763 ce94dbe6 2005-02-13 devnull void
764 ce94dbe6 2005-02-13 devnull mptoberjust(mpint *b, uchar *buf, int len)
765 ce94dbe6 2005-02-13 devnull {
766 ce94dbe6 2005-02-13 devnull int n;
767 ce94dbe6 2005-02-13 devnull
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);
774 ce94dbe6 2005-02-13 devnull }
775 ce94dbe6 2005-02-13 devnull }
776 ce94dbe6 2005-02-13 devnull
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])
779 ce94dbe6 2005-02-13 devnull {
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;
783 ce94dbe6 2005-02-13 devnull
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;
788 ce94dbe6 2005-02-13 devnull }
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");
794 ce94dbe6 2005-02-13 devnull Die:
795 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
796 ce94dbe6 2005-02-13 devnull return -1;
797 ce94dbe6 2005-02-13 devnull }
798 ce94dbe6 2005-02-13 devnull
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;
803 ce94dbe6 2005-02-13 devnull }
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;
810 ce94dbe6 2005-02-13 devnull }
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;
815 ce94dbe6 2005-02-13 devnull }
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;
822 ce94dbe6 2005-02-13 devnull }
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;
830 ce94dbe6 2005-02-13 devnull }
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;
836 ce94dbe6 2005-02-13 devnull }
837 ce94dbe6 2005-02-13 devnull
838 ce94dbe6 2005-02-13 devnull int
839 ce94dbe6 2005-02-13 devnull keysign(Msg *mkey, Msg *mdata, Msg *msig)
840 ce94dbe6 2005-02-13 devnull {
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];
847 ce94dbe6 2005-02-13 devnull
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);
863 ce94dbe6 2005-02-13 devnull }else{
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;
867 ce94dbe6 2005-02-13 devnull }
868 ce94dbe6 2005-02-13 devnull
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;
872 ce94dbe6 2005-02-13 devnull }
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");
877 ce94dbe6 2005-02-13 devnull Die:
878 ce94dbe6 2005-02-13 devnull auth_freerpc(rpc);
879 ce94dbe6 2005-02-13 devnull return -1;
880 ce94dbe6 2005-02-13 devnull }
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;
885 ce94dbe6 2005-02-13 devnull }
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;
889 ce94dbe6 2005-02-13 devnull }
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;
896 ce94dbe6 2005-02-13 devnull }
897 ce94dbe6 2005-02-13 devnull
898 ce94dbe6 2005-02-13 devnull int
899 ce94dbe6 2005-02-13 devnull runmsg(Aconn *a)
900 ce94dbe6 2005-02-13 devnull {
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;
908 ce94dbe6 2005-02-13 devnull
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);
924 ce94dbe6 2005-02-13 devnull break;
925 ce94dbe6 2005-02-13 devnull
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;
938 ce94dbe6 2005-02-13 devnull }
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);
942 ce94dbe6 2005-02-13 devnull break;
943 ce94dbe6 2005-02-13 devnull
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;
955 ce94dbe6 2005-02-13 devnull }
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);
965 ce94dbe6 2005-02-13 devnull
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);
969 ce94dbe6 2005-02-13 devnull
970 ce94dbe6 2005-02-13 devnull mpfree(ek);
971 ce94dbe6 2005-02-13 devnull mpfree(mod);
972 ce94dbe6 2005-02-13 devnull mpfree(chal);
973 ce94dbe6 2005-02-13 devnull break;
974 ce94dbe6 2005-02-13 devnull
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);
991 ce94dbe6 2005-02-13 devnull break;
992 ce94dbe6 2005-02-13 devnull
993 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_ADD_RSA_IDENTITY:
994 ce94dbe6 2005-02-13 devnull /*
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]
997 ce94dbe6 2005-02-13 devnull */
998 ce94dbe6 2005-02-13 devnull goto Failure;
999 ce94dbe6 2005-02-13 devnull
1000 ce94dbe6 2005-02-13 devnull case SSH_AGENTC_REMOVE_RSA_IDENTITY:
1001 ce94dbe6 2005-02-13 devnull /*
1002 ce94dbe6 2005-02-13 devnull msg: n[4] mod[mp] pubexp[mp]
1003 ce94dbe6 2005-02-13 devnull */
1004 ce94dbe6 2005-02-13 devnull goto Failure;
1005 ce94dbe6 2005-02-13 devnull
1006 ce94dbe6 2005-02-13 devnull }
1007 ce94dbe6 2005-02-13 devnull
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;
1011 ce94dbe6 2005-02-13 devnull }
1012 ce94dbe6 2005-02-13 devnull
1013 ce94dbe6 2005-02-13 devnull void*
1014 ce94dbe6 2005-02-13 devnull emalloc(int n)
1015 ce94dbe6 2005-02-13 devnull {
1016 ce94dbe6 2005-02-13 devnull void *v;
1017 ce94dbe6 2005-02-13 devnull
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);
1022 ce94dbe6 2005-02-13 devnull }
1023 ce94dbe6 2005-02-13 devnull return v;
1024 ce94dbe6 2005-02-13 devnull }
1025 ce94dbe6 2005-02-13 devnull
1026 ce94dbe6 2005-02-13 devnull void*
1027 ce94dbe6 2005-02-13 devnull erealloc(void *v, int n)
1028 ce94dbe6 2005-02-13 devnull {
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);
1033 ce94dbe6 2005-02-13 devnull }
1034 ce94dbe6 2005-02-13 devnull return v;
1035 ce94dbe6 2005-02-13 devnull }
1036 ce94dbe6 2005-02-13 devnull