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

Diff for /src/usr.bin/ssh/ssh-add.c between version 1.161 and 1.162

version 1.161, 2021/10/28 02:54:18 version 1.162, 2021/12/19 22:10:24
Line 65 
Line 65 
 #include "digest.h"  #include "digest.h"
 #include "ssh-sk.h"  #include "ssh-sk.h"
 #include "sk-api.h"  #include "sk-api.h"
   #include "hostfile.h"
   
 /* argv0 */  /* argv0 */
 extern char *__progname;  extern char *__progname;
Line 224 
Line 225 
   
 static int  static int
 add_file(int agent_fd, const char *filename, int key_only, int qflag,  add_file(int agent_fd, const char *filename, int key_only, int qflag,
     const char *skprovider)      const char *skprovider, struct dest_constraint **dest_constraints,
       size_t ndest_constraints)
 {  {
         struct sshkey *private, *cert;          struct sshkey *private, *cert;
         char *comment = NULL;          char *comment = NULL;
Line 358 
Line 360 
         }          }
   
         if ((r = ssh_add_identity_constrained(agent_fd, private, comment,          if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
             lifetime, confirm, maxsign, skprovider)) == 0) {              lifetime, confirm, maxsign, skprovider,
               dest_constraints, ndest_constraints)) == 0) {
                 ret = 0;                  ret = 0;
                 if (!qflag) {                  if (!qflag) {
                         fprintf(stderr, "Identity added: %s (%s)\n",                          fprintf(stderr, "Identity added: %s (%s)\n",
Line 410 
Line 413 
         sshkey_free(cert);          sshkey_free(cert);
   
         if ((r = ssh_add_identity_constrained(agent_fd, private, comment,          if ((r = ssh_add_identity_constrained(agent_fd, private, comment,
             lifetime, confirm, maxsign, skprovider)) != 0) {              lifetime, confirm, maxsign, skprovider,
               dest_constraints, ndest_constraints)) != 0) {
                 error_r(r, "Certificate %s (%s) add failed", certpath,                  error_r(r, "Certificate %s (%s) add failed", certpath,
                     private->cert->key_id);                      private->cert->key_id);
                 goto out;                  goto out;
Line 438 
Line 442 
 }  }
   
 static int  static int
 update_card(int agent_fd, int add, const char *id, int qflag)  update_card(int agent_fd, int add, const char *id, int qflag,
       struct dest_constraint **dest_constraints, size_t ndest_constraints)
 {  {
         char *pin = NULL;          char *pin = NULL;
         int r, ret = -1;          int r, ret = -1;
Line 450 
Line 455 
         }          }
   
         if ((r = ssh_update_card(agent_fd, add, id, pin == NULL ? "" : pin,          if ((r = ssh_update_card(agent_fd, add, id, pin == NULL ? "" : pin,
             lifetime, confirm)) == 0) {              lifetime, confirm, dest_constraints, ndest_constraints)) == 0) {
                 ret = 0;                  ret = 0;
                 if (!qflag) {                  if (!qflag) {
                         fprintf(stderr, "Card %s: %s\n",                          fprintf(stderr, "Card %s: %s\n",
Line 571 
Line 576 
 }  }
   
 static int  static int
 load_resident_keys(int agent_fd, const char *skprovider, int qflag)  load_resident_keys(int agent_fd, const char *skprovider, int qflag,
       struct dest_constraint **dest_constraints, size_t ndest_constraints)
 {  {
         struct sshsk_resident_key **srks;          struct sshsk_resident_key **srks;
         size_t nsrks, i;          size_t nsrks, i;
Line 591 
Line 597 
                     fingerprint_hash, SSH_FP_DEFAULT)) == NULL)                      fingerprint_hash, SSH_FP_DEFAULT)) == NULL)
                         fatal_f("sshkey_fingerprint failed");                          fatal_f("sshkey_fingerprint failed");
                 if ((r = ssh_add_identity_constrained(agent_fd, key, "",                  if ((r = ssh_add_identity_constrained(agent_fd, key, "",
                     lifetime, confirm, maxsign, skprovider)) != 0) {                      lifetime, confirm, maxsign, skprovider,
                         error("Unable to add key %s %s", sshkey_type(key), fp);                      dest_constraints, ndest_constraints)) != 0) {
                           error("Unable to add key %s %s",
                               sshkey_type(key), fp);
                         free(fp);                          free(fp);
                         ok = r;                          ok = r;
                         continue;                          continue;
Line 621 
Line 629 
   
 static int  static int
 do_file(int agent_fd, int deleting, int key_only, char *file, int qflag,  do_file(int agent_fd, int deleting, int key_only, char *file, int qflag,
     const char *skprovider)      const char *skprovider, struct dest_constraint **dest_constraints,
       size_t ndest_constraints)
 {  {
         if (deleting) {          if (deleting) {
                 if (delete_file(agent_fd, file, key_only, qflag) == -1)                  if (delete_file(agent_fd, file, key_only, qflag) == -1)
                         return -1;                          return -1;
         } else {          } else {
                 if (add_file(agent_fd, file, key_only, qflag, skprovider) == -1)                  if (add_file(agent_fd, file, key_only, qflag, skprovider,
                       dest_constraints, ndest_constraints) == -1)
                         return -1;                          return -1;
         }          }
         return 0;          return 0;
 }  }
   
   /* Append string 's' to a NULL-terminated array of strings */
 static void  static void
   stringlist_append(char ***listp, const char *s)
   {
           size_t i = 0;
   
           if (*listp == NULL)
                   *listp = xcalloc(2, sizeof(**listp));
           else {
                   for (i = 0; (*listp)[i] != NULL; i++)
                           ; /* count */
                   *listp = xrecallocarray(*listp, i + 1, i + 2, sizeof(**listp));
           }
           (*listp)[i] = xstrdup(s);
   }
   
   static void
   parse_dest_constraint_hop(const char *s, struct dest_constraint_hop *dch,
       char **hostkey_files)
   {
           char *user = NULL, *host, *os, *path;
           size_t i;
           struct hostkeys *hostkeys;
           const struct hostkey_entry *hke;
           int r, want_ca;
   
           memset(dch, '\0', sizeof(*dch));
           os = xstrdup(s);
           if ((host = strchr(os, '@')) == NULL)
                   host = os;
           else {
                   *host++ = '\0';
                   user = os;
           }
           cleanhostname(host);
           /* Trivial case: username@ (all hosts) */
           if (*host == '\0') {
                   if (user == NULL) {
                           fatal("Invalid key destination constraint \"%s\": "
                               "does not specify user or host", s);
                   }
                   dch->user = xstrdup(user);
                   /* other fields left blank */
                   free(os);
                   return;
           }
           if (hostkey_files == NULL)
                   fatal_f("no hostkey files");
           /* Otherwise we need to look up the keys for this hostname */
           hostkeys = init_hostkeys();
           for (i = 0; hostkey_files[i]; i++) {
                   path = tilde_expand_filename(hostkey_files[i], getuid());
                   debug2_f("looking up host keys for \"%s\" in %s", host, path);
                   load_hostkeys(hostkeys, host, path, 0);
                   free(path);
           }
           dch->user = user == NULL ? NULL : xstrdup(user);
           dch->hostname = xstrdup(host);
           for (i = 0; i < hostkeys->num_entries; i++) {
                   hke = hostkeys->entries + i;
                   want_ca = hke->marker == MRK_CA;
                   if (hke->marker != MRK_NONE && !want_ca)
                           continue;
                   debug3_f("%s%s%s: adding %s %skey from %s:%lu as key %u",
                       user == NULL ? "": user, user == NULL ? "" : "@",
                       host, sshkey_type(hke->key), want_ca ? "CA " : "",
                       hke->file, hke->line, dch->nkeys);
                   dch->keys = xrecallocarray(dch->keys, dch->nkeys,
                       dch->nkeys + 1, sizeof(*dch->keys));
                   dch->key_is_ca = xrecallocarray(dch->key_is_ca, dch->nkeys,
                       dch->nkeys + 1, sizeof(*dch->key_is_ca));
                   if ((r = sshkey_from_private(hke->key,
                       &(dch->keys[dch->nkeys]))) != 0)
                           fatal_fr(r, "sshkey_from_private");
                   dch->key_is_ca[dch->nkeys] = want_ca;
                   dch->nkeys++;
           }
           if (dch->nkeys == 0)
                   fatal("No host keys found for destination \"%s\"", host);
           free_hostkeys(hostkeys);
           free(os);
           return;
   }
   
   static void
   parse_dest_constraint(const char *s, struct dest_constraint ***dcp,
       size_t *ndcp, char **hostkey_files)
   {
           struct dest_constraint *dc;
           char *os, *cp;
   
           dc = xcalloc(1, sizeof(*dc));
           os = xstrdup(s);
           if ((cp = strchr(os, '>')) == NULL) {
                   /* initial hop; no 'from' hop specified */
                   parse_dest_constraint_hop(os, &dc->to, hostkey_files);
           } else {
                   /* two hops specified */
                   *(cp++) = '\0';
                   parse_dest_constraint_hop(os, &dc->from, hostkey_files);
                   parse_dest_constraint_hop(cp, &dc->to, hostkey_files);
                   if (dc->from.user != NULL) {
                           fatal("Invalid key constraint %s: cannot specify "
                               "user on 'from' host", os);
                   }
           }
           /* XXX eliminate or error on duplicates */
           debug2_f("constraint %zu: %s%s%s (%u keys) > %s%s%s (%u keys)", *ndcp,
               dc->from.user ? dc->from.user : "", dc->from.user ? "@" : "",
               dc->from.hostname ? dc->from.hostname : "(ORIGIN)", dc->from.nkeys,
               dc->to.user ? dc->to.user : "", dc->to.user ? "@" : "",
               dc->to.hostname ? dc->to.hostname : "(ANY)", dc->to.nkeys);
           *dcp = xrecallocarray(*dcp, *ndcp, *ndcp + 1, sizeof(**dcp));
           (*dcp)[(*ndcp)++] = dc;
           free(os);
   }
   
   
   static void
 usage(void)  usage(void)
 {  {
         fprintf(stderr,          fprintf(stderr,
 "usage: ssh-add [-cDdKkLlqvXx] [-E fingerprint_hash] [-S provider] [-t life]\n"  "usage: ssh-add [-cDdKkLlqvXx] [-E fingerprint_hash] [-S provider] [-t life]\n"
   "               [-H hostkey_file] [-h destination]\n"
 #ifdef WITH_XMSS  #ifdef WITH_XMSS
 "               [-M maxsign] [-m minleft]\n"  "               [-M maxsign] [-m minleft]\n"
 #endif  #endif
Line 655 
Line 784 
         extern int optind;          extern int optind;
         int agent_fd;          int agent_fd;
         char *pkcs11provider = NULL, *skprovider = NULL;          char *pkcs11provider = NULL, *skprovider = NULL;
           char **dest_constraint_strings = NULL, **hostkey_files = NULL;
         int r, i, ch, deleting = 0, ret = 0, key_only = 0, do_download = 0;          int r, i, ch, deleting = 0, ret = 0, key_only = 0, do_download = 0;
         int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0;          int xflag = 0, lflag = 0, Dflag = 0, qflag = 0, Tflag = 0;
         SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;          SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
         LogLevel log_level = SYSLOG_LEVEL_INFO;          LogLevel log_level = SYSLOG_LEVEL_INFO;
           struct dest_constraint **dest_constraints = NULL;
           size_t ndest_constraints = 0;
   
         /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */          /* Ensure that fds 0, 1 and 2 are open or directed to /dev/null */
         sanitise_stdfd();          sanitise_stdfd();
Line 685 
Line 817 
   
         skprovider = getenv("SSH_SK_PROVIDER");          skprovider = getenv("SSH_SK_PROVIDER");
   
         while ((ch = getopt(argc, argv, "vkKlLcdDTxXE:e:M:m:qs:S:t:")) != -1) {          while ((ch = getopt(argc, argv, "vkKlLcdDTxXE:e:h:H:M:m:qs:S:t:")) != -1) {
                 switch (ch) {                  switch (ch) {
                 case 'v':                  case 'v':
                         if (log_level == SYSLOG_LEVEL_INFO)                          if (log_level == SYSLOG_LEVEL_INFO)
Line 698 
Line 830 
                         if (fingerprint_hash == -1)                          if (fingerprint_hash == -1)
                                 fatal("Invalid hash algorithm \"%s\"", optarg);                                  fatal("Invalid hash algorithm \"%s\"", optarg);
                         break;                          break;
                   case 'H':
                           stringlist_append(&hostkey_files, optarg);
                           break;
                   case 'h':
                           stringlist_append(&dest_constraint_strings, optarg);
                           break;
                 case 'k':                  case 'k':
                         key_only = 1;                          key_only = 1;
                         break;                          break;
Line 791 
Line 929 
   
         if (skprovider == NULL)          if (skprovider == NULL)
                 skprovider = "internal";                  skprovider = "internal";
           if (hostkey_files == NULL) {
                   /* use defaults from readconf.c */
                   stringlist_append(&hostkey_files, _PATH_SSH_USER_HOSTFILE);
                   stringlist_append(&hostkey_files, _PATH_SSH_USER_HOSTFILE2);
                   stringlist_append(&hostkey_files, _PATH_SSH_SYSTEM_HOSTFILE);
                   stringlist_append(&hostkey_files, _PATH_SSH_SYSTEM_HOSTFILE2);
           }
           if (dest_constraint_strings != NULL) {
                   for (i = 0; dest_constraint_strings[i] != NULL; i++) {
                           parse_dest_constraint(dest_constraint_strings[i],
                             &dest_constraints, &ndest_constraints, hostkey_files);
                   }
           }
   
         argc -= optind;          argc -= optind;
         argv += optind;          argv += optind;
Line 804 
Line 955 
         }          }
         if (pkcs11provider != NULL) {          if (pkcs11provider != NULL) {
                 if (update_card(agent_fd, !deleting, pkcs11provider,                  if (update_card(agent_fd, !deleting, pkcs11provider,
                     qflag) == -1)                      qflag, dest_constraints, ndest_constraints) == -1)
                         ret = 1;                          ret = 1;
                 goto done;                  goto done;
         }          }
         if (do_download) {          if (do_download) {
                 if (skprovider == NULL)                  if (skprovider == NULL)
                         fatal("Cannot download keys without provider");                          fatal("Cannot download keys without provider");
                 if (load_resident_keys(agent_fd, skprovider, qflag) != 0)                  if (load_resident_keys(agent_fd, skprovider, qflag,
                       dest_constraints, ndest_constraints) != 0)
                         ret = 1;                          ret = 1;
                 goto done;                  goto done;
         }          }
Line 834 
Line 986 
                         if (stat(buf, &st) == -1)                          if (stat(buf, &st) == -1)
                                 continue;                                  continue;
                         if (do_file(agent_fd, deleting, key_only, buf,                          if (do_file(agent_fd, deleting, key_only, buf,
                             qflag, skprovider) == -1)                              qflag, skprovider,
                               dest_constraints, ndest_constraints) == -1)
                                 ret = 1;                                  ret = 1;
                         else                          else
                                 count++;                                  count++;
Line 844 
Line 997 
         } else {          } else {
                 for (i = 0; i < argc; i++) {                  for (i = 0; i < argc; i++) {
                         if (do_file(agent_fd, deleting, key_only,                          if (do_file(agent_fd, deleting, key_only,
                             argv[i], qflag, skprovider) == -1)                              argv[i], qflag, skprovider,
                               dest_constraints, ndest_constraints) == -1)
                                 ret = 1;                                  ret = 1;
                 }                  }
         }          }

Legend:
Removed from v.1.161  
changed lines
  Added in v.1.162