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

Diff for /src/usr.bin/ssh/auth2-pubkey.c between version 1.50 and 1.51

version 1.50, 2015/05/21 06:38:35 version 1.51, 2015/05/21 06:43:30
Line 551 
Line 551 
 }  }
   
 static int  static int
 match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)  process_principals(FILE *f, char *file, struct passwd *pw,
       struct sshkey_cert *cert)
 {  {
         FILE *f;  
         char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;          char line[SSH_MAX_PUBKEY_BYTES], *cp, *ep, *line_opts;
         u_long linenum = 0;          u_long linenum = 0;
         u_int i;          u_int i;
   
         temporarily_use_uid(pw);  
         debug("trying authorized principals file %s", file);  
         if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {  
                 restore_uid();  
                 return 0;  
         }  
         while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {          while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
                 /* Skip leading whitespace. */                  /* Skip leading whitespace. */
                 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)                  for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
Line 591 
Line 585 
                 }                  }
                 for (i = 0; i < cert->nprincipals; i++) {                  for (i = 0; i < cert->nprincipals; i++) {
                         if (strcmp(cp, cert->principals[i]) == 0) {                          if (strcmp(cp, cert->principals[i]) == 0) {
                                 debug3("matched principal \"%.100s\" "                                  debug3("%s:%lu: matched principal \"%.100s\"",
                                     "from file \"%s\" on line %lu",                                      file == NULL ? "(command)" : file,
                                     cert->principals[i], file, linenum);                                      linenum, cert->principals[i]);
                                 if (auth_parse_options(pw, line_opts,                                  if (auth_parse_options(pw, line_opts,
                                     file, linenum) != 1)                                      file, linenum) != 1)
                                         continue;                                          continue;
                                 fclose(f);  
                                 restore_uid();  
                                 return 1;                                  return 1;
                         }                          }
                 }                  }
         }          }
           return 0;
   }
   
   static int
   match_principals_file(char *file, struct passwd *pw, struct sshkey_cert *cert)
   {
           FILE *f;
           int success;
   
           temporarily_use_uid(pw);
           debug("trying authorized principals file %s", file);
           if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {
                   restore_uid();
                   return 0;
           }
           success = process_principals(f, file, pw, cert);
         fclose(f);          fclose(f);
         restore_uid();          restore_uid();
         return 0;          return success;
 }  }
   
 /*  /*
    * Checks whether principal is allowed in output of command.
    * returns 1 if the principal is allowed or 0 otherwise.
    */
   static int
   match_principals_command(struct passwd *user_pw, struct sshkey *key)
   {
           FILE *f = NULL;
           int ok, found_principal = 0;
           struct passwd *pw;
           int i, ac = 0, uid_swapped = 0;
           pid_t pid;
           char *tmp, *username = NULL, *command = NULL, **av = NULL;
           void (*osigchld)(int);
   
           if (options.authorized_principals_command == NULL)
                   return 0;
           if (options.authorized_principals_command_user == NULL) {
                   error("No user for AuthorizedPrincipalsCommand specified, "
                       "skipping");
                   return 0;
           }
   
           /*
            * NB. all returns later this function should go via "out" to
            * ensure the original SIGCHLD handler is restored properly.
            */
           osigchld = signal(SIGCHLD, SIG_DFL);
   
           /* Prepare and verify the user for the command */
           username = percent_expand(options.authorized_principals_command_user,
               "u", user_pw->pw_name, (char *)NULL);
           pw = getpwnam(username);
           if (pw == NULL) {
                   error("AuthorizedPrincipalsCommandUser \"%s\" not found: %s",
                       username, strerror(errno));
                   goto out;
           }
   
           /* Turn the command into an argument vector */
           if (split_argv(options.authorized_principals_command, &ac, &av) != 0) {
                   error("AuthorizedPrincipalsCommand \"%s\" contains "
                       "invalid quotes", command);
                   goto out;
           }
           if (ac == 0) {
                   error("AuthorizedPrincipalsCommand \"%s\" yielded no arguments",
                       command);
                   goto out;
           }
           for (i = 1; i < ac; i++) {
                   tmp = percent_expand(av[i],
                       "u", user_pw->pw_name,
                       "h", user_pw->pw_dir,
                       (char *)NULL);
                   if (tmp == NULL)
                           fatal("%s: percent_expand failed", __func__);
                   free(av[i]);
                   av[i] = tmp;
           }
           /* Prepare a printable command for logs, etc. */
           command = assemble_argv(ac, av);
   
           if ((pid = subprocess("AuthorizedPrincipalsCommand", pw, command,
               ac, av, &f)) == 0)
                   goto out;
   
           uid_swapped = 1;
           temporarily_use_uid(pw);
   
           ok = process_principals(f, NULL, pw, key->cert);
   
           if (exited_cleanly(pid, "AuthorizedPrincipalsCommand", command) != 0)
                   goto out;
   
           /* Read completed successfully */
           found_principal = ok;
    out:
           if (f != NULL)
                   fclose(f);
           signal(SIGCHLD, osigchld);
           for (i = 0; i < ac; i++)
                   free(av[i]);
           free(av);
           if (uid_swapped)
                   restore_uid();
           free(command);
           free(username);
           return found_principal;
   }
   /*
  * Checks whether key is allowed in authorized_keys-format file,   * Checks whether key is allowed in authorized_keys-format file,
  * returns 1 if the key is allowed or 0 otherwise.   * returns 1 if the key is allowed or 0 otherwise.
  */   */
Line 730 
Line 828 
 {  {
         char *ca_fp, *principals_file = NULL;          char *ca_fp, *principals_file = NULL;
         const char *reason;          const char *reason;
         int ret = 0;          int ret = 0, found_principal = 0;
   
         if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)          if (!key_is_cert(key) || options.trusted_user_ca_keys == NULL)
                 return 0;                  return 0;
Line 752 
Line 850 
          * against the username.           * against the username.
          */           */
         if ((principals_file = authorized_principals_file(pw)) != NULL) {          if ((principals_file = authorized_principals_file(pw)) != NULL) {
                 if (!match_principals_file(principals_file, pw, key->cert)) {                  if (match_principals_file(principals_file, pw, key->cert))
                         reason = "Certificate does not contain an "                          found_principal = 1;
                             "authorized principal";          }
           /* Try querying command if specified */
           if (!found_principal && match_principals_command(pw, key))
                   found_principal = 1;
           /* If principals file or command specify, then require a match here */
           if (!found_principal && (principals_file != NULL ||
               options.authorized_principals_command != NULL)) {
                   reason = "Certificate does not contain an authorized principal";
  fail_reason:   fail_reason:
                         error("%s", reason);                  error("%s", reason);
                         auth_debug_add("%s", reason);                  auth_debug_add("%s", reason);
                         goto out;                  goto out;
                 }  
         }          }
         if (key_cert_check_authority(key, 0, 1,          if (key_cert_check_authority(key, 0, 1,
             principals_file == NULL ? pw->pw_name : NULL, &reason) != 0)              principals_file == NULL ? pw->pw_name : NULL, &reason) != 0)

Legend:
Removed from v.1.50  
changed lines
  Added in v.1.51