1 /* $OpenBSD: auth.c,v 1.127 2018/03/12 00:52:01 djm Exp $ */ 2 /* 3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "includes.h" 27 __RCSID("$FreeBSD$"); 28 29 #include <sys/types.h> 30 #include <sys/stat.h> 31 #include <sys/socket.h> 32 #include <sys/wait.h> 33 34 #include <netinet/in.h> 35 36 #include <errno.h> 37 #include <fcntl.h> 38 #ifdef HAVE_PATHS_H 39 # include <paths.h> 40 #endif 41 #include <pwd.h> 42 #ifdef HAVE_LOGIN_H 43 #include <login.h> 44 #endif 45 #ifdef USE_SHADOW 46 #include <shadow.h> 47 #endif 48 #include <stdarg.h> 49 #include <stdio.h> 50 #include <string.h> 51 #include <unistd.h> 52 #include <limits.h> 53 #include <netdb.h> 54 55 #include "xmalloc.h" 56 #include "match.h" 57 #include "groupaccess.h" 58 #include "log.h" 59 #include "buffer.h" 60 #include "misc.h" 61 #include "servconf.h" 62 #include "key.h" 63 #include "hostfile.h" 64 #include "auth.h" 65 #include "auth-options.h" 66 #include "canohost.h" 67 #include "uidswap.h" 68 #include "packet.h" 69 #include "loginrec.h" 70 #ifdef GSSAPI 71 #include "ssh-gss.h" 72 #endif 73 #include "authfile.h" 74 #include "monitor_wrap.h" 75 #include "authfile.h" 76 #include "ssherr.h" 77 #include "compat.h" 78 #include "channels.h" 79 #include "blacklist_client.h" 80 81 /* import */ 82 extern ServerOptions options; 83 extern int use_privsep; 84 extern Buffer loginmsg; 85 extern struct passwd *privsep_pw; 86 extern struct sshauthopt *auth_opts; 87 88 /* Debugging messages */ 89 Buffer auth_debug; 90 int auth_debug_init; 91 92 /* 93 * Check if the user is allowed to log in via ssh. If user is listed 94 * in DenyUsers or one of user's groups is listed in DenyGroups, false 95 * will be returned. If AllowUsers isn't empty and user isn't listed 96 * there, or if AllowGroups isn't empty and one of user's groups isn't 97 * listed there, false will be returned. 98 * If the user's shell is not executable, false will be returned. 99 * Otherwise true is returned. 100 */ 101 int 102 allowed_user(struct passwd * pw) 103 { 104 struct ssh *ssh = active_state; /* XXX */ 105 struct stat st; 106 const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; 107 u_int i; 108 int r; 109 #ifdef USE_SHADOW 110 struct spwd *spw = NULL; 111 #endif 112 113 /* Shouldn't be called if pw is NULL, but better safe than sorry... */ 114 if (!pw || !pw->pw_name) 115 return 0; 116 117 #ifdef USE_SHADOW 118 if (!options.use_pam) 119 spw = getspnam(pw->pw_name); 120 #ifdef HAS_SHADOW_EXPIRE 121 if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) 122 return 0; 123 #endif /* HAS_SHADOW_EXPIRE */ 124 #endif /* USE_SHADOW */ 125 126 /* grab passwd field for locked account check */ 127 passwd = pw->pw_passwd; 128 #ifdef USE_SHADOW 129 if (spw != NULL) 130 #ifdef USE_LIBIAF 131 passwd = get_iaf_password(pw); 132 #else 133 passwd = spw->sp_pwdp; 134 #endif /* USE_LIBIAF */ 135 #endif 136 137 /* check for locked account */ 138 if (!options.use_pam && passwd && *passwd) { 139 int locked = 0; 140 141 #ifdef LOCKED_PASSWD_STRING 142 if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) 143 locked = 1; 144 #endif 145 #ifdef LOCKED_PASSWD_PREFIX 146 if (strncmp(passwd, LOCKED_PASSWD_PREFIX, 147 strlen(LOCKED_PASSWD_PREFIX)) == 0) 148 locked = 1; 149 #endif 150 #ifdef LOCKED_PASSWD_SUBSTR 151 if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) 152 locked = 1; 153 #endif 154 #ifdef USE_LIBIAF 155 free((void *) passwd); 156 #endif /* USE_LIBIAF */ 157 if (locked) { 158 logit("User %.100s not allowed because account is locked", 159 pw->pw_name); 160 return 0; 161 } 162 } 163 164 /* 165 * Deny if shell does not exist or is not executable unless we 166 * are chrooting. 167 */ 168 if (options.chroot_directory == NULL || 169 strcasecmp(options.chroot_directory, "none") == 0) { 170 char *shell = xstrdup((pw->pw_shell[0] == '\0') ? 171 _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ 172 173 if (stat(shell, &st) != 0) { 174 logit("User %.100s not allowed because shell %.100s " 175 "does not exist", pw->pw_name, shell); 176 free(shell); 177 return 0; 178 } 179 if (S_ISREG(st.st_mode) == 0 || 180 (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { 181 logit("User %.100s not allowed because shell %.100s " 182 "is not executable", pw->pw_name, shell); 183 free(shell); 184 return 0; 185 } 186 free(shell); 187 } 188 189 if (options.num_deny_users > 0 || options.num_allow_users > 0 || 190 options.num_deny_groups > 0 || options.num_allow_groups > 0) { 191 hostname = auth_get_canonical_hostname(ssh, options.use_dns); 192 ipaddr = ssh_remote_ipaddr(ssh); 193 } 194 195 /* Return false if user is listed in DenyUsers */ 196 if (options.num_deny_users > 0) { 197 for (i = 0; i < options.num_deny_users; i++) { 198 r = match_user(pw->pw_name, hostname, ipaddr, 199 options.deny_users[i]); 200 if (r < 0) { 201 fatal("Invalid DenyUsers pattern \"%.100s\"", 202 options.deny_users[i]); 203 } else if (r != 0) { 204 logit("User %.100s from %.100s not allowed " 205 "because listed in DenyUsers", 206 pw->pw_name, hostname); 207 return 0; 208 } 209 } 210 } 211 /* Return false if AllowUsers isn't empty and user isn't listed there */ 212 if (options.num_allow_users > 0) { 213 for (i = 0; i < options.num_allow_users; i++) { 214 r = match_user(pw->pw_name, hostname, ipaddr, 215 options.allow_users[i]); 216 if (r < 0) { 217 fatal("Invalid AllowUsers pattern \"%.100s\"", 218 options.allow_users[i]); 219 } else if (r == 1) 220 break; 221 } 222 /* i < options.num_allow_users iff we break for loop */ 223 if (i >= options.num_allow_users) { 224 logit("User %.100s from %.100s not allowed because " 225 "not listed in AllowUsers", pw->pw_name, hostname); 226 return 0; 227 } 228 } 229 if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { 230 /* Get the user's group access list (primary and supplementary) */ 231 if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 232 logit("User %.100s from %.100s not allowed because " 233 "not in any group", pw->pw_name, hostname); 234 return 0; 235 } 236 237 /* Return false if one of user's groups is listed in DenyGroups */ 238 if (options.num_deny_groups > 0) 239 if (ga_match(options.deny_groups, 240 options.num_deny_groups)) { 241 ga_free(); 242 logit("User %.100s from %.100s not allowed " 243 "because a group is listed in DenyGroups", 244 pw->pw_name, hostname); 245 return 0; 246 } 247 /* 248 * Return false if AllowGroups isn't empty and one of user's groups 249 * isn't listed there 250 */ 251 if (options.num_allow_groups > 0) 252 if (!ga_match(options.allow_groups, 253 options.num_allow_groups)) { 254 ga_free(); 255 logit("User %.100s from %.100s not allowed " 256 "because none of user's groups are listed " 257 "in AllowGroups", pw->pw_name, hostname); 258 return 0; 259 } 260 ga_free(); 261 } 262 263 #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER 264 if (!sys_auth_allowed_user(pw, &loginmsg)) 265 return 0; 266 #endif 267 268 /* We found no reason not to let this user try to log on... */ 269 return 1; 270 } 271 272 /* 273 * Formats any key left in authctxt->auth_method_key for inclusion in 274 * auth_log()'s message. Also includes authxtct->auth_method_info if present. 275 */ 276 static char * 277 format_method_key(Authctxt *authctxt) 278 { 279 const struct sshkey *key = authctxt->auth_method_key; 280 const char *methinfo = authctxt->auth_method_info; 281 char *fp, *ret = NULL; 282 283 if (key == NULL) 284 return NULL; 285 286 if (key_is_cert(key)) { 287 fp = sshkey_fingerprint(key->cert->signature_key, 288 options.fingerprint_hash, SSH_FP_DEFAULT); 289 xasprintf(&ret, "%s ID %s (serial %llu) CA %s %s%s%s", 290 sshkey_type(key), key->cert->key_id, 291 (unsigned long long)key->cert->serial, 292 sshkey_type(key->cert->signature_key), 293 fp == NULL ? "(null)" : fp, 294 methinfo == NULL ? "" : ", ", 295 methinfo == NULL ? "" : methinfo); 296 free(fp); 297 } else { 298 fp = sshkey_fingerprint(key, options.fingerprint_hash, 299 SSH_FP_DEFAULT); 300 xasprintf(&ret, "%s %s%s%s", sshkey_type(key), 301 fp == NULL ? "(null)" : fp, 302 methinfo == NULL ? "" : ", ", 303 methinfo == NULL ? "" : methinfo); 304 free(fp); 305 } 306 return ret; 307 } 308 309 void 310 auth_log(Authctxt *authctxt, int authenticated, int partial, 311 const char *method, const char *submethod) 312 { 313 struct ssh *ssh = active_state; /* XXX */ 314 void (*authlog) (const char *fmt,...) = verbose; 315 const char *authmsg; 316 char *extra = NULL; 317 318 if (use_privsep && !mm_is_monitor() && !authctxt->postponed) 319 return; 320 321 /* Raise logging level */ 322 if (authenticated == 1 || 323 !authctxt->valid || 324 authctxt->failures >= options.max_authtries / 2 || 325 strcmp(method, "password") == 0) 326 authlog = logit; 327 328 if (authctxt->postponed) 329 authmsg = "Postponed"; 330 else if (partial) 331 authmsg = "Partial"; 332 else { 333 authmsg = authenticated ? "Accepted" : "Failed"; 334 if (authenticated) 335 BLACKLIST_NOTIFY(BLACKLIST_AUTH_OK, "ssh"); 336 } 337 338 if ((extra = format_method_key(authctxt)) == NULL) { 339 if (authctxt->auth_method_info != NULL) 340 extra = xstrdup(authctxt->auth_method_info); 341 } 342 343 authlog("%s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s", 344 authmsg, 345 method, 346 submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, 347 authctxt->valid ? "" : "invalid user ", 348 authctxt->user, 349 ssh_remote_ipaddr(ssh), 350 ssh_remote_port(ssh), 351 extra != NULL ? ": " : "", 352 extra != NULL ? extra : ""); 353 354 free(extra); 355 356 #ifdef CUSTOM_FAILED_LOGIN 357 if (authenticated == 0 && !authctxt->postponed && 358 (strcmp(method, "password") == 0 || 359 strncmp(method, "keyboard-interactive", 20) == 0 || 360 strcmp(method, "challenge-response") == 0)) 361 record_failed_login(authctxt->user, 362 auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); 363 # ifdef WITH_AIXAUTHENTICATE 364 if (authenticated) 365 sys_auth_record_login(authctxt->user, 366 auth_get_canonical_hostname(ssh, options.use_dns), "ssh", 367 &loginmsg); 368 # endif 369 #endif 370 #ifdef SSH_AUDIT_EVENTS 371 if (authenticated == 0 && !authctxt->postponed) 372 audit_event(audit_classify_auth(method)); 373 #endif 374 } 375 376 377 void 378 auth_maxtries_exceeded(Authctxt *authctxt) 379 { 380 struct ssh *ssh = active_state; /* XXX */ 381 382 error("maximum authentication attempts exceeded for " 383 "%s%.100s from %.200s port %d ssh2", 384 authctxt->valid ? "" : "invalid user ", 385 authctxt->user, 386 ssh_remote_ipaddr(ssh), 387 ssh_remote_port(ssh)); 388 packet_disconnect("Too many authentication failures"); 389 /* NOTREACHED */ 390 } 391 392 /* 393 * Check whether root logins are disallowed. 394 */ 395 int 396 auth_root_allowed(struct ssh *ssh, const char *method) 397 { 398 switch (options.permit_root_login) { 399 case PERMIT_YES: 400 return 1; 401 case PERMIT_NO_PASSWD: 402 if (strcmp(method, "publickey") == 0 || 403 strcmp(method, "hostbased") == 0 || 404 strcmp(method, "gssapi-with-mic") == 0) 405 return 1; 406 break; 407 case PERMIT_FORCED_ONLY: 408 if (auth_opts->force_command != NULL) { 409 logit("Root login accepted for forced command."); 410 return 1; 411 } 412 break; 413 } 414 logit("ROOT LOGIN REFUSED FROM %.200s port %d", 415 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 416 return 0; 417 } 418 419 420 /* 421 * Given a template and a passwd structure, build a filename 422 * by substituting % tokenised options. Currently, %% becomes '%', 423 * %h becomes the home directory and %u the username. 424 * 425 * This returns a buffer allocated by xmalloc. 426 */ 427 char * 428 expand_authorized_keys(const char *filename, struct passwd *pw) 429 { 430 char *file, ret[PATH_MAX]; 431 int i; 432 433 file = percent_expand(filename, "h", pw->pw_dir, 434 "u", pw->pw_name, (char *)NULL); 435 436 /* 437 * Ensure that filename starts anchored. If not, be backward 438 * compatible and prepend the '%h/' 439 */ 440 if (*file == '/') 441 return (file); 442 443 i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file); 444 if (i < 0 || (size_t)i >= sizeof(ret)) 445 fatal("expand_authorized_keys: path too long"); 446 free(file); 447 return (xstrdup(ret)); 448 } 449 450 char * 451 authorized_principals_file(struct passwd *pw) 452 { 453 if (options.authorized_principals_file == NULL) 454 return NULL; 455 return expand_authorized_keys(options.authorized_principals_file, pw); 456 } 457 458 /* return ok if key exists in sysfile or userfile */ 459 HostStatus 460 check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host, 461 const char *sysfile, const char *userfile) 462 { 463 char *user_hostfile; 464 struct stat st; 465 HostStatus host_status; 466 struct hostkeys *hostkeys; 467 const struct hostkey_entry *found; 468 469 hostkeys = init_hostkeys(); 470 load_hostkeys(hostkeys, host, sysfile); 471 if (userfile != NULL) { 472 user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); 473 if (options.strict_modes && 474 (stat(user_hostfile, &st) == 0) && 475 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || 476 (st.st_mode & 022) != 0)) { 477 logit("Authentication refused for %.100s: " 478 "bad owner or modes for %.200s", 479 pw->pw_name, user_hostfile); 480 auth_debug_add("Ignored %.200s: bad ownership or modes", 481 user_hostfile); 482 } else { 483 temporarily_use_uid(pw); 484 load_hostkeys(hostkeys, host, user_hostfile); 485 restore_uid(); 486 } 487 free(user_hostfile); 488 } 489 host_status = check_key_in_hostkeys(hostkeys, key, &found); 490 if (host_status == HOST_REVOKED) 491 error("WARNING: revoked key for %s attempted authentication", 492 found->host); 493 else if (host_status == HOST_OK) 494 debug("%s: key for %s found at %s:%ld", __func__, 495 found->host, found->file, found->line); 496 else 497 debug("%s: key for host %s not found", __func__, host); 498 499 free_hostkeys(hostkeys); 500 501 return host_status; 502 } 503 504 static FILE * 505 auth_openfile(const char *file, struct passwd *pw, int strict_modes, 506 int log_missing, char *file_type) 507 { 508 char line[1024]; 509 struct stat st; 510 int fd; 511 FILE *f; 512 513 if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { 514 if (log_missing || errno != ENOENT) 515 debug("Could not open %s '%s': %s", file_type, file, 516 strerror(errno)); 517 return NULL; 518 } 519 520 if (fstat(fd, &st) < 0) { 521 close(fd); 522 return NULL; 523 } 524 if (!S_ISREG(st.st_mode)) { 525 logit("User %s %s %s is not a regular file", 526 pw->pw_name, file_type, file); 527 close(fd); 528 return NULL; 529 } 530 unset_nonblock(fd); 531 if ((f = fdopen(fd, "r")) == NULL) { 532 close(fd); 533 return NULL; 534 } 535 if (strict_modes && 536 safe_path_fd(fileno(f), file, pw, line, sizeof(line)) != 0) { 537 fclose(f); 538 logit("Authentication refused: %s", line); 539 auth_debug_add("Ignored %s: %s", file_type, line); 540 return NULL; 541 } 542 543 return f; 544 } 545 546 547 FILE * 548 auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) 549 { 550 return auth_openfile(file, pw, strict_modes, 1, "authorized keys"); 551 } 552 553 FILE * 554 auth_openprincipals(const char *file, struct passwd *pw, int strict_modes) 555 { 556 return auth_openfile(file, pw, strict_modes, 0, 557 "authorized principals"); 558 } 559 560 struct passwd * 561 getpwnamallow(const char *user) 562 { 563 struct ssh *ssh = active_state; /* XXX */ 564 #ifdef HAVE_LOGIN_CAP 565 extern login_cap_t *lc; 566 #ifdef BSD_AUTH 567 auth_session_t *as; 568 #endif 569 #endif 570 struct passwd *pw; 571 struct connection_info *ci = get_connection_info(1, options.use_dns); 572 573 ci->user = user; 574 parse_server_match_config(&options, ci); 575 log_change_level(options.log_level); 576 process_permitopen(ssh, &options); 577 578 #if defined(_AIX) && defined(HAVE_SETAUTHDB) 579 aix_setauthdb(user); 580 #endif 581 582 pw = getpwnam(user); 583 584 #if defined(_AIX) && defined(HAVE_SETAUTHDB) 585 aix_restoreauthdb(); 586 #endif 587 #ifdef HAVE_CYGWIN 588 /* 589 * Windows usernames are case-insensitive. To avoid later problems 590 * when trying to match the username, the user is only allowed to 591 * login if the username is given in the same case as stored in the 592 * user database. 593 */ 594 if (pw != NULL && strcmp(user, pw->pw_name) != 0) { 595 logit("Login name %.100s does not match stored username %.100s", 596 user, pw->pw_name); 597 pw = NULL; 598 } 599 #endif 600 if (pw == NULL) { 601 BLACKLIST_NOTIFY(BLACKLIST_BAD_USER, user); 602 logit("Invalid user %.100s from %.100s port %d", 603 user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 604 #ifdef CUSTOM_FAILED_LOGIN 605 record_failed_login(user, 606 auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); 607 #endif 608 #ifdef SSH_AUDIT_EVENTS 609 audit_event(SSH_INVALID_USER); 610 #endif /* SSH_AUDIT_EVENTS */ 611 return (NULL); 612 } 613 if (!allowed_user(pw)) 614 return (NULL); 615 #ifdef HAVE_LOGIN_CAP 616 if ((lc = login_getpwclass(pw)) == NULL) { 617 debug("unable to get login class: %s", user); 618 return (NULL); 619 } 620 #ifdef BSD_AUTH 621 if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || 622 auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { 623 debug("Approval failure for %s", user); 624 pw = NULL; 625 } 626 if (as != NULL) 627 auth_close(as); 628 #endif 629 #endif 630 if (pw != NULL) 631 return (pwcopy(pw)); 632 return (NULL); 633 } 634 635 /* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ 636 int 637 auth_key_is_revoked(struct sshkey *key) 638 { 639 char *fp = NULL; 640 int r; 641 642 if (options.revoked_keys_file == NULL) 643 return 0; 644 if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, 645 SSH_FP_DEFAULT)) == NULL) { 646 r = SSH_ERR_ALLOC_FAIL; 647 error("%s: fingerprint key: %s", __func__, ssh_err(r)); 648 goto out; 649 } 650 651 r = sshkey_check_revoked(key, options.revoked_keys_file); 652 switch (r) { 653 case 0: 654 break; /* not revoked */ 655 case SSH_ERR_KEY_REVOKED: 656 error("Authentication key %s %s revoked by file %s", 657 sshkey_type(key), fp, options.revoked_keys_file); 658 goto out; 659 default: 660 error("Error checking authentication key %s %s in " 661 "revoked keys file %s: %s", sshkey_type(key), fp, 662 options.revoked_keys_file, ssh_err(r)); 663 goto out; 664 } 665 666 /* Success */ 667 r = 0; 668 669 out: 670 free(fp); 671 return r == 0 ? 0 : 1; 672 } 673 674 void 675 auth_debug_add(const char *fmt,...) 676 { 677 char buf[1024]; 678 va_list args; 679 680 if (!auth_debug_init) 681 return; 682 683 va_start(args, fmt); 684 vsnprintf(buf, sizeof(buf), fmt, args); 685 va_end(args); 686 buffer_put_cstring(&auth_debug, buf); 687 } 688 689 void 690 auth_debug_send(void) 691 { 692 char *msg; 693 694 if (!auth_debug_init) 695 return; 696 while (buffer_len(&auth_debug)) { 697 msg = buffer_get_string(&auth_debug, NULL); 698 packet_send_debug("%s", msg); 699 free(msg); 700 } 701 } 702 703 void 704 auth_debug_reset(void) 705 { 706 if (auth_debug_init) 707 buffer_clear(&auth_debug); 708 else { 709 buffer_init(&auth_debug); 710 auth_debug_init = 1; 711 } 712 } 713 714 struct passwd * 715 fakepw(void) 716 { 717 static struct passwd fake; 718 719 memset(&fake, 0, sizeof(fake)); 720 fake.pw_name = "NOUSER"; 721 fake.pw_passwd = 722 "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; 723 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS 724 fake.pw_gecos = "NOUSER"; 725 #endif 726 fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; 727 fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; 728 #ifdef HAVE_STRUCT_PASSWD_PW_CLASS 729 fake.pw_class = ""; 730 #endif 731 fake.pw_dir = "/nonexist"; 732 fake.pw_shell = "/nonexist"; 733 734 return (&fake); 735 } 736 737 /* 738 * Returns the remote DNS hostname as a string. The returned string must not 739 * be freed. NB. this will usually trigger a DNS query the first time it is 740 * called. 741 * This function does additional checks on the hostname to mitigate some 742 * attacks on legacy rhosts-style authentication. 743 * XXX is RhostsRSAAuthentication vulnerable to these? 744 * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) 745 */ 746 747 static char * 748 remote_hostname(struct ssh *ssh) 749 { 750 struct sockaddr_storage from; 751 socklen_t fromlen; 752 struct addrinfo hints, *ai, *aitop; 753 char name[NI_MAXHOST], ntop2[NI_MAXHOST]; 754 const char *ntop = ssh_remote_ipaddr(ssh); 755 756 /* Get IP address of client. */ 757 fromlen = sizeof(from); 758 memset(&from, 0, sizeof(from)); 759 if (getpeername(ssh_packet_get_connection_in(ssh), 760 (struct sockaddr *)&from, &fromlen) < 0) { 761 debug("getpeername failed: %.100s", strerror(errno)); 762 return strdup(ntop); 763 } 764 765 ipv64_normalise_mapped(&from, &fromlen); 766 if (from.ss_family == AF_INET6) 767 fromlen = sizeof(struct sockaddr_in6); 768 769 debug3("Trying to reverse map address %.100s.", ntop); 770 /* Map the IP address to a host name. */ 771 if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), 772 NULL, 0, NI_NAMEREQD) != 0) { 773 /* Host name not found. Use ip address. */ 774 return strdup(ntop); 775 } 776 777 /* 778 * if reverse lookup result looks like a numeric hostname, 779 * someone is trying to trick us by PTR record like following: 780 * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 781 */ 782 memset(&hints, 0, sizeof(hints)); 783 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 784 hints.ai_flags = AI_NUMERICHOST; 785 if (getaddrinfo(name, NULL, &hints, &ai) == 0) { 786 logit("Nasty PTR record \"%s\" is set up for %s, ignoring", 787 name, ntop); 788 freeaddrinfo(ai); 789 return strdup(ntop); 790 } 791 792 /* Names are stored in lowercase. */ 793 lowercase(name); 794 795 /* 796 * Map it back to an IP address and check that the given 797 * address actually is an address of this host. This is 798 * necessary because anyone with access to a name server can 799 * define arbitrary names for an IP address. Mapping from 800 * name to IP address can be trusted better (but can still be 801 * fooled if the intruder has access to the name server of 802 * the domain). 803 */ 804 memset(&hints, 0, sizeof(hints)); 805 hints.ai_family = from.ss_family; 806 hints.ai_socktype = SOCK_STREAM; 807 if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { 808 logit("reverse mapping checking getaddrinfo for %.700s " 809 "[%s] failed.", name, ntop); 810 return strdup(ntop); 811 } 812 /* Look for the address from the list of addresses. */ 813 for (ai = aitop; ai; ai = ai->ai_next) { 814 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, 815 sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && 816 (strcmp(ntop, ntop2) == 0)) 817 break; 818 } 819 freeaddrinfo(aitop); 820 /* If we reached the end of the list, the address was not there. */ 821 if (ai == NULL) { 822 /* Address not found for the host name. */ 823 logit("Address %.100s maps to %.600s, but this does not " 824 "map back to the address.", ntop, name); 825 return strdup(ntop); 826 } 827 return strdup(name); 828 } 829 830 /* 831 * Return the canonical name of the host in the other side of the current 832 * connection. The host name is cached, so it is efficient to call this 833 * several times. 834 */ 835 836 const char * 837 auth_get_canonical_hostname(struct ssh *ssh, int use_dns) 838 { 839 static char *dnsname; 840 841 if (!use_dns) 842 return ssh_remote_ipaddr(ssh); 843 else if (dnsname != NULL) 844 return dnsname; 845 else { 846 dnsname = remote_hostname(ssh); 847 return dnsname; 848 } 849 } 850 851 /* 852 * Runs command in a subprocess wuth a minimal environment. 853 * Returns pid on success, 0 on failure. 854 * The child stdout and stderr maybe captured, left attached or sent to 855 * /dev/null depending on the contents of flags. 856 * "tag" is prepended to log messages. 857 * NB. "command" is only used for logging; the actual command executed is 858 * av[0]. 859 */ 860 pid_t 861 subprocess(const char *tag, struct passwd *pw, const char *command, 862 int ac, char **av, FILE **child, u_int flags) 863 { 864 FILE *f = NULL; 865 struct stat st; 866 int fd, devnull, p[2], i; 867 pid_t pid; 868 char *cp, errmsg[512]; 869 u_int envsize; 870 char **child_env; 871 872 if (child != NULL) 873 *child = NULL; 874 875 debug3("%s: %s command \"%s\" running as %s (flags 0x%x)", __func__, 876 tag, command, pw->pw_name, flags); 877 878 /* Check consistency */ 879 if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 && 880 (flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) { 881 error("%s: inconsistent flags", __func__); 882 return 0; 883 } 884 if (((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) != (child == NULL)) { 885 error("%s: inconsistent flags/output", __func__); 886 return 0; 887 } 888 889 /* 890 * If executing an explicit binary, then verify the it exists 891 * and appears safe-ish to execute 892 */ 893 if (*av[0] != '/') { 894 error("%s path is not absolute", tag); 895 return 0; 896 } 897 temporarily_use_uid(pw); 898 if (stat(av[0], &st) < 0) { 899 error("Could not stat %s \"%s\": %s", tag, 900 av[0], strerror(errno)); 901 restore_uid(); 902 return 0; 903 } 904 if (safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) { 905 error("Unsafe %s \"%s\": %s", tag, av[0], errmsg); 906 restore_uid(); 907 return 0; 908 } 909 /* Prepare to keep the child's stdout if requested */ 910 if (pipe(p) != 0) { 911 error("%s: pipe: %s", tag, strerror(errno)); 912 restore_uid(); 913 return 0; 914 } 915 restore_uid(); 916 917 switch ((pid = fork())) { 918 case -1: /* error */ 919 error("%s: fork: %s", tag, strerror(errno)); 920 close(p[0]); 921 close(p[1]); 922 return 0; 923 case 0: /* child */ 924 /* Prepare a minimal environment for the child. */ 925 envsize = 5; 926 child_env = xcalloc(sizeof(*child_env), envsize); 927 child_set_env(&child_env, &envsize, "PATH", _PATH_STDPATH); 928 child_set_env(&child_env, &envsize, "USER", pw->pw_name); 929 child_set_env(&child_env, &envsize, "LOGNAME", pw->pw_name); 930 child_set_env(&child_env, &envsize, "HOME", pw->pw_dir); 931 if ((cp = getenv("LANG")) != NULL) 932 child_set_env(&child_env, &envsize, "LANG", cp); 933 934 for (i = 0; i < NSIG; i++) 935 signal(i, SIG_DFL); 936 937 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) { 938 error("%s: open %s: %s", tag, _PATH_DEVNULL, 939 strerror(errno)); 940 _exit(1); 941 } 942 if (dup2(devnull, STDIN_FILENO) == -1) { 943 error("%s: dup2: %s", tag, strerror(errno)); 944 _exit(1); 945 } 946 947 /* Set up stdout as requested; leave stderr in place for now. */ 948 fd = -1; 949 if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) 950 fd = p[1]; 951 else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0) 952 fd = devnull; 953 if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) { 954 error("%s: dup2: %s", tag, strerror(errno)); 955 _exit(1); 956 } 957 closefrom(STDERR_FILENO + 1); 958 959 /* Don't use permanently_set_uid() here to avoid fatal() */ 960 if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) != 0) { 961 error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid, 962 strerror(errno)); 963 _exit(1); 964 } 965 if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) != 0) { 966 error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid, 967 strerror(errno)); 968 _exit(1); 969 } 970 /* stdin is pointed to /dev/null at this point */ 971 if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 && 972 dup2(STDIN_FILENO, STDERR_FILENO) == -1) { 973 error("%s: dup2: %s", tag, strerror(errno)); 974 _exit(1); 975 } 976 977 execve(av[0], av, child_env); 978 error("%s exec \"%s\": %s", tag, command, strerror(errno)); 979 _exit(127); 980 default: /* parent */ 981 break; 982 } 983 984 close(p[1]); 985 if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) 986 close(p[0]); 987 else if ((f = fdopen(p[0], "r")) == NULL) { 988 error("%s: fdopen: %s", tag, strerror(errno)); 989 close(p[0]); 990 /* Don't leave zombie child */ 991 kill(pid, SIGTERM); 992 while (waitpid(pid, NULL, 0) == -1 && errno == EINTR) 993 ; 994 return 0; 995 } 996 /* Success */ 997 debug3("%s: %s pid %ld", __func__, tag, (long)pid); 998 if (child != NULL) 999 *child = f; 1000 return pid; 1001 } 1002 1003 /* These functions link key/cert options to the auth framework */ 1004 1005 /* Log sshauthopt options locally and (optionally) for remote transmission */ 1006 void 1007 auth_log_authopts(const char *loc, const struct sshauthopt *opts, int do_remote) 1008 { 1009 int do_env = options.permit_user_env && opts->nenv > 0; 1010 int do_permitopen = opts->npermitopen > 0 && 1011 (options.allow_tcp_forwarding & FORWARD_LOCAL) != 0; 1012 size_t i; 1013 char msg[1024], buf[64]; 1014 1015 snprintf(buf, sizeof(buf), "%d", opts->force_tun_device); 1016 /* Try to keep this alphabetically sorted */ 1017 snprintf(msg, sizeof(msg), "key options:%s%s%s%s%s%s%s%s%s%s%s%s", 1018 opts->permit_agent_forwarding_flag ? " agent-forwarding" : "", 1019 opts->force_command == NULL ? "" : " command", 1020 do_env ? " environment" : "", 1021 opts->valid_before == 0 ? "" : "expires", 1022 do_permitopen ? " permitopen" : "", 1023 opts->permit_port_forwarding_flag ? " port-forwarding" : "", 1024 opts->cert_principals == NULL ? "" : " principals", 1025 opts->permit_pty_flag ? " pty" : "", 1026 opts->force_tun_device == -1 ? "" : " tun=", 1027 opts->force_tun_device == -1 ? "" : buf, 1028 opts->permit_user_rc ? " user-rc" : "", 1029 opts->permit_x11_forwarding_flag ? " x11-forwarding" : ""); 1030 1031 debug("%s: %s", loc, msg); 1032 if (do_remote) 1033 auth_debug_add("%s: %s", loc, msg); 1034 1035 if (options.permit_user_env) { 1036 for (i = 0; i < opts->nenv; i++) { 1037 debug("%s: environment: %s", loc, opts->env[i]); 1038 if (do_remote) { 1039 auth_debug_add("%s: environment: %s", 1040 loc, opts->env[i]); 1041 } 1042 } 1043 } 1044 1045 /* Go into a little more details for the local logs. */ 1046 if (opts->valid_before != 0) { 1047 format_absolute_time(opts->valid_before, buf, sizeof(buf)); 1048 debug("%s: expires at %s", loc, buf); 1049 } 1050 if (opts->cert_principals != NULL) { 1051 debug("%s: authorized principals: \"%s\"", 1052 loc, opts->cert_principals); 1053 } 1054 if (opts->force_command != NULL) 1055 debug("%s: forced command: \"%s\"", loc, opts->force_command); 1056 if ((options.allow_tcp_forwarding & FORWARD_LOCAL) != 0) { 1057 for (i = 0; i < opts->npermitopen; i++) { 1058 debug("%s: permitted open: %s", 1059 loc, opts->permitopen[i]); 1060 } 1061 } 1062 } 1063 1064 /* Activate a new set of key/cert options; merging with what is there. */ 1065 int 1066 auth_activate_options(struct ssh *ssh, struct sshauthopt *opts) 1067 { 1068 struct sshauthopt *old = auth_opts; 1069 const char *emsg = NULL; 1070 1071 debug("%s: setting new authentication options", __func__); 1072 if ((auth_opts = sshauthopt_merge(old, opts, &emsg)) == NULL) { 1073 error("Inconsistent authentication options: %s", emsg); 1074 return -1; 1075 } 1076 return 0; 1077 } 1078 1079 /* Disable forwarding, etc for the session */ 1080 void 1081 auth_restrict_session(struct ssh *ssh) 1082 { 1083 struct sshauthopt *restricted; 1084 1085 debug("%s: restricting session", __func__); 1086 1087 /* A blank sshauthopt defaults to permitting nothing */ 1088 restricted = sshauthopt_new(); 1089 restricted->restricted = 1; 1090 1091 if (auth_activate_options(ssh, restricted) != 0) 1092 fatal("%s: failed to restrict session", __func__); 1093 sshauthopt_free(restricted); 1094 } 1095 1096 int 1097 auth_authorise_keyopts(struct ssh *ssh, struct passwd *pw, 1098 struct sshauthopt *opts, int allow_cert_authority, const char *loc) 1099 { 1100 const char *remote_ip = ssh_remote_ipaddr(ssh); 1101 const char *remote_host = auth_get_canonical_hostname(ssh, 1102 options.use_dns); 1103 time_t now = time(NULL); 1104 char buf[64]; 1105 1106 /* 1107 * Check keys/principals file expiry time. 1108 * NB. validity interval in certificate is handled elsewhere. 1109 */ 1110 if (opts->valid_before && now > 0 && 1111 opts->valid_before < (uint64_t)now) { 1112 format_absolute_time(opts->valid_before, buf, sizeof(buf)); 1113 debug("%s: entry expired at %s", loc, buf); 1114 auth_debug_add("%s: entry expired at %s", loc, buf); 1115 return -1; 1116 } 1117 /* Consistency checks */ 1118 if (opts->cert_principals != NULL && !opts->cert_authority) { 1119 debug("%s: principals on non-CA key", loc); 1120 auth_debug_add("%s: principals on non-CA key", loc); 1121 /* deny access */ 1122 return -1; 1123 } 1124 /* cert-authority flag isn't valid in authorized_principals files */ 1125 if (!allow_cert_authority && opts->cert_authority) { 1126 debug("%s: cert-authority flag invalid here", loc); 1127 auth_debug_add("%s: cert-authority flag invalid here", loc); 1128 /* deny access */ 1129 return -1; 1130 } 1131 1132 /* Perform from= checks */ 1133 if (opts->required_from_host_keys != NULL) { 1134 switch (match_host_and_ip(remote_host, remote_ip, 1135 opts->required_from_host_keys )) { 1136 case 1: 1137 /* Host name matches. */ 1138 break; 1139 case -1: 1140 default: 1141 debug("%s: invalid from criteria", loc); 1142 auth_debug_add("%s: invalid from criteria", loc); 1143 /* FALLTHROUGH */ 1144 case 0: 1145 logit("%s: Authentication tried for %.100s with " 1146 "correct key but not from a permitted " 1147 "host (host=%.200s, ip=%.200s, required=%.200s).", 1148 loc, pw->pw_name, remote_host, remote_ip, 1149 opts->required_from_host_keys); 1150 auth_debug_add("%s: Your host '%.200s' is not " 1151 "permitted to use this key for login.", 1152 loc, remote_host); 1153 /* deny access */ 1154 return -1; 1155 } 1156 } 1157 /* Check source-address restriction from certificate */ 1158 if (opts->required_from_host_cert != NULL) { 1159 switch (addr_match_cidr_list(remote_ip, 1160 opts->required_from_host_cert)) { 1161 case 1: 1162 /* accepted */ 1163 break; 1164 case -1: 1165 default: 1166 /* invalid */ 1167 error("%s: Certificate source-address invalid", 1168 loc); 1169 /* FALLTHROUGH */ 1170 case 0: 1171 logit("%s: Authentication tried for %.100s with valid " 1172 "certificate but not from a permitted source " 1173 "address (%.200s).", loc, pw->pw_name, remote_ip); 1174 auth_debug_add("%s: Your address '%.200s' is not " 1175 "permitted to use this certificate for login.", 1176 loc, remote_ip); 1177 return -1; 1178 } 1179 } 1180 /* 1181 * 1182 * XXX this is spammy. We should report remotely only for keys 1183 * that are successful in actual auth attempts, and not PK_OK 1184 * tests. 1185 */ 1186 auth_log_authopts(loc, opts, 1); 1187 1188 return 0; 1189 } 1190