summaryrefslogtreecommitdiff
path: root/auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'auth.c')
-rw-r--r--auth.c99
1 files changed, 2 insertions, 97 deletions
diff --git a/auth.c b/auth.c
index 96116ecfe..7f073e0f3 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.122 2017/06/24 06:34:38 djm Exp $ */ 1/* $OpenBSD: auth.c,v 1.123 2017/08/18 05:36:45 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -43,9 +43,6 @@
43#ifdef USE_SHADOW 43#ifdef USE_SHADOW
44#include <shadow.h> 44#include <shadow.h>
45#endif 45#endif
46#ifdef HAVE_LIBGEN_H
47#include <libgen.h>
48#endif
49#include <stdarg.h> 46#include <stdarg.h>
50#include <stdio.h> 47#include <stdio.h>
51#include <string.h> 48#include <string.h>
@@ -498,98 +495,6 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host,
498 return host_status; 495 return host_status;
499} 496}
500 497
501/*
502 * Check a given path for security. This is defined as all components
503 * of the path to the file must be owned by either the owner of
504 * of the file or root and no directories must be group or world writable.
505 *
506 * XXX Should any specific check be done for sym links ?
507 *
508 * Takes a file name, its stat information (preferably from fstat() to
509 * avoid races), the uid of the expected owner, their home directory and an
510 * error buffer plus max size as arguments.
511 *
512 * Returns 0 on success and -1 on failure
513 */
514int
515auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,
516 uid_t uid, char *err, size_t errlen)
517{
518 char buf[PATH_MAX], homedir[PATH_MAX];
519 char *cp;
520 int comparehome = 0;
521 struct stat st;
522
523 if (realpath(name, buf) == NULL) {
524 snprintf(err, errlen, "realpath %s failed: %s", name,
525 strerror(errno));
526 return -1;
527 }
528 if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
529 comparehome = 1;
530
531 if (!S_ISREG(stp->st_mode)) {
532 snprintf(err, errlen, "%s is not a regular file", buf);
533 return -1;
534 }
535 if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
536 (stp->st_mode & 022) != 0) {
537 snprintf(err, errlen, "bad ownership or modes for file %s",
538 buf);
539 return -1;
540 }
541
542 /* for each component of the canonical path, walking upwards */
543 for (;;) {
544 if ((cp = dirname(buf)) == NULL) {
545 snprintf(err, errlen, "dirname() failed");
546 return -1;
547 }
548 strlcpy(buf, cp, sizeof(buf));
549
550 if (stat(buf, &st) < 0 ||
551 (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
552 (st.st_mode & 022) != 0) {
553 snprintf(err, errlen,
554 "bad ownership or modes for directory %s", buf);
555 return -1;
556 }
557
558 /* If are past the homedir then we can stop */
559 if (comparehome && strcmp(homedir, buf) == 0)
560 break;
561
562 /*
563 * dirname should always complete with a "/" path,
564 * but we can be paranoid and check for "." too
565 */
566 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
567 break;
568 }
569 return 0;
570}
571
572/*
573 * Version of secure_path() that accepts an open file descriptor to
574 * avoid races.
575 *
576 * Returns 0 on success and -1 on failure
577 */
578static int
579secure_filename(FILE *f, const char *file, struct passwd *pw,
580 char *err, size_t errlen)
581{
582 struct stat st;
583
584 /* check the open file to avoid races */
585 if (fstat(fileno(f), &st) < 0) {
586 snprintf(err, errlen, "cannot stat file %s: %s",
587 file, strerror(errno));
588 return -1;
589 }
590 return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
591}
592
593static FILE * 498static FILE *
594auth_openfile(const char *file, struct passwd *pw, int strict_modes, 499auth_openfile(const char *file, struct passwd *pw, int strict_modes,
595 int log_missing, char *file_type) 500 int log_missing, char *file_type)
@@ -622,7 +527,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes,
622 return NULL; 527 return NULL;
623 } 528 }
624 if (strict_modes && 529 if (strict_modes &&
625 secure_filename(f, file, pw, line, sizeof(line)) != 0) { 530 safe_path_fd(fileno(f), file, pw, line, sizeof(line)) != 0) {
626 fclose(f); 531 fclose(f);
627 logit("Authentication refused: %s", line); 532 logit("Authentication refused: %s", line);
628 auth_debug_add("Ignored %s: %s", file_type, line); 533 auth_debug_add("Ignored %s: %s", file_type, line);