summaryrefslogtreecommitdiff
path: root/ssh-agent.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 14:23:50 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 14:23:50 +0100
commitbaccdb349b31c47cd76fb63211f754ed33a9707e (patch)
treed03653f975fd4eb8bf71bb0c9d168614401202fa /ssh-agent.c
parent487bdb3a5ef6075887b830ccb8a0b14f6da78e93 (diff)
parent9f82e5a9042f2d872e98f48a876fcab3e25dd9bb (diff)
Import openssh_6.8p1.orig.tar.gz
Diffstat (limited to 'ssh-agent.c')
-rw-r--r--ssh-agent.c561
1 files changed, 339 insertions, 222 deletions
diff --git a/ssh-agent.c b/ssh-agent.c
index 25f10c549..aeda656ac 100644
--- a/ssh-agent.c
+++ b/ssh-agent.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: ssh-agent.c,v 1.190 2014/07/25 21:22:03 dtucker Exp $ */ 1/* $OpenBSD: ssh-agent.c,v 1.199 2015/03/04 21:12:59 djm Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -36,6 +36,7 @@
36 36
37#include "includes.h" 37#include "includes.h"
38 38
39#include <sys/param.h> /* MIN MAX */
39#include <sys/types.h> 40#include <sys/types.h>
40#include <sys/param.h> 41#include <sys/param.h>
41#include <sys/resource.h> 42#include <sys/resource.h>
@@ -56,6 +57,7 @@
56 57
57#include <errno.h> 58#include <errno.h>
58#include <fcntl.h> 59#include <fcntl.h>
60#include <limits.h>
59#ifdef HAVE_PATHS_H 61#ifdef HAVE_PATHS_H
60# include <paths.h> 62# include <paths.h>
61#endif 63#endif
@@ -67,16 +69,20 @@
67#include <string.h> 69#include <string.h>
68#include <unistd.h> 70#include <unistd.h>
69 71
72#include "key.h" /* XXX for typedef */
73#include "buffer.h" /* XXX for typedef */
74
70#include "xmalloc.h" 75#include "xmalloc.h"
71#include "ssh.h" 76#include "ssh.h"
72#include "rsa.h" 77#include "rsa.h"
73#include "buffer.h" 78#include "sshbuf.h"
74#include "key.h" 79#include "sshkey.h"
75#include "authfd.h" 80#include "authfd.h"
76#include "compat.h" 81#include "compat.h"
77#include "log.h" 82#include "log.h"
78#include "misc.h" 83#include "misc.h"
79#include "digest.h" 84#include "digest.h"
85#include "ssherr.h"
80 86
81#ifdef ENABLE_PKCS11 87#ifdef ENABLE_PKCS11
82#include "ssh-pkcs11.h" 88#include "ssh-pkcs11.h"
@@ -95,9 +101,9 @@ typedef enum {
95typedef struct { 101typedef struct {
96 int fd; 102 int fd;
97 sock_type type; 103 sock_type type;
98 Buffer input; 104 struct sshbuf *input;
99 Buffer output; 105 struct sshbuf *output;
100 Buffer request; 106 struct sshbuf *request;
101} SocketEntry; 107} SocketEntry;
102 108
103u_int sockets_alloc = 0; 109u_int sockets_alloc = 0;
@@ -105,7 +111,7 @@ SocketEntry *sockets = NULL;
105 111
106typedef struct identity { 112typedef struct identity {
107 TAILQ_ENTRY(identity) next; 113 TAILQ_ENTRY(identity) next;
108 Key *key; 114 struct sshkey *key;
109 char *comment; 115 char *comment;
110 char *provider; 116 char *provider;
111 time_t death; 117 time_t death;
@@ -130,8 +136,8 @@ time_t parent_alive_interval = 0;
130pid_t cleanup_pid = 0; 136pid_t cleanup_pid = 0;
131 137
132/* pathname and directory for AUTH_SOCKET */ 138/* pathname and directory for AUTH_SOCKET */
133char socket_name[MAXPATHLEN]; 139char socket_name[PATH_MAX];
134char socket_dir[MAXPATHLEN]; 140char socket_dir[PATH_MAX];
135 141
136/* locking */ 142/* locking */
137int locked = 0; 143int locked = 0;
@@ -142,15 +148,17 @@ extern char *__progname;
142/* Default lifetime in seconds (0 == forever) */ 148/* Default lifetime in seconds (0 == forever) */
143static long lifetime = 0; 149static long lifetime = 0;
144 150
151static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
152
145static void 153static void
146close_socket(SocketEntry *e) 154close_socket(SocketEntry *e)
147{ 155{
148 close(e->fd); 156 close(e->fd);
149 e->fd = -1; 157 e->fd = -1;
150 e->type = AUTH_UNUSED; 158 e->type = AUTH_UNUSED;
151 buffer_free(&e->input); 159 sshbuf_free(e->input);
152 buffer_free(&e->output); 160 sshbuf_free(e->output);
153 buffer_free(&e->request); 161 sshbuf_free(e->request);
154} 162}
155 163
156static void 164static void
@@ -176,7 +184,7 @@ idtab_lookup(int version)
176static void 184static void
177free_identity(Identity *id) 185free_identity(Identity *id)
178{ 186{
179 key_free(id->key); 187 sshkey_free(id->key);
180 free(id->provider); 188 free(id->provider);
181 free(id->comment); 189 free(id->comment);
182 free(id); 190 free(id);
@@ -184,13 +192,13 @@ free_identity(Identity *id)
184 192
185/* return matching private key for given public key */ 193/* return matching private key for given public key */
186static Identity * 194static Identity *
187lookup_identity(Key *key, int version) 195lookup_identity(struct sshkey *key, int version)
188{ 196{
189 Identity *id; 197 Identity *id;
190 198
191 Idtab *tab = idtab_lookup(version); 199 Idtab *tab = idtab_lookup(version);
192 TAILQ_FOREACH(id, &tab->idlist, next) { 200 TAILQ_FOREACH(id, &tab->idlist, next) {
193 if (key_equal(key, id->key)) 201 if (sshkey_equal(key, id->key))
194 return (id); 202 return (id);
195 } 203 }
196 return (NULL); 204 return (NULL);
@@ -203,8 +211,9 @@ confirm_key(Identity *id)
203 char *p; 211 char *p;
204 int ret = -1; 212 int ret = -1;
205 213
206 p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); 214 p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT);
207 if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", 215 if (p != NULL &&
216 ask_permission("Allow use of key %s?\nKey fingerprint %s.",
208 id->comment, p)) 217 id->comment, p))
209 ret = 0; 218 ret = 0;
210 free(p); 219 free(p);
@@ -212,37 +221,65 @@ confirm_key(Identity *id)
212 return (ret); 221 return (ret);
213} 222}
214 223
224static void
225send_status(SocketEntry *e, int success)
226{
227 int r;
228
229 if ((r = sshbuf_put_u32(e->output, 1)) != 0 ||
230 (r = sshbuf_put_u8(e->output, success ?
231 SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
232 fatal("%s: buffer error: %s", __func__, ssh_err(r));
233}
234
215/* send list of supported public keys to 'client' */ 235/* send list of supported public keys to 'client' */
216static void 236static void
217process_request_identities(SocketEntry *e, int version) 237process_request_identities(SocketEntry *e, int version)
218{ 238{
219 Idtab *tab = idtab_lookup(version); 239 Idtab *tab = idtab_lookup(version);
220 Identity *id; 240 Identity *id;
221 Buffer msg; 241 struct sshbuf *msg;
222 242 int r;
223 buffer_init(&msg); 243
224 buffer_put_char(&msg, (version == 1) ? 244 if ((msg = sshbuf_new()) == NULL)
225 SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 245 fatal("%s: sshbuf_new failed", __func__);
226 buffer_put_int(&msg, tab->nentries); 246 if ((r = sshbuf_put_u8(msg, (version == 1) ?
247 SSH_AGENT_RSA_IDENTITIES_ANSWER :
248 SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
249 (r = sshbuf_put_u32(msg, tab->nentries)) != 0)
250 fatal("%s: buffer error: %s", __func__, ssh_err(r));
227 TAILQ_FOREACH(id, &tab->idlist, next) { 251 TAILQ_FOREACH(id, &tab->idlist, next) {
228 if (id->key->type == KEY_RSA1) { 252 if (id->key->type == KEY_RSA1) {
229#ifdef WITH_SSH1 253#ifdef WITH_SSH1
230 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); 254 if ((r = sshbuf_put_u32(msg,
231 buffer_put_bignum(&msg, id->key->rsa->e); 255 BN_num_bits(id->key->rsa->n))) != 0 ||
232 buffer_put_bignum(&msg, id->key->rsa->n); 256 (r = sshbuf_put_bignum1(msg,
257 id->key->rsa->e)) != 0 ||
258 (r = sshbuf_put_bignum1(msg,
259 id->key->rsa->n)) != 0)
260 fatal("%s: buffer error: %s",
261 __func__, ssh_err(r));
233#endif 262#endif
234 } else { 263 } else {
235 u_char *blob; 264 u_char *blob;
236 u_int blen; 265 size_t blen;
237 key_to_blob(id->key, &blob, &blen); 266
238 buffer_put_string(&msg, blob, blen); 267 if ((r = sshkey_to_blob(id->key, &blob, &blen)) != 0) {
268 error("%s: sshkey_to_blob: %s", __func__,
269 ssh_err(r));
270 continue;
271 }
272 if ((r = sshbuf_put_string(msg, blob, blen)) != 0)
273 fatal("%s: buffer error: %s",
274 __func__, ssh_err(r));
239 free(blob); 275 free(blob);
240 } 276 }
241 buffer_put_cstring(&msg, id->comment); 277 if ((r = sshbuf_put_cstring(msg, id->comment)) != 0)
278 fatal("%s: buffer error: %s", __func__, ssh_err(r));
242 } 279 }
243 buffer_put_int(&e->output, buffer_len(&msg)); 280 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
244 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 281 fatal("%s: buffer error: %s", __func__, ssh_err(r));
245 buffer_free(&msg); 282 sshbuf_free(msg);
246} 283}
247 284
248#ifdef WITH_SSH1 285#ifdef WITH_SSH1
@@ -254,40 +291,48 @@ process_authentication_challenge1(SocketEntry *e)
254 u_int response_type; 291 u_int response_type;
255 BIGNUM *challenge; 292 BIGNUM *challenge;
256 Identity *id; 293 Identity *id;
257 int i, len; 294 int r, len;
258 Buffer msg; 295 struct sshbuf *msg;
259 struct ssh_digest_ctx *md; 296 struct ssh_digest_ctx *md;
260 Key *key; 297 struct sshkey *key;
261 298
262 buffer_init(&msg); 299 if ((msg = sshbuf_new()) == NULL)
263 key = key_new(KEY_RSA1); 300 fatal("%s: sshbuf_new failed", __func__);
301 if ((key = sshkey_new(KEY_RSA1)) == NULL)
302 fatal("%s: sshkey_new failed", __func__);
264 if ((challenge = BN_new()) == NULL) 303 if ((challenge = BN_new()) == NULL)
265 fatal("process_authentication_challenge1: BN_new failed"); 304 fatal("%s: BN_new failed", __func__);
266 305
267 (void) buffer_get_int(&e->request); /* ignored */ 306 if ((r = sshbuf_get_u32(e->request, NULL)) != 0 || /* ignored */
268 buffer_get_bignum(&e->request, key->rsa->e); 307 (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
269 buffer_get_bignum(&e->request, key->rsa->n); 308 (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0 ||
270 buffer_get_bignum(&e->request, challenge); 309 (r = sshbuf_get_bignum1(e->request, challenge)))
310 fatal("%s: buffer error: %s", __func__, ssh_err(r));
271 311
272 /* Only protocol 1.1 is supported */ 312 /* Only protocol 1.1 is supported */
273 if (buffer_len(&e->request) == 0) 313 if (sshbuf_len(e->request) == 0)
274 goto failure; 314 goto failure;
275 buffer_get(&e->request, session_id, 16); 315 if ((r = sshbuf_get(e->request, session_id, sizeof(session_id))) != 0 ||
276 response_type = buffer_get_int(&e->request); 316 (r = sshbuf_get_u32(e->request, &response_type)) != 0)
317 fatal("%s: buffer error: %s", __func__, ssh_err(r));
277 if (response_type != 1) 318 if (response_type != 1)
278 goto failure; 319 goto failure;
279 320
280 id = lookup_identity(key, 1); 321 id = lookup_identity(key, 1);
281 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { 322 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) {
282 Key *private = id->key; 323 struct sshkey *private = id->key;
283 /* Decrypt the challenge using the private key. */ 324 /* Decrypt the challenge using the private key. */
284 if (rsa_private_decrypt(challenge, challenge, private->rsa) != 0) 325 if ((r = rsa_private_decrypt(challenge, challenge,
285 goto failure; 326 private->rsa) != 0)) {
327 fatal("%s: rsa_public_encrypt: %s", __func__,
328 ssh_err(r));
329 goto failure; /* XXX ? */
330 }
286 331
287 /* The response is MD5 of decrypted challenge plus session id. */ 332 /* The response is MD5 of decrypted challenge plus session id */
288 len = BN_num_bytes(challenge); 333 len = BN_num_bytes(challenge);
289 if (len <= 0 || len > 32) { 334 if (len <= 0 || len > 32) {
290 logit("process_authentication_challenge: bad challenge length %d", len); 335 logit("%s: bad challenge length %d", __func__, len);
291 goto failure; 336 goto failure;
292 } 337 }
293 memset(buf, 0, 32); 338 memset(buf, 0, 32);
@@ -300,21 +345,22 @@ process_authentication_challenge1(SocketEntry *e)
300 ssh_digest_free(md); 345 ssh_digest_free(md);
301 346
302 /* Send the response. */ 347 /* Send the response. */
303 buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); 348 if ((r = sshbuf_put_u8(msg, SSH_AGENT_RSA_RESPONSE)) != 0 ||
304 for (i = 0; i < 16; i++) 349 (r = sshbuf_put(msg, mdbuf, sizeof(mdbuf))) != 0)
305 buffer_put_char(&msg, mdbuf[i]); 350 fatal("%s: buffer error: %s", __func__, ssh_err(r));
306 goto send; 351 goto send;
307 } 352 }
308 353
309failure: 354 failure:
310 /* Unknown identity or protocol error. Send failure. */ 355 /* Unknown identity or protocol error. Send failure. */
311 buffer_put_char(&msg, SSH_AGENT_FAILURE); 356 if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
312send: 357 fatal("%s: buffer error: %s", __func__, ssh_err(r));
313 buffer_put_int(&e->output, buffer_len(&msg)); 358 send:
314 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 359 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
315 key_free(key); 360 fatal("%s: buffer error: %s", __func__, ssh_err(r));
361 sshkey_free(key);
316 BN_clear_free(challenge); 362 BN_clear_free(challenge);
317 buffer_free(&msg); 363 sshbuf_free(msg);
318} 364}
319#endif 365#endif
320 366
@@ -323,54 +369,65 @@ static void
323process_sign_request2(SocketEntry *e) 369process_sign_request2(SocketEntry *e)
324{ 370{
325 u_char *blob, *data, *signature = NULL; 371 u_char *blob, *data, *signature = NULL;
326 u_int blen, dlen, slen = 0; 372 size_t blen, dlen, slen = 0;
327 extern int datafellows; 373 u_int compat = 0, flags;
328 int odatafellows; 374 int r, ok = -1;
329 int ok = -1, flags; 375 struct sshbuf *msg;
330 Buffer msg; 376 struct sshkey *key;
331 Key *key; 377 struct identity *id;
332 378
333 datafellows = 0; 379 if ((msg = sshbuf_new()) == NULL)
334 380 fatal("%s: sshbuf_new failed", __func__);
335 blob = buffer_get_string(&e->request, &blen); 381 if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0 ||
336 data = buffer_get_string(&e->request, &dlen); 382 (r = sshbuf_get_string(e->request, &data, &dlen)) != 0 ||
337 383 (r = sshbuf_get_u32(e->request, &flags)) != 0)
338 flags = buffer_get_int(&e->request); 384 fatal("%s: buffer error: %s", __func__, ssh_err(r));
339 odatafellows = datafellows;
340 if (flags & SSH_AGENT_OLD_SIGNATURE) 385 if (flags & SSH_AGENT_OLD_SIGNATURE)
341 datafellows = SSH_BUG_SIGBLOB; 386 compat = SSH_BUG_SIGBLOB;
342 387 if ((r = sshkey_from_blob(blob, blen, &key)) != 0) {
343 key = key_from_blob(blob, blen); 388 error("%s: cannot parse key blob: %s", __func__, ssh_err(ok));
344 if (key != NULL) { 389 goto send;
345 Identity *id = lookup_identity(key, 2);
346 if (id != NULL && (!id->confirm || confirm_key(id) == 0))
347 ok = key_sign(id->key, &signature, &slen, data, dlen);
348 key_free(key);
349 } 390 }
350 buffer_init(&msg); 391 if ((id = lookup_identity(key, 2)) == NULL) {
351 if (ok == 0) { 392 verbose("%s: %s key not found", __func__, sshkey_type(key));
352 buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); 393 goto send;
353 buffer_put_string(&msg, signature, slen);
354 } else {
355 buffer_put_char(&msg, SSH_AGENT_FAILURE);
356 } 394 }
357 buffer_put_int(&e->output, buffer_len(&msg)); 395 if (id->confirm && confirm_key(id) != 0) {
358 buffer_append(&e->output, buffer_ptr(&msg), 396 verbose("%s: user refused key", __func__);
359 buffer_len(&msg)); 397 goto send;
360 buffer_free(&msg); 398 }
399 if ((r = sshkey_sign(id->key, &signature, &slen,
400 data, dlen, compat)) != 0) {
401 error("%s: sshkey_sign: %s", __func__, ssh_err(ok));
402 goto send;
403 }
404 /* Success */
405 ok = 0;
406 send:
407 sshkey_free(key);
408 if (ok == 0) {
409 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
410 (r = sshbuf_put_string(msg, signature, slen)) != 0)
411 fatal("%s: buffer error: %s", __func__, ssh_err(r));
412 } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
413 fatal("%s: buffer error: %s", __func__, ssh_err(r));
414
415 if ((r = sshbuf_put_stringb(e->output, msg)) != 0)
416 fatal("%s: buffer error: %s", __func__, ssh_err(r));
417
418 sshbuf_free(msg);
361 free(data); 419 free(data);
362 free(blob); 420 free(blob);
363 free(signature); 421 free(signature);
364 datafellows = odatafellows;
365} 422}
366 423
367/* shared */ 424/* shared */
368static void 425static void
369process_remove_identity(SocketEntry *e, int version) 426process_remove_identity(SocketEntry *e, int version)
370{ 427{
371 u_int blen; 428 size_t blen;
372 int success = 0; 429 int r, success = 0;
373 Key *key = NULL; 430 struct sshkey *key = NULL;
374 u_char *blob; 431 u_char *blob;
375#ifdef WITH_SSH1 432#ifdef WITH_SSH1
376 u_int bits; 433 u_int bits;
@@ -379,19 +436,27 @@ process_remove_identity(SocketEntry *e, int version)
379 switch (version) { 436 switch (version) {
380#ifdef WITH_SSH1 437#ifdef WITH_SSH1
381 case 1: 438 case 1:
382 key = key_new(KEY_RSA1); 439 if ((key = sshkey_new(KEY_RSA1)) == NULL) {
383 bits = buffer_get_int(&e->request); 440 error("%s: sshkey_new failed", __func__);
384 buffer_get_bignum(&e->request, key->rsa->e); 441 return;
385 buffer_get_bignum(&e->request, key->rsa->n); 442 }
386 443 if ((r = sshbuf_get_u32(e->request, &bits)) != 0 ||
387 if (bits != key_size(key)) 444 (r = sshbuf_get_bignum1(e->request, key->rsa->e)) != 0 ||
388 logit("Warning: identity keysize mismatch: actual %u, announced %u", 445 (r = sshbuf_get_bignum1(e->request, key->rsa->n)) != 0)
389 key_size(key), bits); 446 fatal("%s: buffer error: %s", __func__, ssh_err(r));
447
448 if (bits != sshkey_size(key))
449 logit("Warning: identity keysize mismatch: "
450 "actual %u, announced %u",
451 sshkey_size(key), bits);
390 break; 452 break;
391#endif /* WITH_SSH1 */ 453#endif /* WITH_SSH1 */
392 case 2: 454 case 2:
393 blob = buffer_get_string(&e->request, &blen); 455 if ((r = sshbuf_get_string(e->request, &blob, &blen)) != 0)
394 key = key_from_blob(blob, blen); 456 fatal("%s: buffer error: %s", __func__, ssh_err(r));
457 if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
458 error("%s: sshkey_from_blob failed: %s",
459 __func__, ssh_err(r));
395 free(blob); 460 free(blob);
396 break; 461 break;
397 } 462 }
@@ -415,11 +480,9 @@ process_remove_identity(SocketEntry *e, int version)
415 tab->nentries--; 480 tab->nentries--;
416 success = 1; 481 success = 1;
417 } 482 }
418 key_free(key); 483 sshkey_free(key);
419 } 484 }
420 buffer_put_int(&e->output, 1); 485 send_status(e, success);
421 buffer_put_char(&e->output,
422 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
423} 486}
424 487
425static void 488static void
@@ -439,8 +502,7 @@ process_remove_all_identities(SocketEntry *e, int version)
439 tab->nentries = 0; 502 tab->nentries = 0;
440 503
441 /* Send success. */ 504 /* Send success. */
442 buffer_put_int(&e->output, 1); 505 send_status(e, 1);
443 buffer_put_char(&e->output, SSH_AGENT_SUCCESS);
444} 506}
445 507
446/* removes expired keys and returns number of seconds until the next expiry */ 508/* removes expired keys and returns number of seconds until the next expiry */
@@ -474,71 +536,106 @@ reaper(void)
474 return (deadline - now); 536 return (deadline - now);
475} 537}
476 538
539/*
540 * XXX this and the corresponding serialisation function probably belongs
541 * in key.c
542 */
543#ifdef WITH_SSH1
544static int
545agent_decode_rsa1(struct sshbuf *m, struct sshkey **kp)
546{
547 struct sshkey *k = NULL;
548 int r = SSH_ERR_INTERNAL_ERROR;
549
550 *kp = NULL;
551 if ((k = sshkey_new_private(KEY_RSA1)) == NULL)
552 return SSH_ERR_ALLOC_FAIL;
553
554 if ((r = sshbuf_get_u32(m, NULL)) != 0 || /* ignored */
555 (r = sshbuf_get_bignum1(m, k->rsa->n)) != 0 ||
556 (r = sshbuf_get_bignum1(m, k->rsa->e)) != 0 ||
557 (r = sshbuf_get_bignum1(m, k->rsa->d)) != 0 ||
558 (r = sshbuf_get_bignum1(m, k->rsa->iqmp)) != 0 ||
559 /* SSH1 and SSL have p and q swapped */
560 (r = sshbuf_get_bignum1(m, k->rsa->q)) != 0 || /* p */
561 (r = sshbuf_get_bignum1(m, k->rsa->p)) != 0) /* q */
562 goto out;
563
564 /* Generate additional parameters */
565 if ((r = rsa_generate_additional_parameters(k->rsa)) != 0)
566 goto out;
567 /* enable blinding */
568 if (RSA_blinding_on(k->rsa, NULL) != 1) {
569 r = SSH_ERR_LIBCRYPTO_ERROR;
570 goto out;
571 }
572
573 r = 0; /* success */
574 out:
575 if (r == 0)
576 *kp = k;
577 else
578 sshkey_free(k);
579 return r;
580}
581#endif /* WITH_SSH1 */
582
477static void 583static void
478process_add_identity(SocketEntry *e, int version) 584process_add_identity(SocketEntry *e, int version)
479{ 585{
480 Idtab *tab = idtab_lookup(version); 586 Idtab *tab = idtab_lookup(version);
481 Identity *id; 587 Identity *id;
482 int type, success = 0, confirm = 0; 588 int success = 0, confirm = 0;
483 char *comment; 589 u_int seconds;
590 char *comment = NULL;
484 time_t death = 0; 591 time_t death = 0;
485 Key *k = NULL; 592 struct sshkey *k = NULL;
593 u_char ctype;
594 int r = SSH_ERR_INTERNAL_ERROR;
486 595
487 switch (version) { 596 switch (version) {
488#ifdef WITH_SSH1 597#ifdef WITH_SSH1
489 case 1: 598 case 1:
490 k = key_new_private(KEY_RSA1); 599 r = agent_decode_rsa1(e->request, &k);
491 (void) buffer_get_int(&e->request); /* ignored */
492 buffer_get_bignum(&e->request, k->rsa->n);
493 buffer_get_bignum(&e->request, k->rsa->e);
494 buffer_get_bignum(&e->request, k->rsa->d);
495 buffer_get_bignum(&e->request, k->rsa->iqmp);
496
497 /* SSH and SSL have p and q swapped */
498 buffer_get_bignum(&e->request, k->rsa->q); /* p */
499 buffer_get_bignum(&e->request, k->rsa->p); /* q */
500
501 /* Generate additional parameters */
502 if (rsa_generate_additional_parameters(k->rsa) != 0)
503 fatal("%s: rsa_generate_additional_parameters "
504 "error", __func__);
505
506 /* enable blinding */
507 if (RSA_blinding_on(k->rsa, NULL) != 1) {
508 error("process_add_identity: RSA_blinding_on failed");
509 key_free(k);
510 goto send;
511 }
512 break; 600 break;
513#endif /* WITH_SSH1 */ 601#endif /* WITH_SSH1 */
514 case 2: 602 case 2:
515 k = key_private_deserialize(&e->request); 603 r = sshkey_private_deserialize(e->request, &k);
516 if (k == NULL) {
517 buffer_clear(&e->request);
518 goto send;
519 }
520 break; 604 break;
521 } 605 }
522 if (k == NULL) 606 if (r != 0 || k == NULL ||
523 goto send; 607 (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) {
524 comment = buffer_get_string(&e->request, NULL); 608 error("%s: decode private key: %s", __func__, ssh_err(r));
609 goto err;
610 }
525 611
526 while (buffer_len(&e->request)) { 612 while (sshbuf_len(e->request)) {
527 switch ((type = buffer_get_char(&e->request))) { 613 if ((r = sshbuf_get_u8(e->request, &ctype)) != 0) {
614 error("%s: buffer error: %s", __func__, ssh_err(r));
615 goto err;
616 }
617 switch (ctype) {
528 case SSH_AGENT_CONSTRAIN_LIFETIME: 618 case SSH_AGENT_CONSTRAIN_LIFETIME:
529 death = monotime() + buffer_get_int(&e->request); 619 if ((r = sshbuf_get_u32(e->request, &seconds)) != 0) {
620 error("%s: bad lifetime constraint: %s",
621 __func__, ssh_err(r));
622 goto err;
623 }
624 death = monotime() + seconds;
530 break; 625 break;
531 case SSH_AGENT_CONSTRAIN_CONFIRM: 626 case SSH_AGENT_CONSTRAIN_CONFIRM:
532 confirm = 1; 627 confirm = 1;
533 break; 628 break;
534 default: 629 default:
535 error("process_add_identity: " 630 error("%s: Unknown constraint %d", __func__, ctype);
536 "Unknown constraint type %d", type); 631 err:
632 sshbuf_reset(e->request);
537 free(comment); 633 free(comment);
538 key_free(k); 634 sshkey_free(k);
539 goto send; 635 goto send;
540 } 636 }
541 } 637 }
638
542 success = 1; 639 success = 1;
543 if (lifetime && !death) 640 if (lifetime && !death)
544 death = monotime() + lifetime; 641 death = monotime() + lifetime;
@@ -549,26 +646,25 @@ process_add_identity(SocketEntry *e, int version)
549 /* Increment the number of identities. */ 646 /* Increment the number of identities. */
550 tab->nentries++; 647 tab->nentries++;
551 } else { 648 } else {
552 key_free(k); 649 sshkey_free(k);
553 free(id->comment); 650 free(id->comment);
554 } 651 }
555 id->comment = comment; 652 id->comment = comment;
556 id->death = death; 653 id->death = death;
557 id->confirm = confirm; 654 id->confirm = confirm;
558send: 655send:
559 buffer_put_int(&e->output, 1); 656 send_status(e, success);
560 buffer_put_char(&e->output,
561 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
562} 657}
563 658
564/* XXX todo: encrypt sensitive data with passphrase */ 659/* XXX todo: encrypt sensitive data with passphrase */
565static void 660static void
566process_lock_agent(SocketEntry *e, int lock) 661process_lock_agent(SocketEntry *e, int lock)
567{ 662{
568 int success = 0; 663 int r, success = 0;
569 char *passwd; 664 char *passwd;
570 665
571 passwd = buffer_get_string(&e->request, NULL); 666 if ((r = sshbuf_get_cstring(e->request, &passwd, NULL)) != 0)
667 fatal("%s: buffer error: %s", __func__, ssh_err(r));
572 if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { 668 if (locked && !lock && strcmp(passwd, lock_passwd) == 0) {
573 locked = 0; 669 locked = 0;
574 explicit_bzero(lock_passwd, strlen(lock_passwd)); 670 explicit_bzero(lock_passwd, strlen(lock_passwd));
@@ -582,25 +678,25 @@ process_lock_agent(SocketEntry *e, int lock)
582 } 678 }
583 explicit_bzero(passwd, strlen(passwd)); 679 explicit_bzero(passwd, strlen(passwd));
584 free(passwd); 680 free(passwd);
585 681 send_status(e, success);
586 buffer_put_int(&e->output, 1);
587 buffer_put_char(&e->output,
588 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
589} 682}
590 683
591static void 684static void
592no_identities(SocketEntry *e, u_int type) 685no_identities(SocketEntry *e, u_int type)
593{ 686{
594 Buffer msg; 687 struct sshbuf *msg;
688 int r;
595 689
596 buffer_init(&msg); 690 if ((msg = sshbuf_new()) == NULL)
597 buffer_put_char(&msg, 691 fatal("%s: sshbuf_new failed", __func__);
692 if ((r = sshbuf_put_u8(msg,
598 (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? 693 (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ?
599 SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 694 SSH_AGENT_RSA_IDENTITIES_ANSWER :
600 buffer_put_int(&msg, 0); 695 SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
601 buffer_put_int(&e->output, buffer_len(&msg)); 696 (r = sshbuf_put_u32(msg, 0)) != 0 ||
602 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 697 (r = sshbuf_put_stringb(e->output, msg)) != 0)
603 buffer_free(&msg); 698 fatal("%s: buffer error: %s", __func__, ssh_err(r));
699 sshbuf_free(msg);
604} 700}
605 701
606#ifdef ENABLE_PKCS11 702#ifdef ENABLE_PKCS11
@@ -608,19 +704,27 @@ static void
608process_add_smartcard_key(SocketEntry *e) 704process_add_smartcard_key(SocketEntry *e)
609{ 705{
610 char *provider = NULL, *pin; 706 char *provider = NULL, *pin;
611 int i, type, version, count = 0, success = 0, confirm = 0; 707 int r, i, version, count = 0, success = 0, confirm = 0;
708 u_int seconds;
612 time_t death = 0; 709 time_t death = 0;
613 Key **keys = NULL, *k; 710 u_char type;
711 struct sshkey **keys = NULL, *k;
614 Identity *id; 712 Identity *id;
615 Idtab *tab; 713 Idtab *tab;
616 714
617 provider = buffer_get_string(&e->request, NULL); 715 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
618 pin = buffer_get_string(&e->request, NULL); 716 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
717 fatal("%s: buffer error: %s", __func__, ssh_err(r));
619 718
620 while (buffer_len(&e->request)) { 719 while (sshbuf_len(e->request)) {
621 switch ((type = buffer_get_char(&e->request))) { 720 if ((r = sshbuf_get_u8(e->request, &type)) != 0)
721 fatal("%s: buffer error: %s", __func__, ssh_err(r));
722 switch (type) {
622 case SSH_AGENT_CONSTRAIN_LIFETIME: 723 case SSH_AGENT_CONSTRAIN_LIFETIME:
623 death = monotime() + buffer_get_int(&e->request); 724 if ((r = sshbuf_get_u32(e->request, &seconds)) != 0)
725 fatal("%s: buffer error: %s",
726 __func__, ssh_err(r));
727 death = monotime() + seconds;
624 break; 728 break;
625 case SSH_AGENT_CONSTRAIN_CONFIRM: 729 case SSH_AGENT_CONSTRAIN_CONFIRM:
626 confirm = 1; 730 confirm = 1;
@@ -650,7 +754,7 @@ process_add_smartcard_key(SocketEntry *e)
650 tab->nentries++; 754 tab->nentries++;
651 success = 1; 755 success = 1;
652 } else { 756 } else {
653 key_free(k); 757 sshkey_free(k);
654 } 758 }
655 keys[i] = NULL; 759 keys[i] = NULL;
656 } 760 }
@@ -658,21 +762,20 @@ send:
658 free(pin); 762 free(pin);
659 free(provider); 763 free(provider);
660 free(keys); 764 free(keys);
661 buffer_put_int(&e->output, 1); 765 send_status(e, success);
662 buffer_put_char(&e->output,
663 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
664} 766}
665 767
666static void 768static void
667process_remove_smartcard_key(SocketEntry *e) 769process_remove_smartcard_key(SocketEntry *e)
668{ 770{
669 char *provider = NULL, *pin = NULL; 771 char *provider = NULL, *pin = NULL;
670 int version, success = 0; 772 int r, version, success = 0;
671 Identity *id, *nxt; 773 Identity *id, *nxt;
672 Idtab *tab; 774 Idtab *tab;
673 775
674 provider = buffer_get_string(&e->request, NULL); 776 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 ||
675 pin = buffer_get_string(&e->request, NULL); 777 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0)
778 fatal("%s: buffer error: %s", __func__, ssh_err(r));
676 free(pin); 779 free(pin);
677 780
678 for (version = 1; version < 3; version++) { 781 for (version = 1; version < 3; version++) {
@@ -695,9 +798,7 @@ process_remove_smartcard_key(SocketEntry *e)
695 error("process_remove_smartcard_key:" 798 error("process_remove_smartcard_key:"
696 " pkcs11_del_provider failed"); 799 " pkcs11_del_provider failed");
697 free(provider); 800 free(provider);
698 buffer_put_int(&e->output, 1); 801 send_status(e, success);
699 buffer_put_char(&e->output,
700 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE);
701} 802}
702#endif /* ENABLE_PKCS11 */ 803#endif /* ENABLE_PKCS11 */
703 804
@@ -706,30 +807,31 @@ process_remove_smartcard_key(SocketEntry *e)
706static void 807static void
707process_message(SocketEntry *e) 808process_message(SocketEntry *e)
708{ 809{
709 u_int msg_len, type; 810 u_int msg_len;
710 u_char *cp; 811 u_char type;
812 const u_char *cp;
813 int r;
711 814
712 if (buffer_len(&e->input) < 5) 815 if (sshbuf_len(e->input) < 5)
713 return; /* Incomplete message. */ 816 return; /* Incomplete message. */
714 cp = buffer_ptr(&e->input); 817 cp = sshbuf_ptr(e->input);
715 msg_len = get_u32(cp); 818 msg_len = PEEK_U32(cp);
716 if (msg_len > 256 * 1024) { 819 if (msg_len > 256 * 1024) {
717 close_socket(e); 820 close_socket(e);
718 return; 821 return;
719 } 822 }
720 if (buffer_len(&e->input) < msg_len + 4) 823 if (sshbuf_len(e->input) < msg_len + 4)
721 return; 824 return;
722 825
723 /* move the current input to e->request */ 826 /* move the current input to e->request */
724 buffer_consume(&e->input, 4); 827 sshbuf_reset(e->request);
725 buffer_clear(&e->request); 828 if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 ||
726 buffer_append(&e->request, buffer_ptr(&e->input), msg_len); 829 (r = sshbuf_get_u8(e->request, &type)) != 0)
727 buffer_consume(&e->input, msg_len); 830 fatal("%s: buffer error: %s", __func__, ssh_err(r));
728 type = buffer_get_char(&e->request);
729 831
730 /* check wheter agent is locked */ 832 /* check wheter agent is locked */
731 if (locked && type != SSH_AGENTC_UNLOCK) { 833 if (locked && type != SSH_AGENTC_UNLOCK) {
732 buffer_clear(&e->request); 834 sshbuf_reset(e->request);
733 switch (type) { 835 switch (type) {
734 case SSH_AGENTC_REQUEST_RSA_IDENTITIES: 836 case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
735 case SSH2_AGENTC_REQUEST_IDENTITIES: 837 case SSH2_AGENTC_REQUEST_IDENTITIES:
@@ -738,8 +840,7 @@ process_message(SocketEntry *e)
738 break; 840 break;
739 default: 841 default:
740 /* send a fail message for all other request types */ 842 /* send a fail message for all other request types */
741 buffer_put_int(&e->output, 1); 843 send_status(e, 0);
742 buffer_put_char(&e->output, SSH_AGENT_FAILURE);
743 } 844 }
744 return; 845 return;
745 } 846 }
@@ -765,10 +866,10 @@ process_message(SocketEntry *e)
765 case SSH_AGENTC_REMOVE_RSA_IDENTITY: 866 case SSH_AGENTC_REMOVE_RSA_IDENTITY:
766 process_remove_identity(e, 1); 867 process_remove_identity(e, 1);
767 break; 868 break;
869#endif
768 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: 870 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES:
769 process_remove_all_identities(e, 1); 871 process_remove_all_identities(e, 1); /* safe for !WITH_SSH1 */
770 break; 872 break;
771#endif
772 /* ssh2 */ 873 /* ssh2 */
773 case SSH2_AGENTC_SIGN_REQUEST: 874 case SSH2_AGENTC_SIGN_REQUEST:
774 process_sign_request2(e); 875 process_sign_request2(e);
@@ -798,9 +899,8 @@ process_message(SocketEntry *e)
798 default: 899 default:
799 /* Unknown message. Respond with failure. */ 900 /* Unknown message. Respond with failure. */
800 error("Unknown message %d", type); 901 error("Unknown message %d", type);
801 buffer_clear(&e->request); 902 sshbuf_reset(e->request);
802 buffer_put_int(&e->output, 1); 903 send_status(e, 0);
803 buffer_put_char(&e->output, SSH_AGENT_FAILURE);
804 break; 904 break;
805 } 905 }
806} 906}
@@ -818,9 +918,12 @@ new_socket(sock_type type, int fd)
818 for (i = 0; i < sockets_alloc; i++) 918 for (i = 0; i < sockets_alloc; i++)
819 if (sockets[i].type == AUTH_UNUSED) { 919 if (sockets[i].type == AUTH_UNUSED) {
820 sockets[i].fd = fd; 920 sockets[i].fd = fd;
821 buffer_init(&sockets[i].input); 921 if ((sockets[i].input = sshbuf_new()) == NULL)
822 buffer_init(&sockets[i].output); 922 fatal("%s: sshbuf_new failed", __func__);
823 buffer_init(&sockets[i].request); 923 if ((sockets[i].output = sshbuf_new()) == NULL)
924 fatal("%s: sshbuf_new failed", __func__);
925 if ((sockets[i].request = sshbuf_new()) == NULL)
926 fatal("%s: sshbuf_new failed", __func__);
824 sockets[i].type = type; 927 sockets[i].type = type;
825 return; 928 return;
826 } 929 }
@@ -831,9 +934,12 @@ new_socket(sock_type type, int fd)
831 sockets[i].type = AUTH_UNUSED; 934 sockets[i].type = AUTH_UNUSED;
832 sockets_alloc = new_alloc; 935 sockets_alloc = new_alloc;
833 sockets[old_alloc].fd = fd; 936 sockets[old_alloc].fd = fd;
834 buffer_init(&sockets[old_alloc].input); 937 if ((sockets[old_alloc].input = sshbuf_new()) == NULL)
835 buffer_init(&sockets[old_alloc].output); 938 fatal("%s: sshbuf_new failed", __func__);
836 buffer_init(&sockets[old_alloc].request); 939 if ((sockets[old_alloc].output = sshbuf_new()) == NULL)
940 fatal("%s: sshbuf_new failed", __func__);
941 if ((sockets[old_alloc].request = sshbuf_new()) == NULL)
942 fatal("%s: sshbuf_new failed", __func__);
837 sockets[old_alloc].type = type; 943 sockets[old_alloc].type = type;
838} 944}
839 945
@@ -879,7 +985,7 @@ prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp,
879 case AUTH_SOCKET: 985 case AUTH_SOCKET:
880 case AUTH_CONNECTION: 986 case AUTH_CONNECTION:
881 FD_SET(sockets[i].fd, *fdrp); 987 FD_SET(sockets[i].fd, *fdrp);
882 if (buffer_len(&sockets[i].output) > 0) 988 if (sshbuf_len(sockets[i].output) > 0)
883 FD_SET(sockets[i].fd, *fdwp); 989 FD_SET(sockets[i].fd, *fdwp);
884 break; 990 break;
885 default: 991 default:
@@ -906,7 +1012,7 @@ after_select(fd_set *readset, fd_set *writeset)
906 struct sockaddr_un sunaddr; 1012 struct sockaddr_un sunaddr;
907 socklen_t slen; 1013 socklen_t slen;
908 char buf[1024]; 1014 char buf[1024];
909 int len, sock; 1015 int len, sock, r;
910 u_int i, orig_alloc; 1016 u_int i, orig_alloc;
911 uid_t euid; 1017 uid_t euid;
912 gid_t egid; 1018 gid_t egid;
@@ -942,11 +1048,11 @@ after_select(fd_set *readset, fd_set *writeset)
942 } 1048 }
943 break; 1049 break;
944 case AUTH_CONNECTION: 1050 case AUTH_CONNECTION:
945 if (buffer_len(&sockets[i].output) > 0 && 1051 if (sshbuf_len(sockets[i].output) > 0 &&
946 FD_ISSET(sockets[i].fd, writeset)) { 1052 FD_ISSET(sockets[i].fd, writeset)) {
947 len = write(sockets[i].fd, 1053 len = write(sockets[i].fd,
948 buffer_ptr(&sockets[i].output), 1054 sshbuf_ptr(sockets[i].output),
949 buffer_len(&sockets[i].output)); 1055 sshbuf_len(sockets[i].output));
950 if (len == -1 && (errno == EAGAIN || 1056 if (len == -1 && (errno == EAGAIN ||
951 errno == EWOULDBLOCK || 1057 errno == EWOULDBLOCK ||
952 errno == EINTR)) 1058 errno == EINTR))
@@ -955,7 +1061,10 @@ after_select(fd_set *readset, fd_set *writeset)
955 close_socket(&sockets[i]); 1061 close_socket(&sockets[i]);
956 break; 1062 break;
957 } 1063 }
958 buffer_consume(&sockets[i].output, len); 1064 if ((r = sshbuf_consume(sockets[i].output,
1065 len)) != 0)
1066 fatal("%s: buffer error: %s",
1067 __func__, ssh_err(r));
959 } 1068 }
960 if (FD_ISSET(sockets[i].fd, readset)) { 1069 if (FD_ISSET(sockets[i].fd, readset)) {
961 len = read(sockets[i].fd, buf, sizeof(buf)); 1070 len = read(sockets[i].fd, buf, sizeof(buf));
@@ -967,7 +1076,10 @@ after_select(fd_set *readset, fd_set *writeset)
967 close_socket(&sockets[i]); 1076 close_socket(&sockets[i]);
968 break; 1077 break;
969 } 1078 }
970 buffer_append(&sockets[i].input, buf, len); 1079 if ((r = sshbuf_put(sockets[i].input,
1080 buf, len)) != 0)
1081 fatal("%s: buffer error: %s",
1082 __func__, ssh_err(r));
971 explicit_bzero(buf, sizeof(buf)); 1083 explicit_bzero(buf, sizeof(buf));
972 process_message(&sockets[i]); 1084 process_message(&sockets[i]);
973 } 1085 }
@@ -1025,8 +1137,8 @@ static void
1025usage(void) 1137usage(void)
1026{ 1138{
1027 fprintf(stderr, 1139 fprintf(stderr,
1028 "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-t life]\n" 1140 "usage: ssh-agent [-c | -s] [-d] [-a bind_address] [-E fingerprint_hash]\n"
1029 " [command [arg ...]]\n" 1141 " [-t life] [command [arg ...]]\n"
1030 " ssh-agent [-c | -s] -k\n"); 1142 " ssh-agent [-c | -s] -k\n");
1031 exit(1); 1143 exit(1);
1032} 1144}
@@ -1069,8 +1181,13 @@ main(int ac, char **av)
1069 __progname = ssh_get_progname(av[0]); 1181 __progname = ssh_get_progname(av[0]);
1070 seed_rng(); 1182 seed_rng();
1071 1183
1072 while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { 1184 while ((ch = getopt(ac, av, "cdksE:a:t:")) != -1) {
1073 switch (ch) { 1185 switch (ch) {
1186 case 'E':
1187 fingerprint_hash = ssh_digest_alg_by_name(optarg);
1188 if (fingerprint_hash == -1)
1189 fatal("Invalid hash algorithm \"%s\"", optarg);
1190 break;
1074 case 'c': 1191 case 'c':
1075 if (s_flag) 1192 if (s_flag)
1076 usage(); 1193 usage();