00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "includes.h"
00026 RCSID("$OpenBSD: auth.c,v 1.60 2005/06/17 02:44:32 djm Exp $");
00027
00028 #ifdef HAVE_LOGIN_H
00029 #include <login.h>
00030 #endif
00031 #ifdef USE_SHADOW
00032 #include <shadow.h>
00033 #endif
00034
00035 #ifdef HAVE_LIBGEN_H
00036 #include <libgen.h>
00037 #endif
00038
00039 #include "xmalloc.h"
00040 #include "match.h"
00041 #include "groupaccess.h"
00042 #include "log.h"
00043 #include "servconf.h"
00044 #include "auth.h"
00045 #include "auth-options.h"
00046 #include "canohost.h"
00047 #include "buffer.h"
00048 #include "bufaux.h"
00049 #include "uidswap.h"
00050 #include "misc.h"
00051 #include "bufaux.h"
00052 #include "packet.h"
00053 #include "loginrec.h"
00054 #include "monitor_wrap.h"
00055
00056
00057 extern ServerOptions options;
00058 extern Buffer loginmsg;
00059
00060
00061 Buffer auth_debug;
00062 int auth_debug_init;
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073 int
00074 allowed_user(struct passwd * pw)
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
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
00095 #endif
00096
00097
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
00105 #else
00106 passwd = pw->pw_passwd;
00107 #endif
00108
00109
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
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
00138
00139
00140 shell = (pw->pw_shell[0] == '\0') ? _PATH_BSHELL : pw->pw_shell;
00141
00142
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
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
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
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
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
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
00205
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
00225 return 1;
00226 }
00227
00228 void
00229 auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
00230 {
00231 void (*authlog) (const char *fmt,...) = verbose;
00232 char *authmsg;
00233
00234
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
00271
00272
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
00287
00288
00289
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 }
00302
00303
00304
00305
00306 int
00307 auth_root_allowed(char *method)
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 }
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336 static char *
00337 expand_authorized_keys(const char *filename, struct passwd *pw)
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
00346
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 }
00360
00361 char *
00362 authorized_keys_file(struct passwd *pw)
00363 {
00364 return expand_authorized_keys(options.authorized_keys_file, pw);
00365 }
00366
00367 char *
00368 authorized_keys_file2(struct passwd *pw)
00369 {
00370 return expand_authorized_keys(options.authorized_keys_file2, pw);
00371 }
00372
00373
00374 HostStatus
00375 check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
00376 const char *sysfile, const char *userfile)
00377 {
00378 Key *found;
00379 char *user_hostfile;
00380 struct stat st;
00381 HostStatus host_status;
00382
00383
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 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424 int
00425 secure_filename(FILE *f, const char *file, struct passwd *pw,
00426 char *err, size_t errlen)
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
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
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
00469 if (comparehome && strcmp(homedir, buf) == 0) {
00470 debug3("secure_filename: terminating check at '%s'",
00471 buf);
00472 break;
00473 }
00474
00475
00476
00477
00478 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
00479 break;
00480 }
00481 return 0;
00482 }
00483
00484 struct passwd *
00485 getpwnamallow(const char *user)
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
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 }
00529
00530 void
00531 auth_debug_add(const char *fmt,...)
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 }
00544
00545 void
00546 auth_debug_send(void)
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 }
00558
00559 void
00560 auth_debug_reset(void)
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 }
00569
00570 struct passwd *
00571 fakepw(void)
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 }