summaryrefslogtreecommitdiff
path: root/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth.c')
-rw-r--r--auth.c77
1 files changed, 57 insertions, 20 deletions
diff --git a/auth.c b/auth.c
index a8cffd5c1..6128fa460 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.96 2012/05/13 01:42:32 dtucker Exp $ */ 1/* $OpenBSD: auth.c,v 1.101 2013/02/06 00:22:21 dtucker Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -71,6 +71,7 @@
71#endif 71#endif
72#include "authfile.h" 72#include "authfile.h"
73#include "monitor_wrap.h" 73#include "monitor_wrap.h"
74#include "krl.h"
74 75
75/* import */ 76/* import */
76extern ServerOptions options; 77extern ServerOptions options;
@@ -251,7 +252,8 @@ allowed_user(struct passwd * pw)
251} 252}
252 253
253void 254void
254auth_log(Authctxt *authctxt, int authenticated, char *method, char *info) 255auth_log(Authctxt *authctxt, int authenticated, int partial,
256 const char *method, const char *submethod, const char *info)
255{ 257{
256 void (*authlog) (const char *fmt,...) = verbose; 258 void (*authlog) (const char *fmt,...) = verbose;
257 char *authmsg; 259 char *authmsg;
@@ -268,12 +270,15 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
268 270
269 if (authctxt->postponed) 271 if (authctxt->postponed)
270 authmsg = "Postponed"; 272 authmsg = "Postponed";
273 else if (partial)
274 authmsg = "Partial";
271 else 275 else
272 authmsg = authenticated ? "Accepted" : "Failed"; 276 authmsg = authenticated ? "Accepted" : "Failed";
273 277
274 authlog("%s %s for %s%.100s from %.200s port %d%s", 278 authlog("%s %s%s%s for %s%.100s from %.200s port %d%s",
275 authmsg, 279 authmsg,
276 method, 280 method,
281 submethod != NULL ? "/" : "", submethod == NULL ? "" : submethod,
277 authctxt->valid ? "" : "invalid user ", 282 authctxt->valid ? "" : "invalid user ",
278 authctxt->user, 283 authctxt->user,
279 get_remote_ipaddr(), 284 get_remote_ipaddr(),
@@ -303,7 +308,7 @@ auth_log(Authctxt *authctxt, int authenticated, char *method, char *info)
303 * Check whether root logins are disallowed. 308 * Check whether root logins are disallowed.
304 */ 309 */
305int 310int
306auth_root_allowed(char *method) 311auth_root_allowed(const char *method)
307{ 312{
308 switch (options.permit_root_login) { 313 switch (options.permit_root_login) {
309 case PERMIT_YES: 314 case PERMIT_YES:
@@ -409,41 +414,42 @@ check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
409 return host_status; 414 return host_status;
410} 415}
411 416
412
413/* 417/*
414 * Check a given file for security. This is defined as all components 418 * Check a given path for security. This is defined as all components
415 * of the path to the file must be owned by either the owner of 419 * of the path to the file must be owned by either the owner of
416 * of the file or root and no directories must be group or world writable. 420 * of the file or root and no directories must be group or world writable.
417 * 421 *
418 * XXX Should any specific check be done for sym links ? 422 * XXX Should any specific check be done for sym links ?
419 * 423 *
420 * Takes an open file descriptor, the file name, a uid and and 424 * Takes a file name, its stat information (preferably from fstat() to
425 * avoid races), the uid of the expected owner, their home directory and an
421 * error buffer plus max size as arguments. 426 * error buffer plus max size as arguments.
422 * 427 *
423 * Returns 0 on success and -1 on failure 428 * Returns 0 on success and -1 on failure
424 */ 429 */
425static int 430int
426secure_filename(FILE *f, const char *file, struct passwd *pw, 431auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
427 char *err, size_t errlen) 432 uid_t uid, char *err, size_t errlen)
428{ 433{
429 uid_t uid = pw->pw_uid;
430 char buf[MAXPATHLEN], homedir[MAXPATHLEN]; 434 char buf[MAXPATHLEN], homedir[MAXPATHLEN];
431 char *cp; 435 char *cp;
432 int comparehome = 0; 436 int comparehome = 0;
433 struct stat st; 437 struct stat st;
434 438
435 if (realpath(file, buf) == NULL) { 439 if (realpath(name, buf) == NULL) {
436 snprintf(err, errlen, "realpath %s failed: %s", file, 440 snprintf(err, errlen, "realpath %s failed: %s", name,
437 strerror(errno)); 441 strerror(errno));
438 return -1; 442 return -1;
439 } 443 }
440 if (realpath(pw->pw_dir, homedir) != NULL) 444 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
441 comparehome = 1; 445 comparehome = 1;
442 446
443 /* check the open file to avoid races */ 447 if (!S_ISREG(stp->st_mode)) {
444 if (fstat(fileno(f), &st) < 0 || 448 snprintf(err, errlen, "%s is not a regular file", buf);
445 (st.st_uid != 0 && st.st_uid != uid) || 449 return -1;
446 (st.st_mode & 022) != 0) { 450 }
451 if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
452 (stp->st_mode & 022) != 0) {
447 snprintf(err, errlen, "bad ownership or modes for file %s", 453 snprintf(err, errlen, "bad ownership or modes for file %s",
448 buf); 454 buf);
449 return -1; 455 return -1;
@@ -458,7 +464,7 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
458 strlcpy(buf, cp, sizeof(buf)); 464 strlcpy(buf, cp, sizeof(buf));
459 465
460 if (stat(buf, &st) < 0 || 466 if (stat(buf, &st) < 0 ||
461 (st.st_uid != 0 && st.st_uid != uid) || 467 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
462 (st.st_mode & 022) != 0) { 468 (st.st_mode & 022) != 0) {
463 snprintf(err, errlen, 469 snprintf(err, errlen,
464 "bad ownership or modes for directory %s", buf); 470 "bad ownership or modes for directory %s", buf);
@@ -479,6 +485,27 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
479 return 0; 485 return 0;
480} 486}
481 487
488/*
489 * Version of secure_path() that accepts an open file descriptor to
490 * avoid races.
491 *
492 * Returns 0 on success and -1 on failure
493 */
494static int
495secure_filename(FILE *f, const char *file, struct passwd *pw,
496 char *err, size_t errlen)
497{
498 struct stat st;
499
500 /* check the open file to avoid races */
501 if (fstat(fileno(f), &st) < 0) {
502 snprintf(err, errlen, "cannot stat file %s: %s",
503 file, strerror(errno));
504 return -1;
505 }
506 return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
507}
508
482static FILE * 509static FILE *
483auth_openfile(const char *file, struct passwd *pw, int strict_modes, 510auth_openfile(const char *file, struct passwd *pw, int strict_modes,
484 int log_missing, char *file_type) 511 int log_missing, char *file_type)
@@ -614,7 +641,16 @@ auth_key_is_revoked(Key *key)
614 641
615 if (options.revoked_keys_file == NULL) 642 if (options.revoked_keys_file == NULL)
616 return 0; 643 return 0;
617 644 switch (ssh_krl_file_contains_key(options.revoked_keys_file, key)) {
645 case 0:
646 return 0; /* Not revoked */
647 case -2:
648 break; /* Not a KRL */
649 default:
650 goto revoked;
651 }
652 debug3("%s: treating %s as a key list", __func__,
653 options.revoked_keys_file);
618 switch (key_in_file(key, options.revoked_keys_file, 0)) { 654 switch (key_in_file(key, options.revoked_keys_file, 0)) {
619 case 0: 655 case 0:
620 /* key not revoked */ 656 /* key not revoked */
@@ -625,6 +661,7 @@ auth_key_is_revoked(Key *key)
625 "authentication"); 661 "authentication");
626 return 1; 662 return 1;
627 case 1: 663 case 1:
664 revoked:
628 /* Key revoked */ 665 /* Key revoked */
629 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX); 666 key_fp = key_fingerprint(key, SSH_FP_MD5, SSH_FP_HEX);
630 error("WARNING: authentication attempt with a revoked " 667 error("WARNING: authentication attempt with a revoked "