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