1 /* $OpenBSD: ssh-agent.c,v 1.278 2021/04/03 06:18:41 djm 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 "includes.h" 38 39 #include <sys/types.h> 40 #include <sys/param.h> 41 #include <sys/resource.h> 42 #include <sys/stat.h> 43 #include <sys/socket.h> 44 #include <sys/wait.h> 45 #ifdef HAVE_SYS_TIME_H 46 # include <sys/time.h> 47 #endif 48 #ifdef HAVE_SYS_UN_H 49 # include <sys/un.h> 50 #endif 51 #include "openbsd-compat/sys-queue.h" 52 53 #ifdef WITH_OPENSSL 54 #include <openssl/evp.h> 55 #include "openbsd-compat/openssl-compat.h" 56 #endif 57 58 #include <errno.h> 59 #include <fcntl.h> 60 #include <limits.h> 61 #ifdef HAVE_PATHS_H 62 # include <paths.h> 63 #endif 64 #ifdef HAVE_POLL_H 65 # include <poll.h> 66 #endif 67 #include <signal.h> 68 #include <stdarg.h> 69 #include <stdio.h> 70 #include <stdlib.h> 71 #include <time.h> 72 #include <string.h> 73 #include <unistd.h> 74 #ifdef HAVE_UTIL_H 75 # include <util.h> 76 #endif 77 78 #include "xmalloc.h" 79 #include "ssh.h" 80 #include "ssh2.h" 81 #include "sshbuf.h" 82 #include "sshkey.h" 83 #include "authfd.h" 84 #include "compat.h" 85 #include "log.h" 86 #include "misc.h" 87 #include "digest.h" 88 #include "ssherr.h" 89 #include "match.h" 90 #include "msg.h" 91 #include "ssherr.h" 92 #include "pathnames.h" 93 #include "ssh-pkcs11.h" 94 #include "sk-api.h" 95 96 #ifndef DEFAULT_ALLOWED_PROVIDERS 97 # define DEFAULT_ALLOWED_PROVIDERS "/usr/lib*/*,/usr/local/lib*/*" 98 #endif 99 100 /* Maximum accepted message length */ 101 #define AGENT_MAX_LEN (256*1024) 102 /* Maximum bytes to read from client socket */ 103 #define AGENT_RBUF_LEN (4096) 104 105 typedef enum { 106 AUTH_UNUSED = 0, 107 AUTH_SOCKET = 1, 108 AUTH_CONNECTION = 2, 109 } sock_type; 110 111 typedef struct socket_entry { 112 int fd; 113 sock_type type; 114 struct sshbuf *input; 115 struct sshbuf *output; 116 struct sshbuf *request; 117 } SocketEntry; 118 119 u_int sockets_alloc = 0; 120 SocketEntry *sockets = NULL; 121 122 typedef struct identity { 123 TAILQ_ENTRY(identity) next; 124 struct sshkey *key; 125 char *comment; 126 char *provider; 127 time_t death; 128 u_int confirm; 129 char *sk_provider; 130 } Identity; 131 132 struct idtable { 133 int nentries; 134 TAILQ_HEAD(idqueue, identity) idlist; 135 }; 136 137 /* private key table */ 138 struct idtable *idtab; 139 140 int max_fd = 0; 141 142 /* pid of shell == parent of agent */ 143 pid_t parent_pid = -1; 144 time_t parent_alive_interval = 0; 145 146 /* pid of process for which cleanup_socket is applicable */ 147 pid_t cleanup_pid = 0; 148 149 /* pathname and directory for AUTH_SOCKET */ 150 char socket_name[PATH_MAX]; 151 char socket_dir[PATH_MAX]; 152 153 /* Pattern-list of allowed PKCS#11/Security key paths */ 154 static char *allowed_providers; 155 156 /* locking */ 157 #define LOCK_SIZE 32 158 #define LOCK_SALT_SIZE 16 159 #define LOCK_ROUNDS 1 160 int locked = 0; 161 u_char lock_pwhash[LOCK_SIZE]; 162 u_char lock_salt[LOCK_SALT_SIZE]; 163 164 extern char *__progname; 165 166 /* Default lifetime in seconds (0 == forever) */ 167 static int lifetime = 0; 168 169 static int fingerprint_hash = SSH_FP_HASH_DEFAULT; 170 171 /* Refuse signing of non-SSH messages for web-origin FIDO keys */ 172 static int restrict_websafe = 1; 173 174 static void 175 close_socket(SocketEntry *e) 176 { 177 close(e->fd); 178 sshbuf_free(e->input); 179 sshbuf_free(e->output); 180 sshbuf_free(e->request); 181 memset(e, '\0', sizeof(*e)); 182 e->fd = -1; 183 e->type = AUTH_UNUSED; 184 } 185 186 static void 187 idtab_init(void) 188 { 189 idtab = xcalloc(1, sizeof(*idtab)); 190 TAILQ_INIT(&idtab->idlist); 191 idtab->nentries = 0; 192 } 193 194 static void 195 free_identity(Identity *id) 196 { 197 sshkey_free(id->key); 198 free(id->provider); 199 free(id->comment); 200 free(id->sk_provider); 201 free(id); 202 } 203 204 /* return matching private key for given public key */ 205 static Identity * 206 lookup_identity(struct sshkey *key) 207 { 208 Identity *id; 209 210 TAILQ_FOREACH(id, &idtab->idlist, next) { 211 if (sshkey_equal(key, id->key)) 212 return (id); 213 } 214 return (NULL); 215 } 216 217 /* Check confirmation of keysign request */ 218 static int 219 confirm_key(Identity *id, const char *extra) 220 { 221 char *p; 222 int ret = -1; 223 224 p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); 225 if (p != NULL && 226 ask_permission("Allow use of key %s?\nKey fingerprint %s.%s%s", 227 id->comment, p, 228 extra == NULL ? "" : "\n", extra == NULL ? "" : extra)) 229 ret = 0; 230 free(p); 231 232 return (ret); 233 } 234 235 static void 236 send_status(SocketEntry *e, int success) 237 { 238 int r; 239 240 if ((r = sshbuf_put_u32(e->output, 1)) != 0 || 241 (r = sshbuf_put_u8(e->output, success ? 242 SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0) 243 fatal_fr(r, "compose"); 244 } 245 246 /* send list of supported public keys to 'client' */ 247 static void 248 process_request_identities(SocketEntry *e) 249 { 250 Identity *id; 251 struct sshbuf *msg; 252 int r; 253 254 debug2_f("entering"); 255 256 if ((msg = sshbuf_new()) == NULL) 257 fatal_f("sshbuf_new failed"); 258 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || 259 (r = sshbuf_put_u32(msg, idtab->nentries)) != 0) 260 fatal_fr(r, "compose"); 261 TAILQ_FOREACH(id, &idtab->idlist, next) { 262 if ((r = sshkey_puts_opts(id->key, msg, 263 SSHKEY_SERIALIZE_INFO)) != 0 || 264 (r = sshbuf_put_cstring(msg, id->comment)) != 0) { 265 error_fr(r, "compose key/comment"); 266 continue; 267 } 268 } 269 if ((r = sshbuf_put_stringb(e->output, msg)) != 0) 270 fatal_fr(r, "enqueue"); 271 sshbuf_free(msg); 272 } 273 274 275 static char * 276 agent_decode_alg(struct sshkey *key, u_int flags) 277 { 278 if (key->type == KEY_RSA) { 279 if (flags & SSH_AGENT_RSA_SHA2_256) 280 return "rsa-sha2-256"; 281 else if (flags & SSH_AGENT_RSA_SHA2_512) 282 return "rsa-sha2-512"; 283 } else if (key->type == KEY_RSA_CERT) { 284 if (flags & SSH_AGENT_RSA_SHA2_256) 285 return "rsa-sha2-256-cert-v01@openssh.com"; 286 else if (flags & SSH_AGENT_RSA_SHA2_512) 287 return "rsa-sha2-512-cert-v01@openssh.com"; 288 } 289 return NULL; 290 } 291 292 /* 293 * Attempt to parse the contents of a buffer as a SSH publickey userauth 294 * request, checking its contents for consistency and matching the embedded 295 * key against the one that is being used for signing. 296 * Note: does not modify msg buffer. 297 * Optionally extract the username and session ID from the request. 298 */ 299 static int 300 parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key, 301 char **userp, struct sshbuf **sess_idp) 302 { 303 struct sshbuf *b = NULL, *sess_id = NULL; 304 char *user = NULL, *service = NULL, *method = NULL, *pkalg = NULL; 305 int r; 306 u_char t, sig_follows; 307 struct sshkey *mkey = NULL; 308 309 if (userp != NULL) 310 *userp = NULL; 311 if (sess_idp != NULL) 312 *sess_idp = NULL; 313 if ((b = sshbuf_fromb(msg)) == NULL) 314 fatal_f("sshbuf_fromb"); 315 316 /* SSH userauth request */ 317 if ((r = sshbuf_froms(b, &sess_id)) != 0) 318 goto out; 319 if (sshbuf_len(sess_id) == 0) { 320 r = SSH_ERR_INVALID_FORMAT; 321 goto out; 322 } 323 if ((r = sshbuf_get_u8(b, &t)) != 0 || /* SSH2_MSG_USERAUTH_REQUEST */ 324 (r = sshbuf_get_cstring(b, &user, NULL)) != 0 || /* server user */ 325 (r = sshbuf_get_cstring(b, &service, NULL)) != 0 || /* service */ 326 (r = sshbuf_get_cstring(b, &method, NULL)) != 0 || /* method */ 327 (r = sshbuf_get_u8(b, &sig_follows)) != 0 || /* sig-follows */ 328 (r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || /* alg */ 329 (r = sshkey_froms(b, &mkey)) != 0) /* key */ 330 goto out; 331 if (t != SSH2_MSG_USERAUTH_REQUEST || 332 sig_follows != 1 || 333 strcmp(service, "ssh-connection") != 0 || 334 !sshkey_equal(expected_key, mkey) || 335 sshkey_type_from_name(pkalg) != expected_key->type) { 336 r = SSH_ERR_INVALID_FORMAT; 337 goto out; 338 } 339 if (strcmp(method, "publickey") != 0) { 340 r = SSH_ERR_INVALID_FORMAT; 341 goto out; 342 } 343 if (sshbuf_len(b) != 0) { 344 r = SSH_ERR_INVALID_FORMAT; 345 goto out; 346 } 347 /* success */ 348 r = 0; 349 debug3_f("well formed userauth"); 350 if (userp != NULL) { 351 *userp = user; 352 user = NULL; 353 } 354 if (sess_idp != NULL) { 355 *sess_idp = sess_id; 356 sess_id = NULL; 357 } 358 out: 359 sshbuf_free(b); 360 sshbuf_free(sess_id); 361 free(user); 362 free(service); 363 free(method); 364 free(pkalg); 365 sshkey_free(mkey); 366 return r; 367 } 368 369 /* 370 * Attempt to parse the contents of a buffer as a SSHSIG signature request. 371 * Note: does not modify buffer. 372 */ 373 static int 374 parse_sshsig_request(struct sshbuf *msg) 375 { 376 int r; 377 struct sshbuf *b; 378 379 if ((b = sshbuf_fromb(msg)) == NULL) 380 fatal_f("sshbuf_fromb"); 381 382 if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) != 0 || 383 (r = sshbuf_consume(b, 6)) != 0 || 384 (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* namespace */ 385 (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || /* reserved */ 386 (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* hashalg */ 387 (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) /* H(msg) */ 388 goto out; 389 if (sshbuf_len(b) != 0) { 390 r = SSH_ERR_INVALID_FORMAT; 391 goto out; 392 } 393 /* success */ 394 r = 0; 395 out: 396 sshbuf_free(b); 397 return r; 398 } 399 400 /* 401 * This function inspects a message to be signed by a FIDO key that has a 402 * web-like application string (i.e. one that does not begin with "ssh:". 403 * It checks that the message is one of those expected for SSH operations 404 * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges 405 * for the web. 406 */ 407 static int 408 check_websafe_message_contents(struct sshkey *key, struct sshbuf *data) 409 { 410 if (parse_userauth_request(data, key, NULL, NULL) == 0) { 411 debug_f("signed data matches public key userauth request"); 412 return 1; 413 } 414 if (parse_sshsig_request(data) == 0) { 415 debug_f("signed data matches SSHSIG signature request"); 416 return 1; 417 } 418 419 /* XXX check CA signature operation */ 420 421 error("web-origin key attempting to sign non-SSH message"); 422 return 0; 423 } 424 425 /* ssh2 only */ 426 static void 427 process_sign_request2(SocketEntry *e) 428 { 429 u_char *signature = NULL; 430 size_t slen = 0; 431 u_int compat = 0, flags; 432 int r, ok = -1; 433 char *fp = NULL; 434 struct sshbuf *msg = NULL, *data = NULL; 435 struct sshkey *key = NULL; 436 struct identity *id; 437 struct notifier_ctx *notifier = NULL; 438 439 debug_f("entering"); 440 441 if ((msg = sshbuf_new()) == NULL || (data = sshbuf_new()) == NULL) 442 fatal_f("sshbuf_new failed"); 443 if ((r = sshkey_froms(e->request, &key)) != 0 || 444 (r = sshbuf_get_stringb(e->request, data)) != 0 || 445 (r = sshbuf_get_u32(e->request, &flags)) != 0) { 446 error_fr(r, "parse"); 447 goto send; 448 } 449 450 if ((id = lookup_identity(key)) == NULL) { 451 verbose_f("%s key not found", sshkey_type(key)); 452 goto send; 453 } 454 if (id->confirm && confirm_key(id, NULL) != 0) { 455 verbose_f("user refused key"); 456 goto send; 457 } 458 if (sshkey_is_sk(id->key)) { 459 if (strncmp(id->key->sk_application, "ssh:", 4) != 0 && 460 !check_websafe_message_contents(key, data)) { 461 /* error already logged */ 462 goto send; 463 } 464 if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { 465 if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, 466 SSH_FP_DEFAULT)) == NULL) 467 fatal_f("fingerprint failed"); 468 notifier = notify_start(0, 469 "Confirm user presence for key %s %s", 470 sshkey_type(id->key), fp); 471 } 472 } 473 /* XXX support PIN required FIDO keys */ 474 if ((r = sshkey_sign(id->key, &signature, &slen, 475 sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags), 476 id->sk_provider, NULL, compat)) != 0) { 477 error_fr(r, "sshkey_sign"); 478 goto send; 479 } 480 /* Success */ 481 ok = 0; 482 send: 483 notify_complete(notifier, "User presence confirmed"); 484 485 if (ok == 0) { 486 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 || 487 (r = sshbuf_put_string(msg, signature, slen)) != 0) 488 fatal_fr(r, "compose"); 489 } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) 490 fatal_fr(r, "compose failure"); 491 492 if ((r = sshbuf_put_stringb(e->output, msg)) != 0) 493 fatal_fr(r, "enqueue"); 494 495 sshbuf_free(data); 496 sshbuf_free(msg); 497 sshkey_free(key); 498 free(fp); 499 free(signature); 500 } 501 502 /* shared */ 503 static void 504 process_remove_identity(SocketEntry *e) 505 { 506 int r, success = 0; 507 struct sshkey *key = NULL; 508 Identity *id; 509 510 debug2_f("entering"); 511 if ((r = sshkey_froms(e->request, &key)) != 0) { 512 error_fr(r, "parse key"); 513 goto done; 514 } 515 if ((id = lookup_identity(key)) == NULL) { 516 debug_f("key not found"); 517 goto done; 518 } 519 /* We have this key, free it. */ 520 if (idtab->nentries < 1) 521 fatal_f("internal error: nentries %d", idtab->nentries); 522 TAILQ_REMOVE(&idtab->idlist, id, next); 523 free_identity(id); 524 idtab->nentries--; 525 success = 1; 526 done: 527 sshkey_free(key); 528 send_status(e, success); 529 } 530 531 static void 532 process_remove_all_identities(SocketEntry *e) 533 { 534 Identity *id; 535 536 debug2_f("entering"); 537 /* Loop over all identities and clear the keys. */ 538 for (id = TAILQ_FIRST(&idtab->idlist); id; 539 id = TAILQ_FIRST(&idtab->idlist)) { 540 TAILQ_REMOVE(&idtab->idlist, id, next); 541 free_identity(id); 542 } 543 544 /* Mark that there are no identities. */ 545 idtab->nentries = 0; 546 547 /* Send success. */ 548 send_status(e, 1); 549 } 550 551 /* removes expired keys and returns number of seconds until the next expiry */ 552 static time_t 553 reaper(void) 554 { 555 time_t deadline = 0, now = monotime(); 556 Identity *id, *nxt; 557 558 for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { 559 nxt = TAILQ_NEXT(id, next); 560 if (id->death == 0) 561 continue; 562 if (now >= id->death) { 563 debug("expiring key '%s'", id->comment); 564 TAILQ_REMOVE(&idtab->idlist, id, next); 565 free_identity(id); 566 idtab->nentries--; 567 } else 568 deadline = (deadline == 0) ? id->death : 569 MINIMUM(deadline, id->death); 570 } 571 if (deadline == 0 || deadline <= now) 572 return 0; 573 else 574 return (deadline - now); 575 } 576 577 static int 578 parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp) 579 { 580 char *ext_name = NULL; 581 int r; 582 583 if ((r = sshbuf_get_cstring(m, &ext_name, NULL)) != 0) { 584 error_fr(r, "parse constraint extension"); 585 goto out; 586 } 587 debug_f("constraint ext %s", ext_name); 588 if (strcmp(ext_name, "sk-provider@openssh.com") == 0) { 589 if (sk_providerp == NULL) { 590 error_f("%s not valid here", ext_name); 591 r = SSH_ERR_INVALID_FORMAT; 592 goto out; 593 } 594 if (*sk_providerp != NULL) { 595 error_f("%s already set", ext_name); 596 r = SSH_ERR_INVALID_FORMAT; 597 goto out; 598 } 599 if ((r = sshbuf_get_cstring(m, sk_providerp, NULL)) != 0) { 600 error_fr(r, "parse %s", ext_name); 601 goto out; 602 } 603 } else { 604 error_f("unsupported constraint \"%s\"", ext_name); 605 r = SSH_ERR_FEATURE_UNSUPPORTED; 606 goto out; 607 } 608 /* success */ 609 r = 0; 610 out: 611 free(ext_name); 612 return r; 613 } 614 615 static int 616 parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp, 617 u_int *secondsp, int *confirmp, char **sk_providerp) 618 { 619 u_char ctype; 620 int r; 621 u_int seconds, maxsign = 0; 622 623 while (sshbuf_len(m)) { 624 if ((r = sshbuf_get_u8(m, &ctype)) != 0) { 625 error_fr(r, "parse constraint type"); 626 goto out; 627 } 628 switch (ctype) { 629 case SSH_AGENT_CONSTRAIN_LIFETIME: 630 if (*deathp != 0) { 631 error_f("lifetime already set"); 632 r = SSH_ERR_INVALID_FORMAT; 633 goto out; 634 } 635 if ((r = sshbuf_get_u32(m, &seconds)) != 0) { 636 error_fr(r, "parse lifetime constraint"); 637 goto out; 638 } 639 *deathp = monotime() + seconds; 640 *secondsp = seconds; 641 break; 642 case SSH_AGENT_CONSTRAIN_CONFIRM: 643 if (*confirmp != 0) { 644 error_f("confirm already set"); 645 r = SSH_ERR_INVALID_FORMAT; 646 goto out; 647 } 648 *confirmp = 1; 649 break; 650 case SSH_AGENT_CONSTRAIN_MAXSIGN: 651 if (k == NULL) { 652 error_f("maxsign not valid here"); 653 r = SSH_ERR_INVALID_FORMAT; 654 goto out; 655 } 656 if (maxsign != 0) { 657 error_f("maxsign already set"); 658 r = SSH_ERR_INVALID_FORMAT; 659 goto out; 660 } 661 if ((r = sshbuf_get_u32(m, &maxsign)) != 0) { 662 error_fr(r, "parse maxsign constraint"); 663 goto out; 664 } 665 if ((r = sshkey_enable_maxsign(k, maxsign)) != 0) { 666 error_fr(r, "enable maxsign"); 667 goto out; 668 } 669 break; 670 case SSH_AGENT_CONSTRAIN_EXTENSION: 671 if ((r = parse_key_constraint_extension(m, 672 sk_providerp)) != 0) 673 goto out; /* error already logged */ 674 break; 675 default: 676 error_f("Unknown constraint %d", ctype); 677 r = SSH_ERR_FEATURE_UNSUPPORTED; 678 goto out; 679 } 680 } 681 /* success */ 682 r = 0; 683 out: 684 return r; 685 } 686 687 static void 688 process_add_identity(SocketEntry *e) 689 { 690 Identity *id; 691 int success = 0, confirm = 0; 692 char *fp, *comment = NULL, *sk_provider = NULL; 693 char canonical_provider[PATH_MAX]; 694 time_t death = 0; 695 u_int seconds = 0; 696 struct sshkey *k = NULL; 697 int r = SSH_ERR_INTERNAL_ERROR; 698 699 debug2_f("entering"); 700 if ((r = sshkey_private_deserialize(e->request, &k)) != 0 || 701 k == NULL || 702 (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { 703 error_fr(r, "parse"); 704 goto out; 705 } 706 if (parse_key_constraints(e->request, k, &death, &seconds, &confirm, 707 &sk_provider) != 0) { 708 error_f("failed to parse constraints"); 709 sshbuf_reset(e->request); 710 goto out; 711 } 712 713 if (sk_provider != NULL) { 714 if (!sshkey_is_sk(k)) { 715 error("Cannot add provider: %s is not an " 716 "authenticator-hosted key", sshkey_type(k)); 717 goto out; 718 } 719 if (strcasecmp(sk_provider, "internal") == 0) { 720 debug_f("internal provider"); 721 } else { 722 if (realpath(sk_provider, canonical_provider) == NULL) { 723 verbose("failed provider \"%.100s\": " 724 "realpath: %s", sk_provider, 725 strerror(errno)); 726 goto out; 727 } 728 free(sk_provider); 729 sk_provider = xstrdup(canonical_provider); 730 if (match_pattern_list(sk_provider, 731 allowed_providers, 0) != 1) { 732 error("Refusing add key: " 733 "provider %s not allowed", sk_provider); 734 goto out; 735 } 736 } 737 } 738 if ((r = sshkey_shield_private(k)) != 0) { 739 error_fr(r, "shield private"); 740 goto out; 741 } 742 if (lifetime && !death) 743 death = monotime() + lifetime; 744 if ((id = lookup_identity(k)) == NULL) { 745 id = xcalloc(1, sizeof(Identity)); 746 TAILQ_INSERT_TAIL(&idtab->idlist, id, next); 747 /* Increment the number of identities. */ 748 idtab->nentries++; 749 } else { 750 /* key state might have been updated */ 751 sshkey_free(id->key); 752 free(id->comment); 753 free(id->sk_provider); 754 } 755 /* success */ 756 id->key = k; 757 id->comment = comment; 758 id->death = death; 759 id->confirm = confirm; 760 id->sk_provider = sk_provider; 761 762 if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT, 763 SSH_FP_DEFAULT)) == NULL) 764 fatal_f("sshkey_fingerprint failed"); 765 debug_f("add %s %s \"%.100s\" (life: %u) (confirm: %u) " 766 "(provider: %s)", sshkey_ssh_name(k), fp, comment, seconds, 767 confirm, sk_provider == NULL ? "none" : sk_provider); 768 free(fp); 769 /* transferred */ 770 k = NULL; 771 comment = NULL; 772 sk_provider = NULL; 773 success = 1; 774 out: 775 free(sk_provider); 776 free(comment); 777 sshkey_free(k); 778 send_status(e, success); 779 } 780 781 /* XXX todo: encrypt sensitive data with passphrase */ 782 static void 783 process_lock_agent(SocketEntry *e, int lock) 784 { 785 int r, success = 0, delay; 786 char *passwd; 787 u_char passwdhash[LOCK_SIZE]; 788 static u_int fail_count = 0; 789 size_t pwlen; 790 791 debug2_f("entering"); 792 /* 793 * This is deliberately fatal: the user has requested that we lock, 794 * but we can't parse their request properly. The only safe thing to 795 * do is abort. 796 */ 797 if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0) 798 fatal_fr(r, "parse"); 799 if (pwlen == 0) { 800 debug("empty password not supported"); 801 } else if (locked && !lock) { 802 if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt), 803 passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0) 804 fatal("bcrypt_pbkdf"); 805 if (timingsafe_bcmp(passwdhash, lock_pwhash, LOCK_SIZE) == 0) { 806 debug("agent unlocked"); 807 locked = 0; 808 fail_count = 0; 809 explicit_bzero(lock_pwhash, sizeof(lock_pwhash)); 810 success = 1; 811 } else { 812 /* delay in 0.1s increments up to 10s */ 813 if (fail_count < 100) 814 fail_count++; 815 delay = 100000 * fail_count; 816 debug("unlock failed, delaying %0.1lf seconds", 817 (double)delay/1000000); 818 usleep(delay); 819 } 820 explicit_bzero(passwdhash, sizeof(passwdhash)); 821 } else if (!locked && lock) { 822 debug("agent locked"); 823 locked = 1; 824 arc4random_buf(lock_salt, sizeof(lock_salt)); 825 if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt), 826 lock_pwhash, sizeof(lock_pwhash), LOCK_ROUNDS) < 0) 827 fatal("bcrypt_pbkdf"); 828 success = 1; 829 } 830 freezero(passwd, pwlen); 831 send_status(e, success); 832 } 833 834 static void 835 no_identities(SocketEntry *e) 836 { 837 struct sshbuf *msg; 838 int r; 839 840 if ((msg = sshbuf_new()) == NULL) 841 fatal_f("sshbuf_new failed"); 842 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || 843 (r = sshbuf_put_u32(msg, 0)) != 0 || 844 (r = sshbuf_put_stringb(e->output, msg)) != 0) 845 fatal_fr(r, "compose"); 846 sshbuf_free(msg); 847 } 848 849 #ifdef ENABLE_PKCS11 850 static void 851 process_add_smartcard_key(SocketEntry *e) 852 { 853 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; 854 char **comments = NULL; 855 int r, i, count = 0, success = 0, confirm = 0; 856 u_int seconds = 0; 857 time_t death = 0; 858 struct sshkey **keys = NULL, *k; 859 Identity *id; 860 861 debug2_f("entering"); 862 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || 863 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) { 864 error_fr(r, "parse"); 865 goto send; 866 } 867 if (parse_key_constraints(e->request, NULL, &death, &seconds, &confirm, 868 NULL) != 0) { 869 error_f("failed to parse constraints"); 870 goto send; 871 } 872 if (realpath(provider, canonical_provider) == NULL) { 873 verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", 874 provider, strerror(errno)); 875 goto send; 876 } 877 if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { 878 verbose("refusing PKCS#11 add of \"%.100s\": " 879 "provider not allowed", canonical_provider); 880 goto send; 881 } 882 debug_f("add %.100s", canonical_provider); 883 if (lifetime && !death) 884 death = monotime() + lifetime; 885 886 count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments); 887 for (i = 0; i < count; i++) { 888 k = keys[i]; 889 if (lookup_identity(k) == NULL) { 890 id = xcalloc(1, sizeof(Identity)); 891 id->key = k; 892 keys[i] = NULL; /* transferred */ 893 id->provider = xstrdup(canonical_provider); 894 if (*comments[i] != '\0') { 895 id->comment = comments[i]; 896 comments[i] = NULL; /* transferred */ 897 } else { 898 id->comment = xstrdup(canonical_provider); 899 } 900 id->death = death; 901 id->confirm = confirm; 902 TAILQ_INSERT_TAIL(&idtab->idlist, id, next); 903 idtab->nentries++; 904 success = 1; 905 } 906 /* XXX update constraints for existing keys */ 907 sshkey_free(keys[i]); 908 free(comments[i]); 909 } 910 send: 911 free(pin); 912 free(provider); 913 free(keys); 914 free(comments); 915 send_status(e, success); 916 } 917 918 static void 919 process_remove_smartcard_key(SocketEntry *e) 920 { 921 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; 922 int r, success = 0; 923 Identity *id, *nxt; 924 925 debug2_f("entering"); 926 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || 927 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) { 928 error_fr(r, "parse"); 929 goto send; 930 } 931 free(pin); 932 933 if (realpath(provider, canonical_provider) == NULL) { 934 verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", 935 provider, strerror(errno)); 936 goto send; 937 } 938 939 debug_f("remove %.100s", canonical_provider); 940 for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { 941 nxt = TAILQ_NEXT(id, next); 942 /* Skip file--based keys */ 943 if (id->provider == NULL) 944 continue; 945 if (!strcmp(canonical_provider, id->provider)) { 946 TAILQ_REMOVE(&idtab->idlist, id, next); 947 free_identity(id); 948 idtab->nentries--; 949 } 950 } 951 if (pkcs11_del_provider(canonical_provider) == 0) 952 success = 1; 953 else 954 error_f("pkcs11_del_provider failed"); 955 send: 956 free(provider); 957 send_status(e, success); 958 } 959 #endif /* ENABLE_PKCS11 */ 960 961 /* 962 * dispatch incoming message. 963 * returns 1 on success, 0 for incomplete messages or -1 on error. 964 */ 965 static int 966 process_message(u_int socknum) 967 { 968 u_int msg_len; 969 u_char type; 970 const u_char *cp; 971 int r; 972 SocketEntry *e; 973 974 if (socknum >= sockets_alloc) 975 fatal_f("sock %u >= allocated %u", socknum, sockets_alloc); 976 e = &sockets[socknum]; 977 978 if (sshbuf_len(e->input) < 5) 979 return 0; /* Incomplete message header. */ 980 cp = sshbuf_ptr(e->input); 981 msg_len = PEEK_U32(cp); 982 if (msg_len > AGENT_MAX_LEN) { 983 debug_f("socket %u (fd=%d) message too long %u > %u", 984 socknum, e->fd, msg_len, AGENT_MAX_LEN); 985 return -1; 986 } 987 if (sshbuf_len(e->input) < msg_len + 4) 988 return 0; /* Incomplete message body. */ 989 990 /* move the current input to e->request */ 991 sshbuf_reset(e->request); 992 if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 || 993 (r = sshbuf_get_u8(e->request, &type)) != 0) { 994 if (r == SSH_ERR_MESSAGE_INCOMPLETE || 995 r == SSH_ERR_STRING_TOO_LARGE) { 996 error_fr(r, "parse"); 997 return -1; 998 } 999 fatal_fr(r, "parse"); 1000 } 1001 1002 debug_f("socket %u (fd=%d) type %d", socknum, e->fd, type); 1003 1004 /* check whether agent is locked */ 1005 if (locked && type != SSH_AGENTC_UNLOCK) { 1006 sshbuf_reset(e->request); 1007 switch (type) { 1008 case SSH2_AGENTC_REQUEST_IDENTITIES: 1009 /* send empty lists */ 1010 no_identities(e); 1011 break; 1012 default: 1013 /* send a fail message for all other request types */ 1014 send_status(e, 0); 1015 } 1016 return 1; 1017 } 1018 1019 switch (type) { 1020 case SSH_AGENTC_LOCK: 1021 case SSH_AGENTC_UNLOCK: 1022 process_lock_agent(e, type == SSH_AGENTC_LOCK); 1023 break; 1024 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: 1025 process_remove_all_identities(e); /* safe for !WITH_SSH1 */ 1026 break; 1027 /* ssh2 */ 1028 case SSH2_AGENTC_SIGN_REQUEST: 1029 process_sign_request2(e); 1030 break; 1031 case SSH2_AGENTC_REQUEST_IDENTITIES: 1032 process_request_identities(e); 1033 break; 1034 case SSH2_AGENTC_ADD_IDENTITY: 1035 case SSH2_AGENTC_ADD_ID_CONSTRAINED: 1036 process_add_identity(e); 1037 break; 1038 case SSH2_AGENTC_REMOVE_IDENTITY: 1039 process_remove_identity(e); 1040 break; 1041 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: 1042 process_remove_all_identities(e); 1043 break; 1044 #ifdef ENABLE_PKCS11 1045 case SSH_AGENTC_ADD_SMARTCARD_KEY: 1046 case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: 1047 process_add_smartcard_key(e); 1048 break; 1049 case SSH_AGENTC_REMOVE_SMARTCARD_KEY: 1050 process_remove_smartcard_key(e); 1051 break; 1052 #endif /* ENABLE_PKCS11 */ 1053 default: 1054 /* Unknown message. Respond with failure. */ 1055 error("Unknown message %d", type); 1056 sshbuf_reset(e->request); 1057 send_status(e, 0); 1058 break; 1059 } 1060 return 1; 1061 } 1062 1063 static void 1064 new_socket(sock_type type, int fd) 1065 { 1066 u_int i, old_alloc, new_alloc; 1067 1068 debug_f("type = %s", type == AUTH_CONNECTION ? "CONNECTION" : 1069 (type == AUTH_SOCKET ? "SOCKET" : "UNKNOWN")); 1070 set_nonblock(fd); 1071 1072 if (fd > max_fd) 1073 max_fd = fd; 1074 1075 for (i = 0; i < sockets_alloc; i++) 1076 if (sockets[i].type == AUTH_UNUSED) { 1077 sockets[i].fd = fd; 1078 if ((sockets[i].input = sshbuf_new()) == NULL || 1079 (sockets[i].output = sshbuf_new()) == NULL || 1080 (sockets[i].request = sshbuf_new()) == NULL) 1081 fatal_f("sshbuf_new failed"); 1082 sockets[i].type = type; 1083 return; 1084 } 1085 old_alloc = sockets_alloc; 1086 new_alloc = sockets_alloc + 10; 1087 sockets = xrecallocarray(sockets, old_alloc, new_alloc, 1088 sizeof(sockets[0])); 1089 for (i = old_alloc; i < new_alloc; i++) 1090 sockets[i].type = AUTH_UNUSED; 1091 sockets_alloc = new_alloc; 1092 sockets[old_alloc].fd = fd; 1093 if ((sockets[old_alloc].input = sshbuf_new()) == NULL || 1094 (sockets[old_alloc].output = sshbuf_new()) == NULL || 1095 (sockets[old_alloc].request = sshbuf_new()) == NULL) 1096 fatal_f("sshbuf_new failed"); 1097 sockets[old_alloc].type = type; 1098 } 1099 1100 static int 1101 handle_socket_read(u_int socknum) 1102 { 1103 struct sockaddr_un sunaddr; 1104 socklen_t slen; 1105 uid_t euid; 1106 gid_t egid; 1107 int fd; 1108 1109 slen = sizeof(sunaddr); 1110 fd = accept(sockets[socknum].fd, (struct sockaddr *)&sunaddr, &slen); 1111 if (fd == -1) { 1112 error("accept from AUTH_SOCKET: %s", strerror(errno)); 1113 return -1; 1114 } 1115 if (getpeereid(fd, &euid, &egid) == -1) { 1116 error("getpeereid %d failed: %s", fd, strerror(errno)); 1117 close(fd); 1118 return -1; 1119 } 1120 if ((euid != 0) && (getuid() != euid)) { 1121 error("uid mismatch: peer euid %u != uid %u", 1122 (u_int) euid, (u_int) getuid()); 1123 close(fd); 1124 return -1; 1125 } 1126 new_socket(AUTH_CONNECTION, fd); 1127 return 0; 1128 } 1129 1130 static int 1131 handle_conn_read(u_int socknum) 1132 { 1133 char buf[AGENT_RBUF_LEN]; 1134 ssize_t len; 1135 int r; 1136 1137 if ((len = read(sockets[socknum].fd, buf, sizeof(buf))) <= 0) { 1138 if (len == -1) { 1139 if (errno == EAGAIN || errno == EINTR) 1140 return 0; 1141 error_f("read error on socket %u (fd %d): %s", 1142 socknum, sockets[socknum].fd, strerror(errno)); 1143 } 1144 return -1; 1145 } 1146 if ((r = sshbuf_put(sockets[socknum].input, buf, len)) != 0) 1147 fatal_fr(r, "compose"); 1148 explicit_bzero(buf, sizeof(buf)); 1149 for (;;) { 1150 if ((r = process_message(socknum)) == -1) 1151 return -1; 1152 else if (r == 0) 1153 break; 1154 } 1155 return 0; 1156 } 1157 1158 static int 1159 handle_conn_write(u_int socknum) 1160 { 1161 ssize_t len; 1162 int r; 1163 1164 if (sshbuf_len(sockets[socknum].output) == 0) 1165 return 0; /* shouldn't happen */ 1166 if ((len = write(sockets[socknum].fd, 1167 sshbuf_ptr(sockets[socknum].output), 1168 sshbuf_len(sockets[socknum].output))) <= 0) { 1169 if (len == -1) { 1170 if (errno == EAGAIN || errno == EINTR) 1171 return 0; 1172 error_f("read error on socket %u (fd %d): %s", 1173 socknum, sockets[socknum].fd, strerror(errno)); 1174 } 1175 return -1; 1176 } 1177 if ((r = sshbuf_consume(sockets[socknum].output, len)) != 0) 1178 fatal_fr(r, "consume"); 1179 return 0; 1180 } 1181 1182 static void 1183 after_poll(struct pollfd *pfd, size_t npfd, u_int maxfds) 1184 { 1185 size_t i; 1186 u_int socknum, activefds = npfd; 1187 1188 for (i = 0; i < npfd; i++) { 1189 if (pfd[i].revents == 0) 1190 continue; 1191 /* Find sockets entry */ 1192 for (socknum = 0; socknum < sockets_alloc; socknum++) { 1193 if (sockets[socknum].type != AUTH_SOCKET && 1194 sockets[socknum].type != AUTH_CONNECTION) 1195 continue; 1196 if (pfd[i].fd == sockets[socknum].fd) 1197 break; 1198 } 1199 if (socknum >= sockets_alloc) { 1200 error_f("no socket for fd %d", pfd[i].fd); 1201 continue; 1202 } 1203 /* Process events */ 1204 switch (sockets[socknum].type) { 1205 case AUTH_SOCKET: 1206 if ((pfd[i].revents & (POLLIN|POLLERR)) == 0) 1207 break; 1208 if (npfd > maxfds) { 1209 debug3("out of fds (active %u >= limit %u); " 1210 "skipping accept", activefds, maxfds); 1211 break; 1212 } 1213 if (handle_socket_read(socknum) == 0) 1214 activefds++; 1215 break; 1216 case AUTH_CONNECTION: 1217 if ((pfd[i].revents & (POLLIN|POLLERR)) != 0 && 1218 handle_conn_read(socknum) != 0) { 1219 goto close_sock; 1220 } 1221 if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 && 1222 handle_conn_write(socknum) != 0) { 1223 close_sock: 1224 if (activefds == 0) 1225 fatal("activefds == 0 at close_sock"); 1226 close_socket(&sockets[socknum]); 1227 activefds--; 1228 break; 1229 } 1230 break; 1231 default: 1232 break; 1233 } 1234 } 1235 } 1236 1237 static int 1238 prepare_poll(struct pollfd **pfdp, size_t *npfdp, int *timeoutp, u_int maxfds) 1239 { 1240 struct pollfd *pfd = *pfdp; 1241 size_t i, j, npfd = 0; 1242 time_t deadline; 1243 int r; 1244 1245 /* Count active sockets */ 1246 for (i = 0; i < sockets_alloc; i++) { 1247 switch (sockets[i].type) { 1248 case AUTH_SOCKET: 1249 case AUTH_CONNECTION: 1250 npfd++; 1251 break; 1252 case AUTH_UNUSED: 1253 break; 1254 default: 1255 fatal("Unknown socket type %d", sockets[i].type); 1256 break; 1257 } 1258 } 1259 if (npfd != *npfdp && 1260 (pfd = recallocarray(pfd, *npfdp, npfd, sizeof(*pfd))) == NULL) 1261 fatal_f("recallocarray failed"); 1262 *pfdp = pfd; 1263 *npfdp = npfd; 1264 1265 for (i = j = 0; i < sockets_alloc; i++) { 1266 switch (sockets[i].type) { 1267 case AUTH_SOCKET: 1268 if (npfd > maxfds) { 1269 debug3("out of fds (active %zu >= limit %u); " 1270 "skipping arming listener", npfd, maxfds); 1271 break; 1272 } 1273 pfd[j].fd = sockets[i].fd; 1274 pfd[j].revents = 0; 1275 pfd[j].events = POLLIN; 1276 j++; 1277 break; 1278 case AUTH_CONNECTION: 1279 pfd[j].fd = sockets[i].fd; 1280 pfd[j].revents = 0; 1281 /* 1282 * Only prepare to read if we can handle a full-size 1283 * input read buffer and enqueue a max size reply.. 1284 */ 1285 if ((r = sshbuf_check_reserve(sockets[i].input, 1286 AGENT_RBUF_LEN)) == 0 && 1287 (r = sshbuf_check_reserve(sockets[i].output, 1288 AGENT_MAX_LEN)) == 0) 1289 pfd[j].events = POLLIN; 1290 else if (r != SSH_ERR_NO_BUFFER_SPACE) 1291 fatal_fr(r, "reserve"); 1292 if (sshbuf_len(sockets[i].output) > 0) 1293 pfd[j].events |= POLLOUT; 1294 j++; 1295 break; 1296 default: 1297 break; 1298 } 1299 } 1300 deadline = reaper(); 1301 if (parent_alive_interval != 0) 1302 deadline = (deadline == 0) ? parent_alive_interval : 1303 MINIMUM(deadline, parent_alive_interval); 1304 if (deadline == 0) { 1305 *timeoutp = -1; /* INFTIM */ 1306 } else { 1307 if (deadline > INT_MAX / 1000) 1308 *timeoutp = INT_MAX / 1000; 1309 else 1310 *timeoutp = deadline * 1000; 1311 } 1312 return (1); 1313 } 1314 1315 static void 1316 cleanup_socket(void) 1317 { 1318 if (cleanup_pid != 0 && getpid() != cleanup_pid) 1319 return; 1320 debug_f("cleanup"); 1321 if (socket_name[0]) 1322 unlink(socket_name); 1323 if (socket_dir[0]) 1324 rmdir(socket_dir); 1325 } 1326 1327 void 1328 cleanup_exit(int i) 1329 { 1330 cleanup_socket(); 1331 _exit(i); 1332 } 1333 1334 /*ARGSUSED*/ 1335 static void 1336 cleanup_handler(int sig) 1337 { 1338 cleanup_socket(); 1339 #ifdef ENABLE_PKCS11 1340 pkcs11_terminate(); 1341 #endif 1342 _exit(2); 1343 } 1344 1345 static void 1346 check_parent_exists(void) 1347 { 1348 /* 1349 * If our parent has exited then getppid() will return (pid_t)1, 1350 * so testing for that should be safe. 1351 */ 1352 if (parent_pid != -1 && getppid() != parent_pid) { 1353 /* printf("Parent has died - Authentication agent exiting.\n"); */ 1354 cleanup_socket(); 1355 _exit(2); 1356 } 1357 } 1358 1359 static void 1360 usage(void) 1361 { 1362 fprintf(stderr, 1363 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" 1364 " [-P allowed_providers] [-t life]\n" 1365 " ssh-agent [-a bind_address] [-E fingerprint_hash] [-P allowed_providers]\n" 1366 " [-t life] command [arg ...]\n" 1367 " ssh-agent [-c | -s] -k\n"); 1368 exit(1); 1369 } 1370 1371 int 1372 main(int ac, char **av) 1373 { 1374 int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0; 1375 int sock, ch, result, saved_errno; 1376 char *shell, *format, *pidstr, *agentsocket = NULL; 1377 #ifdef HAVE_SETRLIMIT 1378 struct rlimit rlim; 1379 #endif 1380 extern int optind; 1381 extern char *optarg; 1382 pid_t pid; 1383 char pidstrbuf[1 + 3 * sizeof pid]; 1384 size_t len; 1385 mode_t prev_mask; 1386 int timeout = -1; /* INFTIM */ 1387 struct pollfd *pfd = NULL; 1388 size_t npfd = 0; 1389 u_int maxfds; 1390 1391 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 1392 sanitise_stdfd(); 1393 1394 /* drop */ 1395 setegid(getgid()); 1396 setgid(getgid()); 1397 1398 platform_disable_tracing(0); /* strict=no */ 1399 1400 #ifdef RLIMIT_NOFILE 1401 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) 1402 fatal("%s: getrlimit: %s", __progname, strerror(errno)); 1403 #endif 1404 1405 __progname = ssh_get_progname(av[0]); 1406 seed_rng(); 1407 1408 while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) { 1409 switch (ch) { 1410 case 'E': 1411 fingerprint_hash = ssh_digest_alg_by_name(optarg); 1412 if (fingerprint_hash == -1) 1413 fatal("Invalid hash algorithm \"%s\"", optarg); 1414 break; 1415 case 'c': 1416 if (s_flag) 1417 usage(); 1418 c_flag++; 1419 break; 1420 case 'k': 1421 k_flag++; 1422 break; 1423 case 'O': 1424 if (strcmp(optarg, "no-restrict-websafe") == 0) 1425 restrict_websafe = 0; 1426 else 1427 fatal("Unknown -O option"); 1428 break; 1429 case 'P': 1430 if (allowed_providers != NULL) 1431 fatal("-P option already specified"); 1432 allowed_providers = xstrdup(optarg); 1433 break; 1434 case 's': 1435 if (c_flag) 1436 usage(); 1437 s_flag++; 1438 break; 1439 case 'd': 1440 if (d_flag || D_flag) 1441 usage(); 1442 d_flag++; 1443 break; 1444 case 'D': 1445 if (d_flag || D_flag) 1446 usage(); 1447 D_flag++; 1448 break; 1449 case 'a': 1450 agentsocket = optarg; 1451 break; 1452 case 't': 1453 if ((lifetime = convtime(optarg)) == -1) { 1454 fprintf(stderr, "Invalid lifetime\n"); 1455 usage(); 1456 } 1457 break; 1458 default: 1459 usage(); 1460 } 1461 } 1462 ac -= optind; 1463 av += optind; 1464 1465 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) 1466 usage(); 1467 1468 if (allowed_providers == NULL) 1469 allowed_providers = xstrdup(DEFAULT_ALLOWED_PROVIDERS); 1470 1471 if (ac == 0 && !c_flag && !s_flag) { 1472 shell = getenv("SHELL"); 1473 if (shell != NULL && (len = strlen(shell)) > 2 && 1474 strncmp(shell + len - 3, "csh", 3) == 0) 1475 c_flag = 1; 1476 } 1477 if (k_flag) { 1478 const char *errstr = NULL; 1479 1480 pidstr = getenv(SSH_AGENTPID_ENV_NAME); 1481 if (pidstr == NULL) { 1482 fprintf(stderr, "%s not set, cannot kill agent\n", 1483 SSH_AGENTPID_ENV_NAME); 1484 exit(1); 1485 } 1486 pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr); 1487 if (errstr) { 1488 fprintf(stderr, 1489 "%s=\"%s\", which is not a good PID: %s\n", 1490 SSH_AGENTPID_ENV_NAME, pidstr, errstr); 1491 exit(1); 1492 } 1493 if (kill(pid, SIGTERM) == -1) { 1494 perror("kill"); 1495 exit(1); 1496 } 1497 format = c_flag ? "unsetenv %s;\n" : "unset %s;\n"; 1498 printf(format, SSH_AUTHSOCKET_ENV_NAME); 1499 printf(format, SSH_AGENTPID_ENV_NAME); 1500 printf("echo Agent pid %ld killed;\n", (long)pid); 1501 exit(0); 1502 } 1503 1504 /* 1505 * Minimum file descriptors: 1506 * stdio (3) + listener (1) + syslog (1 maybe) + connection (1) + 1507 * a few spare for libc / stack protectors / sanitisers, etc. 1508 */ 1509 #define SSH_AGENT_MIN_FDS (3+1+1+1+4) 1510 if (rlim.rlim_cur < SSH_AGENT_MIN_FDS) 1511 fatal("%s: file descriptor rlimit %lld too low (minimum %u)", 1512 __progname, (long long)rlim.rlim_cur, SSH_AGENT_MIN_FDS); 1513 maxfds = rlim.rlim_cur - SSH_AGENT_MIN_FDS; 1514 1515 parent_pid = getpid(); 1516 1517 if (agentsocket == NULL) { 1518 /* Create private directory for agent socket */ 1519 mktemp_proto(socket_dir, sizeof(socket_dir)); 1520 if (mkdtemp(socket_dir) == NULL) { 1521 perror("mkdtemp: private socket dir"); 1522 exit(1); 1523 } 1524 snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, 1525 (long)parent_pid); 1526 } else { 1527 /* Try to use specified agent socket */ 1528 socket_dir[0] = '\0'; 1529 strlcpy(socket_name, agentsocket, sizeof socket_name); 1530 } 1531 1532 /* 1533 * Create socket early so it will exist before command gets run from 1534 * the parent. 1535 */ 1536 prev_mask = umask(0177); 1537 sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); 1538 if (sock < 0) { 1539 /* XXX - unix_listener() calls error() not perror() */ 1540 *socket_name = '\0'; /* Don't unlink any existing file */ 1541 cleanup_exit(1); 1542 } 1543 umask(prev_mask); 1544 1545 /* 1546 * Fork, and have the parent execute the command, if any, or present 1547 * the socket data. The child continues as the authentication agent. 1548 */ 1549 if (D_flag || d_flag) { 1550 log_init(__progname, 1551 d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, 1552 SYSLOG_FACILITY_AUTH, 1); 1553 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; 1554 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, 1555 SSH_AUTHSOCKET_ENV_NAME); 1556 printf("echo Agent pid %ld;\n", (long)parent_pid); 1557 fflush(stdout); 1558 goto skip; 1559 } 1560 pid = fork(); 1561 if (pid == -1) { 1562 perror("fork"); 1563 cleanup_exit(1); 1564 } 1565 if (pid != 0) { /* Parent - execute the given command. */ 1566 close(sock); 1567 snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid); 1568 if (ac == 0) { 1569 format = c_flag ? "setenv %s %s;\n" : "%s=%s; export %s;\n"; 1570 printf(format, SSH_AUTHSOCKET_ENV_NAME, socket_name, 1571 SSH_AUTHSOCKET_ENV_NAME); 1572 printf(format, SSH_AGENTPID_ENV_NAME, pidstrbuf, 1573 SSH_AGENTPID_ENV_NAME); 1574 printf("echo Agent pid %ld;\n", (long)pid); 1575 exit(0); 1576 } 1577 if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 || 1578 setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) { 1579 perror("setenv"); 1580 exit(1); 1581 } 1582 execvp(av[0], av); 1583 perror(av[0]); 1584 exit(1); 1585 } 1586 /* child */ 1587 log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0); 1588 1589 if (setsid() == -1) { 1590 error("setsid: %s", strerror(errno)); 1591 cleanup_exit(1); 1592 } 1593 1594 (void)chdir("/"); 1595 if (stdfd_devnull(1, 1, 1) == -1) 1596 error_f("stdfd_devnull failed"); 1597 1598 #ifdef HAVE_SETRLIMIT 1599 /* deny core dumps, since memory contains unencrypted private keys */ 1600 rlim.rlim_cur = rlim.rlim_max = 0; 1601 if (setrlimit(RLIMIT_CORE, &rlim) == -1) { 1602 error("setrlimit RLIMIT_CORE: %s", strerror(errno)); 1603 cleanup_exit(1); 1604 } 1605 #endif 1606 1607 skip: 1608 1609 cleanup_pid = getpid(); 1610 1611 #ifdef ENABLE_PKCS11 1612 pkcs11_init(0); 1613 #endif 1614 new_socket(AUTH_SOCKET, sock); 1615 if (ac > 0) 1616 parent_alive_interval = 10; 1617 idtab_init(); 1618 ssh_signal(SIGPIPE, SIG_IGN); 1619 ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN); 1620 ssh_signal(SIGHUP, cleanup_handler); 1621 ssh_signal(SIGTERM, cleanup_handler); 1622 1623 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) 1624 fatal("%s: pledge: %s", __progname, strerror(errno)); 1625 platform_pledge_agent(); 1626 1627 while (1) { 1628 prepare_poll(&pfd, &npfd, &timeout, maxfds); 1629 result = poll(pfd, npfd, timeout); 1630 saved_errno = errno; 1631 if (parent_alive_interval != 0) 1632 check_parent_exists(); 1633 (void) reaper(); /* remove expired keys */ 1634 if (result == -1) { 1635 if (saved_errno == EINTR) 1636 continue; 1637 fatal("poll: %s", strerror(saved_errno)); 1638 } else if (result > 0) 1639 after_poll(pfd, npfd, maxfds); 1640 } 1641 /* NOTREACHED */ 1642 } 1643