1 /* $OpenBSD: auth.c,v 1.115 2016/06/15 00:40:40 dtucker 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 33 #include <netinet/in.h> 34 35 #include <errno.h> 36 #include <fcntl.h> 37 #ifdef HAVE_PATHS_H 38 # include <paths.h> 39 #endif 40 #include <pwd.h> 41 #ifdef HAVE_LOGIN_H 42 #include <login.h> 43 #endif 44 #ifdef USE_SHADOW 45 #include <shadow.h> 46 #endif 47 #ifdef HAVE_LIBGEN_H 48 #include <libgen.h> 49 #endif 50 #include <stdarg.h> 51 #include <stdio.h> 52 #include <string.h> 53 #include <unistd.h> 54 #include <limits.h> 55 #include <netdb.h> 56 57 #include "xmalloc.h" 58 #include "match.h" 59 #include "groupaccess.h" 60 #include "log.h" 61 #include "buffer.h" 62 #include "misc.h" 63 #include "servconf.h" 64 #include "key.h" 65 #include "hostfile.h" 66 #include "auth.h" 67 #include "auth-options.h" 68 #include "canohost.h" 69 #include "uidswap.h" 70 #include "packet.h" 71 #include "loginrec.h" 72 #ifdef GSSAPI 73 #include "ssh-gss.h" 74 #endif 75 #include "authfile.h" 76 #include "monitor_wrap.h" 77 #include "authfile.h" 78 #include "ssherr.h" 79 #include "compat.h" 80 #include "blacklist_client.h" 81 82 /* import */ 83 extern ServerOptions options; 84 extern int use_privsep; 85 extern Buffer loginmsg; 86 extern struct passwd *privsep_pw; 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 #ifdef USE_SHADOW 109 struct spwd *spw = NULL; 110 #endif 111 112 /* Shouldn't be called if pw is NULL, but better safe than sorry... */ 113 if (!pw || !pw->pw_name) 114 return 0; 115 116 #ifdef USE_SHADOW 117 if (!options.use_pam) 118 spw = getspnam(pw->pw_name); 119 #ifdef HAS_SHADOW_EXPIRE 120 if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) 121 return 0; 122 #endif /* HAS_SHADOW_EXPIRE */ 123 #endif /* USE_SHADOW */ 124 125 /* grab passwd field for locked account check */ 126 passwd = pw->pw_passwd; 127 #ifdef USE_SHADOW 128 if (spw != NULL) 129 #ifdef USE_LIBIAF 130 passwd = get_iaf_password(pw); 131 #else 132 passwd = spw->sp_pwdp; 133 #endif /* USE_LIBIAF */ 134 #endif 135 136 /* check for locked account */ 137 if (!options.use_pam && passwd && *passwd) { 138 int locked = 0; 139 140 #ifdef LOCKED_PASSWD_STRING 141 if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) 142 locked = 1; 143 #endif 144 #ifdef LOCKED_PASSWD_PREFIX 145 if (strncmp(passwd, LOCKED_PASSWD_PREFIX, 146 strlen(LOCKED_PASSWD_PREFIX)) == 0) 147 locked = 1; 148 #endif 149 #ifdef LOCKED_PASSWD_SUBSTR 150 if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) 151 locked = 1; 152 #endif 153 #ifdef USE_LIBIAF 154 free((void *) passwd); 155 #endif /* USE_LIBIAF */ 156 if (locked) { 157 logit("User %.100s not allowed because account is locked", 158 pw->pw_name); 159 return 0; 160 } 161 } 162 163 /* 164 * Deny if shell does not exist or is not executable unless we 165 * are chrooting. 166 */ 167 if (options.chroot_directory == NULL || 168 strcasecmp(options.chroot_directory, "none") == 0) { 169 char *shell = xstrdup((pw->pw_shell[0] == '\0') ? 170 _PATH_BSHELL : pw->pw_shell); /* empty = /bin/sh */ 171 172 if (stat(shell, &st) != 0) { 173 logit("User %.100s not allowed because shell %.100s " 174 "does not exist", pw->pw_name, shell); 175 free(shell); 176 return 0; 177 } 178 if (S_ISREG(st.st_mode) == 0 || 179 (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { 180 logit("User %.100s not allowed because shell %.100s " 181 "is not executable", pw->pw_name, shell); 182 free(shell); 183 return 0; 184 } 185 free(shell); 186 } 187 188 if (options.num_deny_users > 0 || options.num_allow_users > 0 || 189 options.num_deny_groups > 0 || options.num_allow_groups > 0) { 190 hostname = auth_get_canonical_hostname(ssh, options.use_dns); 191 ipaddr = ssh_remote_ipaddr(ssh); 192 } 193 194 /* Return false if user is listed in DenyUsers */ 195 if (options.num_deny_users > 0) { 196 for (i = 0; i < options.num_deny_users; i++) 197 if (match_user(pw->pw_name, hostname, ipaddr, 198 options.deny_users[i])) { 199 logit("User %.100s from %.100s not allowed " 200 "because listed in DenyUsers", 201 pw->pw_name, hostname); 202 return 0; 203 } 204 } 205 /* Return false if AllowUsers isn't empty and user isn't listed there */ 206 if (options.num_allow_users > 0) { 207 for (i = 0; i < options.num_allow_users; i++) 208 if (match_user(pw->pw_name, hostname, ipaddr, 209 options.allow_users[i])) 210 break; 211 /* i < options.num_allow_users iff we break for loop */ 212 if (i >= options.num_allow_users) { 213 logit("User %.100s from %.100s not allowed because " 214 "not listed in AllowUsers", pw->pw_name, hostname); 215 return 0; 216 } 217 } 218 if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { 219 /* Get the user's group access list (primary and supplementary) */ 220 if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 221 logit("User %.100s from %.100s not allowed because " 222 "not in any group", pw->pw_name, hostname); 223 return 0; 224 } 225 226 /* Return false if one of user's groups is listed in DenyGroups */ 227 if (options.num_deny_groups > 0) 228 if (ga_match(options.deny_groups, 229 options.num_deny_groups)) { 230 ga_free(); 231 logit("User %.100s from %.100s not allowed " 232 "because a group is listed in DenyGroups", 233 pw->pw_name, hostname); 234 return 0; 235 } 236 /* 237 * Return false if AllowGroups isn't empty and one of user's groups 238 * isn't listed there 239 */ 240 if (options.num_allow_groups > 0) 241 if (!ga_match(options.allow_groups, 242 options.num_allow_groups)) { 243 ga_free(); 244 logit("User %.100s from %.100s not allowed " 245 "because none of user's groups are listed " 246 "in AllowGroups", pw->pw_name, hostname); 247 return 0; 248 } 249 ga_free(); 250 } 251 252 #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER 253 if (!sys_auth_allowed_user(pw, &loginmsg)) 254 return 0; 255 #endif 256 257 /* We found no reason not to let this user try to log on... */ 258 return 1; 259 } 260 261 void 262 auth_info(Authctxt *authctxt, const char *fmt, ...) 263 { 264 va_list ap; 265 int i; 266 267 free(authctxt->info); 268 authctxt->info = NULL; 269 270 va_start(ap, fmt); 271 i = vasprintf(&authctxt->info, fmt, ap); 272 va_end(ap); 273 274 if (i < 0 || authctxt->info == NULL) 275 fatal("vasprintf failed"); 276 } 277 278 void 279 auth_log(Authctxt *authctxt, int authenticated, int partial, 280 const char *method, const char *submethod) 281 { 282 struct ssh *ssh = active_state; /* XXX */ 283 void (*authlog) (const char *fmt,...) = verbose; 284 char *authmsg; 285 286 if (use_privsep && !mm_is_monitor() && !authctxt->postponed) 287 return; 288 289 /* Raise logging level */ 290 if (authenticated == 1 || 291 !authctxt->valid || 292 authctxt->failures >= options.max_authtries / 2 || 293 strcmp(method, "password") == 0) 294 authlog = logit; 295 296 if (authctxt->postponed) 297 authmsg = "Postponed"; 298 else if (partial) 299 authmsg = "Partial"; 300 else { 301 authmsg = authenticated ? "Accepted" : "Failed"; 302 if (authenticated) 303 BLACKLIST_NOTIFY(BLACKLIST_AUTH_OK); 304 } 305 306 authlog("%s %s%s%s for %s%.100s from %.200s port %d %s%s%s", 307 authmsg, 308 method, 309 submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod, 310 authctxt->valid ? "" : "invalid user ", 311 authctxt->user, 312 ssh_remote_ipaddr(ssh), 313 ssh_remote_port(ssh), 314 compat20 ? "ssh2" : "ssh1", 315 authctxt->info != NULL ? ": " : "", 316 authctxt->info != NULL ? authctxt->info : ""); 317 free(authctxt->info); 318 authctxt->info = NULL; 319 320 #ifdef CUSTOM_FAILED_LOGIN 321 if (authenticated == 0 && !authctxt->postponed && 322 (strcmp(method, "password") == 0 || 323 strncmp(method, "keyboard-interactive", 20) == 0 || 324 strcmp(method, "challenge-response") == 0)) 325 record_failed_login(authctxt->user, 326 auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); 327 # ifdef WITH_AIXAUTHENTICATE 328 if (authenticated) 329 sys_auth_record_login(authctxt->user, 330 auth_get_canonical_hostname(ssh, options.use_dns), "ssh", 331 &loginmsg); 332 # endif 333 #endif 334 #ifdef SSH_AUDIT_EVENTS 335 if (authenticated == 0 && !authctxt->postponed) 336 audit_event(audit_classify_auth(method)); 337 #endif 338 } 339 340 341 void 342 auth_maxtries_exceeded(Authctxt *authctxt) 343 { 344 struct ssh *ssh = active_state; /* XXX */ 345 346 error("maximum authentication attempts exceeded for " 347 "%s%.100s from %.200s port %d %s", 348 authctxt->valid ? "" : "invalid user ", 349 authctxt->user, 350 ssh_remote_ipaddr(ssh), 351 ssh_remote_port(ssh), 352 compat20 ? "ssh2" : "ssh1"); 353 packet_disconnect("Too many authentication failures"); 354 /* NOTREACHED */ 355 } 356 357 /* 358 * Check whether root logins are disallowed. 359 */ 360 int 361 auth_root_allowed(const char *method) 362 { 363 struct ssh *ssh = active_state; /* XXX */ 364 365 switch (options.permit_root_login) { 366 case PERMIT_YES: 367 return 1; 368 case PERMIT_NO_PASSWD: 369 if (strcmp(method, "publickey") == 0 || 370 strcmp(method, "hostbased") == 0 || 371 strcmp(method, "gssapi-with-mic") == 0) 372 return 1; 373 break; 374 case PERMIT_FORCED_ONLY: 375 if (forced_command) { 376 logit("Root login accepted for forced command."); 377 return 1; 378 } 379 break; 380 } 381 logit("ROOT LOGIN REFUSED FROM %.200s port %d", 382 ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 383 return 0; 384 } 385 386 387 /* 388 * Given a template and a passwd structure, build a filename 389 * by substituting % tokenised options. Currently, %% becomes '%', 390 * %h becomes the home directory and %u the username. 391 * 392 * This returns a buffer allocated by xmalloc. 393 */ 394 char * 395 expand_authorized_keys(const char *filename, struct passwd *pw) 396 { 397 char *file, ret[PATH_MAX]; 398 int i; 399 400 file = percent_expand(filename, "h", pw->pw_dir, 401 "u", pw->pw_name, (char *)NULL); 402 403 /* 404 * Ensure that filename starts anchored. If not, be backward 405 * compatible and prepend the '%h/' 406 */ 407 if (*file == '/') 408 return (file); 409 410 i = snprintf(ret, sizeof(ret), "%s/%s", pw->pw_dir, file); 411 if (i < 0 || (size_t)i >= sizeof(ret)) 412 fatal("expand_authorized_keys: path too long"); 413 free(file); 414 return (xstrdup(ret)); 415 } 416 417 char * 418 authorized_principals_file(struct passwd *pw) 419 { 420 if (options.authorized_principals_file == NULL) 421 return NULL; 422 return expand_authorized_keys(options.authorized_principals_file, pw); 423 } 424 425 /* return ok if key exists in sysfile or userfile */ 426 HostStatus 427 check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, 428 const char *sysfile, const char *userfile) 429 { 430 char *user_hostfile; 431 struct stat st; 432 HostStatus host_status; 433 struct hostkeys *hostkeys; 434 const struct hostkey_entry *found; 435 436 hostkeys = init_hostkeys(); 437 load_hostkeys(hostkeys, host, sysfile); 438 if (userfile != NULL) { 439 user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); 440 if (options.strict_modes && 441 (stat(user_hostfile, &st) == 0) && 442 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || 443 (st.st_mode & 022) != 0)) { 444 logit("Authentication refused for %.100s: " 445 "bad owner or modes for %.200s", 446 pw->pw_name, user_hostfile); 447 auth_debug_add("Ignored %.200s: bad ownership or modes", 448 user_hostfile); 449 } else { 450 temporarily_use_uid(pw); 451 load_hostkeys(hostkeys, host, user_hostfile); 452 restore_uid(); 453 } 454 free(user_hostfile); 455 } 456 host_status = check_key_in_hostkeys(hostkeys, key, &found); 457 if (host_status == HOST_REVOKED) 458 error("WARNING: revoked key for %s attempted authentication", 459 found->host); 460 else if (host_status == HOST_OK) 461 debug("%s: key for %s found at %s:%ld", __func__, 462 found->host, found->file, found->line); 463 else 464 debug("%s: key for host %s not found", __func__, host); 465 466 free_hostkeys(hostkeys); 467 468 return host_status; 469 } 470 471 /* 472 * Check a given path for security. This is defined as all components 473 * of the path to the file must be owned by either the owner of 474 * of the file or root and no directories must be group or world writable. 475 * 476 * XXX Should any specific check be done for sym links ? 477 * 478 * Takes a file name, its stat information (preferably from fstat() to 479 * avoid races), the uid of the expected owner, their home directory and an 480 * error buffer plus max size as arguments. 481 * 482 * Returns 0 on success and -1 on failure 483 */ 484 int 485 auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, 486 uid_t uid, char *err, size_t errlen) 487 { 488 char buf[PATH_MAX], homedir[PATH_MAX]; 489 char *cp; 490 int comparehome = 0; 491 struct stat st; 492 493 if (realpath(name, buf) == NULL) { 494 snprintf(err, errlen, "realpath %s failed: %s", name, 495 strerror(errno)); 496 return -1; 497 } 498 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) 499 comparehome = 1; 500 501 if (!S_ISREG(stp->st_mode)) { 502 snprintf(err, errlen, "%s is not a regular file", buf); 503 return -1; 504 } 505 if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || 506 (stp->st_mode & 022) != 0) { 507 snprintf(err, errlen, "bad ownership or modes for file %s", 508 buf); 509 return -1; 510 } 511 512 /* for each component of the canonical path, walking upwards */ 513 for (;;) { 514 if ((cp = dirname(buf)) == NULL) { 515 snprintf(err, errlen, "dirname() failed"); 516 return -1; 517 } 518 strlcpy(buf, cp, sizeof(buf)); 519 520 if (stat(buf, &st) < 0 || 521 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || 522 (st.st_mode & 022) != 0) { 523 snprintf(err, errlen, 524 "bad ownership or modes for directory %s", buf); 525 return -1; 526 } 527 528 /* If are past the homedir then we can stop */ 529 if (comparehome && strcmp(homedir, buf) == 0) 530 break; 531 532 /* 533 * dirname should always complete with a "/" path, 534 * but we can be paranoid and check for "." too 535 */ 536 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) 537 break; 538 } 539 return 0; 540 } 541 542 /* 543 * Version of secure_path() that accepts an open file descriptor to 544 * avoid races. 545 * 546 * Returns 0 on success and -1 on failure 547 */ 548 static int 549 secure_filename(FILE *f, const char *file, struct passwd *pw, 550 char *err, size_t errlen) 551 { 552 struct stat st; 553 554 /* check the open file to avoid races */ 555 if (fstat(fileno(f), &st) < 0) { 556 snprintf(err, errlen, "cannot stat file %s: %s", 557 file, strerror(errno)); 558 return -1; 559 } 560 return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); 561 } 562 563 static FILE * 564 auth_openfile(const char *file, struct passwd *pw, int strict_modes, 565 int log_missing, char *file_type) 566 { 567 char line[1024]; 568 struct stat st; 569 int fd; 570 FILE *f; 571 572 if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { 573 if (log_missing || errno != ENOENT) 574 debug("Could not open %s '%s': %s", file_type, file, 575 strerror(errno)); 576 return NULL; 577 } 578 579 if (fstat(fd, &st) < 0) { 580 close(fd); 581 return NULL; 582 } 583 if (!S_ISREG(st.st_mode)) { 584 logit("User %s %s %s is not a regular file", 585 pw->pw_name, file_type, file); 586 close(fd); 587 return NULL; 588 } 589 unset_nonblock(fd); 590 if ((f = fdopen(fd, "r")) == NULL) { 591 close(fd); 592 return NULL; 593 } 594 if (strict_modes && 595 secure_filename(f, file, pw, line, sizeof(line)) != 0) { 596 fclose(f); 597 logit("Authentication refused: %s", line); 598 auth_debug_add("Ignored %s: %s", file_type, line); 599 return NULL; 600 } 601 602 return f; 603 } 604 605 606 FILE * 607 auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) 608 { 609 return auth_openfile(file, pw, strict_modes, 1, "authorized keys"); 610 } 611 612 FILE * 613 auth_openprincipals(const char *file, struct passwd *pw, int strict_modes) 614 { 615 return auth_openfile(file, pw, strict_modes, 0, 616 "authorized principals"); 617 } 618 619 struct passwd * 620 getpwnamallow(const char *user) 621 { 622 struct ssh *ssh = active_state; /* XXX */ 623 #ifdef HAVE_LOGIN_CAP 624 extern login_cap_t *lc; 625 #ifdef BSD_AUTH 626 auth_session_t *as; 627 #endif 628 #endif 629 struct passwd *pw; 630 struct connection_info *ci = get_connection_info(1, options.use_dns); 631 632 ci->user = user; 633 parse_server_match_config(&options, ci); 634 635 #if defined(_AIX) && defined(HAVE_SETAUTHDB) 636 aix_setauthdb(user); 637 #endif 638 639 pw = getpwnam(user); 640 641 #if defined(_AIX) && defined(HAVE_SETAUTHDB) 642 aix_restoreauthdb(); 643 #endif 644 #ifdef HAVE_CYGWIN 645 /* 646 * Windows usernames are case-insensitive. To avoid later problems 647 * when trying to match the username, the user is only allowed to 648 * login if the username is given in the same case as stored in the 649 * user database. 650 */ 651 if (pw != NULL && strcmp(user, pw->pw_name) != 0) { 652 logit("Login name %.100s does not match stored username %.100s", 653 user, pw->pw_name); 654 pw = NULL; 655 } 656 #endif 657 if (pw == NULL) { 658 BLACKLIST_NOTIFY(BLACKLIST_AUTH_FAIL); 659 logit("Invalid user %.100s from %.100s port %d", 660 user, ssh_remote_ipaddr(ssh), ssh_remote_port(ssh)); 661 #ifdef CUSTOM_FAILED_LOGIN 662 record_failed_login(user, 663 auth_get_canonical_hostname(ssh, options.use_dns), "ssh"); 664 #endif 665 #ifdef SSH_AUDIT_EVENTS 666 audit_event(SSH_INVALID_USER); 667 #endif /* SSH_AUDIT_EVENTS */ 668 return (NULL); 669 } 670 if (!allowed_user(pw)) 671 return (NULL); 672 #ifdef HAVE_LOGIN_CAP 673 if ((lc = login_getpwclass(pw)) == NULL) { 674 debug("unable to get login class: %s", user); 675 return (NULL); 676 } 677 #ifdef BSD_AUTH 678 if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || 679 auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { 680 debug("Approval failure for %s", user); 681 pw = NULL; 682 } 683 if (as != NULL) 684 auth_close(as); 685 #endif 686 #endif 687 if (pw != NULL) 688 return (pwcopy(pw)); 689 return (NULL); 690 } 691 692 /* Returns 1 if key is revoked by revoked_keys_file, 0 otherwise */ 693 int 694 auth_key_is_revoked(Key *key) 695 { 696 char *fp = NULL; 697 int r; 698 699 if (options.revoked_keys_file == NULL) 700 return 0; 701 if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, 702 SSH_FP_DEFAULT)) == NULL) { 703 r = SSH_ERR_ALLOC_FAIL; 704 error("%s: fingerprint key: %s", __func__, ssh_err(r)); 705 goto out; 706 } 707 708 r = sshkey_check_revoked(key, options.revoked_keys_file); 709 switch (r) { 710 case 0: 711 break; /* not revoked */ 712 case SSH_ERR_KEY_REVOKED: 713 error("Authentication key %s %s revoked by file %s", 714 sshkey_type(key), fp, options.revoked_keys_file); 715 goto out; 716 default: 717 error("Error checking authentication key %s %s in " 718 "revoked keys file %s: %s", sshkey_type(key), fp, 719 options.revoked_keys_file, ssh_err(r)); 720 goto out; 721 } 722 723 /* Success */ 724 r = 0; 725 726 out: 727 free(fp); 728 return r == 0 ? 0 : 1; 729 } 730 731 void 732 auth_debug_add(const char *fmt,...) 733 { 734 char buf[1024]; 735 va_list args; 736 737 if (!auth_debug_init) 738 return; 739 740 va_start(args, fmt); 741 vsnprintf(buf, sizeof(buf), fmt, args); 742 va_end(args); 743 buffer_put_cstring(&auth_debug, buf); 744 } 745 746 void 747 auth_debug_send(void) 748 { 749 char *msg; 750 751 if (!auth_debug_init) 752 return; 753 while (buffer_len(&auth_debug)) { 754 msg = buffer_get_string(&auth_debug, NULL); 755 packet_send_debug("%s", msg); 756 free(msg); 757 } 758 } 759 760 void 761 auth_debug_reset(void) 762 { 763 if (auth_debug_init) 764 buffer_clear(&auth_debug); 765 else { 766 buffer_init(&auth_debug); 767 auth_debug_init = 1; 768 } 769 } 770 771 struct passwd * 772 fakepw(void) 773 { 774 static struct passwd fake; 775 776 memset(&fake, 0, sizeof(fake)); 777 fake.pw_name = "NOUSER"; 778 fake.pw_passwd = 779 "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; 780 #ifdef HAVE_STRUCT_PASSWD_PW_GECOS 781 fake.pw_gecos = "NOUSER"; 782 #endif 783 fake.pw_uid = privsep_pw == NULL ? (uid_t)-1 : privsep_pw->pw_uid; 784 fake.pw_gid = privsep_pw == NULL ? (gid_t)-1 : privsep_pw->pw_gid; 785 #ifdef HAVE_STRUCT_PASSWD_PW_CLASS 786 fake.pw_class = ""; 787 #endif 788 fake.pw_dir = "/nonexist"; 789 fake.pw_shell = "/nonexist"; 790 791 return (&fake); 792 } 793 794 /* 795 * Returns the remote DNS hostname as a string. The returned string must not 796 * be freed. NB. this will usually trigger a DNS query the first time it is 797 * called. 798 * This function does additional checks on the hostname to mitigate some 799 * attacks on legacy rhosts-style authentication. 800 * XXX is RhostsRSAAuthentication vulnerable to these? 801 * XXX Can we remove these checks? (or if not, remove RhostsRSAAuthentication?) 802 */ 803 804 static char * 805 remote_hostname(struct ssh *ssh) 806 { 807 struct sockaddr_storage from; 808 socklen_t fromlen; 809 struct addrinfo hints, *ai, *aitop; 810 char name[NI_MAXHOST], ntop2[NI_MAXHOST]; 811 const char *ntop = ssh_remote_ipaddr(ssh); 812 813 /* Get IP address of client. */ 814 fromlen = sizeof(from); 815 memset(&from, 0, sizeof(from)); 816 if (getpeername(ssh_packet_get_connection_in(ssh), 817 (struct sockaddr *)&from, &fromlen) < 0) { 818 debug("getpeername failed: %.100s", strerror(errno)); 819 return strdup(ntop); 820 } 821 822 ipv64_normalise_mapped(&from, &fromlen); 823 if (from.ss_family == AF_INET6) 824 fromlen = sizeof(struct sockaddr_in6); 825 826 debug3("Trying to reverse map address %.100s.", ntop); 827 /* Map the IP address to a host name. */ 828 if (getnameinfo((struct sockaddr *)&from, fromlen, name, sizeof(name), 829 NULL, 0, NI_NAMEREQD) != 0) { 830 /* Host name not found. Use ip address. */ 831 return strdup(ntop); 832 } 833 834 /* 835 * if reverse lookup result looks like a numeric hostname, 836 * someone is trying to trick us by PTR record like following: 837 * 1.1.1.10.in-addr.arpa. IN PTR 2.3.4.5 838 */ 839 memset(&hints, 0, sizeof(hints)); 840 hints.ai_socktype = SOCK_DGRAM; /*dummy*/ 841 hints.ai_flags = AI_NUMERICHOST; 842 if (getaddrinfo(name, NULL, &hints, &ai) == 0) { 843 logit("Nasty PTR record \"%s\" is set up for %s, ignoring", 844 name, ntop); 845 freeaddrinfo(ai); 846 return strdup(ntop); 847 } 848 849 /* Names are stored in lowercase. */ 850 lowercase(name); 851 852 /* 853 * Map it back to an IP address and check that the given 854 * address actually is an address of this host. This is 855 * necessary because anyone with access to a name server can 856 * define arbitrary names for an IP address. Mapping from 857 * name to IP address can be trusted better (but can still be 858 * fooled if the intruder has access to the name server of 859 * the domain). 860 */ 861 memset(&hints, 0, sizeof(hints)); 862 hints.ai_family = from.ss_family; 863 hints.ai_socktype = SOCK_STREAM; 864 if (getaddrinfo(name, NULL, &hints, &aitop) != 0) { 865 logit("reverse mapping checking getaddrinfo for %.700s " 866 "[%s] failed.", name, ntop); 867 return strdup(ntop); 868 } 869 /* Look for the address from the list of addresses. */ 870 for (ai = aitop; ai; ai = ai->ai_next) { 871 if (getnameinfo(ai->ai_addr, ai->ai_addrlen, ntop2, 872 sizeof(ntop2), NULL, 0, NI_NUMERICHOST) == 0 && 873 (strcmp(ntop, ntop2) == 0)) 874 break; 875 } 876 freeaddrinfo(aitop); 877 /* If we reached the end of the list, the address was not there. */ 878 if (ai == NULL) { 879 /* Address not found for the host name. */ 880 logit("Address %.100s maps to %.600s, but this does not " 881 "map back to the address.", ntop, name); 882 return strdup(ntop); 883 } 884 return strdup(name); 885 } 886 887 /* 888 * Return the canonical name of the host in the other side of the current 889 * connection. The host name is cached, so it is efficient to call this 890 * several times. 891 */ 892 893 const char * 894 auth_get_canonical_hostname(struct ssh *ssh, int use_dns) 895 { 896 static char *dnsname; 897 898 if (!use_dns) 899 return ssh_remote_ipaddr(ssh); 900 else if (dnsname != NULL) 901 return dnsname; 902 else { 903 dnsname = remote_hostname(ssh); 904 return dnsname; 905 } 906 } 907