#include "includes.h"#include "xmalloc.h"#include "match.h"#include "groupaccess.h"#include "log.h"#include "servconf.h"#include "auth.h"#include "auth-options.h"#include "canohost.h"#include "buffer.h"#include "bufaux.h"#include "uidswap.h"#include "misc.h"#include "packet.h"#include "loginrec.h"#include "monitor_wrap.h"Go to the source code of this file.
Functions | |
| RCSID ("$OpenBSD: auth.c,v 1.60 2005/06/17 02:44:32 djm Exp $") | |
| int | allowed_user (struct passwd *pw) |
| void | auth_log (Authctxt *authctxt, int authenticated, char *method, char *info) |
| int | auth_root_allowed (char *method) |
| static char * | expand_authorized_keys (const char *filename, struct passwd *pw) |
| char * | authorized_keys_file (struct passwd *pw) |
| char * | authorized_keys_file2 (struct passwd *pw) |
| HostStatus | check_key_in_hostfiles (struct passwd *pw, Key *key, const char *host, const char *sysfile, const char *userfile) |
| int | secure_filename (FILE *f, const char *file, struct passwd *pw, char *err, size_t errlen) |
| passwd * | getpwnamallow (const char *user) |
| void | auth_debug_add (const char *fmt,...) |
| void | auth_debug_send (void) |
| void | auth_debug_reset (void) |
| passwd * | fakepw (void) |
Variables | |
| ServerOptions | options |
| Buffer | loginmsg |
| Buffer | auth_debug |
| int | auth_debug_init |
|
|
Definition at line 74 of file auth.c. References _PATH_BSHELL, ServerOptions::allow_groups, ServerOptions::allow_users, ServerOptions::deny_groups, ServerOptions::deny_users, ga_free(), ga_init(), ga_match(), get_canonical_hostname(), get_remote_ipaddr(), hostname, locked, logit(), match_user(), ServerOptions::num_allow_groups, ServerOptions::num_allow_users, ServerOptions::num_deny_groups, ServerOptions::num_deny_users, S_ISREG, S_IXGRP, S_IXOTH, S_IXUSR, ServerOptions::use_dns, and ServerOptions::use_pam. Referenced by getpwnamallow(). 00075 { 00076 struct stat st; 00077 const char *hostname = NULL, *ipaddr = NULL, *passwd = NULL; 00078 char *shell; 00079 u_int i; 00080 #ifdef USE_SHADOW 00081 struct spwd *spw = NULL; 00082 #endif 00083 00084 /* Shouldn't be called if pw is NULL, but better safe than sorry... */ 00085 if (!pw || !pw->pw_name) 00086 return 0; 00087 00088 #ifdef USE_SHADOW 00089 if (!options.use_pam) 00090 spw = getspnam(pw->pw_name); 00091 #ifdef HAS_SHADOW_EXPIRE 00092 if (!options.use_pam && spw != NULL && auth_shadow_acctexpired(spw)) 00093 return 0; 00094 #endif /* HAS_SHADOW_EXPIRE */ 00095 #endif /* USE_SHADOW */ 00096 00097 /* grab passwd field for locked account check */ 00098 #ifdef USE_SHADOW 00099 if (spw != NULL) 00100 #if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) 00101 passwd = get_iaf_password(pw); 00102 #else 00103 passwd = spw->sp_pwdp; 00104 #endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */ 00105 #else 00106 passwd = pw->pw_passwd; 00107 #endif 00108 00109 /* check for locked account */ 00110 if (!options.use_pam && passwd && *passwd) { 00111 int locked = 0; 00112 00113 #ifdef LOCKED_PASSWD_STRING 00114 if (strcmp(passwd, LOCKED_PASSWD_STRING) == 0) 00115 locked = 1; 00116 #endif 00117 #ifdef LOCKED_PASSWD_PREFIX 00118 if (strncmp(passwd, LOCKED_PASSWD_PREFIX, 00119 strlen(LOCKED_PASSWD_PREFIX)) == 0) 00120 locked = 1; 00121 #endif 00122 #ifdef LOCKED_PASSWD_SUBSTR 00123 if (strstr(passwd, LOCKED_PASSWD_SUBSTR)) 00124 locked = 1; 00125 #endif 00126 #if defined(HAVE_LIBIAF) && !defined(BROKEN_LIBIAF) 00127 free(passwd); 00128 #endif /* HAVE_LIBIAF && !BROKEN_LIBIAF */ 00129 if (locked) { 00130 logit("User %.100s not allowed because account is locked", 00131 pw->pw_name); 00132 return 0; 00133 } 00134 } 00135 00136 /* 00137 * Get the shell from the password data. An empty shell field is 00138 * legal, and means /bin/sh. 00139 */ 00140 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell; 00141 00142 /* deny if shell does not exists or is not executable */ 00143 if (stat(shell, &st) != 0) { 00144 logit("User %.100s not allowed because shell %.100s does not exist", 00145 pw->pw_name, shell); 00146 return 0; 00147 } 00148 if (S_ISREG(st.st_mode) == 0 || 00149 (st.st_mode & (S_IXOTH|S_IXUSR|S_IXGRP)) == 0) { 00150 logit("User %.100s not allowed because shell %.100s is not executable", 00151 pw->pw_name, shell); 00152 return 0; 00153 } 00154 00155 if (options.num_deny_users > 0 || options.num_allow_users > 0 || 00156 options.num_deny_groups > 0 || options.num_allow_groups > 0) { 00157 hostname = get_canonical_hostname(options.use_dns); 00158 ipaddr = get_remote_ipaddr(); 00159 } 00160 00161 /* Return false if user is listed in DenyUsers */ 00162 if (options.num_deny_users > 0) { 00163 for (i = 0; i < options.num_deny_users; i++) 00164 if (match_user(pw->pw_name, hostname, ipaddr, 00165 options.deny_users[i])) { 00166 logit("User %.100s from %.100s not allowed " 00167 "because listed in DenyUsers", 00168 pw->pw_name, hostname); 00169 return 0; 00170 } 00171 } 00172 /* Return false if AllowUsers isn't empty and user isn't listed there */ 00173 if (options.num_allow_users > 0) { 00174 for (i = 0; i < options.num_allow_users; i++) 00175 if (match_user(pw->pw_name, hostname, ipaddr, 00176 options.allow_users[i])) 00177 break; 00178 /* i < options.num_allow_users iff we break for loop */ 00179 if (i >= options.num_allow_users) { 00180 logit("User %.100s from %.100s not allowed because " 00181 "not listed in AllowUsers", pw->pw_name, hostname); 00182 return 0; 00183 } 00184 } 00185 if (options.num_deny_groups > 0 || options.num_allow_groups > 0) { 00186 /* Get the user's group access list (primary and supplementary) */ 00187 if (ga_init(pw->pw_name, pw->pw_gid) == 0) { 00188 logit("User %.100s from %.100s not allowed because " 00189 "not in any group", pw->pw_name, hostname); 00190 return 0; 00191 } 00192 00193 /* Return false if one of user's groups is listed in DenyGroups */ 00194 if (options.num_deny_groups > 0) 00195 if (ga_match(options.deny_groups, 00196 options.num_deny_groups)) { 00197 ga_free(); 00198 logit("User %.100s from %.100s not allowed " 00199 "because a group is listed in DenyGroups", 00200 pw->pw_name, hostname); 00201 return 0; 00202 } 00203 /* 00204 * Return false if AllowGroups isn't empty and one of user's groups 00205 * isn't listed there 00206 */ 00207 if (options.num_allow_groups > 0) 00208 if (!ga_match(options.allow_groups, 00209 options.num_allow_groups)) { 00210 ga_free(); 00211 logit("User %.100s from %.100s not allowed " 00212 "because none of user's groups are listed " 00213 "in AllowGroups", pw->pw_name, hostname); 00214 return 0; 00215 } 00216 ga_free(); 00217 } 00218 00219 #ifdef CUSTOM_SYS_AUTH_ALLOWED_USER 00220 if (!sys_auth_allowed_user(pw, &loginmsg)) 00221 return 0; 00222 #endif 00223 00224 /* We found no reason not to let this user try to log on... */ 00225 return 1; 00226 }
|
|
||||||||||||
|
Definition at line 531 of file auth.c. References args, auth_debug_init, buffer_put_cstring(), and vsnprintf(). Referenced by auth_parse_options(), auth_rhosts2_raw(), and check_rhosts_file(). 00532 { 00533 char buf[1024]; 00534 va_list args; 00535 00536 if (!auth_debug_init) 00537 return; 00538 00539 va_start(args, fmt); 00540 vsnprintf(buf, sizeof(buf), fmt, args); 00541 va_end(args); 00542 buffer_put_cstring(&auth_debug, buf); 00543 }
|
|
|
Definition at line 560 of file auth.c. References auth_debug_init, buffer_clear(), and buffer_init(). Referenced by auth_clear_options(), and auth_rhosts2(). 00561 { 00562 if (auth_debug_init) 00563 buffer_clear(&auth_debug); 00564 else { 00565 buffer_init(&auth_debug); 00566 auth_debug_init = 1; 00567 } 00568 }
|
|
|
Definition at line 546 of file auth.c. References auth_debug_init, buffer_get_string(), buffer_len(), packet_send_debug(), and xfree(). Referenced by auth_parse_options(), and auth_rhosts2(). 00547 { 00548 char *msg; 00549 00550 if (!auth_debug_init) 00551 return; 00552 while (buffer_len(&auth_debug)) { 00553 msg = buffer_get_string(&auth_debug, NULL); 00554 packet_send_debug("%s", msg); 00555 xfree(msg); 00556 } 00557 }
|
|
||||||||||||||||||||
|
Definition at line 229 of file auth.c. References debug3(), error(), Authctxt::failures, get_canonical_hostname(), get_remote_ipaddr(), get_remote_port(), logit(), ServerOptions::max_authtries, Authctxt::postponed, PRIVSEP, record_failed_login(), ServerOptions::use_dns, Authctxt::user, Authctxt::valid, and verbose(). Referenced by do_authloop(), monitor_child_preauth(), and userauth_finish(). 00230 { 00231 void (*authlog) (const char *fmt,...) = verbose; 00232 char *authmsg; 00233 00234 /* Raise logging level */ 00235 if (authenticated == 1 || 00236 !authctxt->valid || 00237 authctxt->failures >= options.max_authtries / 2 || 00238 strcmp(method, "password") == 0) 00239 authlog = logit; 00240 00241 if (authctxt->postponed) 00242 authmsg = "Postponed"; 00243 else 00244 authmsg = authenticated ? "Accepted" : "Failed"; 00245 00246 authlog("%s %s for %s%.100s from %.200s port %d%s", 00247 authmsg, 00248 method, 00249 authctxt->valid ? "" : "invalid user ", 00250 authctxt->user, 00251 get_remote_ipaddr(), 00252 get_remote_port(), 00253 info); 00254 00255 #ifdef CUSTOM_FAILED_LOGIN 00256 if (authenticated == 0 && !authctxt->postponed && 00257 (strcmp(method, "password") == 0 || 00258 strncmp(method, "keyboard-interactive", 20) == 0 || 00259 strcmp(method, "challenge-response") == 0)) 00260 record_failed_login(authctxt->user, 00261 get_canonical_hostname(options.use_dns), "ssh"); 00262 #endif 00263 #ifdef SSH_AUDIT_EVENTS 00264 if (authenticated == 0 && !authctxt->postponed) { 00265 ssh_audit_event_t event; 00266 00267 debug3("audit failed auth attempt, method %s euid %d", 00268 method, (int)geteuid()); 00269 /* 00270 * Because the auth loop is used in both monitor and slave, 00271 * we must be careful to send each event only once and with 00272 * enough privs to write the event. 00273 */ 00274 event = audit_classify_auth(method); 00275 switch(event) { 00276 case SSH_AUTH_FAIL_NONE: 00277 case SSH_AUTH_FAIL_PASSWD: 00278 case SSH_AUTH_FAIL_KBDINT: 00279 if (geteuid() == 0) 00280 audit_event(event); 00281 break; 00282 case SSH_AUTH_FAIL_PUBKEY: 00283 case SSH_AUTH_FAIL_HOSTBASED: 00284 case SSH_AUTH_FAIL_GSSAPI: 00285 /* 00286 * This is required to handle the case where privsep 00287 * is enabled but it's root logging in, since 00288 * use_privsep won't be cleared until after a 00289 * successful login. 00290 */ 00291 if (geteuid() == 0) 00292 audit_event(event); 00293 else 00294 PRIVSEP(audit_event(event)); 00295 break; 00296 default: 00297 error("unknown authentication audit event %d", event); 00298 } 00299 } 00300 #endif 00301 }
|
|
|
Definition at line 307 of file auth.c. References forced_command, get_remote_ipaddr(), logit(), PERMIT_FORCED_ONLY, PERMIT_NO_PASSWD, ServerOptions::permit_root_login, and PERMIT_YES. Referenced by do_authloop(), monitor_child_preauth(), and userauth_finish(). 00308 { 00309 switch (options.permit_root_login) { 00310 case PERMIT_YES: 00311 return 1; 00312 break; 00313 case PERMIT_NO_PASSWD: 00314 if (strcmp(method, "password") != 0) 00315 return 1; 00316 break; 00317 case PERMIT_FORCED_ONLY: 00318 if (forced_command) { 00319 logit("Root login accepted for forced command."); 00320 return 1; 00321 } 00322 break; 00323 } 00324 logit("ROOT LOGIN REFUSED FROM %.200s", get_remote_ipaddr()); 00325 return 0; 00326 }
|
|
|
Definition at line 362 of file auth.c. References ServerOptions::authorized_keys_file, and expand_authorized_keys(). Referenced by auth_rsa_key_allowed(), and user_key_allowed(). 00363 { 00364 return expand_authorized_keys(options.authorized_keys_file, pw); 00365 }
|
|
|
Definition at line 368 of file auth.c. References ServerOptions::authorized_keys_file2, and expand_authorized_keys(). Referenced by user_key_allowed(). 00369 { 00370 return expand_authorized_keys(options.authorized_keys_file2, pw); 00371 }
|
|
||||||||||||||||||||||||
|
Definition at line 375 of file auth.c. References check_host_in_hostfile(), debug2(), HOST_OK, key_free(), key_new(), logit(), restore_uid(), ServerOptions::strict_modes, temporarily_use_uid(), tilde_expand_filename(), Key::type, and xfree(). Referenced by auth_rhosts_rsa_key_allowed(), and hostbased_key_allowed(). 00377 { 00378 Key *found; 00379 char *user_hostfile; 00380 struct stat st; 00381 HostStatus host_status; 00382 00383 /* Check if we know the host and its host key. */ 00384 found = key_new(key->type); 00385 host_status = check_host_in_hostfile(sysfile, host, key, found, NULL); 00386 00387 if (host_status != HOST_OK && userfile != NULL) { 00388 user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); 00389 if (options.strict_modes && 00390 (stat(user_hostfile, &st) == 0) && 00391 ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || 00392 (st.st_mode & 022) != 0)) { 00393 logit("Authentication refused for %.100s: " 00394 "bad owner or modes for %.200s", 00395 pw->pw_name, user_hostfile); 00396 } else { 00397 temporarily_use_uid(pw); 00398 host_status = check_host_in_hostfile(user_hostfile, 00399 host, key, found, NULL); 00400 restore_uid(); 00401 } 00402 xfree(user_hostfile); 00403 } 00404 key_free(found); 00405 00406 debug2("check_key_in_hostfiles: key %s for %s", host_status == HOST_OK ? 00407 "ok" : "not found", host); 00408 return host_status; 00409 }
|
|
||||||||||||
|
Definition at line 337 of file auth.c. References fatal(), file, MAXPATHLEN, percent_expand(), strlcat(), strlcpy(), xfree(), and xmalloc(). Referenced by authorized_keys_file(), and authorized_keys_file2(). 00338 { 00339 char *file, *ret; 00340 00341 file = percent_expand(filename, "h", pw->pw_dir, 00342 "u", pw->pw_name, (char *)NULL); 00343 00344 /* 00345 * Ensure that filename starts anchored. If not, be backward 00346 * compatible and prepend the '%h/' 00347 */ 00348 if (*file == '/') 00349 return (file); 00350 00351 ret = xmalloc(MAXPATHLEN); 00352 if (strlcpy(ret, pw->pw_dir, MAXPATHLEN) >= MAXPATHLEN || 00353 strlcat(ret, "/", MAXPATHLEN) >= MAXPATHLEN || 00354 strlcat(ret, file, MAXPATHLEN) >= MAXPATHLEN) 00355 fatal("expand_authorized_keys: path too long"); 00356 00357 xfree(file); 00358 return (ret); 00359 }
|
|
|
Definition at line 571 of file auth.c. Referenced by do_authentication(), input_userauth_request(), and mm_answer_pwnamallow(). 00572 { 00573 static struct passwd fake; 00574 00575 memset(&fake, 0, sizeof(fake)); 00576 fake.pw_name = "NOUSER"; 00577 fake.pw_passwd = 00578 "$2a$06$r3.juUaHZDlIbQaO2dS9FuYxL1W9M81R1Tc92PoSNmzvpEqLkLGrK"; 00579 fake.pw_gecos = "NOUSER"; 00580 fake.pw_uid = (uid_t)-1; 00581 fake.pw_gid = (gid_t)-1; 00582 #ifdef HAVE_PW_CLASS_IN_PASSWD 00583 fake.pw_class = ""; 00584 #endif 00585 fake.pw_dir = "/nonexist"; 00586 fake.pw_shell = "/nonexist"; 00587 00588 return (&fake); 00589 }
|
|
|
Definition at line 485 of file auth.c. References allowed_user(), debug(), get_canonical_hostname(), get_remote_ipaddr(), logit(), pwcopy(), record_failed_login(), and ServerOptions::use_dns. Referenced by do_authentication(), input_userauth_request(), and mm_answer_pwnamallow(). 00486 { 00487 #ifdef HAVE_LOGIN_CAP 00488 extern login_cap_t *lc; 00489 #ifdef BSD_AUTH 00490 auth_session_t *as; 00491 #endif 00492 #endif 00493 struct passwd *pw; 00494 00495 pw = getpwnam(user); 00496 if (pw == NULL) { 00497 logit("Invalid user %.100s from %.100s", 00498 user, get_remote_ipaddr()); 00499 #ifdef CUSTOM_FAILED_LOGIN 00500 record_failed_login(user, 00501 get_canonical_hostname(options.use_dns), "ssh"); 00502 #endif 00503 #ifdef SSH_AUDIT_EVENTS 00504 audit_event(SSH_INVALID_USER); 00505 #endif /* SSH_AUDIT_EVENTS */ 00506 return (NULL); 00507 } 00508 if (!allowed_user(pw)) 00509 return (NULL); 00510 #ifdef HAVE_LOGIN_CAP 00511 if ((lc = login_getclass(pw->pw_class)) == NULL) { 00512 debug("unable to get login class: %s", user); 00513 return (NULL); 00514 } 00515 #ifdef BSD_AUTH 00516 if ((as = auth_open()) == NULL || auth_setpwd(as, pw) != 0 || 00517 auth_approval(as, lc, pw->pw_name, "ssh") <= 0) { 00518 debug("Approval failure for %s", user); 00519 pw = NULL; 00520 } 00521 if (as != NULL) 00522 auth_close(as); 00523 #endif 00524 #endif 00525 if (pw != NULL) 00526 return (pwcopy(pw)); 00527 return (NULL); 00528 }
|
|
||||||||||||
|
|
|
||||||||||||||||||||||||
|
Definition at line 425 of file auth.c. References debug3(), dirname(), MAXPATHLEN, realpath(), snprintf(), and strlcpy(). Referenced by auth_rsa_key_allowed(), and user_key_allowed2(). 00427 { 00428 uid_t uid = pw->pw_uid; 00429 char buf[MAXPATHLEN], homedir[MAXPATHLEN]; 00430 char *cp; 00431 int comparehome = 0; 00432 struct stat st; 00433 00434 if (realpath(file, buf) == NULL) { 00435 snprintf(err, errlen, "realpath %s failed: %s", file, 00436 strerror(errno)); 00437 return -1; 00438 } 00439 if (realpath(pw->pw_dir, homedir) != NULL) 00440 comparehome = 1; 00441 00442 /* check the open file to avoid races */ 00443 if (fstat(fileno(f), &st) < 0 || 00444 (st.st_uid != 0 && st.st_uid != uid) || 00445 (st.st_mode & 022) != 0) { 00446 snprintf(err, errlen, "bad ownership or modes for file %s", 00447 buf); 00448 return -1; 00449 } 00450 00451 /* for each component of the canonical path, walking upwards */ 00452 for (;;) { 00453 if ((cp = dirname(buf)) == NULL) { 00454 snprintf(err, errlen, "dirname() failed"); 00455 return -1; 00456 } 00457 strlcpy(buf, cp, sizeof(buf)); 00458 00459 debug3("secure_filename: checking '%s'", buf); 00460 if (stat(buf, &st) < 0 || 00461 (st.st_uid != 0 && st.st_uid != uid) || 00462 (st.st_mode & 022) != 0) { 00463 snprintf(err, errlen, 00464 "bad ownership or modes for directory %s", buf); 00465 return -1; 00466 } 00467 00468 /* If are passed the homedir then we can stop */ 00469 if (comparehome && strcmp(homedir, buf) == 0) { 00470 debug3("secure_filename: terminating check at '%s'", 00471 buf); 00472 break; 00473 } 00474 /* 00475 * dirname should always complete with a "/" path, 00476 * but we can be paranoid and check for "." too 00477 */ 00478 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) 00479 break; 00480 } 00481 return 0; 00482 }
|
|
|
|
|
|
Definition at line 62 of file auth.c. Referenced by auth_debug_add(), auth_debug_reset(), auth_debug_send(), and mm_append_debug(). |
|
|
|
|
|
|