|
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 | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | 4 | * |
|
43 | 43 | #ifdef USE_SHADOW |
44 | 44 | #include <shadow.h> |
45 | 45 | #endif |
46 | | -#ifdef HAVE_LIBGEN_H |
47 | | -#include <libgen.h> |
48 | | -#endif |
49 | 46 | #include <stdarg.h> |
50 | 47 | #include <stdio.h> |
51 | 48 | #include <string.h> |
@@ -508,98 +505,6 @@ check_key_in_hostfiles(struct passwd *pw, struct sshkey *key, const char *host, |
508 | 505 | return host_status; |
509 | 506 | } |
510 | 507 |
|
511 | | -/* |
512 | | - * Check a given path for security. This is defined as all components |
513 | | - * of the path to the file must be owned by either the owner of |
514 | | - * of the file or root and no directories must be group or world writable. |
515 | | - * |
516 | | - * XXX Should any specific check be done for sym links ? |
517 | | - * |
518 | | - * Takes a file name, its stat information (preferably from fstat() to |
519 | | - * avoid races), the uid of the expected owner, their home directory and an |
520 | | - * error buffer plus max size as arguments. |
521 | | - * |
522 | | - * Returns 0 on success and -1 on failure |
523 | | - */ |
524 | | -int |
525 | | -auth_secure_path(const char *name, struct stat *stp, const char *pw_dir, |
526 | | - uid_t uid, char *err, size_t errlen) |
527 | | -{ |
528 | | - char buf[PATH_MAX], homedir[PATH_MAX]; |
529 | | - char *cp; |
530 | | - int comparehome = 0; |
531 | | - struct stat st; |
532 | | - |
533 | | - if (realpath(name, buf) == NULL) { |
534 | | - snprintf(err, errlen, "realpath %s failed: %s", name, |
535 | | - strerror(errno)); |
536 | | - return -1; |
537 | | - } |
538 | | - if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL) |
539 | | - comparehome = 1; |
540 | | - |
541 | | - if (!S_ISREG(stp->st_mode)) { |
542 | | - snprintf(err, errlen, "%s is not a regular file", buf); |
543 | | - return -1; |
544 | | - } |
545 | | - if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) || |
546 | | - (stp->st_mode & 022) != 0) { |
547 | | - snprintf(err, errlen, "bad ownership or modes for file %s", |
548 | | - buf); |
549 | | - return -1; |
550 | | - } |
551 | | - |
552 | | - /* for each component of the canonical path, walking upwards */ |
553 | | - for (;;) { |
554 | | - if ((cp = dirname(buf)) == NULL) { |
555 | | - snprintf(err, errlen, "dirname() failed"); |
556 | | - return -1; |
557 | | - } |
558 | | - strlcpy(buf, cp, sizeof(buf)); |
559 | | - |
560 | | - if (stat(buf, &st) < 0 || |
561 | | - (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) || |
562 | | - (st.st_mode & 022) != 0) { |
563 | | - snprintf(err, errlen, |
564 | | - "bad ownership or modes for directory %s", buf); |
565 | | - return -1; |
566 | | - } |
567 | | - |
568 | | - /* If are past the homedir then we can stop */ |
569 | | - if (comparehome && strcmp(homedir, buf) == 0) |
570 | | - break; |
571 | | - |
572 | | - /* |
573 | | - * dirname should always complete with a "/" path, |
574 | | - * but we can be paranoid and check for "." too |
575 | | - */ |
576 | | - if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0)) |
577 | | - break; |
578 | | - } |
579 | | - return 0; |
580 | | -} |
581 | | - |
582 | | -/* |
583 | | - * Version of secure_path() that accepts an open file descriptor to |
584 | | - * avoid races. |
585 | | - * |
586 | | - * Returns 0 on success and -1 on failure |
587 | | - */ |
588 | | -static int |
589 | | -secure_filename(FILE *f, const char *file, struct passwd *pw, |
590 | | - char *err, size_t errlen) |
591 | | -{ |
592 | | - struct stat st; |
593 | | - |
594 | | - /* check the open file to avoid races */ |
595 | | - if (fstat(fileno(f), &st) < 0) { |
596 | | - snprintf(err, errlen, "cannot stat file %s: %s", |
597 | | - file, strerror(errno)); |
598 | | - return -1; |
599 | | - } |
600 | | - return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen); |
601 | | -} |
602 | | - |
603 | 508 | static FILE * |
604 | 509 | auth_openfile(const char *file, struct passwd *pw, int strict_modes, |
605 | 510 | int log_missing, char *file_type) |
@@ -646,7 +551,7 @@ auth_openfile(const char *file, struct passwd *pw, int strict_modes, |
646 | 551 | return NULL; |
647 | 552 | } |
648 | 553 | if (strict_modes && |
649 | | - secure_filename(f, file, pw, line, sizeof(line)) != 0) { |
| 554 | + safe_path_fd(fileno(f), file, pw, line, sizeof(line)) != 0) { |
650 | 555 | fclose(f); |
651 | 556 | logit("Authentication refused: %s", line); |
652 | 557 | auth_debug_add("Ignored %s: %s", file_type, line); |
|
0 commit comments