1 /* $NetBSD: ssh-agent.c,v 1.4 2009/12/27 01:40:47 christos Exp $ */ 2 /* $OpenBSD: ssh-agent.c,v 1.161 2009/03/23 19:38:04 tobias Exp $ */ 3 /* 4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 6 * All rights reserved 7 * The authentication agent program. 8 * 9 * As far as I am concerned, the code I have written for this software 10 * can be used freely for any purpose. Any derived versions of this 11 * software must be clearly marked as such, and if the derived work is 12 * incompatible with the protocol description in the RFC file, it must be 13 * called by a name other than "ssh" or "Secure Shell". 14 * 15 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions 19 * are met: 20 * 1. Redistributions of source code must retain the above copyright 21 * notice, this list of conditions and the following disclaimer. 22 * 2. Redistributions in binary form must reproduce the above copyright 23 * notice, this list of conditions and the following disclaimer in the 24 * documentation and/or other materials provided with the distribution. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 27 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 28 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 29 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 30 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 31 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 35 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 */ 37 38 #include "includes.h" 39 __RCSID("$NetBSD: ssh-agent.c,v 1.4 2009/12/27 01:40:47 christos Exp $"); 40 #include <sys/types.h> 41 #include <sys/time.h> 42 #include <sys/queue.h> 43 #include <sys/resource.h> 44 #include <sys/types.h> 45 #include <sys/socket.h> 46 #include <sys/un.h> 47 #include <sys/param.h> 48 49 #include <openssl/evp.h> 50 #include <openssl/md5.h> 51 52 #include <errno.h> 53 #include <fcntl.h> 54 #include <paths.h> 55 #include <signal.h> 56 #include <stdlib.h> 57 #include <stdio.h> 58 #include <string.h> 59 #include <time.h> 60 #include <unistd.h> 61 62 #include "xmalloc.h" 63 #include "ssh.h" 64 #include "rsa.h" 65 #include "buffer.h" 66 #include "key.h" 67 #include "authfd.h" 68 #include "compat.h" 69 #include "log.h" 70 #include "misc.h" 71 #include "getpeereid.h" 72 73 #ifdef SMARTCARD 74 #include "scard.h" 75 #endif 76 77 typedef enum { 78 AUTH_UNUSED, 79 AUTH_SOCKET, 80 AUTH_CONNECTION 81 } sock_type; 82 83 typedef struct { 84 int fd; 85 sock_type type; 86 Buffer input; 87 Buffer output; 88 Buffer request; 89 } SocketEntry; 90 91 u_int sockets_alloc = 0; 92 SocketEntry *sockets = NULL; 93 94 typedef struct identity { 95 TAILQ_ENTRY(identity) next; 96 Key *key; 97 char *comment; 98 u_int death; 99 u_int confirm; 100 } Identity; 101 102 typedef struct { 103 int nentries; 104 TAILQ_HEAD(idqueue, identity) idlist; 105 } Idtab; 106 107 /* private key table, one per protocol version */ 108 Idtab idtable[3]; 109 110 int max_fd = 0; 111 112 /* pid of shell == parent of agent */ 113 pid_t parent_pid = -1; 114 u_int parent_alive_interval = 0; 115 116 /* pathname and directory for AUTH_SOCKET */ 117 char socket_name[MAXPATHLEN]; 118 char socket_dir[MAXPATHLEN]; 119 120 /* locking */ 121 int locked = 0; 122 char *lock_passwd = NULL; 123 124 extern char *__progname; 125 126 /* Default lifetime (0 == forever) */ 127 static int lifetime = 0; 128 129 static void 130 close_socket(SocketEntry *e) 131 { 132 close(e->fd); 133 e->fd = -1; 134 e->type = AUTH_UNUSED; 135 buffer_free(&e->input); 136 buffer_free(&e->output); 137 buffer_free(&e->request); 138 } 139 140 static void 141 idtab_init(void) 142 { 143 int i; 144 145 for (i = 0; i <=2; i++) { 146 TAILQ_INIT(&idtable[i].idlist); 147 idtable[i].nentries = 0; 148 } 149 } 150 151 /* return private key table for requested protocol version */ 152 static Idtab * 153 idtab_lookup(int version) 154 { 155 if (version < 1 || version > 2) 156 fatal("internal error, bad protocol version %d", version); 157 return &idtable[version]; 158 } 159 160 static void 161 free_identity(Identity *id) 162 { 163 key_free(id->key); 164 xfree(id->comment); 165 xfree(id); 166 } 167 168 /* return matching private key for given public key */ 169 static Identity * 170 lookup_identity(Key *key, int version) 171 { 172 Identity *id; 173 174 Idtab *tab = idtab_lookup(version); 175 TAILQ_FOREACH(id, &tab->idlist, next) { 176 if (key_equal(key, id->key)) 177 return (id); 178 } 179 return (NULL); 180 } 181 182 /* Check confirmation of keysign request */ 183 static int 184 confirm_key(Identity *id) 185 { 186 char *p; 187 int ret = -1; 188 189 p = key_fingerprint(id->key, SSH_FP_MD5, SSH_FP_HEX); 190 if (ask_permission("Allow use of key %s?\nKey fingerprint %s.", 191 id->comment, p)) 192 ret = 0; 193 xfree(p); 194 195 return (ret); 196 } 197 198 /* send list of supported public keys to 'client' */ 199 static void 200 process_request_identities(SocketEntry *e, int version) 201 { 202 Idtab *tab = idtab_lookup(version); 203 Identity *id; 204 Buffer msg; 205 206 buffer_init(&msg); 207 buffer_put_char(&msg, (version == 1) ? 208 SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 209 buffer_put_int(&msg, tab->nentries); 210 TAILQ_FOREACH(id, &tab->idlist, next) { 211 if (id->key->type == KEY_RSA1) { 212 buffer_put_int(&msg, BN_num_bits(id->key->rsa->n)); 213 buffer_put_bignum(&msg, id->key->rsa->e); 214 buffer_put_bignum(&msg, id->key->rsa->n); 215 } else { 216 u_char *blob; 217 u_int blen; 218 key_to_blob(id->key, &blob, &blen); 219 buffer_put_string(&msg, blob, blen); 220 xfree(blob); 221 } 222 buffer_put_cstring(&msg, id->comment); 223 } 224 buffer_put_int(&e->output, buffer_len(&msg)); 225 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 226 buffer_free(&msg); 227 } 228 229 /* ssh1 only */ 230 static void 231 process_authentication_challenge1(SocketEntry *e) 232 { 233 u_char buf[32], mdbuf[16], session_id[16]; 234 u_int response_type; 235 BIGNUM *challenge; 236 Identity *id; 237 int i, len; 238 Buffer msg; 239 MD5_CTX md; 240 Key *key; 241 242 buffer_init(&msg); 243 key = key_new(KEY_RSA1); 244 if ((challenge = BN_new()) == NULL) 245 fatal("process_authentication_challenge1: BN_new failed"); 246 247 (void) buffer_get_int(&e->request); /* ignored */ 248 buffer_get_bignum(&e->request, key->rsa->e); 249 buffer_get_bignum(&e->request, key->rsa->n); 250 buffer_get_bignum(&e->request, challenge); 251 252 /* Only protocol 1.1 is supported */ 253 if (buffer_len(&e->request) == 0) 254 goto failure; 255 buffer_get(&e->request, session_id, 16); 256 response_type = buffer_get_int(&e->request); 257 if (response_type != 1) 258 goto failure; 259 260 id = lookup_identity(key, 1); 261 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) { 262 Key *private = id->key; 263 /* Decrypt the challenge using the private key. */ 264 if (rsa_private_decrypt(challenge, challenge, private->rsa) <= 0) 265 goto failure; 266 267 /* The response is MD5 of decrypted challenge plus session id. */ 268 len = BN_num_bytes(challenge); 269 if (len <= 0 || len > 32) { 270 logit("process_authentication_challenge: bad challenge length %d", len); 271 goto failure; 272 } 273 memset(buf, 0, 32); 274 BN_bn2bin(challenge, buf + 32 - len); 275 MD5_Init(&md); 276 MD5_Update(&md, buf, 32); 277 MD5_Update(&md, session_id, 16); 278 MD5_Final(mdbuf, &md); 279 280 /* Send the response. */ 281 buffer_put_char(&msg, SSH_AGENT_RSA_RESPONSE); 282 for (i = 0; i < 16; i++) 283 buffer_put_char(&msg, mdbuf[i]); 284 goto send; 285 } 286 287 failure: 288 /* Unknown identity or protocol error. Send failure. */ 289 buffer_put_char(&msg, SSH_AGENT_FAILURE); 290 send: 291 buffer_put_int(&e->output, buffer_len(&msg)); 292 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 293 key_free(key); 294 BN_clear_free(challenge); 295 buffer_free(&msg); 296 } 297 298 /* ssh2 only */ 299 static void 300 process_sign_request2(SocketEntry *e) 301 { 302 u_char *blob, *data, *signature = NULL; 303 u_int blen, dlen, slen = 0; 304 extern int datafellows; 305 int odatafellows; 306 int ok = -1, flags; 307 Buffer msg; 308 Key *key; 309 310 odatafellows = datafellows; 311 datafellows = 0; 312 313 blob = buffer_get_string(&e->request, &blen); 314 data = buffer_get_string(&e->request, &dlen); 315 316 flags = buffer_get_int(&e->request); 317 if (flags & SSH_AGENT_OLD_SIGNATURE) 318 datafellows = SSH_BUG_SIGBLOB; 319 320 key = key_from_blob(blob, blen); 321 if (key != NULL) { 322 Identity *id = lookup_identity(key, 2); 323 if (id != NULL && (!id->confirm || confirm_key(id) == 0)) 324 ok = key_sign(id->key, &signature, &slen, data, dlen); 325 key_free(key); 326 } 327 buffer_init(&msg); 328 if (ok == 0) { 329 buffer_put_char(&msg, SSH2_AGENT_SIGN_RESPONSE); 330 buffer_put_string(&msg, signature, slen); 331 } else { 332 buffer_put_char(&msg, SSH_AGENT_FAILURE); 333 } 334 buffer_put_int(&e->output, buffer_len(&msg)); 335 buffer_append(&e->output, buffer_ptr(&msg), 336 buffer_len(&msg)); 337 buffer_free(&msg); 338 xfree(data); 339 xfree(blob); 340 if (signature != NULL) 341 xfree(signature); 342 datafellows = odatafellows; 343 } 344 345 /* shared */ 346 static void 347 process_remove_identity(SocketEntry *e, int version) 348 { 349 u_int blen, bits; 350 int success = 0; 351 Key *key = NULL; 352 u_char *blob; 353 354 switch (version) { 355 case 1: 356 key = key_new(KEY_RSA1); 357 bits = buffer_get_int(&e->request); 358 buffer_get_bignum(&e->request, key->rsa->e); 359 buffer_get_bignum(&e->request, key->rsa->n); 360 361 if (bits != key_size(key)) 362 logit("Warning: identity keysize mismatch: actual %u, announced %u", 363 key_size(key), bits); 364 break; 365 case 2: 366 blob = buffer_get_string(&e->request, &blen); 367 key = key_from_blob(blob, blen); 368 xfree(blob); 369 break; 370 } 371 if (key != NULL) { 372 Identity *id = lookup_identity(key, version); 373 if (id != NULL) { 374 /* 375 * We have this key. Free the old key. Since we 376 * don't want to leave empty slots in the middle of 377 * the array, we actually free the key there and move 378 * all the entries between the empty slot and the end 379 * of the array. 380 */ 381 Idtab *tab = idtab_lookup(version); 382 if (tab->nentries < 1) 383 fatal("process_remove_identity: " 384 "internal error: tab->nentries %d", 385 tab->nentries); 386 TAILQ_REMOVE(&tab->idlist, id, next); 387 free_identity(id); 388 tab->nentries--; 389 success = 1; 390 } 391 key_free(key); 392 } 393 buffer_put_int(&e->output, 1); 394 buffer_put_char(&e->output, 395 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 396 } 397 398 static void 399 process_remove_all_identities(SocketEntry *e, int version) 400 { 401 Idtab *tab = idtab_lookup(version); 402 Identity *id; 403 404 /* Loop over all identities and clear the keys. */ 405 while ((id = TAILQ_FIRST(&tab->idlist)) != NULL) { 406 TAILQ_REMOVE(&tab->idlist, id, next); 407 free_identity(id); 408 } 409 410 /* Mark that there are no identities. */ 411 tab->nentries = 0; 412 413 /* Send success. */ 414 buffer_put_int(&e->output, 1); 415 buffer_put_char(&e->output, SSH_AGENT_SUCCESS); 416 } 417 418 /* removes expired keys and returns number of seconds until the next expiry */ 419 static u_int 420 reaper(void) 421 { 422 u_int deadline = 0, now = time(NULL); 423 Identity *id, *nxt; 424 int version; 425 Idtab *tab; 426 427 for (version = 1; version < 3; version++) { 428 tab = idtab_lookup(version); 429 for (id = TAILQ_FIRST(&tab->idlist); id; id = nxt) { 430 nxt = TAILQ_NEXT(id, next); 431 if (id->death == 0) 432 continue; 433 if (now >= id->death) { 434 debug("expiring key '%s'", id->comment); 435 TAILQ_REMOVE(&tab->idlist, id, next); 436 free_identity(id); 437 tab->nentries--; 438 } else 439 deadline = (deadline == 0) ? id->death : 440 MIN(deadline, id->death); 441 } 442 } 443 if (deadline == 0 || deadline <= now) 444 return 0; 445 else 446 return (deadline - now); 447 } 448 449 static void 450 process_add_identity(SocketEntry *e, int version) 451 { 452 Idtab *tab = idtab_lookup(version); 453 Identity *id; 454 int type, success = 0, death = 0, confirm = 0; 455 char *type_name, *comment; 456 Key *k = NULL; 457 458 switch (version) { 459 case 1: 460 k = key_new_private(KEY_RSA1); 461 (void) buffer_get_int(&e->request); /* ignored */ 462 buffer_get_bignum(&e->request, k->rsa->n); 463 buffer_get_bignum(&e->request, k->rsa->e); 464 buffer_get_bignum(&e->request, k->rsa->d); 465 buffer_get_bignum(&e->request, k->rsa->iqmp); 466 467 /* SSH and SSL have p and q swapped */ 468 buffer_get_bignum(&e->request, k->rsa->q); /* p */ 469 buffer_get_bignum(&e->request, k->rsa->p); /* q */ 470 471 /* Generate additional parameters */ 472 rsa_generate_additional_parameters(k->rsa); 473 break; 474 case 2: 475 type_name = buffer_get_string(&e->request, NULL); 476 type = key_type_from_name(type_name); 477 xfree(type_name); 478 switch (type) { 479 case KEY_DSA: 480 k = key_new_private(type); 481 buffer_get_bignum2(&e->request, k->dsa->p); 482 buffer_get_bignum2(&e->request, k->dsa->q); 483 buffer_get_bignum2(&e->request, k->dsa->g); 484 buffer_get_bignum2(&e->request, k->dsa->pub_key); 485 buffer_get_bignum2(&e->request, k->dsa->priv_key); 486 break; 487 case KEY_RSA: 488 k = key_new_private(type); 489 buffer_get_bignum2(&e->request, k->rsa->n); 490 buffer_get_bignum2(&e->request, k->rsa->e); 491 buffer_get_bignum2(&e->request, k->rsa->d); 492 buffer_get_bignum2(&e->request, k->rsa->iqmp); 493 buffer_get_bignum2(&e->request, k->rsa->p); 494 buffer_get_bignum2(&e->request, k->rsa->q); 495 496 /* Generate additional parameters */ 497 rsa_generate_additional_parameters(k->rsa); 498 break; 499 default: 500 buffer_clear(&e->request); 501 goto send; 502 } 503 break; 504 } 505 /* enable blinding */ 506 switch (k->type) { 507 case KEY_RSA: 508 case KEY_RSA1: 509 if (RSA_blinding_on(k->rsa, NULL) != 1) { 510 error("process_add_identity: RSA_blinding_on failed"); 511 key_free(k); 512 goto send; 513 } 514 break; 515 } 516 comment = buffer_get_string(&e->request, NULL); 517 if (k == NULL) { 518 xfree(comment); 519 goto send; 520 } 521 while (buffer_len(&e->request)) { 522 switch ((type = buffer_get_char(&e->request))) { 523 case SSH_AGENT_CONSTRAIN_LIFETIME: 524 death = time(NULL) + buffer_get_int(&e->request); 525 break; 526 case SSH_AGENT_CONSTRAIN_CONFIRM: 527 confirm = 1; 528 break; 529 default: 530 error("process_add_identity: " 531 "Unknown constraint type %d", type); 532 xfree(comment); 533 key_free(k); 534 goto send; 535 } 536 } 537 success = 1; 538 if (lifetime && !death) 539 death = time(NULL) + lifetime; 540 if ((id = lookup_identity(k, version)) == NULL) { 541 id = xmalloc(sizeof(Identity)); 542 id->key = k; 543 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 544 /* Increment the number of identities. */ 545 tab->nentries++; 546 } else { 547 key_free(k); 548 xfree(id->comment); 549 } 550 id->comment = comment; 551 id->death = death; 552 id->confirm = confirm; 553 send: 554 buffer_put_int(&e->output, 1); 555 buffer_put_char(&e->output, 556 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 557 } 558 559 /* XXX todo: encrypt sensitive data with passphrase */ 560 static void 561 process_lock_agent(SocketEntry *e, int lock) 562 { 563 int success = 0; 564 char *passwd; 565 566 passwd = buffer_get_string(&e->request, NULL); 567 if (locked && !lock && strcmp(passwd, lock_passwd) == 0) { 568 locked = 0; 569 memset(lock_passwd, 0, strlen(lock_passwd)); 570 xfree(lock_passwd); 571 lock_passwd = NULL; 572 success = 1; 573 } else if (!locked && lock) { 574 locked = 1; 575 lock_passwd = xstrdup(passwd); 576 success = 1; 577 } 578 memset(passwd, 0, strlen(passwd)); 579 xfree(passwd); 580 581 buffer_put_int(&e->output, 1); 582 buffer_put_char(&e->output, 583 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 584 } 585 586 static void 587 no_identities(SocketEntry *e, u_int type) 588 { 589 Buffer msg; 590 591 buffer_init(&msg); 592 buffer_put_char(&msg, 593 (type == SSH_AGENTC_REQUEST_RSA_IDENTITIES) ? 594 SSH_AGENT_RSA_IDENTITIES_ANSWER : SSH2_AGENT_IDENTITIES_ANSWER); 595 buffer_put_int(&msg, 0); 596 buffer_put_int(&e->output, buffer_len(&msg)); 597 buffer_append(&e->output, buffer_ptr(&msg), buffer_len(&msg)); 598 buffer_free(&msg); 599 } 600 601 #ifdef SMARTCARD 602 static void 603 process_add_smartcard_key(SocketEntry *e) 604 { 605 char *sc_reader_id = NULL, *pin; 606 int i, type, version, success = 0, death = 0, confirm = 0; 607 Key **keys, *k; 608 Identity *id; 609 Idtab *tab; 610 611 sc_reader_id = buffer_get_string(&e->request, NULL); 612 pin = buffer_get_string(&e->request, NULL); 613 614 while (buffer_len(&e->request)) { 615 switch ((type = buffer_get_char(&e->request))) { 616 case SSH_AGENT_CONSTRAIN_LIFETIME: 617 death = time(NULL) + buffer_get_int(&e->request); 618 break; 619 case SSH_AGENT_CONSTRAIN_CONFIRM: 620 confirm = 1; 621 break; 622 default: 623 error("process_add_smartcard_key: " 624 "Unknown constraint type %d", type); 625 xfree(sc_reader_id); 626 xfree(pin); 627 goto send; 628 } 629 } 630 if (lifetime && !death) 631 death = time(NULL) + lifetime; 632 633 keys = sc_get_keys(sc_reader_id, pin); 634 xfree(sc_reader_id); 635 xfree(pin); 636 637 if (keys == NULL || keys[0] == NULL) { 638 error("sc_get_keys failed"); 639 goto send; 640 } 641 for (i = 0; keys[i] != NULL; i++) { 642 k = keys[i]; 643 version = k->type == KEY_RSA1 ? 1 : 2; 644 tab = idtab_lookup(version); 645 if (lookup_identity(k, version) == NULL) { 646 id = xmalloc(sizeof(Identity)); 647 id->key = k; 648 id->comment = sc_get_key_label(k); 649 id->death = death; 650 id->confirm = confirm; 651 TAILQ_INSERT_TAIL(&tab->idlist, id, next); 652 tab->nentries++; 653 success = 1; 654 } else { 655 key_free(k); 656 } 657 keys[i] = NULL; 658 } 659 xfree(keys); 660 send: 661 buffer_put_int(&e->output, 1); 662 buffer_put_char(&e->output, 663 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 664 } 665 666 static void 667 process_remove_smartcard_key(SocketEntry *e) 668 { 669 char *sc_reader_id = NULL, *pin; 670 int i, version, success = 0; 671 Key **keys, *k = NULL; 672 Identity *id; 673 Idtab *tab; 674 675 sc_reader_id = buffer_get_string(&e->request, NULL); 676 pin = buffer_get_string(&e->request, NULL); 677 keys = sc_get_keys(sc_reader_id, pin); 678 xfree(sc_reader_id); 679 xfree(pin); 680 681 if (keys == NULL || keys[0] == NULL) { 682 error("sc_get_keys failed"); 683 goto send; 684 } 685 for (i = 0; keys[i] != NULL; i++) { 686 k = keys[i]; 687 version = k->type == KEY_RSA1 ? 1 : 2; 688 if ((id = lookup_identity(k, version)) != NULL) { 689 tab = idtab_lookup(version); 690 TAILQ_REMOVE(&tab->idlist, id, next); 691 tab->nentries--; 692 free_identity(id); 693 success = 1; 694 } 695 key_free(k); 696 keys[i] = NULL; 697 } 698 xfree(keys); 699 send: 700 buffer_put_int(&e->output, 1); 701 buffer_put_char(&e->output, 702 success ? SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE); 703 } 704 #endif /* SMARTCARD */ 705 706 /* dispatch incoming messages */ 707 708 static void 709 process_message(SocketEntry *e) 710 { 711 u_int msg_len, type; 712 u_char *cp; 713 714 if (buffer_len(&e->input) < 5) 715 return; /* Incomplete message. */ 716 cp = buffer_ptr(&e->input); 717 msg_len = get_u32(cp); 718 if (msg_len > 256 * 1024) { 719 close_socket(e); 720 return; 721 } 722 if (buffer_len(&e->input) < msg_len + 4) 723 return; 724 725 /* move the current input to e->request */ 726 buffer_consume(&e->input, 4); 727 buffer_clear(&e->request); 728 buffer_append(&e->request, buffer_ptr(&e->input), msg_len); 729 buffer_consume(&e->input, msg_len); 730 type = buffer_get_char(&e->request); 731 732 /* check wheter agent is locked */ 733 if (locked && type != SSH_AGENTC_UNLOCK) { 734 buffer_clear(&e->request); 735 switch (type) { 736 case SSH_AGENTC_REQUEST_RSA_IDENTITIES: 737 case SSH2_AGENTC_REQUEST_IDENTITIES: 738 /* send empty lists */ 739 no_identities(e, type); 740 break; 741 default: 742 /* send a fail message for all other request types */ 743 buffer_put_int(&e->output, 1); 744 buffer_put_char(&e->output, SSH_AGENT_FAILURE); 745 } 746 return; 747 } 748 749 debug("type %d", type); 750 switch (type) { 751 case SSH_AGENTC_LOCK: 752 case SSH_AGENTC_UNLOCK: 753 process_lock_agent(e, type == SSH_AGENTC_LOCK); 754 break; 755 /* ssh1 */ 756 case SSH_AGENTC_RSA_CHALLENGE: 757 process_authentication_challenge1(e); 758 break; 759 case SSH_AGENTC_REQUEST_RSA_IDENTITIES: 760 process_request_identities(e, 1); 761 break; 762 case SSH_AGENTC_ADD_RSA_IDENTITY: 763 case SSH_AGENTC_ADD_RSA_ID_CONSTRAINED: 764 process_add_identity(e, 1); 765 break; 766 case SSH_AGENTC_REMOVE_RSA_IDENTITY: 767 process_remove_identity(e, 1); 768 break; 769 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: 770 process_remove_all_identities(e, 1); 771 break; 772 /* ssh2 */ 773 case SSH2_AGENTC_SIGN_REQUEST: 774 process_sign_request2(e); 775 break; 776 case SSH2_AGENTC_REQUEST_IDENTITIES: 777 process_request_identities(e, 2); 778 break; 779 case SSH2_AGENTC_ADD_IDENTITY: 780 case SSH2_AGENTC_ADD_ID_CONSTRAINED: 781 process_add_identity(e, 2); 782 break; 783 case SSH2_AGENTC_REMOVE_IDENTITY: 784 process_remove_identity(e, 2); 785 break; 786 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: 787 process_remove_all_identities(e, 2); 788 break; 789 #ifdef SMARTCARD 790 case SSH_AGENTC_ADD_SMARTCARD_KEY: 791 case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: 792 process_add_smartcard_key(e); 793 break; 794 case SSH_AGENTC_REMOVE_SMARTCARD_KEY: 795 process_remove_smartcard_key(e); 796 break; 797 #endif /* SMARTCARD */ 798 default: 799 /* Unknown message. Respond with failure. */ 800 error("Unknown message %d", type); 801 buffer_clear(&e->request); 802 buffer_put_int(&e->output, 1); 803 buffer_put_char(&e->output, SSH_AGENT_FAILURE); 804 break; 805 } 806 } 807 808 static void 809 new_socket(sock_type type, int fd) 810 { 811 u_int i, old_alloc, new_alloc; 812 813 set_nonblock(fd); 814 815 if (fd > max_fd) 816 max_fd = fd; 817 818 for (i = 0; i < sockets_alloc; i++) 819 if (sockets[i].type == AUTH_UNUSED) { 820 sockets[i].fd = fd; 821 buffer_init(&sockets[i].input); 822 buffer_init(&sockets[i].output); 823 buffer_init(&sockets[i].request); 824 sockets[i].type = type; 825 return; 826 } 827 old_alloc = sockets_alloc; 828 new_alloc = sockets_alloc + 10; 829 sockets = xrealloc(sockets, new_alloc, sizeof(sockets[0])); 830 for (i = old_alloc; i < new_alloc; i++) 831 sockets[i].type = AUTH_UNUSED; 832 sockets_alloc = new_alloc; 833 sockets[old_alloc].fd = fd; 834 buffer_init(&sockets[old_alloc].input); 835 buffer_init(&sockets[old_alloc].output); 836 buffer_init(&sockets[old_alloc].request); 837 sockets[old_alloc].type = type; 838 } 839 840 static int 841 prepare_select(fd_set **fdrp, fd_set **fdwp, int *fdl, u_int *nallocp, 842 struct timeval **tvpp) 843 { 844 u_int i, sz, deadline; 845 int n = 0; 846 static struct timeval tv; 847 848 for (i = 0; i < sockets_alloc; i++) { 849 switch (sockets[i].type) { 850 case AUTH_SOCKET: 851 case AUTH_CONNECTION: 852 n = MAX(n, sockets[i].fd); 853 break; 854 case AUTH_UNUSED: 855 break; 856 default: 857 fatal("Unknown socket type %d", sockets[i].type); 858 break; 859 } 860 } 861 862 sz = howmany(n+1, NFDBITS) * sizeof(fd_mask); 863 if (*fdrp == NULL || sz > *nallocp) { 864 if (*fdrp) 865 xfree(*fdrp); 866 if (*fdwp) 867 xfree(*fdwp); 868 *fdrp = xmalloc(sz); 869 *fdwp = xmalloc(sz); 870 *nallocp = sz; 871 } 872 if (n < *fdl) 873 debug("XXX shrink: %d < %d", n, *fdl); 874 *fdl = n; 875 memset(*fdrp, 0, sz); 876 memset(*fdwp, 0, sz); 877 878 for (i = 0; i < sockets_alloc; i++) { 879 switch (sockets[i].type) { 880 case AUTH_SOCKET: 881 case AUTH_CONNECTION: 882 FD_SET(sockets[i].fd, *fdrp); 883 if (buffer_len(&sockets[i].output) > 0) 884 FD_SET(sockets[i].fd, *fdwp); 885 break; 886 default: 887 break; 888 } 889 } 890 deadline = reaper(); 891 if (parent_alive_interval != 0) 892 deadline = (deadline == 0) ? parent_alive_interval : 893 MIN(deadline, parent_alive_interval); 894 if (deadline == 0) { 895 *tvpp = NULL; 896 } else { 897 tv.tv_sec = deadline; 898 tv.tv_usec = 0; 899 *tvpp = &tv; 900 } 901 return (1); 902 } 903 904 static void 905 after_select(fd_set *readset, fd_set *writeset) 906 { 907 struct sockaddr_un sunaddr; 908 socklen_t slen; 909 char buf[1024]; 910 int len, sock; 911 u_int i; 912 uid_t euid; 913 gid_t egid; 914 915 for (i = 0; i < sockets_alloc; i++) 916 switch (sockets[i].type) { 917 case AUTH_UNUSED: 918 break; 919 case AUTH_SOCKET: 920 if (FD_ISSET(sockets[i].fd, readset)) { 921 slen = sizeof(sunaddr); 922 sock = accept(sockets[i].fd, 923 (struct sockaddr *)&sunaddr, &slen); 924 if (sock < 0) { 925 error("accept from AUTH_SOCKET: %s", 926 strerror(errno)); 927 break; 928 } 929 if (getpeereid(sock, &euid, &egid) < 0) { 930 error("getpeereid %d failed: %s", 931 sock, strerror(errno)); 932 close(sock); 933 break; 934 } 935 if ((euid != 0) && (getuid() != euid)) { 936 error("uid mismatch: " 937 "peer euid %u != uid %u", 938 (u_int) euid, (u_int) getuid()); 939 close(sock); 940 break; 941 } 942 new_socket(AUTH_CONNECTION, sock); 943 } 944 break; 945 case AUTH_CONNECTION: 946 if (buffer_len(&sockets[i].output) > 0 && 947 FD_ISSET(sockets[i].fd, writeset)) { 948 do { 949 len = write(sockets[i].fd, 950 buffer_ptr(&sockets[i].output), 951 buffer_len(&sockets[i].output)); 952 if (len == -1 && (errno == EAGAIN || 953 errno == EINTR)) 954 continue; 955 break; 956 } while (1); 957 if (len <= 0) { 958 close_socket(&sockets[i]); 959 break; 960 } 961 buffer_consume(&sockets[i].output, len); 962 } 963 if (FD_ISSET(sockets[i].fd, readset)) { 964 do { 965 len = read(sockets[i].fd, buf, sizeof(buf)); 966 if (len == -1 && (errno == EAGAIN || 967 errno == EINTR)) 968 continue; 969 break; 970 } while (1); 971 if (len <= 0) { 972 close_socket(&sockets[i]); 973 break; 974 } 975 buffer_append(&sockets[i].input, buf, len); 976 process_message(&sockets[i]); 977 } 978 break; 979 default: 980 fatal("Unknown type %d", sockets[i].type); 981 } 982 } 983 984 static void 985 cleanup_socket(void) 986 { 987 if (socket_name[0]) 988 unlink(socket_name); 989 if (socket_dir[0]) 990 rmdir(socket_dir); 991 } 992 993 void 994 cleanup_exit(int i) 995 { 996 cleanup_socket(); 997 _exit(i); 998 } 999 1000 /*ARGSUSED*/ 1001 static void 1002 cleanup_handler(int sig) 1003 { 1004 cleanup_socket(); 1005 _exit(2); 1006 } 1007 1008 static void 1009 check_parent_exists(void) 1010 { 1011 if (parent_pid != -1 && kill(parent_pid, 0) < 0) { 1012 /* printf("Parent has died - Authentication agent exiting.\n"); */ 1013 cleanup_socket(); 1014 _exit(2); 1015 } 1016 } 1017 1018 static void 1019 usage(void) 1020 { 1021 fprintf(stderr, "usage: %s [options] [command [arg ...]]\n", 1022 __progname); 1023 fprintf(stderr, "Options:\n"); 1024 fprintf(stderr, " -c Generate C-shell commands on stdout.\n"); 1025 fprintf(stderr, " -s Generate Bourne shell commands on stdout.\n"); 1026 fprintf(stderr, " -k Kill the current agent.\n"); 1027 fprintf(stderr, " -d Debug mode.\n"); 1028 fprintf(stderr, " -a socket Bind agent socket to given name.\n"); 1029 fprintf(stderr, " -t life Default identity lifetime (seconds).\n"); 1030 exit(1); 1031 } 1032 1033 int 1034 main(int ac, char **av) 1035 { 1036 int c_flag = 0, d_flag = 0, k_flag = 0, s_flag = 0; 1037 int sock, fd, ch, result, saved_errno; 1038 u_int nalloc; 1039 char *shell, *format, *pidstr, *agentsocket = NULL; 1040 fd_set *readsetp = NULL, *writesetp = NULL; 1041 struct sockaddr_un sunaddr; 1042 struct rlimit rlim; 1043 extern int optind; 1044 extern char *optarg; 1045 pid_t pid; 1046 char pidstrbuf[1 + 3 * sizeof pid]; 1047 struct timeval *tvp = NULL; 1048 size_t len; 1049 1050 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1051 sanitise_stdfd(); 1052 1053 /* drop */ 1054 setegid(getgid()); 1055 setgid(getgid()); 1056 1057 SSLeay_add_all_algorithms(); 1058 1059 while ((ch = getopt(ac, av, "cdksa:t:")) != -1) { 1060 switch (ch) { 1061 case 'c': 1062 if (s_flag) 1063 usage(); 1064 c_flag++; 1065 break; 1066 case 'k': 1067 k_flag++; 1068 break; 1069 case 's': 1070 if (c_flag) 1071 usage(); 1072 s_flag++; 1073 break; 1074 case 'd': 1075 if (d_flag) 1076 usage(); 1077 d_flag++; 1078 break; 1079 case 'a': 1080 agentsocket = optarg; 1081 break; 1082 case 't': 1083 if ((lifetime = convtime(optarg)) == -1) { 1084 fprintf(stderr, "Invalid lifetime\n"); 1085 usage(); 1086 } 1087 break; 1088 default: 1089 usage(); 1090 } 1091 } 1092 ac -= optind; 1093 av += optind; 1094 1095 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag)) 1096 usage(); 1097 1098 if (ac == 0 && !c_flag && !s_flag) { 1099 shell = getenv("SHELL"); 1100 if (shell != NULL && (len = strlen(shell)) > 2 && 1101 strncmp(shell + len - 3, "csh", 3) == 0) 1102 c_flag = 1; 1103 } 1104 if (k_flag) { 1105 const char *errstr = NULL; 1106 1107 pidstr = getenv(SSH_AGENTPID_ENV_NAME); 1108 if (pidstr == NULL) { 1109 fprintf(stderr, "%s not set, cannot kill agent\n", 1110 SSH_AGENTPID_ENV_NAME); 1111 exit(1); 1112 } 1113 pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr); 1114 if (errstr) { 1115 fprintf(stderr, 1116 "%s=\"%s\", which is not a good PID: %s\n", 1117 SSH_AGENTPID_ENV_NAME, pidstr, errstr); 1118 exit(1); 1119 } 1120 if (kill(pid, SIGTERM) == -1) { 1121 perror("kill"); 1122 exit(1); 1123 } 1124 format = c_flag ? "unsetenv %s;\n" : "unset %s;\n"; 1125 printf(format, SSH_AUTHSOCKET_ENV_NAME); 1126 printf(format, SSH_AGENTPID_ENV_NAME); 1127 printf("echo Agent pid %ld killed;\n", (long)pid); 1128 exit(0); 1129 } 1130 parent_pid = getpid(); 1131 1132 if (agentsocket == NULL) { 1133 /* Create private directory for agent socket */ 1134 strlcpy(socket_dir, "/tmp/ssh-XXXXXXXXXX", sizeof socket_dir); 1135 if (mkdtemp(socket_dir) == NULL) { 1136 perror("mkdtemp: private socket dir"); 1137 exit(1); 1138 } 1139 snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, 1140 (long)parent_pid); 1141 } else { 1142 /* Try to use specified agent socket */ 1143 socket_dir[0] = '\0'; 1144 strlcpy(socket_name, agentsocket, sizeof socket_name); 1145 } 1146 1147 /* 1148 * Create socket early so it will exist before command gets run from 1149 * the parent. 1150 */ 1151 sock = socket(AF_UNIX, SOCK_STREAM, 0); 1152 if (sock < 0) { 1153 perror("socket"); 1154 *socket_name = '\0'; /* Don't unlink any existing file */ 1155 cleanup_exit(1); 1156 } 1157 memset(&sunaddr, 0, sizeof(sunaddr)); 1158 sunaddr.sun_family = AF_UNIX; 1159 strlcpy(sunaddr.sun_path, socket_name, sizeof(sunaddr.sun_path)); 1160 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { 1161 perror("bind"); 1162 *socket_name = '\0'; /* Don't unlink any existing file */ 1163 cleanup_exit(1); 1164 } 1165 if (listen(sock, SSH_LISTEN_BACKLOG) < 0) { 1166 perror("listen"); 1167 cleanup_exit(1); 1168 } 1169 1170 /* 1171 * Fork, and have the parent execute the command, if any, or present 1172 * the socket data. The child continues as the authentication agent. 1173 */ 1174 if (d_flag) { 1175 log_init(__progname, SYSLOG_LEVEL_DEBUG1, SYSLOG_FACILITY_AUTH, 1); 1176 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; 1177 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, 1178 SSH_AUTHSOCKET_ENV_NAME); 1179 printf("echo Agent pid %ld;\n", (long)parent_pid); 1180 goto skip; 1181 } 1182 pid = fork(); 1183 if (pid == -1) { 1184 perror("fork"); 1185 cleanup_exit(1); 1186 } 1187 if (pid != 0) { /* Parent - execute the given command. */ 1188 close(sock); 1189 snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid); 1190 if (ac == 0) { 1191 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; 1192 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, 1193 SSH_AUTHSOCKET_ENV_NAME); 1194 printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, 1195 SSH_AGENTPID_ENV_NAME); 1196 printf("echo Agent pid %ld;\n", (long)pid); 1197 exit(0); 1198 } 1199 if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 || 1200 setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) { 1201 perror("setenv"); 1202 exit(1); 1203 } 1204 execvp(av[0], av); 1205 perror(av[0]); 1206 exit(1); 1207 } 1208 /* child */ 1209 log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0); 1210 1211 if (setsid() == -1) { 1212 error("setsid: %s", strerror(errno)); 1213 cleanup_exit(1); 1214 } 1215 1216 (void)chdir("/"); 1217 if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { 1218 /* XXX might close listen socket */ 1219 (void)dup2(fd, STDIN_FILENO); 1220 (void)dup2(fd, STDOUT_FILENO); 1221 (void)dup2(fd, STDERR_FILENO); 1222 if (fd > 2) 1223 close(fd); 1224 } 1225 1226 /* deny core dumps, since memory contains unencrypted private keys */ 1227 rlim.rlim_cur = rlim.rlim_max = 0; 1228 if (setrlimit(RLIMIT_CORE, &rlim) < 0) { 1229 error("setrlimit RLIMIT_CORE: %s", strerror(errno)); 1230 cleanup_exit(1); 1231 } 1232 1233 skip: 1234 new_socket(AUTH_SOCKET, sock); 1235 if (ac > 0) 1236 parent_alive_interval = 10; 1237 idtab_init(); 1238 if (!d_flag) 1239 signal(SIGINT, SIG_IGN); 1240 signal(SIGPIPE, SIG_IGN); 1241 signal(SIGHUP, cleanup_handler); 1242 signal(SIGTERM, cleanup_handler); 1243 nalloc = 0; 1244 1245 while (1) { 1246 prepare_select(&readsetp, &writesetp, &max_fd, &nalloc, &tvp); 1247 result = select(max_fd + 1, readsetp, writesetp, NULL, tvp); 1248 saved_errno = errno; 1249 if (parent_alive_interval != 0) 1250 check_parent_exists(); 1251 (void) reaper(); /* remove expired keys */ 1252 if (result < 0) { 1253 if (saved_errno == EINTR) 1254 continue; 1255 fatal("select: %s", strerror(saved_errno)); 1256 } else if (result > 0) 1257 after_select(readsetp, writesetp); 1258 } 1259 /* NOTREACHED */ 1260 } 1261