[BACK]Return to auth.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / ssh

Diff for /src/usr.bin/ssh/auth.c between version 1.122 and 1.123

version 1.122, 2017/06/24 06:34:38 version 1.123, 2017/08/18 05:36:45
Line 29 
Line 29 
   
 #include <errno.h>  #include <errno.h>
 #include <fcntl.h>  #include <fcntl.h>
 #include <libgen.h>  
 #include <login_cap.h>  #include <login_cap.h>
 #include <paths.h>  #include <paths.h>
 #include <pwd.h>  #include <pwd.h>
Line 406 
Line 405 
         return host_status;          return host_status;
 }  }
   
 /*  
  * Check a given path for security. This is defined as all components  
  * of the path to the file must be owned by either the owner of  
  * of the file or root and no directories must be group or world writable.  
  *  
  * XXX Should any specific check be done for sym links ?  
  *  
  * Takes a file name, its stat information (preferably from fstat() to  
  * avoid races), the uid of the expected owner, their home directory and an  
  * error buffer plus max size as arguments.  
  *  
  * Returns 0 on success and -1 on failure  
  */  
 int  
 auth_secure_path(const char *name, struct stat *stp, const char *pw_dir,  
     uid_t uid, char *err, size_t errlen)  
 {  
         char buf[PATH_MAX], homedir[PATH_MAX];  
         char *cp;  
         int comparehome = 0;  
         struct stat st;  
   
         if (realpath(name, buf) == NULL) {  
                 snprintf(err, errlen, "realpath %s failed: %s", name,  
                     strerror(errno));  
                 return -1;  
         }  
         if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)  
                 comparehome = 1;  
   
         if (!S_ISREG(stp->st_mode)) {  
                 snprintf(err, errlen, "%s is not a regular file", buf);  
                 return -1;  
         }  
         if ((stp->st_uid != 0 && stp->st_uid != uid) ||  
             (stp->st_mode & 022) != 0) {  
                 snprintf(err, errlen, "bad ownership or modes for file %s",  
                     buf);  
                 return -1;  
         }  
   
         /* for each component of the canonical path, walking upwards */  
         for (;;) {  
                 if ((cp = dirname(buf)) == NULL) {  
                         snprintf(err, errlen, "dirname() failed");  
                         return -1;  
                 }  
                 strlcpy(buf, cp, sizeof(buf));  
   
                 if (stat(buf, &st) < 0 ||  
                     (st.st_uid != 0 && st.st_uid != uid) ||  
                     (st.st_mode & 022) != 0) {  
                         snprintf(err, errlen,  
                             "bad ownership or modes for directory %s", buf);  
                         return -1;  
                 }  
   
                 /* If are past the homedir then we can stop */  
                 if (comparehome && strcmp(homedir, buf) == 0)  
                         break;  
   
                 /*  
                  * dirname should always complete with a "/" path,  
                  * but we can be paranoid and check for "." too  
                  */  
                 if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))  
                         break;  
         }  
         return 0;  
 }  
   
 /*  
  * Version of secure_path() that accepts an open file descriptor to  
  * avoid races.  
  *  
  * Returns 0 on success and -1 on failure  
  */  
 static int  
 secure_filename(FILE *f, const char *file, struct passwd *pw,  
     char *err, size_t errlen)  
 {  
         struct stat st;  
   
         /* check the open file to avoid races */  
         if (fstat(fileno(f), &st) < 0) {  
                 snprintf(err, errlen, "cannot stat file %s: %s",  
                     file, strerror(errno));  
                 return -1;  
         }  
         return auth_secure_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);  
 }  
   
 static FILE *  static FILE *
 auth_openfile(const char *file, struct passwd *pw, int strict_modes,  auth_openfile(const char *file, struct passwd *pw, int strict_modes,
     int log_missing, char *file_type)      int log_missing, char *file_type)
Line 530 
Line 437 
                 return NULL;                  return NULL;
         }          }
         if (strict_modes &&          if (strict_modes &&
             secure_filename(f, file, pw, line, sizeof(line)) != 0) {              safe_path_fd(fileno(f), file, pw, line, sizeof(line)) != 0) {
                 fclose(f);                  fclose(f);
                 logit("Authentication refused: %s", line);                  logit("Authentication refused: %s", line);
                 auth_debug_add("Ignored %s: %s", file_type, line);                  auth_debug_add("Ignored %s: %s", file_type, line);

Legend:
Removed from v.1.122  
changed lines
  Added in v.1.123