1 /* $NetBSD: ssh-agent.c,v 1.39 2024/06/29 08:02:40 mrg Exp $ */ 2 /* $OpenBSD: ssh-agent.c,v 1.306 2024/03/09 05:12:13 djm Exp $ */ 3 4 /* 5 * Author: Tatu Ylonen <ylo@cs.hut.fi> 6 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * All rights reserved 8 * The authentication agent program. 9 * 10 * As far as I am concerned, the code I have written for this software 11 * can be used freely for any purpose. Any derived versions of this 12 * software must be clearly marked as such, and if the derived work is 13 * incompatible with the protocol description in the RFC file, it must be 14 * called by a name other than "ssh" or "Secure Shell". 15 * 16 * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 17 * 18 * Redistribution and use in source and binary forms, with or without 19 * modification, are permitted provided that the following conditions 20 * are met: 21 * 1. Redistributions of source code must retain the above copyright 22 * notice, this list of conditions and the following disclaimer. 23 * 2. Redistributions in binary form must reproduce the above copyright 24 * notice, this list of conditions and the following disclaimer in the 25 * documentation and/or other materials provided with the distribution. 26 * 27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 */ 38 39 #include "includes.h" 40 __RCSID("$NetBSD: ssh-agent.c,v 1.39 2024/06/29 08:02:40 mrg Exp $"); 41 42 #include <sys/param.h> /* MIN MAX */ 43 #include <sys/types.h> 44 #include <sys/time.h> 45 #include <sys/queue.h> 46 #include <sys/resource.h> 47 #include <sys/socket.h> 48 #include <sys/stat.h> 49 #include <sys/un.h> 50 #include <sys/wait.h> 51 52 #ifdef WITH_OPENSSL 53 #include <openssl/evp.h> 54 #endif 55 56 #include <errno.h> 57 #include <fcntl.h> 58 #include <paths.h> 59 #include <poll.h> 60 #include <signal.h> 61 #include <stdlib.h> 62 #include <stdio.h> 63 #include <string.h> 64 #include <stdarg.h> 65 #include <limits.h> 66 #include <time.h> 67 #include <unistd.h> 68 #include <util.h> 69 70 #include "xmalloc.h" 71 #include "ssh.h" 72 #include "ssh2.h" 73 #include "sshbuf.h" 74 #include "sshkey.h" 75 #include "authfd.h" 76 #include "log.h" 77 #include "misc.h" 78 #include "getpeereid.h" 79 #include "digest.h" 80 #include "ssherr.h" 81 #include "match.h" 82 #include "msg.h" 83 #include "pathnames.h" 84 #include "ssh-pkcs11.h" 85 #include "sk-api.h" 86 #include "myproposal.h" 87 88 #ifndef DEFAULT_ALLOWED_PROVIDERS 89 # define DEFAULT_ALLOWED_PROVIDERS "/usr/lib*/*,/usr/pkg/lib*/*" 90 #endif 91 92 /* Maximum accepted message length */ 93 #define AGENT_MAX_LEN (256*1024) 94 /* Maximum bytes to read from client socket */ 95 #define AGENT_RBUF_LEN (4096) 96 /* Maximum number of recorded session IDs/hostkeys per connection */ 97 #define AGENT_MAX_SESSION_IDS 16 98 /* Maximum size of session ID */ 99 #define AGENT_MAX_SID_LEN 128 100 /* Maximum number of destination constraints to accept on a key */ 101 #define AGENT_MAX_DEST_CONSTRAINTS 1024 102 /* Maximum number of associated certificate constraints to accept on a key */ 103 #define AGENT_MAX_EXT_CERTS 1024 104 105 /* XXX store hostkey_sid in a refcounted tree */ 106 107 typedef enum { 108 AUTH_UNUSED = 0, 109 AUTH_SOCKET = 1, 110 AUTH_CONNECTION = 2, 111 } sock_type; 112 113 struct hostkey_sid { 114 struct sshkey *key; 115 struct sshbuf *sid; 116 int forwarded; 117 }; 118 119 typedef struct socket_entry { 120 int fd; 121 sock_type type; 122 struct sshbuf *input; 123 struct sshbuf *output; 124 struct sshbuf *request; 125 size_t nsession_ids; 126 struct hostkey_sid *session_ids; 127 int session_bind_attempted; 128 } SocketEntry; 129 130 u_int sockets_alloc = 0; 131 SocketEntry *sockets = NULL; 132 133 typedef struct identity { 134 TAILQ_ENTRY(identity) next; 135 struct sshkey *key; 136 char *comment; 137 char *provider; 138 time_t death; 139 u_int confirm; 140 char *sk_provider; 141 struct dest_constraint *dest_constraints; 142 size_t ndest_constraints; 143 } Identity; 144 145 struct idtable { 146 int nentries; 147 TAILQ_HEAD(idqueue, identity) idlist; 148 }; 149 150 /* private key table */ 151 struct idtable *idtab; 152 153 int max_fd = 0; 154 155 /* pid of shell == parent of agent */ 156 pid_t parent_pid = -1; 157 time_t parent_alive_interval = 0; 158 159 sig_atomic_t signalled = 0; 160 161 /* pid of process for which cleanup_socket is applicable */ 162 pid_t cleanup_pid = 0; 163 164 /* pathname and directory for AUTH_SOCKET */ 165 char socket_name[PATH_MAX]; 166 char socket_dir[PATH_MAX]; 167 168 /* Pattern-list of allowed PKCS#11/Security key paths */ 169 static char *allowed_providers; 170 171 /* 172 * Allows PKCS11 providers or SK keys that use non-internal providers to 173 * be added over a remote connection (identified by session-bind@openssh.com). 174 */ 175 static int remote_add_provider; 176 177 /* locking */ 178 #define LOCK_SIZE 32 179 #define LOCK_SALT_SIZE 16 180 #define LOCK_ROUNDS 1 181 int locked = 0; 182 u_char lock_pwhash[LOCK_SIZE]; 183 u_char lock_salt[LOCK_SALT_SIZE]; 184 185 extern char *__progname; 186 187 /* Default lifetime in seconds (0 == forever) */ 188 static int lifetime = 0; 189 190 static int fingerprint_hash = SSH_FP_HASH_DEFAULT; 191 192 /* Refuse signing of non-SSH messages for web-origin FIDO keys */ 193 static int restrict_websafe = 1; 194 195 static void 196 close_socket(SocketEntry *e) 197 { 198 size_t i; 199 200 close(e->fd); 201 sshbuf_free(e->input); 202 sshbuf_free(e->output); 203 sshbuf_free(e->request); 204 for (i = 0; i < e->nsession_ids; i++) { 205 sshkey_free(e->session_ids[i].key); 206 sshbuf_free(e->session_ids[i].sid); 207 } 208 free(e->session_ids); 209 memset(e, '\0', sizeof(*e)); 210 e->fd = -1; 211 e->type = AUTH_UNUSED; 212 } 213 214 static void 215 idtab_init(void) 216 { 217 idtab = xcalloc(1, sizeof(*idtab)); 218 TAILQ_INIT(&idtab->idlist); 219 idtab->nentries = 0; 220 } 221 222 static void 223 free_dest_constraint_hop(struct dest_constraint_hop *dch) 224 { 225 u_int i; 226 227 if (dch == NULL) 228 return; 229 free(dch->user); 230 free(dch->hostname); 231 for (i = 0; i < dch->nkeys; i++) 232 sshkey_free(dch->keys[i]); 233 free(dch->keys); 234 free(dch->key_is_ca); 235 } 236 237 static void 238 free_dest_constraints(struct dest_constraint *dcs, size_t ndcs) 239 { 240 size_t i; 241 242 for (i = 0; i < ndcs; i++) { 243 free_dest_constraint_hop(&dcs[i].from); 244 free_dest_constraint_hop(&dcs[i].to); 245 } 246 free(dcs); 247 } 248 249 #ifdef ENABLE_PKCS11 250 static void 251 dup_dest_constraint_hop(const struct dest_constraint_hop *dch, 252 struct dest_constraint_hop *out) 253 { 254 u_int i; 255 int r; 256 257 out->user = dch->user == NULL ? NULL : xstrdup(dch->user); 258 out->hostname = dch->hostname == NULL ? NULL : xstrdup(dch->hostname); 259 out->is_ca = dch->is_ca; 260 out->nkeys = dch->nkeys; 261 out->keys = out->nkeys == 0 ? NULL : 262 xcalloc(out->nkeys, sizeof(*out->keys)); 263 out->key_is_ca = out->nkeys == 0 ? NULL : 264 xcalloc(out->nkeys, sizeof(*out->key_is_ca)); 265 for (i = 0; i < dch->nkeys; i++) { 266 if (dch->keys[i] != NULL && 267 (r = sshkey_from_private(dch->keys[i], 268 &(out->keys[i]))) != 0) 269 fatal_fr(r, "copy key"); 270 out->key_is_ca[i] = dch->key_is_ca[i]; 271 } 272 } 273 274 static struct dest_constraint * 275 dup_dest_constraints(const struct dest_constraint *dcs, size_t ndcs) 276 { 277 size_t i; 278 struct dest_constraint *ret; 279 280 if (ndcs == 0) 281 return NULL; 282 ret = xcalloc(ndcs, sizeof(*ret)); 283 for (i = 0; i < ndcs; i++) { 284 dup_dest_constraint_hop(&dcs[i].from, &ret[i].from); 285 dup_dest_constraint_hop(&dcs[i].to, &ret[i].to); 286 } 287 return ret; 288 } 289 #endif /* ENABLE_PKCS11 */ 290 291 #ifdef DEBUG_CONSTRAINTS 292 static void 293 dump_dest_constraint_hop(const struct dest_constraint_hop *dch) 294 { 295 u_int i; 296 char *fp; 297 298 debug_f("user %s hostname %s is_ca %d nkeys %u", 299 dch->user == NULL ? "(null)" : dch->user, 300 dch->hostname == NULL ? "(null)" : dch->hostname, 301 dch->is_ca, dch->nkeys); 302 for (i = 0; i < dch->nkeys; i++) { 303 fp = NULL; 304 if (dch->keys[i] != NULL && 305 (fp = sshkey_fingerprint(dch->keys[i], 306 SSH_FP_HASH_DEFAULT, SSH_FP_DEFAULT)) == NULL) 307 fatal_f("fingerprint failed"); 308 debug_f("key %u/%u: %s%s%s key_is_ca %d", i, dch->nkeys, 309 dch->keys[i] == NULL ? "" : sshkey_ssh_name(dch->keys[i]), 310 dch->keys[i] == NULL ? "" : " ", 311 dch->keys[i] == NULL ? "none" : fp, 312 dch->key_is_ca[i]); 313 free(fp); 314 } 315 } 316 #endif /* DEBUG_CONSTRAINTS */ 317 318 static void 319 dump_dest_constraints(const char *context, 320 const struct dest_constraint *dcs, size_t ndcs) 321 { 322 #ifdef DEBUG_CONSTRAINTS 323 size_t i; 324 325 debug_f("%s: %zu constraints", context, ndcs); 326 for (i = 0; i < ndcs; i++) { 327 debug_f("constraint %zu / %zu: from: ", i, ndcs); 328 dump_dest_constraint_hop(&dcs[i].from); 329 debug_f("constraint %zu / %zu: to: ", i, ndcs); 330 dump_dest_constraint_hop(&dcs[i].to); 331 } 332 debug_f("done for %s", context); 333 #endif /* DEBUG_CONSTRAINTS */ 334 } 335 336 static void 337 free_identity(Identity *id) 338 { 339 sshkey_free(id->key); 340 free(id->provider); 341 free(id->comment); 342 free(id->sk_provider); 343 free_dest_constraints(id->dest_constraints, id->ndest_constraints); 344 free(id); 345 } 346 347 /* 348 * Match 'key' against the key/CA list in a destination constraint hop 349 * Returns 0 on success or -1 otherwise. 350 */ 351 static int 352 match_key_hop(const char *tag, const struct sshkey *key, 353 const struct dest_constraint_hop *dch) 354 { 355 const char *reason = NULL; 356 const char *hostname = dch->hostname ? dch->hostname : "(ORIGIN)"; 357 u_int i; 358 char *fp; 359 360 if (key == NULL) 361 return -1; 362 /* XXX logspam */ 363 if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, 364 SSH_FP_DEFAULT)) == NULL) 365 fatal_f("fingerprint failed"); 366 debug3_f("%s: entering hostname %s, requested key %s %s, %u keys avail", 367 tag, hostname, sshkey_type(key), fp, dch->nkeys); 368 free(fp); 369 for (i = 0; i < dch->nkeys; i++) { 370 if (dch->keys[i] == NULL) 371 return -1; 372 /* XXX logspam */ 373 if ((fp = sshkey_fingerprint(dch->keys[i], SSH_FP_HASH_DEFAULT, 374 SSH_FP_DEFAULT)) == NULL) 375 fatal_f("fingerprint failed"); 376 debug3_f("%s: key %u: %s%s %s", tag, i, 377 dch->key_is_ca[i] ? "CA " : "", 378 sshkey_type(dch->keys[i]), fp); 379 free(fp); 380 if (!sshkey_is_cert(key)) { 381 /* plain key */ 382 if (dch->key_is_ca[i] || 383 !sshkey_equal(key, dch->keys[i])) 384 continue; 385 return 0; 386 } 387 /* certificate */ 388 if (!dch->key_is_ca[i]) 389 continue; 390 if (key->cert == NULL || key->cert->signature_key == NULL) 391 return -1; /* shouldn't happen */ 392 if (!sshkey_equal(key->cert->signature_key, dch->keys[i])) 393 continue; 394 if (sshkey_cert_check_host(key, hostname, 1, 395 SSH_ALLOWED_CA_SIGALGS, &reason) != 0) { 396 debug_f("cert %s / hostname %s rejected: %s", 397 key->cert->key_id, hostname, reason); 398 continue; 399 } 400 return 0; 401 } 402 return -1; 403 } 404 405 /* Check destination constraints on an identity against the hostkey/user */ 406 static int 407 permitted_by_dest_constraints(const struct sshkey *fromkey, 408 const struct sshkey *tokey, Identity *id, const char *user, 409 const char **hostnamep) 410 { 411 size_t i; 412 struct dest_constraint *d; 413 414 if (hostnamep != NULL) 415 *hostnamep = NULL; 416 for (i = 0; i < id->ndest_constraints; i++) { 417 d = id->dest_constraints + i; 418 /* XXX remove logspam */ 419 debug2_f("constraint %zu %s%s%s (%u keys) > %s%s%s (%u keys)", 420 i, d->from.user ? d->from.user : "", 421 d->from.user ? "@" : "", 422 d->from.hostname ? d->from.hostname : "(ORIGIN)", 423 d->from.nkeys, 424 d->to.user ? d->to.user : "", d->to.user ? "@" : "", 425 d->to.hostname ? d->to.hostname : "(ANY)", d->to.nkeys); 426 427 /* Match 'from' key */ 428 if (fromkey == NULL) { 429 /* We are matching the first hop */ 430 if (d->from.hostname != NULL || d->from.nkeys != 0) 431 continue; 432 } else if (match_key_hop("from", fromkey, &d->from) != 0) 433 continue; 434 435 /* Match 'to' key */ 436 if (tokey != NULL && match_key_hop("to", tokey, &d->to) != 0) 437 continue; 438 439 /* Match user if specified */ 440 if (d->to.user != NULL && user != NULL && 441 !match_pattern(user, d->to.user)) 442 continue; 443 444 /* successfully matched this constraint */ 445 if (hostnamep != NULL) 446 *hostnamep = d->to.hostname; 447 debug2_f("allowed for hostname %s", 448 d->to.hostname == NULL ? "*" : d->to.hostname); 449 return 0; 450 } 451 /* no match */ 452 debug2_f("%s identity \"%s\" not permitted for this destination", 453 sshkey_type(id->key), id->comment); 454 return -1; 455 } 456 457 /* 458 * Check whether hostkeys on a SocketEntry and the optionally specified user 459 * are permitted by the destination constraints on the Identity. 460 * Returns 0 on success or -1 otherwise. 461 */ 462 static int 463 identity_permitted(Identity *id, SocketEntry *e, char *user, 464 const char **forward_hostnamep, const char **last_hostnamep) 465 { 466 size_t i; 467 const char **hp; 468 struct hostkey_sid *hks; 469 const struct sshkey *fromkey = NULL; 470 const char *test_user; 471 char *fp1, *fp2; 472 473 /* XXX remove logspam */ 474 debug3_f("entering: key %s comment \"%s\", %zu socket bindings, " 475 "%zu constraints", sshkey_type(id->key), id->comment, 476 e->nsession_ids, id->ndest_constraints); 477 if (id->ndest_constraints == 0) 478 return 0; /* unconstrained */ 479 if (e->session_bind_attempted && e->nsession_ids == 0) { 480 error_f("previous session bind failed on socket"); 481 return -1; 482 } 483 if (e->nsession_ids == 0) 484 return 0; /* local use */ 485 /* 486 * Walk through the hops recorded by session_id and try to find a 487 * constraint that satisfies each. 488 */ 489 for (i = 0; i < e->nsession_ids; i++) { 490 hks = e->session_ids + i; 491 if (hks->key == NULL) 492 fatal_f("internal error: no bound key"); 493 /* XXX remove logspam */ 494 fp1 = fp2 = NULL; 495 if (fromkey != NULL && 496 (fp1 = sshkey_fingerprint(fromkey, SSH_FP_HASH_DEFAULT, 497 SSH_FP_DEFAULT)) == NULL) 498 fatal_f("fingerprint failed"); 499 if ((fp2 = sshkey_fingerprint(hks->key, SSH_FP_HASH_DEFAULT, 500 SSH_FP_DEFAULT)) == NULL) 501 fatal_f("fingerprint failed"); 502 debug3_f("socketentry fd=%d, entry %zu %s, " 503 "from hostkey %s %s to user %s hostkey %s %s", 504 e->fd, i, hks->forwarded ? "FORWARD" : "AUTH", 505 fromkey ? sshkey_type(fromkey) : "(ORIGIN)", 506 fromkey ? fp1 : "", user ? user : "(ANY)", 507 sshkey_type(hks->key), fp2); 508 free(fp1); 509 free(fp2); 510 /* 511 * Record the hostnames for the initial forwarding and 512 * the final destination. 513 */ 514 hp = NULL; 515 if (i == e->nsession_ids - 1) 516 hp = last_hostnamep; 517 else if (i == 0) 518 hp = forward_hostnamep; 519 /* Special handling for final recorded binding */ 520 test_user = NULL; 521 if (i == e->nsession_ids - 1) { 522 /* Can only check user at final hop */ 523 test_user = user; 524 /* 525 * user is only presented for signature requests. 526 * If this is the case, make sure last binding is not 527 * for a forwarding. 528 */ 529 if (hks->forwarded && user != NULL) { 530 error_f("tried to sign on forwarding hop"); 531 return -1; 532 } 533 } else if (!hks->forwarded) { 534 error_f("tried to forward though signing bind"); 535 return -1; 536 } 537 if (permitted_by_dest_constraints(fromkey, hks->key, id, 538 test_user, hp) != 0) 539 return -1; 540 fromkey = hks->key; 541 } 542 /* 543 * Another special case: if the last bound session ID was for a 544 * forwarding, and this function is not being called to check a sign 545 * request (i.e. no 'user' supplied), then only permit the key if 546 * there is a permission that would allow it to be used at another 547 * destination. This hides keys that are allowed to be used to 548 * authenticate *to* a host but not permitted for *use* beyond it. 549 */ 550 hks = &e->session_ids[e->nsession_ids - 1]; 551 if (hks->forwarded && user == NULL && 552 permitted_by_dest_constraints(hks->key, NULL, id, 553 NULL, NULL) != 0) { 554 debug3_f("key permitted at host but not after"); 555 return -1; 556 } 557 558 /* success */ 559 return 0; 560 } 561 562 static int 563 socket_is_remote(SocketEntry *e) 564 { 565 return e->session_bind_attempted || (e->nsession_ids != 0); 566 } 567 568 /* return matching private key for given public key */ 569 static Identity * 570 lookup_identity(struct sshkey *key) 571 { 572 Identity *id; 573 574 TAILQ_FOREACH(id, &idtab->idlist, next) { 575 if (sshkey_equal(key, id->key)) 576 return (id); 577 } 578 return (NULL); 579 } 580 581 /* Check confirmation of keysign request */ 582 static int 583 confirm_key(Identity *id, const char *extra) 584 { 585 char *p; 586 int ret = -1; 587 588 p = sshkey_fingerprint(id->key, fingerprint_hash, SSH_FP_DEFAULT); 589 if (p != NULL && 590 ask_permission("Allow use of key %s?\nKey fingerprint %s.%s%s", 591 id->comment, p, 592 extra == NULL ? "" : "\n", extra == NULL ? "" : extra)) 593 ret = 0; 594 free(p); 595 596 return (ret); 597 } 598 599 static void 600 send_status(SocketEntry *e, int success) 601 { 602 int r; 603 604 if ((r = sshbuf_put_u32(e->output, 1)) != 0 || 605 (r = sshbuf_put_u8(e->output, success ? 606 SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0) 607 fatal_fr(r, "compose"); 608 } 609 610 /* send list of supported public keys to 'client' */ 611 static void 612 process_request_identities(SocketEntry *e) 613 { 614 Identity *id; 615 struct sshbuf *msg, *keys; 616 int r; 617 u_int i = 0, nentries = 0; 618 char *fp; 619 620 debug2_f("entering"); 621 622 if ((msg = sshbuf_new()) == NULL || (keys = sshbuf_new()) == NULL) 623 fatal_f("sshbuf_new failed"); 624 TAILQ_FOREACH(id, &idtab->idlist, next) { 625 if ((fp = sshkey_fingerprint(id->key, SSH_FP_HASH_DEFAULT, 626 SSH_FP_DEFAULT)) == NULL) 627 fatal_f("fingerprint failed"); 628 debug_f("key %u / %u: %s %s", i++, idtab->nentries, 629 sshkey_ssh_name(id->key), fp); 630 dump_dest_constraints(__func__, 631 id->dest_constraints, id->ndest_constraints); 632 free(fp); 633 /* identity not visible, don't include in response */ 634 if (identity_permitted(id, e, NULL, NULL, NULL) != 0) 635 continue; 636 if ((r = sshkey_puts_opts(id->key, keys, 637 SSHKEY_SERIALIZE_INFO)) != 0 || 638 (r = sshbuf_put_cstring(keys, id->comment)) != 0) { 639 error_fr(r, "compose key/comment"); 640 continue; 641 } 642 nentries++; 643 } 644 debug2_f("replying with %u allowed of %u available keys", 645 nentries, idtab->nentries); 646 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || 647 (r = sshbuf_put_u32(msg, nentries)) != 0 || 648 (r = sshbuf_putb(msg, keys)) != 0) 649 fatal_fr(r, "compose"); 650 if ((r = sshbuf_put_stringb(e->output, msg)) != 0) 651 fatal_fr(r, "enqueue"); 652 sshbuf_free(msg); 653 sshbuf_free(keys); 654 } 655 656 657 static const char * 658 agent_decode_alg(struct sshkey *key, u_int flags) 659 { 660 if (key->type == KEY_RSA) { 661 if (flags & SSH_AGENT_RSA_SHA2_256) 662 return "rsa-sha2-256"; 663 else if (flags & SSH_AGENT_RSA_SHA2_512) 664 return "rsa-sha2-512"; 665 } else if (key->type == KEY_RSA_CERT) { 666 if (flags & SSH_AGENT_RSA_SHA2_256) 667 return "rsa-sha2-256-cert-v01@openssh.com"; 668 else if (flags & SSH_AGENT_RSA_SHA2_512) 669 return "rsa-sha2-512-cert-v01@openssh.com"; 670 } 671 return NULL; 672 } 673 674 /* 675 * Attempt to parse the contents of a buffer as a SSH publickey userauth 676 * request, checking its contents for consistency and matching the embedded 677 * key against the one that is being used for signing. 678 * Note: does not modify msg buffer. 679 * Optionally extract the username, session ID and/or hostkey from the request. 680 */ 681 static int 682 parse_userauth_request(struct sshbuf *msg, const struct sshkey *expected_key, 683 char **userp, struct sshbuf **sess_idp, struct sshkey **hostkeyp) 684 { 685 struct sshbuf *b = NULL, *sess_id = NULL; 686 char *user = NULL, *service = NULL, *method = NULL, *pkalg = NULL; 687 int r; 688 u_char t, sig_follows; 689 struct sshkey *mkey = NULL, *hostkey = NULL; 690 691 if (userp != NULL) 692 *userp = NULL; 693 if (sess_idp != NULL) 694 *sess_idp = NULL; 695 if (hostkeyp != NULL) 696 *hostkeyp = NULL; 697 if ((b = sshbuf_fromb(msg)) == NULL) 698 fatal_f("sshbuf_fromb"); 699 700 /* SSH userauth request */ 701 if ((r = sshbuf_froms(b, &sess_id)) != 0) 702 goto out; 703 if (sshbuf_len(sess_id) == 0) { 704 r = SSH_ERR_INVALID_FORMAT; 705 goto out; 706 } 707 if ((r = sshbuf_get_u8(b, &t)) != 0 || /* SSH2_MSG_USERAUTH_REQUEST */ 708 (r = sshbuf_get_cstring(b, &user, NULL)) != 0 || /* server user */ 709 (r = sshbuf_get_cstring(b, &service, NULL)) != 0 || /* service */ 710 (r = sshbuf_get_cstring(b, &method, NULL)) != 0 || /* method */ 711 (r = sshbuf_get_u8(b, &sig_follows)) != 0 || /* sig-follows */ 712 (r = sshbuf_get_cstring(b, &pkalg, NULL)) != 0 || /* alg */ 713 (r = sshkey_froms(b, &mkey)) != 0) /* key */ 714 goto out; 715 if (t != SSH2_MSG_USERAUTH_REQUEST || 716 sig_follows != 1 || 717 strcmp(service, "ssh-connection") != 0 || 718 !sshkey_equal(expected_key, mkey) || 719 sshkey_type_from_name(pkalg) != expected_key->type) { 720 r = SSH_ERR_INVALID_FORMAT; 721 goto out; 722 } 723 if (strcmp(method, "publickey-hostbound-v00@openssh.com") == 0) { 724 if ((r = sshkey_froms(b, &hostkey)) != 0) 725 goto out; 726 } else if (strcmp(method, "publickey") != 0) { 727 r = SSH_ERR_INVALID_FORMAT; 728 goto out; 729 } 730 if (sshbuf_len(b) != 0) { 731 r = SSH_ERR_INVALID_FORMAT; 732 goto out; 733 } 734 /* success */ 735 r = 0; 736 debug3_f("well formed userauth"); 737 if (userp != NULL) { 738 *userp = user; 739 user = NULL; 740 } 741 if (sess_idp != NULL) { 742 *sess_idp = sess_id; 743 sess_id = NULL; 744 } 745 if (hostkeyp != NULL) { 746 *hostkeyp = hostkey; 747 hostkey = NULL; 748 } 749 out: 750 sshbuf_free(b); 751 sshbuf_free(sess_id); 752 free(user); 753 free(service); 754 free(method); 755 free(pkalg); 756 sshkey_free(mkey); 757 sshkey_free(hostkey); 758 return r; 759 } 760 761 /* 762 * Attempt to parse the contents of a buffer as a SSHSIG signature request. 763 * Note: does not modify buffer. 764 */ 765 static int 766 parse_sshsig_request(struct sshbuf *msg) 767 { 768 int r; 769 struct sshbuf *b; 770 771 if ((b = sshbuf_fromb(msg)) == NULL) 772 fatal_f("sshbuf_fromb"); 773 774 if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) != 0 || 775 (r = sshbuf_consume(b, 6)) != 0 || 776 (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* namespace */ 777 (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0 || /* reserved */ 778 (r = sshbuf_get_cstring(b, NULL, NULL)) != 0 || /* hashalg */ 779 (r = sshbuf_get_string_direct(b, NULL, NULL)) != 0) /* H(msg) */ 780 goto out; 781 if (sshbuf_len(b) != 0) { 782 r = SSH_ERR_INVALID_FORMAT; 783 goto out; 784 } 785 /* success */ 786 r = 0; 787 out: 788 sshbuf_free(b); 789 return r; 790 } 791 792 /* 793 * This function inspects a message to be signed by a FIDO key that has a 794 * web-like application string (i.e. one that does not begin with "ssh:". 795 * It checks that the message is one of those expected for SSH operations 796 * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges 797 * for the web. 798 */ 799 static int 800 check_websafe_message_contents(struct sshkey *key, struct sshbuf *data) 801 { 802 if (parse_userauth_request(data, key, NULL, NULL, NULL) == 0) { 803 debug_f("signed data matches public key userauth request"); 804 return 1; 805 } 806 if (parse_sshsig_request(data) == 0) { 807 debug_f("signed data matches SSHSIG signature request"); 808 return 1; 809 } 810 811 /* XXX check CA signature operation */ 812 813 error("web-origin key attempting to sign non-SSH message"); 814 return 0; 815 } 816 817 static int 818 buf_equal(const struct sshbuf *a, const struct sshbuf *b) 819 { 820 if (sshbuf_ptr(a) == NULL || sshbuf_ptr(b) == NULL) 821 return SSH_ERR_INVALID_ARGUMENT; 822 if (sshbuf_len(a) != sshbuf_len(b)) 823 return SSH_ERR_INVALID_FORMAT; 824 if (timingsafe_bcmp(sshbuf_ptr(a), sshbuf_ptr(b), sshbuf_len(a)) != 0) 825 return SSH_ERR_INVALID_FORMAT; 826 return 0; 827 } 828 829 /* ssh2 only */ 830 static void 831 process_sign_request2(SocketEntry *e) 832 { 833 u_char *signature = NULL; 834 size_t slen = 0; 835 u_int compat = 0, flags; 836 int r, ok = -1, retried = 0; 837 char *fp = NULL, *pin = NULL, *prompt = NULL; 838 char *user = NULL, *sig_dest = NULL; 839 const char *fwd_host = NULL, *dest_host = NULL; 840 struct sshbuf *msg = NULL, *data = NULL, *sid = NULL; 841 struct sshkey *key = NULL, *hostkey = NULL; 842 struct identity *id; 843 struct notifier_ctx *notifier = NULL; 844 845 debug_f("entering"); 846 847 if ((msg = sshbuf_new()) == NULL || (data = sshbuf_new()) == NULL) 848 fatal_f("sshbuf_new failed"); 849 if ((r = sshkey_froms(e->request, &key)) != 0 || 850 (r = sshbuf_get_stringb(e->request, data)) != 0 || 851 (r = sshbuf_get_u32(e->request, &flags)) != 0) { 852 error_fr(r, "parse"); 853 goto send; 854 } 855 856 if ((id = lookup_identity(key)) == NULL) { 857 verbose_f("%s key not found", sshkey_type(key)); 858 goto send; 859 } 860 if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, 861 SSH_FP_DEFAULT)) == NULL) 862 fatal_f("fingerprint failed"); 863 864 if (id->ndest_constraints != 0) { 865 if (e->nsession_ids == 0) { 866 logit_f("refusing use of destination-constrained key " 867 "to sign on unbound connection"); 868 goto send; 869 } 870 if (parse_userauth_request(data, key, &user, &sid, 871 &hostkey) != 0) { 872 logit_f("refusing use of destination-constrained key " 873 "to sign an unidentified signature"); 874 goto send; 875 } 876 /* XXX logspam */ 877 debug_f("user=%s", user); 878 if (identity_permitted(id, e, user, &fwd_host, &dest_host) != 0) 879 goto send; 880 /* XXX display fwd_host/dest_host in askpass UI */ 881 /* 882 * Ensure that the session ID is the most recent one 883 * registered on the socket - it should have been bound by 884 * ssh immediately before userauth. 885 */ 886 if (buf_equal(sid, 887 e->session_ids[e->nsession_ids - 1].sid) != 0) { 888 error_f("unexpected session ID (%zu listed) on " 889 "signature request for target user %s with " 890 "key %s %s", e->nsession_ids, user, 891 sshkey_type(id->key), fp); 892 goto send; 893 } 894 /* 895 * Ensure that the hostkey embedded in the signature matches 896 * the one most recently bound to the socket. An exception is 897 * made for the initial forwarding hop. 898 */ 899 if (e->nsession_ids > 1 && hostkey == NULL) { 900 error_f("refusing use of destination-constrained key: " 901 "no hostkey recorded in signature for forwarded " 902 "connection"); 903 goto send; 904 } 905 if (hostkey != NULL && !sshkey_equal(hostkey, 906 e->session_ids[e->nsession_ids - 1].key)) { 907 error_f("refusing use of destination-constrained key: " 908 "mismatch between hostkey in request and most " 909 "recently bound session"); 910 goto send; 911 } 912 xasprintf(&sig_dest, "public key authentication request for " 913 "user \"%s\" to listed host", user); 914 } 915 if (id->confirm && confirm_key(id, sig_dest) != 0) { 916 verbose_f("user refused key"); 917 goto send; 918 } 919 if (sshkey_is_sk(id->key)) { 920 if (restrict_websafe && 921 strncmp(id->key->sk_application, "ssh:", 4) != 0 && 922 !check_websafe_message_contents(key, data)) { 923 /* error already logged */ 924 goto send; 925 } 926 if (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) { 927 notifier = notify_start(0, 928 "Confirm user presence for key %s %s%s%s", 929 sshkey_type(id->key), fp, 930 sig_dest == NULL ? "" : "\n", 931 sig_dest == NULL ? "" : sig_dest); 932 } 933 } 934 retry_pin: 935 if ((r = sshkey_sign(id->key, &signature, &slen, 936 sshbuf_ptr(data), sshbuf_len(data), agent_decode_alg(key, flags), 937 id->sk_provider, pin, compat)) != 0) { 938 debug_fr(r, "sshkey_sign"); 939 if (pin == NULL && !retried && sshkey_is_sk(id->key) && 940 r == SSH_ERR_KEY_WRONG_PASSPHRASE) { 941 notify_complete(notifier, NULL); 942 notifier = NULL; 943 /* XXX include sig_dest */ 944 xasprintf(&prompt, "Enter PIN%sfor %s key %s: ", 945 (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD) ? 946 " and confirm user presence " : " ", 947 sshkey_type(id->key), fp); 948 pin = read_passphrase(prompt, RP_USE_ASKPASS); 949 retried = 1; 950 goto retry_pin; 951 } 952 error_fr(r, "sshkey_sign"); 953 goto send; 954 } 955 /* Success */ 956 ok = 0; 957 debug_f("good signature"); 958 send: 959 notify_complete(notifier, "User presence confirmed"); 960 961 if (ok == 0) { 962 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 || 963 (r = sshbuf_put_string(msg, signature, slen)) != 0) 964 fatal_fr(r, "compose"); 965 } else if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0) 966 fatal_fr(r, "compose failure"); 967 968 if ((r = sshbuf_put_stringb(e->output, msg)) != 0) 969 fatal_fr(r, "enqueue"); 970 971 sshbuf_free(sid); 972 sshbuf_free(data); 973 sshbuf_free(msg); 974 sshkey_free(key); 975 sshkey_free(hostkey); 976 free(fp); 977 free(signature); 978 free(sig_dest); 979 free(user); 980 free(prompt); 981 if (pin != NULL) 982 freezero(pin, strlen(pin)); 983 } 984 985 /* shared */ 986 static void 987 process_remove_identity(SocketEntry *e) 988 { 989 int r, success = 0; 990 struct sshkey *key = NULL; 991 Identity *id; 992 993 debug2_f("entering"); 994 if ((r = sshkey_froms(e->request, &key)) != 0) { 995 error_fr(r, "parse key"); 996 goto done; 997 } 998 if ((id = lookup_identity(key)) == NULL) { 999 debug_f("key not found"); 1000 goto done; 1001 } 1002 /* identity not visible, cannot be removed */ 1003 if (identity_permitted(id, e, NULL, NULL, NULL) != 0) 1004 goto done; /* error already logged */ 1005 /* We have this key, free it. */ 1006 if (idtab->nentries < 1) 1007 fatal_f("internal error: nentries %d", idtab->nentries); 1008 TAILQ_REMOVE(&idtab->idlist, id, next); 1009 free_identity(id); 1010 idtab->nentries--; 1011 success = 1; 1012 done: 1013 sshkey_free(key); 1014 send_status(e, success); 1015 } 1016 1017 static void 1018 process_remove_all_identities(SocketEntry *e) 1019 { 1020 Identity *id; 1021 1022 debug2_f("entering"); 1023 /* Loop over all identities and clear the keys. */ 1024 for (id = TAILQ_FIRST(&idtab->idlist); id; 1025 id = TAILQ_FIRST(&idtab->idlist)) { 1026 TAILQ_REMOVE(&idtab->idlist, id, next); 1027 free_identity(id); 1028 } 1029 1030 /* Mark that there are no identities. */ 1031 idtab->nentries = 0; 1032 1033 /* Send success. */ 1034 send_status(e, 1); 1035 } 1036 1037 /* removes expired keys and returns number of seconds until the next expiry */ 1038 static time_t 1039 reaper(void) 1040 { 1041 time_t deadline = 0, now = monotime(); 1042 Identity *id, *nxt; 1043 1044 for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { 1045 nxt = TAILQ_NEXT(id, next); 1046 if (id->death == 0) 1047 continue; 1048 if (now >= id->death) { 1049 debug("expiring key '%s'", id->comment); 1050 TAILQ_REMOVE(&idtab->idlist, id, next); 1051 free_identity(id); 1052 idtab->nentries--; 1053 } else 1054 deadline = (deadline == 0) ? id->death : 1055 MINIMUM(deadline, id->death); 1056 } 1057 if (deadline == 0 || deadline <= now) 1058 return 0; 1059 else 1060 return (deadline - now); 1061 } 1062 1063 static int 1064 parse_dest_constraint_hop(struct sshbuf *b, struct dest_constraint_hop *dch) 1065 { 1066 u_char key_is_ca; 1067 size_t elen = 0; 1068 int r; 1069 struct sshkey *k = NULL; 1070 char *fp; 1071 1072 memset(dch, '\0', sizeof(*dch)); 1073 if ((r = sshbuf_get_cstring(b, &dch->user, NULL)) != 0 || 1074 (r = sshbuf_get_cstring(b, &dch->hostname, NULL)) != 0 || 1075 (r = sshbuf_get_string_direct(b, NULL, &elen)) != 0) { 1076 error_fr(r, "parse"); 1077 goto out; 1078 } 1079 if (elen != 0) { 1080 error_f("unsupported extensions (len %zu)", elen); 1081 r = SSH_ERR_FEATURE_UNSUPPORTED; 1082 goto out; 1083 } 1084 if (*dch->hostname == '\0') { 1085 free(dch->hostname); 1086 dch->hostname = NULL; 1087 } 1088 if (*dch->user == '\0') { 1089 free(dch->user); 1090 dch->user = NULL; 1091 } 1092 while (sshbuf_len(b) != 0) { 1093 dch->keys = xrecallocarray(dch->keys, dch->nkeys, 1094 dch->nkeys + 1, sizeof(*dch->keys)); 1095 dch->key_is_ca = xrecallocarray(dch->key_is_ca, dch->nkeys, 1096 dch->nkeys + 1, sizeof(*dch->key_is_ca)); 1097 if ((r = sshkey_froms(b, &k)) != 0 || 1098 (r = sshbuf_get_u8(b, &key_is_ca)) != 0) 1099 goto out; 1100 if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT, 1101 SSH_FP_DEFAULT)) == NULL) 1102 fatal_f("fingerprint failed"); 1103 debug3_f("%s%s%s: adding %skey %s %s", 1104 dch->user == NULL ? "" : dch->user, 1105 dch->user == NULL ? "" : "@", 1106 dch->hostname, key_is_ca ? "CA " : "", sshkey_type(k), fp); 1107 free(fp); 1108 dch->keys[dch->nkeys] = k; 1109 dch->key_is_ca[dch->nkeys] = key_is_ca != 0; 1110 dch->nkeys++; 1111 k = NULL; /* transferred */ 1112 } 1113 /* success */ 1114 r = 0; 1115 out: 1116 sshkey_free(k); 1117 return r; 1118 } 1119 1120 static int 1121 parse_dest_constraint(struct sshbuf *m, struct dest_constraint *dc) 1122 { 1123 struct sshbuf *b = NULL, *frombuf = NULL, *tobuf = NULL; 1124 int r; 1125 size_t elen = 0; 1126 1127 debug3_f("entering"); 1128 1129 memset(dc, '\0', sizeof(*dc)); 1130 if ((r = sshbuf_froms(m, &b)) != 0 || 1131 (r = sshbuf_froms(b, &frombuf)) != 0 || 1132 (r = sshbuf_froms(b, &tobuf)) != 0 || 1133 (r = sshbuf_get_string_direct(b, NULL, &elen)) != 0) { 1134 error_fr(r, "parse"); 1135 goto out; 1136 } 1137 if ((r = parse_dest_constraint_hop(frombuf, &dc->from)) != 0 || 1138 (r = parse_dest_constraint_hop(tobuf, &dc->to)) != 0) 1139 goto out; /* already logged */ 1140 if (elen != 0) { 1141 error_f("unsupported extensions (len %zu)", elen); 1142 r = SSH_ERR_FEATURE_UNSUPPORTED; 1143 goto out; 1144 } 1145 debug2_f("parsed %s (%u keys) > %s%s%s (%u keys)", 1146 dc->from.hostname ? dc->from.hostname : "(ORIGIN)", dc->from.nkeys, 1147 dc->to.user ? dc->to.user : "", dc->to.user ? "@" : "", 1148 dc->to.hostname ? dc->to.hostname : "(ANY)", dc->to.nkeys); 1149 /* check consistency */ 1150 if ((dc->from.hostname == NULL) != (dc->from.nkeys == 0) || 1151 dc->from.user != NULL) { 1152 error_f("inconsistent \"from\" specification"); 1153 r = SSH_ERR_INVALID_FORMAT; 1154 goto out; 1155 } 1156 if (dc->to.hostname == NULL || dc->to.nkeys == 0) { 1157 error_f("incomplete \"to\" specification"); 1158 r = SSH_ERR_INVALID_FORMAT; 1159 goto out; 1160 } 1161 /* success */ 1162 r = 0; 1163 out: 1164 sshbuf_free(b); 1165 sshbuf_free(frombuf); 1166 sshbuf_free(tobuf); 1167 return r; 1168 } 1169 1170 static int 1171 parse_key_constraint_extension(struct sshbuf *m, char **sk_providerp, 1172 struct dest_constraint **dcsp, size_t *ndcsp, int *cert_onlyp, 1173 struct sshkey ***certs, size_t *ncerts) 1174 { 1175 char *ext_name = NULL; 1176 int r; 1177 struct sshbuf *b = NULL; 1178 u_char v; 1179 struct sshkey *k; 1180 1181 if ((r = sshbuf_get_cstring(m, &ext_name, NULL)) != 0) { 1182 error_fr(r, "parse constraint extension"); 1183 goto out; 1184 } 1185 debug_f("constraint ext %s", ext_name); 1186 if (strcmp(ext_name, "sk-provider@openssh.com") == 0) { 1187 if (sk_providerp == NULL) { 1188 error_f("%s not valid here", ext_name); 1189 r = SSH_ERR_INVALID_FORMAT; 1190 goto out; 1191 } 1192 if (*sk_providerp != NULL) { 1193 error_f("%s already set", ext_name); 1194 r = SSH_ERR_INVALID_FORMAT; 1195 goto out; 1196 } 1197 if ((r = sshbuf_get_cstring(m, sk_providerp, NULL)) != 0) { 1198 error_fr(r, "parse %s", ext_name); 1199 goto out; 1200 } 1201 } else if (strcmp(ext_name, 1202 "restrict-destination-v00@openssh.com") == 0) { 1203 if (*dcsp != NULL) { 1204 error_f("%s already set", ext_name); 1205 goto out; 1206 } 1207 if ((r = sshbuf_froms(m, &b)) != 0) { 1208 error_fr(r, "parse %s outer", ext_name); 1209 goto out; 1210 } 1211 while (sshbuf_len(b) != 0) { 1212 if (*ndcsp >= AGENT_MAX_DEST_CONSTRAINTS) { 1213 error_f("too many %s constraints", ext_name); 1214 goto out; 1215 } 1216 *dcsp = xrecallocarray(*dcsp, *ndcsp, *ndcsp + 1, 1217 sizeof(**dcsp)); 1218 if ((r = parse_dest_constraint(b, 1219 *dcsp + (*ndcsp)++)) != 0) 1220 goto out; /* error already logged */ 1221 } 1222 } else if (strcmp(ext_name, 1223 "associated-certs-v00@openssh.com") == 0) { 1224 if (certs == NULL || ncerts == NULL || cert_onlyp == NULL) { 1225 error_f("%s not valid here", ext_name); 1226 r = SSH_ERR_INVALID_FORMAT; 1227 goto out; 1228 } 1229 if (*certs != NULL) { 1230 error_f("%s already set", ext_name); 1231 goto out; 1232 } 1233 if ((r = sshbuf_get_u8(m, &v)) != 0 || 1234 (r = sshbuf_froms(m, &b)) != 0) { 1235 error_fr(r, "parse %s", ext_name); 1236 goto out; 1237 } 1238 *cert_onlyp = v != 0; 1239 while (sshbuf_len(b) != 0) { 1240 if (*ncerts >= AGENT_MAX_EXT_CERTS) { 1241 error_f("too many %s constraints", ext_name); 1242 goto out; 1243 } 1244 *certs = xrecallocarray(*certs, *ncerts, *ncerts + 1, 1245 sizeof(**certs)); 1246 if ((r = sshkey_froms(b, &k)) != 0) { 1247 error_fr(r, "parse key"); 1248 goto out; 1249 } 1250 (*certs)[(*ncerts)++] = k; 1251 } 1252 } else { 1253 error_f("unsupported constraint \"%s\"", ext_name); 1254 r = SSH_ERR_FEATURE_UNSUPPORTED; 1255 goto out; 1256 } 1257 /* success */ 1258 r = 0; 1259 out: 1260 free(ext_name); 1261 sshbuf_free(b); 1262 return r; 1263 } 1264 1265 static int 1266 parse_key_constraints(struct sshbuf *m, struct sshkey *k, time_t *deathp, 1267 u_int *secondsp, int *confirmp, char **sk_providerp, 1268 struct dest_constraint **dcsp, size_t *ndcsp, 1269 int *cert_onlyp, size_t *ncerts, struct sshkey ***certs) 1270 { 1271 u_char ctype; 1272 int r; 1273 u_int seconds, maxsign = 0; 1274 1275 while (sshbuf_len(m)) { 1276 if ((r = sshbuf_get_u8(m, &ctype)) != 0) { 1277 error_fr(r, "parse constraint type"); 1278 goto out; 1279 } 1280 switch (ctype) { 1281 case SSH_AGENT_CONSTRAIN_LIFETIME: 1282 if (*deathp != 0) { 1283 error_f("lifetime already set"); 1284 r = SSH_ERR_INVALID_FORMAT; 1285 goto out; 1286 } 1287 if ((r = sshbuf_get_u32(m, &seconds)) != 0) { 1288 error_fr(r, "parse lifetime constraint"); 1289 goto out; 1290 } 1291 *deathp = monotime() + seconds; 1292 *secondsp = seconds; 1293 break; 1294 case SSH_AGENT_CONSTRAIN_CONFIRM: 1295 if (*confirmp != 0) { 1296 error_f("confirm already set"); 1297 r = SSH_ERR_INVALID_FORMAT; 1298 goto out; 1299 } 1300 *confirmp = 1; 1301 break; 1302 case SSH_AGENT_CONSTRAIN_MAXSIGN: 1303 if (k == NULL) { 1304 error_f("maxsign not valid here"); 1305 r = SSH_ERR_INVALID_FORMAT; 1306 goto out; 1307 } 1308 if (maxsign != 0) { 1309 error_f("maxsign already set"); 1310 r = SSH_ERR_INVALID_FORMAT; 1311 goto out; 1312 } 1313 if ((r = sshbuf_get_u32(m, &maxsign)) != 0) { 1314 error_fr(r, "parse maxsign constraint"); 1315 goto out; 1316 } 1317 if ((r = sshkey_enable_maxsign(k, maxsign)) != 0) { 1318 error_fr(r, "enable maxsign"); 1319 goto out; 1320 } 1321 break; 1322 case SSH_AGENT_CONSTRAIN_EXTENSION: 1323 if ((r = parse_key_constraint_extension(m, 1324 sk_providerp, dcsp, ndcsp, 1325 cert_onlyp, certs, ncerts)) != 0) 1326 goto out; /* error already logged */ 1327 break; 1328 default: 1329 error_f("Unknown constraint %d", ctype); 1330 r = SSH_ERR_FEATURE_UNSUPPORTED; 1331 goto out; 1332 } 1333 } 1334 /* success */ 1335 r = 0; 1336 out: 1337 return r; 1338 } 1339 1340 static void 1341 process_add_identity(SocketEntry *e) 1342 { 1343 Identity *id; 1344 int success = 0, confirm = 0; 1345 char *fp, *comment = NULL, *sk_provider = NULL; 1346 char canonical_provider[PATH_MAX]; 1347 time_t death = 0; 1348 u_int seconds = 0; 1349 struct dest_constraint *dest_constraints = NULL; 1350 size_t ndest_constraints = 0; 1351 struct sshkey *k = NULL; 1352 int r = SSH_ERR_INTERNAL_ERROR; 1353 1354 debug2_f("entering"); 1355 if ((r = sshkey_private_deserialize(e->request, &k)) != 0 || 1356 k == NULL || 1357 (r = sshbuf_get_cstring(e->request, &comment, NULL)) != 0) { 1358 error_fr(r, "parse"); 1359 goto out; 1360 } 1361 if (parse_key_constraints(e->request, k, &death, &seconds, &confirm, 1362 &sk_provider, &dest_constraints, &ndest_constraints, 1363 NULL, NULL, NULL) != 0) { 1364 error_f("failed to parse constraints"); 1365 sshbuf_reset(e->request); 1366 goto out; 1367 } 1368 dump_dest_constraints(__func__, dest_constraints, ndest_constraints); 1369 1370 if (sk_provider != NULL) { 1371 if (!sshkey_is_sk(k)) { 1372 error("Cannot add provider: %s is not an " 1373 "authenticator-hosted key", sshkey_type(k)); 1374 goto out; 1375 } 1376 if (strcasecmp(sk_provider, "internal") == 0) { 1377 debug_f("internal provider"); 1378 } else { 1379 if (socket_is_remote(e) && !remote_add_provider) { 1380 verbose("failed add of SK provider \"%.100s\": " 1381 "remote addition of providers is disabled", 1382 sk_provider); 1383 goto out; 1384 } 1385 if (realpath(sk_provider, canonical_provider) == NULL) { 1386 verbose("failed provider \"%.100s\": " 1387 "realpath: %s", sk_provider, 1388 strerror(errno)); 1389 goto out; 1390 } 1391 free(sk_provider); 1392 sk_provider = xstrdup(canonical_provider); 1393 if (match_pattern_list(sk_provider, 1394 allowed_providers, 0) != 1) { 1395 error("Refusing add key: " 1396 "provider %s not allowed", sk_provider); 1397 goto out; 1398 } 1399 } 1400 } 1401 if ((r = sshkey_shield_private(k)) != 0) { 1402 error_fr(r, "shield private"); 1403 goto out; 1404 } 1405 if (lifetime && !death) 1406 death = monotime() + lifetime; 1407 if ((id = lookup_identity(k)) == NULL) { 1408 id = xcalloc(1, sizeof(Identity)); 1409 TAILQ_INSERT_TAIL(&idtab->idlist, id, next); 1410 /* Increment the number of identities. */ 1411 idtab->nentries++; 1412 } else { 1413 /* identity not visible, do not update */ 1414 if (identity_permitted(id, e, NULL, NULL, NULL) != 0) 1415 goto out; /* error already logged */ 1416 /* key state might have been updated */ 1417 sshkey_free(id->key); 1418 free(id->comment); 1419 free(id->sk_provider); 1420 free_dest_constraints(id->dest_constraints, 1421 id->ndest_constraints); 1422 } 1423 /* success */ 1424 id->key = k; 1425 id->comment = comment; 1426 id->death = death; 1427 id->confirm = confirm; 1428 id->sk_provider = sk_provider; 1429 id->dest_constraints = dest_constraints; 1430 id->ndest_constraints = ndest_constraints; 1431 1432 if ((fp = sshkey_fingerprint(k, SSH_FP_HASH_DEFAULT, 1433 SSH_FP_DEFAULT)) == NULL) 1434 fatal_f("sshkey_fingerprint failed"); 1435 debug_f("add %s %s \"%.100s\" (life: %u) (confirm: %u) " 1436 "(provider: %s) (destination constraints: %zu)", 1437 sshkey_ssh_name(k), fp, comment, seconds, confirm, 1438 sk_provider == NULL ? "none" : sk_provider, ndest_constraints); 1439 free(fp); 1440 /* transferred */ 1441 k = NULL; 1442 comment = NULL; 1443 sk_provider = NULL; 1444 dest_constraints = NULL; 1445 ndest_constraints = 0; 1446 success = 1; 1447 out: 1448 free(sk_provider); 1449 free(comment); 1450 sshkey_free(k); 1451 free_dest_constraints(dest_constraints, ndest_constraints); 1452 send_status(e, success); 1453 } 1454 1455 /* XXX todo: encrypt sensitive data with passphrase */ 1456 static void 1457 process_lock_agent(SocketEntry *e, int lock) 1458 { 1459 int r, success = 0, delay; 1460 char *passwd; 1461 u_char passwdhash[LOCK_SIZE]; 1462 static u_int fail_count = 0; 1463 size_t pwlen; 1464 1465 debug2_f("entering"); 1466 /* 1467 * This is deliberately fatal: the user has requested that we lock, 1468 * but we can't parse their request properly. The only safe thing to 1469 * do is abort. 1470 */ 1471 if ((r = sshbuf_get_cstring(e->request, &passwd, &pwlen)) != 0) 1472 fatal_fr(r, "parse"); 1473 if (pwlen == 0) { 1474 debug("empty password not supported"); 1475 } else if (locked && !lock) { 1476 if (bcrypt_pbkdf(passwd, pwlen, (uint8_t *)lock_salt, sizeof(lock_salt), 1477 (uint8_t *)passwdhash, sizeof(passwdhash), LOCK_ROUNDS) < 0) 1478 fatal("bcrypt_pbkdf"); 1479 if (timingsafe_bcmp(passwdhash, lock_pwhash, LOCK_SIZE) == 0) { 1480 debug("agent unlocked"); 1481 locked = 0; 1482 fail_count = 0; 1483 explicit_bzero(lock_pwhash, sizeof(lock_pwhash)); 1484 success = 1; 1485 } else { 1486 /* delay in 0.1s increments up to 10s */ 1487 if (fail_count < 100) 1488 fail_count++; 1489 delay = 100000 * fail_count; 1490 debug("unlock failed, delaying %0.1lf seconds", 1491 (double)delay/1000000); 1492 usleep(delay); 1493 } 1494 explicit_bzero(passwdhash, sizeof(passwdhash)); 1495 } else if (!locked && lock) { 1496 debug("agent locked"); 1497 locked = 1; 1498 arc4random_buf(lock_salt, sizeof(lock_salt)); 1499 if (bcrypt_pbkdf(passwd, pwlen, lock_salt, sizeof(lock_salt), 1500 lock_pwhash, sizeof(lock_pwhash), LOCK_ROUNDS) < 0) 1501 fatal("bcrypt_pbkdf"); 1502 success = 1; 1503 } 1504 freezero(passwd, pwlen); 1505 send_status(e, success); 1506 } 1507 1508 static void 1509 no_identities(SocketEntry *e) 1510 { 1511 struct sshbuf *msg; 1512 int r; 1513 1514 if ((msg = sshbuf_new()) == NULL) 1515 fatal_f("sshbuf_new failed"); 1516 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_IDENTITIES_ANSWER)) != 0 || 1517 (r = sshbuf_put_u32(msg, 0)) != 0 || 1518 (r = sshbuf_put_stringb(e->output, msg)) != 0) 1519 fatal_fr(r, "compose"); 1520 sshbuf_free(msg); 1521 } 1522 1523 #ifdef ENABLE_PKCS11 1524 /* Add an identity to idlist; takes ownership of 'key' and 'comment' */ 1525 static void 1526 add_p11_identity(struct sshkey *key, char *comment, const char *provider, 1527 time_t death, u_int confirm, struct dest_constraint *dest_constraints, 1528 size_t ndest_constraints) 1529 { 1530 Identity *id; 1531 1532 if (lookup_identity(key) != NULL) { 1533 sshkey_free(key); 1534 free(comment); 1535 return; 1536 } 1537 id = xcalloc(1, sizeof(Identity)); 1538 id->key = key; 1539 id->comment = comment; 1540 id->provider = xstrdup(provider); 1541 id->death = death; 1542 id->confirm = confirm; 1543 id->dest_constraints = dup_dest_constraints(dest_constraints, 1544 ndest_constraints); 1545 id->ndest_constraints = ndest_constraints; 1546 TAILQ_INSERT_TAIL(&idtab->idlist, id, next); 1547 idtab->nentries++; 1548 } 1549 1550 static void 1551 process_add_smartcard_key(SocketEntry *e) 1552 { 1553 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; 1554 char **comments = NULL; 1555 int r, i, count = 0, success = 0, confirm = 0; 1556 u_int seconds = 0; 1557 time_t death = 0; 1558 struct sshkey **keys = NULL, *k; 1559 struct dest_constraint *dest_constraints = NULL; 1560 size_t j, ndest_constraints = 0, ncerts = 0; 1561 struct sshkey **certs = NULL; 1562 int cert_only = 0; 1563 1564 debug2_f("entering"); 1565 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || 1566 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) { 1567 error_fr(r, "parse"); 1568 goto send; 1569 } 1570 if (parse_key_constraints(e->request, NULL, &death, &seconds, &confirm, 1571 NULL, &dest_constraints, &ndest_constraints, &cert_only, 1572 &ncerts, &certs) != 0) { 1573 error_f("failed to parse constraints"); 1574 goto send; 1575 } 1576 dump_dest_constraints(__func__, dest_constraints, ndest_constraints); 1577 if (socket_is_remote(e) && !remote_add_provider) { 1578 verbose("failed PKCS#11 add of \"%.100s\": remote addition of " 1579 "providers is disabled", provider); 1580 goto send; 1581 } 1582 if (realpath(provider, canonical_provider) == NULL) { 1583 verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", 1584 provider, strerror(errno)); 1585 goto send; 1586 } 1587 if (match_pattern_list(canonical_provider, allowed_providers, 0) != 1) { 1588 verbose("refusing PKCS#11 add of \"%.100s\": " 1589 "provider not allowed", canonical_provider); 1590 goto send; 1591 } 1592 debug_f("add %.100s", canonical_provider); 1593 if (lifetime && !death) 1594 death = monotime() + lifetime; 1595 1596 count = pkcs11_add_provider(canonical_provider, pin, &keys, &comments); 1597 for (i = 0; i < count; i++) { 1598 if (comments[i] == NULL || comments[i][0] == '\0') { 1599 free(comments[i]); 1600 comments[i] = xstrdup(canonical_provider); 1601 } 1602 for (j = 0; j < ncerts; j++) { 1603 if (!sshkey_is_cert(certs[j])) 1604 continue; 1605 if (!sshkey_equal_public(keys[i], certs[j])) 1606 continue; 1607 if (pkcs11_make_cert(keys[i], certs[j], &k) != 0) 1608 continue; 1609 add_p11_identity(k, xstrdup(comments[i]), 1610 canonical_provider, death, confirm, 1611 dest_constraints, ndest_constraints); 1612 success = 1; 1613 } 1614 if (!cert_only && lookup_identity(keys[i]) == NULL) { 1615 add_p11_identity(keys[i], comments[i], 1616 canonical_provider, death, confirm, 1617 dest_constraints, ndest_constraints); 1618 keys[i] = NULL; /* transferred */ 1619 comments[i] = NULL; /* transferred */ 1620 success = 1; 1621 } 1622 /* XXX update constraints for existing keys */ 1623 sshkey_free(keys[i]); 1624 free(comments[i]); 1625 } 1626 send: 1627 free(pin); 1628 free(provider); 1629 free(keys); 1630 free(comments); 1631 free_dest_constraints(dest_constraints, ndest_constraints); 1632 for (j = 0; j < ncerts; j++) 1633 sshkey_free(certs[j]); 1634 free(certs); 1635 send_status(e, success); 1636 } 1637 1638 static void 1639 process_remove_smartcard_key(SocketEntry *e) 1640 { 1641 char *provider = NULL, *pin = NULL, canonical_provider[PATH_MAX]; 1642 int r, success = 0; 1643 Identity *id, *nxt; 1644 1645 debug2_f("entering"); 1646 if ((r = sshbuf_get_cstring(e->request, &provider, NULL)) != 0 || 1647 (r = sshbuf_get_cstring(e->request, &pin, NULL)) != 0) { 1648 error_fr(r, "parse"); 1649 goto send; 1650 } 1651 free(pin); 1652 1653 if (realpath(provider, canonical_provider) == NULL) { 1654 verbose("failed PKCS#11 add of \"%.100s\": realpath: %s", 1655 provider, strerror(errno)); 1656 goto send; 1657 } 1658 1659 debug_f("remove %.100s", canonical_provider); 1660 for (id = TAILQ_FIRST(&idtab->idlist); id; id = nxt) { 1661 nxt = TAILQ_NEXT(id, next); 1662 /* Skip file--based keys */ 1663 if (id->provider == NULL) 1664 continue; 1665 if (!strcmp(canonical_provider, id->provider)) { 1666 TAILQ_REMOVE(&idtab->idlist, id, next); 1667 free_identity(id); 1668 idtab->nentries--; 1669 } 1670 } 1671 if (pkcs11_del_provider(canonical_provider) == 0) 1672 success = 1; 1673 else 1674 error_f("pkcs11_del_provider failed"); 1675 send: 1676 free(provider); 1677 send_status(e, success); 1678 } 1679 #endif /* ENABLE_PKCS11 */ 1680 1681 static int 1682 process_ext_session_bind(SocketEntry *e) 1683 { 1684 int r, sid_match, key_match; 1685 struct sshkey *key = NULL; 1686 struct sshbuf *sid = NULL, *sig = NULL; 1687 char *fp = NULL; 1688 size_t i; 1689 u_char fwd = 0; 1690 1691 debug2_f("entering"); 1692 e->session_bind_attempted = 1; 1693 if ((r = sshkey_froms(e->request, &key)) != 0 || 1694 (r = sshbuf_froms(e->request, &sid)) != 0 || 1695 (r = sshbuf_froms(e->request, &sig)) != 0 || 1696 (r = sshbuf_get_u8(e->request, &fwd)) != 0) { 1697 error_fr(r, "parse"); 1698 goto out; 1699 } 1700 if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT, 1701 SSH_FP_DEFAULT)) == NULL) 1702 fatal_f("fingerprint failed"); 1703 /* check signature with hostkey on session ID */ 1704 if ((r = sshkey_verify(key, sshbuf_ptr(sig), sshbuf_len(sig), 1705 sshbuf_ptr(sid), sshbuf_len(sid), NULL, 0, NULL)) != 0) { 1706 error_fr(r, "sshkey_verify for %s %s", sshkey_type(key), fp); 1707 goto out; 1708 } 1709 /* check whether sid/key already recorded */ 1710 for (i = 0; i < e->nsession_ids; i++) { 1711 if (!e->session_ids[i].forwarded) { 1712 error_f("attempt to bind session ID to socket " 1713 "previously bound for authentication attempt"); 1714 r = -1; 1715 goto out; 1716 } 1717 sid_match = buf_equal(sid, e->session_ids[i].sid) == 0; 1718 key_match = sshkey_equal(key, e->session_ids[i].key); 1719 if (sid_match && key_match) { 1720 debug_f("session ID already recorded for %s %s", 1721 sshkey_type(key), fp); 1722 r = 0; 1723 goto out; 1724 } else if (sid_match) { 1725 error_f("session ID recorded against different key " 1726 "for %s %s", sshkey_type(key), fp); 1727 r = -1; 1728 goto out; 1729 } 1730 /* 1731 * new sid with previously-seen key can happen, e.g. multiple 1732 * connections to the same host. 1733 */ 1734 } 1735 /* record new key/sid */ 1736 if (e->nsession_ids >= AGENT_MAX_SESSION_IDS) { 1737 error_f("too many session IDs recorded"); 1738 goto out; 1739 } 1740 e->session_ids = xrecallocarray(e->session_ids, e->nsession_ids, 1741 e->nsession_ids + 1, sizeof(*e->session_ids)); 1742 i = e->nsession_ids++; 1743 debug_f("recorded %s %s (slot %zu of %d)", sshkey_type(key), fp, i, 1744 AGENT_MAX_SESSION_IDS); 1745 e->session_ids[i].key = key; 1746 e->session_ids[i].forwarded = fwd != 0; 1747 key = NULL; /* transferred */ 1748 /* can't transfer sid; it's refcounted and scoped to request's life */ 1749 if ((e->session_ids[i].sid = sshbuf_new()) == NULL) 1750 fatal_f("sshbuf_new"); 1751 if ((r = sshbuf_putb(e->session_ids[i].sid, sid)) != 0) 1752 fatal_fr(r, "sshbuf_putb session ID"); 1753 /* success */ 1754 r = 0; 1755 out: 1756 free(fp); 1757 sshkey_free(key); 1758 sshbuf_free(sid); 1759 sshbuf_free(sig); 1760 return r == 0 ? 1 : 0; 1761 } 1762 1763 static void 1764 process_extension(SocketEntry *e) 1765 { 1766 int r, success = 0; 1767 char *name; 1768 1769 debug2_f("entering"); 1770 if ((r = sshbuf_get_cstring(e->request, &name, NULL)) != 0) { 1771 error_fr(r, "parse"); 1772 goto send; 1773 } 1774 if (strcmp(name, "session-bind@openssh.com") == 0) 1775 success = process_ext_session_bind(e); 1776 else 1777 debug_f("unsupported extension \"%s\"", name); 1778 free(name); 1779 send: 1780 send_status(e, success); 1781 } 1782 /* 1783 * dispatch incoming message. 1784 * returns 1 on success, 0 for incomplete messages or -1 on error. 1785 */ 1786 static int 1787 process_message(u_int socknum) 1788 { 1789 u_int msg_len; 1790 u_char type; 1791 const u_char *cp; 1792 int r; 1793 SocketEntry *e; 1794 1795 if (socknum >= sockets_alloc) 1796 fatal_f("sock %u >= allocated %u", socknum, sockets_alloc); 1797 e = &sockets[socknum]; 1798 1799 if (sshbuf_len(e->input) < 5) 1800 return 0; /* Incomplete message header. */ 1801 cp = sshbuf_ptr(e->input); 1802 msg_len = PEEK_U32(cp); 1803 if (msg_len > AGENT_MAX_LEN) { 1804 debug_f("socket %u (fd=%d) message too long %u > %u", 1805 socknum, e->fd, msg_len, AGENT_MAX_LEN); 1806 return -1; 1807 } 1808 if (sshbuf_len(e->input) < msg_len + 4) 1809 return 0; /* Incomplete message body. */ 1810 1811 /* move the current input to e->request */ 1812 sshbuf_reset(e->request); 1813 if ((r = sshbuf_get_stringb(e->input, e->request)) != 0 || 1814 (r = sshbuf_get_u8(e->request, &type)) != 0) { 1815 if (r == SSH_ERR_MESSAGE_INCOMPLETE || 1816 r == SSH_ERR_STRING_TOO_LARGE) { 1817 error_fr(r, "parse"); 1818 return -1; 1819 } 1820 fatal_fr(r, "parse"); 1821 } 1822 1823 debug_f("socket %u (fd=%d) type %d", socknum, e->fd, type); 1824 1825 /* check whether agent is locked */ 1826 if (locked && type != SSH_AGENTC_UNLOCK) { 1827 sshbuf_reset(e->request); 1828 switch (type) { 1829 case SSH2_AGENTC_REQUEST_IDENTITIES: 1830 /* send empty lists */ 1831 no_identities(e); 1832 break; 1833 default: 1834 /* send a fail message for all other request types */ 1835 send_status(e, 0); 1836 } 1837 return 1; 1838 } 1839 1840 switch (type) { 1841 case SSH_AGENTC_LOCK: 1842 case SSH_AGENTC_UNLOCK: 1843 process_lock_agent(e, type == SSH_AGENTC_LOCK); 1844 break; 1845 case SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES: 1846 process_remove_all_identities(e); /* safe for !WITH_SSH1 */ 1847 break; 1848 /* ssh2 */ 1849 case SSH2_AGENTC_SIGN_REQUEST: 1850 process_sign_request2(e); 1851 break; 1852 case SSH2_AGENTC_REQUEST_IDENTITIES: 1853 process_request_identities(e); 1854 break; 1855 case SSH2_AGENTC_ADD_IDENTITY: 1856 case SSH2_AGENTC_ADD_ID_CONSTRAINED: 1857 process_add_identity(e); 1858 break; 1859 case SSH2_AGENTC_REMOVE_IDENTITY: 1860 process_remove_identity(e); 1861 break; 1862 case SSH2_AGENTC_REMOVE_ALL_IDENTITIES: 1863 process_remove_all_identities(e); 1864 break; 1865 #ifdef ENABLE_PKCS11 1866 case SSH_AGENTC_ADD_SMARTCARD_KEY: 1867 case SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED: 1868 process_add_smartcard_key(e); 1869 break; 1870 case SSH_AGENTC_REMOVE_SMARTCARD_KEY: 1871 process_remove_smartcard_key(e); 1872 break; 1873 #endif /* ENABLE_PKCS11 */ 1874 case SSH_AGENTC_EXTENSION: 1875 process_extension(e); 1876 break; 1877 default: 1878 /* Unknown message. Respond with failure. */ 1879 error("Unknown message %d", type); 1880 sshbuf_reset(e->request); 1881 send_status(e, 0); 1882 break; 1883 } 1884 return 1; 1885 } 1886 1887 static void 1888 new_socket(sock_type type, int fd) 1889 { 1890 u_int i, old_alloc, new_alloc; 1891 1892 debug_f("type = %s", type == AUTH_CONNECTION ? "CONNECTION" : 1893 (type == AUTH_SOCKET ? "SOCKET" : "UNKNOWN")); 1894 set_nonblock(fd); 1895 1896 if (fd > max_fd) 1897 max_fd = fd; 1898 1899 for (i = 0; i < sockets_alloc; i++) 1900 if (sockets[i].type == AUTH_UNUSED) { 1901 sockets[i].fd = fd; 1902 if ((sockets[i].input = sshbuf_new()) == NULL || 1903 (sockets[i].output = sshbuf_new()) == NULL || 1904 (sockets[i].request = sshbuf_new()) == NULL) 1905 fatal_f("sshbuf_new failed"); 1906 sockets[i].type = type; 1907 return; 1908 } 1909 old_alloc = sockets_alloc; 1910 new_alloc = sockets_alloc + 10; 1911 sockets = xrecallocarray(sockets, old_alloc, new_alloc, 1912 sizeof(sockets[0])); 1913 for (i = old_alloc; i < new_alloc; i++) 1914 sockets[i].type = AUTH_UNUSED; 1915 sockets_alloc = new_alloc; 1916 sockets[old_alloc].fd = fd; 1917 if ((sockets[old_alloc].input = sshbuf_new()) == NULL || 1918 (sockets[old_alloc].output = sshbuf_new()) == NULL || 1919 (sockets[old_alloc].request = sshbuf_new()) == NULL) 1920 fatal_f("sshbuf_new failed"); 1921 sockets[old_alloc].type = type; 1922 } 1923 1924 static int 1925 handle_socket_read(u_int socknum) 1926 { 1927 struct sockaddr_un sunaddr; 1928 socklen_t slen; 1929 uid_t euid; 1930 gid_t egid; 1931 int fd; 1932 1933 slen = sizeof(sunaddr); 1934 fd = accept(sockets[socknum].fd, (struct sockaddr *)&sunaddr, &slen); 1935 if (fd == -1) { 1936 error("accept from AUTH_SOCKET: %s", strerror(errno)); 1937 return -1; 1938 } 1939 if (getpeereid(fd, &euid, &egid) == -1) { 1940 error("getpeereid %d failed: %s", fd, strerror(errno)); 1941 close(fd); 1942 return -1; 1943 } 1944 if ((euid != 0) && (getuid() != euid)) { 1945 error("uid mismatch: peer euid %u != uid %u", 1946 (u_int) euid, (u_int) getuid()); 1947 close(fd); 1948 return -1; 1949 } 1950 new_socket(AUTH_CONNECTION, fd); 1951 return 0; 1952 } 1953 1954 static int 1955 handle_conn_read(u_int socknum) 1956 { 1957 char buf[AGENT_RBUF_LEN]; 1958 ssize_t len; 1959 int r; 1960 1961 if ((len = read(sockets[socknum].fd, buf, sizeof(buf))) <= 0) { 1962 if (len == -1) { 1963 if (errno == EAGAIN || errno == EINTR) 1964 return 0; 1965 error_f("read error on socket %u (fd %d): %s", 1966 socknum, sockets[socknum].fd, strerror(errno)); 1967 } 1968 return -1; 1969 } 1970 if ((r = sshbuf_put(sockets[socknum].input, buf, len)) != 0) 1971 fatal_fr(r, "compose"); 1972 explicit_bzero(buf, sizeof(buf)); 1973 for (;;) { 1974 if ((r = process_message(socknum)) == -1) 1975 return -1; 1976 else if (r == 0) 1977 break; 1978 } 1979 return 0; 1980 } 1981 1982 static int 1983 handle_conn_write(u_int socknum) 1984 { 1985 ssize_t len; 1986 int r; 1987 1988 if (sshbuf_len(sockets[socknum].output) == 0) 1989 return 0; /* shouldn't happen */ 1990 if ((len = write(sockets[socknum].fd, 1991 sshbuf_ptr(sockets[socknum].output), 1992 sshbuf_len(sockets[socknum].output))) <= 0) { 1993 if (len == -1) { 1994 if (errno == EAGAIN || errno == EINTR) 1995 return 0; 1996 error_f("read error on socket %u (fd %d): %s", 1997 socknum, sockets[socknum].fd, strerror(errno)); 1998 } 1999 return -1; 2000 } 2001 if ((r = sshbuf_consume(sockets[socknum].output, len)) != 0) 2002 fatal_fr(r, "consume"); 2003 return 0; 2004 } 2005 2006 static void 2007 after_poll(struct pollfd *pfd, size_t npfd, u_int maxfds) 2008 { 2009 size_t i; 2010 u_int socknum, activefds = npfd; 2011 2012 for (i = 0; i < npfd; i++) { 2013 if (pfd[i].revents == 0) 2014 continue; 2015 /* Find sockets entry */ 2016 for (socknum = 0; socknum < sockets_alloc; socknum++) { 2017 if (sockets[socknum].type != AUTH_SOCKET && 2018 sockets[socknum].type != AUTH_CONNECTION) 2019 continue; 2020 if (pfd[i].fd == sockets[socknum].fd) 2021 break; 2022 } 2023 if (socknum >= sockets_alloc) { 2024 error_f("no socket for fd %d", pfd[i].fd); 2025 continue; 2026 } 2027 /* Process events */ 2028 switch (sockets[socknum].type) { 2029 case AUTH_SOCKET: 2030 if ((pfd[i].revents & (POLLIN|POLLERR)) == 0) 2031 break; 2032 if (npfd > maxfds) { 2033 debug3("out of fds (active %u >= limit %u); " 2034 "skipping accept", activefds, maxfds); 2035 break; 2036 } 2037 if (handle_socket_read(socknum) == 0) 2038 activefds++; 2039 break; 2040 case AUTH_CONNECTION: 2041 if ((pfd[i].revents & (POLLIN|POLLHUP|POLLERR)) != 0 && 2042 handle_conn_read(socknum) != 0) 2043 goto close_sock; 2044 if ((pfd[i].revents & (POLLOUT|POLLHUP)) != 0 && 2045 handle_conn_write(socknum) != 0) { 2046 close_sock: 2047 if (activefds == 0) 2048 fatal("activefds == 0 at close_sock"); 2049 close_socket(&sockets[socknum]); 2050 activefds--; 2051 break; 2052 } 2053 break; 2054 default: 2055 break; 2056 } 2057 } 2058 } 2059 2060 static int 2061 prepare_poll(struct pollfd **pfdp, size_t *npfdp, struct timespec *timeoutp, u_int maxfds) 2062 { 2063 struct pollfd *pfd = *pfdp; 2064 size_t i, j, npfd = 0; 2065 time_t deadline; 2066 int r; 2067 2068 /* Count active sockets */ 2069 for (i = 0; i < sockets_alloc; i++) { 2070 switch (sockets[i].type) { 2071 case AUTH_SOCKET: 2072 case AUTH_CONNECTION: 2073 npfd++; 2074 break; 2075 case AUTH_UNUSED: 2076 break; 2077 default: 2078 fatal("Unknown socket type %d", sockets[i].type); 2079 break; 2080 } 2081 } 2082 if (npfd != *npfdp && 2083 (pfd = recallocarray(pfd, *npfdp, npfd, sizeof(*pfd))) == NULL) 2084 fatal_f("recallocarray failed"); 2085 *pfdp = pfd; 2086 *npfdp = npfd; 2087 2088 for (i = j = 0; i < sockets_alloc; i++) { 2089 switch (sockets[i].type) { 2090 case AUTH_SOCKET: 2091 if (npfd > maxfds) { 2092 debug3("out of fds (active %zu >= limit %u); " 2093 "skipping arming listener", npfd, maxfds); 2094 break; 2095 } 2096 pfd[j].fd = sockets[i].fd; 2097 pfd[j].revents = 0; 2098 pfd[j].events = POLLIN; 2099 j++; 2100 break; 2101 case AUTH_CONNECTION: 2102 pfd[j].fd = sockets[i].fd; 2103 pfd[j].revents = 0; 2104 /* 2105 * Only prepare to read if we can handle a full-size 2106 * input read buffer and enqueue a max size reply.. 2107 */ 2108 if ((r = sshbuf_check_reserve(sockets[i].input, 2109 AGENT_RBUF_LEN)) == 0 && 2110 (r = sshbuf_check_reserve(sockets[i].output, 2111 AGENT_MAX_LEN)) == 0) 2112 pfd[j].events = POLLIN; 2113 else if (r != SSH_ERR_NO_BUFFER_SPACE) 2114 fatal_fr(r, "reserve"); 2115 if (sshbuf_len(sockets[i].output) > 0) 2116 pfd[j].events |= POLLOUT; 2117 j++; 2118 break; 2119 default: 2120 break; 2121 } 2122 } 2123 deadline = reaper(); 2124 if (parent_alive_interval != 0) 2125 deadline = (deadline == 0) ? parent_alive_interval : 2126 MINIMUM(deadline, parent_alive_interval); 2127 if (deadline != 0) 2128 ptimeout_deadline_sec(timeoutp, deadline); 2129 return (1); 2130 } 2131 2132 static void 2133 cleanup_socket(void) 2134 { 2135 if (cleanup_pid != 0 && getpid() != cleanup_pid) 2136 return; 2137 debug_f("cleanup"); 2138 if (socket_name[0]) 2139 unlink(socket_name); 2140 if (socket_dir[0]) 2141 rmdir(socket_dir); 2142 } 2143 2144 void 2145 cleanup_exit(int i) 2146 { 2147 cleanup_socket(); 2148 #ifdef ENABLE_PKCS11 2149 pkcs11_terminate(); 2150 #endif 2151 _exit(i); 2152 } 2153 2154 static void 2155 cleanup_handler(int sig) 2156 { 2157 signalled = sig; 2158 } 2159 2160 static void 2161 check_parent_exists(void) 2162 { 2163 /* 2164 * If our parent has exited then getppid() will return (pid_t)1, 2165 * so testing for that should be safe. 2166 */ 2167 if (parent_pid != -1 && getppid() != parent_pid) { 2168 /* printf("Parent has died - Authentication agent exiting.\n"); */ 2169 cleanup_socket(); 2170 _exit(2); 2171 } 2172 } 2173 2174 __dead static void 2175 usage(void) 2176 { 2177 fprintf(stderr, 2178 "usage: ssh-agent [-c | -s] [-Dd] [-a bind_address] [-E fingerprint_hash]\n" 2179 " [-O option] [-P allowed_providers] [-t life]\n" 2180 " ssh-agent [-a bind_address] [-E fingerprint_hash] [-O option]\n" 2181 " [-P allowed_providers] [-t life] command [arg ...]\n" 2182 " ssh-agent [-c | -s] -k\n"); 2183 exit(1); 2184 } 2185 2186 static void 2187 csh_setenv(const char *name, const char *value) 2188 { 2189 printf("setenv %s %s;\n", name, value); 2190 } 2191 2192 static void 2193 csh_unsetenv(const char *name) 2194 { 2195 printf("unsetenv %s;\n", name); 2196 } 2197 2198 static void 2199 sh_setenv(const char *name, const char *value) 2200 { 2201 printf("%s=%s; export %s;\n", name, value, name); 2202 } 2203 2204 static void 2205 sh_unsetenv(const char *name) 2206 { 2207 printf("unset %s;\n", name); 2208 } 2209 int 2210 main(int ac, char **av) 2211 { 2212 int c_flag = 0, d_flag = 0, D_flag = 0, k_flag = 0, s_flag = 0; 2213 int sock, ch, result, saved_errno; 2214 char *shell, *pidstr, *agentsocket = NULL; 2215 struct rlimit rlim; 2216 void (*f_setenv)(const char *, const char *); 2217 void (*f_unsetenv)(const char *); 2218 extern int optind; 2219 extern char *optarg; 2220 pid_t pid; 2221 char pidstrbuf[1 + 3 * sizeof pid]; 2222 size_t len; 2223 mode_t prev_mask; 2224 struct timespec timeout; 2225 struct pollfd *pfd = NULL; 2226 size_t npfd = 0; 2227 u_int maxfds; 2228 sigset_t nsigset, osigset; 2229 2230 /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */ 2231 sanitise_stdfd(); 2232 2233 /* drop */ 2234 (void)setegid(getgid()); 2235 (void)setgid(getgid()); 2236 2237 if (getrlimit(RLIMIT_NOFILE, &rlim) == -1) 2238 fatal("%s: getrlimit: %s", __progname, strerror(errno)); 2239 2240 #ifdef WITH_OPENSSL 2241 OpenSSL_add_all_algorithms(); 2242 #endif 2243 2244 while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) { 2245 switch (ch) { 2246 case 'E': 2247 fingerprint_hash = ssh_digest_alg_by_name(optarg); 2248 if (fingerprint_hash == -1) 2249 fatal("Invalid hash algorithm \"%s\"", optarg); 2250 break; 2251 case 'c': 2252 if (s_flag) 2253 usage(); 2254 c_flag++; 2255 break; 2256 case 'k': 2257 k_flag++; 2258 break; 2259 case 'O': 2260 if (strcmp(optarg, "no-restrict-websafe") == 0) 2261 restrict_websafe = 0; 2262 else if (strcmp(optarg, "allow-remote-pkcs11") == 0) 2263 remote_add_provider = 1; 2264 else 2265 fatal("Unknown -O option"); 2266 break; 2267 case 'P': 2268 if (allowed_providers != NULL) 2269 fatal("-P option already specified"); 2270 allowed_providers = xstrdup(optarg); 2271 break; 2272 case 's': 2273 if (c_flag) 2274 usage(); 2275 s_flag++; 2276 break; 2277 case 'd': 2278 if (d_flag || D_flag) 2279 usage(); 2280 d_flag++; 2281 break; 2282 case 'D': 2283 if (d_flag || D_flag) 2284 usage(); 2285 D_flag++; 2286 break; 2287 case 'a': 2288 agentsocket = optarg; 2289 break; 2290 case 't': 2291 if ((lifetime = convtime(optarg)) == -1) { 2292 fprintf(stderr, "Invalid lifetime\n"); 2293 usage(); 2294 } 2295 break; 2296 default: 2297 usage(); 2298 } 2299 } 2300 ac -= optind; 2301 av += optind; 2302 2303 if (ac > 0 && (c_flag || k_flag || s_flag || d_flag || D_flag)) 2304 usage(); 2305 2306 if (allowed_providers == NULL) 2307 allowed_providers = xstrdup(DEFAULT_ALLOWED_PROVIDERS); 2308 2309 if (ac == 0 && !c_flag && !s_flag) { 2310 shell = getenv("SHELL"); 2311 if (shell != NULL && (len = strlen(shell)) > 2 && 2312 strncmp(shell + len - 3, "csh", 3) == 0) 2313 c_flag = 1; 2314 } 2315 if (c_flag) { 2316 f_setenv = csh_setenv; 2317 f_unsetenv = csh_unsetenv; 2318 } else { 2319 f_setenv = sh_setenv; 2320 f_unsetenv = sh_unsetenv; 2321 } 2322 if (k_flag) { 2323 const char *errstr = NULL; 2324 2325 pidstr = getenv(SSH_AGENTPID_ENV_NAME); 2326 if (pidstr == NULL) { 2327 fprintf(stderr, "%s not set, cannot kill agent\n", 2328 SSH_AGENTPID_ENV_NAME); 2329 exit(1); 2330 } 2331 pid = (int)strtonum(pidstr, 2, INT_MAX, &errstr); 2332 if (errstr) { 2333 fprintf(stderr, 2334 "%s=\"%s\", which is not a good PID: %s\n", 2335 SSH_AGENTPID_ENV_NAME, pidstr, errstr); 2336 exit(1); 2337 } 2338 if (kill(pid, SIGTERM) == -1) { 2339 perror("kill"); 2340 exit(1); 2341 } 2342 (*f_unsetenv)(SSH_AUTHSOCKET_ENV_NAME); 2343 (*f_unsetenv)(SSH_AGENTPID_ENV_NAME); 2344 printf("echo Agent pid %ld killed;\n", (long)pid); 2345 exit(0); 2346 } 2347 2348 /* 2349 * Minimum file descriptors: 2350 * stdio (3) + listener (1) + syslog (1 maybe) + connection (1) + 2351 * a few spare for libc / stack protectors / sanitisers, etc. 2352 */ 2353 #define SSH_AGENT_MIN_FDS (3+1+1+1+4) 2354 if (rlim.rlim_cur < SSH_AGENT_MIN_FDS) 2355 fatal("%s: file descriptor rlimit %lld too low (minimum %u)", 2356 __progname, (long long)rlim.rlim_cur, SSH_AGENT_MIN_FDS); 2357 maxfds = rlim.rlim_cur - SSH_AGENT_MIN_FDS; 2358 2359 parent_pid = getpid(); 2360 2361 if (agentsocket == NULL) { 2362 /* Create private directory for agent socket */ 2363 mktemp_proto(socket_dir, sizeof(socket_dir)); 2364 if (mkdtemp(socket_dir) == NULL) { 2365 perror("mkdtemp: private socket dir"); 2366 exit(1); 2367 } 2368 snprintf(socket_name, sizeof socket_name, "%s/agent.%ld", socket_dir, 2369 (long)parent_pid); 2370 } else { 2371 /* Try to use specified agent socket */ 2372 socket_dir[0] = '\0'; 2373 strlcpy(socket_name, agentsocket, sizeof socket_name); 2374 } 2375 2376 /* 2377 * Create socket early so it will exist before command gets run from 2378 * the parent. 2379 */ 2380 prev_mask = umask(0177); 2381 sock = unix_listener(socket_name, SSH_LISTEN_BACKLOG, 0); 2382 if (sock < 0) { 2383 /* XXX - unix_listener() calls error() not perror() */ 2384 *socket_name = '\0'; /* Don't unlink any existing file */ 2385 cleanup_exit(1); 2386 } 2387 umask(prev_mask); 2388 2389 /* 2390 * Fork, and have the parent execute the command, if any, or present 2391 * the socket data. The child continues as the authentication agent. 2392 */ 2393 if (D_flag || d_flag) { 2394 log_init(__progname, 2395 d_flag ? SYSLOG_LEVEL_DEBUG3 : SYSLOG_LEVEL_INFO, 2396 SYSLOG_FACILITY_AUTH, 1); 2397 if (c_flag) 2398 printf("setenv %s %s;\n", 2399 SSH_AUTHSOCKET_ENV_NAME, socket_name); 2400 else 2401 printf("%s=%s; export %s;\n", 2402 SSH_AUTHSOCKET_ENV_NAME, socket_name, 2403 SSH_AUTHSOCKET_ENV_NAME); 2404 printf("echo Agent pid %ld;\n", (long)parent_pid); 2405 fflush(stdout); 2406 goto skip; 2407 } 2408 pid = fork(); 2409 if (pid == -1) { 2410 perror("fork"); 2411 cleanup_exit(1); 2412 } 2413 if (pid != 0) { /* Parent - execute the given command. */ 2414 close(sock); 2415 snprintf(pidstrbuf, sizeof pidstrbuf, "%ld", (long)pid); 2416 if (ac == 0) { 2417 (*f_setenv)(SSH_AUTHSOCKET_ENV_NAME, socket_name); 2418 (*f_setenv)(SSH_AGENTPID_ENV_NAME, pidstrbuf); 2419 printf("echo Agent pid %ld;\n", (long)pid); 2420 exit(0); 2421 } 2422 if (setenv(SSH_AUTHSOCKET_ENV_NAME, socket_name, 1) == -1 || 2423 setenv(SSH_AGENTPID_ENV_NAME, pidstrbuf, 1) == -1) { 2424 perror("setenv"); 2425 exit(1); 2426 } 2427 execvp(av[0], av); 2428 perror(av[0]); 2429 exit(1); 2430 } 2431 /* child */ 2432 log_init(__progname, SYSLOG_LEVEL_INFO, SYSLOG_FACILITY_AUTH, 0); 2433 2434 if (setsid() == -1) { 2435 error("setsid: %s", strerror(errno)); 2436 cleanup_exit(1); 2437 } 2438 2439 (void)chdir("/"); 2440 if (stdfd_devnull(1, 1, 1) == -1) 2441 error_f("stdfd_devnull failed"); 2442 2443 /* deny core dumps, since memory contains unencrypted private keys */ 2444 rlim.rlim_cur = rlim.rlim_max = 0; 2445 if (setrlimit(RLIMIT_CORE, &rlim) == -1) { 2446 error("setrlimit RLIMIT_CORE: %s", strerror(errno)); 2447 cleanup_exit(1); 2448 } 2449 2450 skip: 2451 2452 cleanup_pid = getpid(); 2453 2454 #ifdef ENABLE_PKCS11 2455 pkcs11_init(0); 2456 #endif 2457 new_socket(AUTH_SOCKET, sock); 2458 if (ac > 0) 2459 parent_alive_interval = 10; 2460 idtab_init(); 2461 ssh_signal(SIGPIPE, SIG_IGN); 2462 ssh_signal(SIGINT, (d_flag | D_flag) ? cleanup_handler : SIG_IGN); 2463 ssh_signal(SIGHUP, cleanup_handler); 2464 ssh_signal(SIGTERM, cleanup_handler); 2465 2466 sigemptyset(&nsigset); 2467 sigaddset(&nsigset, SIGINT); 2468 sigaddset(&nsigset, SIGHUP); 2469 sigaddset(&nsigset, SIGTERM); 2470 2471 #ifdef __OpenBSD__ 2472 if (pledge("stdio rpath cpath unix id proc exec", NULL) == -1) 2473 fatal("%s: pledge: %s", __progname, strerror(errno)); 2474 #endif 2475 2476 while (1) { 2477 sigprocmask(SIG_BLOCK, &nsigset, &osigset); 2478 if (signalled != 0) { 2479 logit("exiting on signal %d", (int)signalled); 2480 cleanup_exit(2); 2481 } 2482 ptimeout_init(&timeout); 2483 prepare_poll(&pfd, &npfd, &timeout, maxfds); 2484 result = ppoll(pfd, npfd, ptimeout_get_tsp(&timeout), &osigset); 2485 sigprocmask(SIG_SETMASK, &osigset, NULL); 2486 saved_errno = errno; 2487 if (parent_alive_interval != 0) 2488 check_parent_exists(); 2489 (void) reaper(); /* remove expired keys */ 2490 if (result == -1) { 2491 if (saved_errno == EINTR) 2492 continue; 2493 fatal("poll: %s", strerror(saved_errno)); 2494 } else if (result > 0) 2495 after_poll(pfd, npfd, maxfds); 2496 } 2497 /* NOTREACHED */ 2498 } 2499