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

Diff for /src/usr.bin/ssh/ssh-keyscan.c between version 1.94 and 1.95

version 1.94, 2015/01/19 20:16:15 version 1.95, 2015/01/19 20:32:39
Line 18 
Line 18 
   
 #include <errno.h>  #include <errno.h>
 #include <netdb.h>  #include <netdb.h>
 #include <setjmp.h>  
 #include <stdarg.h>  #include <stdarg.h>
 #include <stdio.h>  #include <stdio.h>
 #include <stdlib.h>  #include <stdlib.h>
Line 29 
Line 28 
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "ssh.h"  #include "ssh.h"
 #include "ssh1.h"  #include "ssh1.h"
 #include "buffer.h"  #include "sshbuf.h"
 #include "key.h"  #include "sshkey.h"
 #include "cipher.h"  #include "cipher.h"
 #include "kex.h"  #include "kex.h"
 #include "compat.h"  #include "compat.h"
Line 41 
Line 40 
 #include "atomicio.h"  #include "atomicio.h"
 #include "misc.h"  #include "misc.h"
 #include "hostfile.h"  #include "hostfile.h"
   #include "ssherr.h"
   #include "ssh_api.h"
   
 /* Flag indicating whether IPv4 or IPv6.  This can be set on the command line.  /* Flag indicating whether IPv4 or IPv6.  This can be set on the command line.
    Default value is AF_UNSPEC means both IPv4 and IPv6. */     Default value is AF_UNSPEC means both IPv4 and IPv6. */
Line 70 
Line 71 
 fd_set *read_wait;  fd_set *read_wait;
 size_t read_wait_nfdset;  size_t read_wait_nfdset;
 int ncon;  int ncon;
 int nonfatal_fatal = 0;  
 jmp_buf kexjmp;  
 Key *kexjmp_key;  
   
 /*  /*
  * Keep a connection structure for each file descriptor.  The state   * Keep a connection structure for each file descriptor.  The state
Line 89 
Line 87 
         int c_len;              /* Total bytes which must be read. */          int c_len;              /* Total bytes which must be read. */
         int c_off;              /* Length of data read so far. */          int c_off;              /* Length of data read so far. */
         int c_keytype;          /* Only one of KT_RSA1, KT_DSA, or KT_RSA */          int c_keytype;          /* Only one of KT_RSA1, KT_DSA, or KT_RSA */
           int c_done;             /* SSH2 done */
         char *c_namebase;       /* Address to free for c_name and c_namelist */          char *c_namebase;       /* Address to free for c_name and c_namelist */
         char *c_name;           /* Hostname of connection for errors */          char *c_name;           /* Hostname of connection for errors */
         char *c_namelist;       /* Pointer to other possible addresses */          char *c_namelist;       /* Pointer to other possible addresses */
         char *c_output_name;    /* Hostname of connection for output */          char *c_output_name;    /* Hostname of connection for output */
         char *c_data;           /* Data read from this fd */          char *c_data;           /* Data read from this fd */
         struct kex *c_kex;      /* The key-exchange struct for ssh2 */          struct ssh *c_ssh;      /* SSH-connection */
         struct timeval c_tv;    /* Time at which connection gets aborted */          struct timeval c_tv;    /* Time at which connection gets aborted */
         TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */          TAILQ_ENTRY(Connection) c_link; /* List of connections in timeout order. */
 } con;  } con;
Line 102 
Line 101 
 TAILQ_HEAD(conlist, Connection) tq;     /* Timeout Queue */  TAILQ_HEAD(conlist, Connection) tq;     /* Timeout Queue */
 con *fdcon;  con *fdcon;
   
   static void keyprint(con *c, struct sshkey *key);
   
 static int  static int
 fdlim_get(int hard)  fdlim_get(int hard)
 {  {
Line 169 
Line 170 
 }  }
   
 #ifdef WITH_SSH1  #ifdef WITH_SSH1
 static Key *  static struct sshkey *
 keygrab_ssh1(con *c)  keygrab_ssh1(con *c)
 {  {
         static Key *rsa;          static struct sshkey *rsa;
         static Buffer msg;          static struct sshbuf *msg;
           int r;
           u_char type;
   
         if (rsa == NULL) {          if (rsa == NULL) {
                 buffer_init(&msg);                  if ((rsa = sshkey_new(KEY_RSA1)) == NULL) {
                 rsa = key_new(KEY_RSA1);                          error("%s: sshkey_new failed", __func__);
                           return NULL;
                   }
                   if ((msg = sshbuf_new()) == NULL)
                           fatal("%s: sshbuf_new failed", __func__);
         }          }
         buffer_append(&msg, c->c_data, c->c_plen);          if ((r = sshbuf_put(msg, c->c_data, c->c_plen)) != 0 ||
         buffer_consume(&msg, 8 - (c->c_plen & 7));      /* padding */              (r = sshbuf_consume(msg, 8 - (c->c_plen & 7))) != 0 || /* padding */
         if (buffer_get_char(&msg) != (int) SSH_SMSG_PUBLIC_KEY) {              (r = sshbuf_get_u8(msg, &type)) != 0)
                   goto buf_err;
           if (type != (int) SSH_SMSG_PUBLIC_KEY) {
                 error("%s: invalid packet type", c->c_name);                  error("%s: invalid packet type", c->c_name);
                 buffer_clear(&msg);                  sshbuf_reset(msg);
                 return NULL;                  return NULL;
         }          }
         buffer_consume(&msg, 8);                /* cookie */          if ((r = sshbuf_consume(msg, 8)) != 0 || /* cookie */
               /* server key */
               (r = sshbuf_get_u32(msg, NULL)) != 0 ||
               (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
               (r = sshbuf_get_bignum1(msg, NULL)) != 0 ||
               /* host key */
               (r = sshbuf_get_u32(msg, NULL)) != 0 ||
               (r = sshbuf_get_bignum1(msg, rsa->rsa->e)) != 0 ||
               (r = sshbuf_get_bignum1(msg, rsa->rsa->n)) != 0) {
    buf_err:
                   error("%s: buffer error: %s", __func__, ssh_err(r));
                   sshbuf_reset(msg);
                   return NULL;
           }
   
         /* server key */          sshbuf_reset(msg);
         (void) buffer_get_int(&msg);  
         buffer_get_bignum(&msg, rsa->rsa->e);  
         buffer_get_bignum(&msg, rsa->rsa->n);  
   
         /* host key */  
         (void) buffer_get_int(&msg);  
         buffer_get_bignum(&msg, rsa->rsa->e);  
         buffer_get_bignum(&msg, rsa->rsa->n);  
   
         buffer_clear(&msg);  
   
         return (rsa);          return (rsa);
 }  }
 #endif  #endif
   
 static int  static int
 hostjump(Key *hostkey, struct ssh *ssh)  key_print_wrapper(struct sshkey *hostkey, struct ssh *ssh)
 {  {
         kexjmp_key = hostkey;          con *c;
         longjmp(kexjmp, 1);  
           if ((c = ssh_get_app_data(ssh)) != NULL)
                   keyprint(c, hostkey);
           /* always abort key exchange */
           return -1;
 }  }
   
 static int  static int
Line 227 
Line 243 
         return 0;          return 0;
 }  }
   
 static Key *  static void
 keygrab_ssh2(con *c)  keygrab_ssh2(con *c)
 {  {
         char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };          char *myproposal[PROPOSAL_MAX] = { KEX_CLIENT };
         int r, j;          int r;
   
         packet_set_connection(c->c_fd, c->c_fd);  
         enable_compat20();          enable_compat20();
         myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =          myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] =
             c->c_keytype == KT_DSA ?  "ssh-dss" :              c->c_keytype == KT_DSA ?  "ssh-dss" :
             (c->c_keytype == KT_RSA ? "ssh-rsa" :              (c->c_keytype == KT_RSA ? "ssh-rsa" :
             (c->c_keytype == KT_ED25519 ? "ssh-ed25519" :              (c->c_keytype == KT_ED25519 ? "ssh-ed25519" :
             "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521"));              "ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521"));
         if ((r = kex_setup(active_state, myproposal)) < 0)          if ((r = kex_setup(c->c_ssh, myproposal)) != 0) {
                 fatal("%s: kex_setup: %s", __func__, ssh_err(r));                  free(c->c_ssh);
         c->c_kex = active_state->kex;                  fprintf(stderr, "kex_setup: %s\n", ssh_err(r));
 #ifdef WITH_OPENSSL  
         c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;  
         c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;  
         c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;  
         c->c_kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;  
         c->c_kex->kex[KEX_ECDH_SHA2] = kexecdh_client;  
 #endif  
         c->c_kex->kex[KEX_C25519_SHA256] = kexc25519_client;  
         c->c_kex->verify_host_key = hostjump;  
   
         if (!(j = setjmp(kexjmp))) {  
                 nonfatal_fatal = 1;  
                 dispatch_run(DISPATCH_BLOCK, &c->c_kex->done, active_state);  
                 fprintf(stderr, "Impossible! dispatch_run() returned!\n");  
                 exit(1);                  exit(1);
         }          }
         nonfatal_fatal = 0;  #ifdef WITH_OPENSSL
         free(c->c_kex);          c->c_ssh->kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
         c->c_kex = NULL;          c->c_ssh->kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
         packet_close();          c->c_ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
           c->c_ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
         return j < 0? NULL : kexjmp_key;          c->c_ssh->kex->kex[KEX_ECDH_SHA2] = kexecdh_client;
   #endif
           c->c_ssh->kex->kex[KEX_C25519_SHA256] = kexc25519_client;
           ssh_set_verify_host_key_callback(c->c_ssh, key_print_wrapper);
           /*
            * do the key-exchange until an error occurs or until
            * the key_print_wrapper() callback sets c_done.
            */
           ssh_dispatch_run(c->c_ssh, DISPATCH_BLOCK, &c->c_done, c->c_ssh);
 }  }
   
 static void  static void
 keyprint(con *c, Key *key)  keyprint(con *c, struct sshkey *key)
 {  {
         char *host = c->c_output_name ? c->c_output_name : c->c_name;          char *host = c->c_output_name ? c->c_output_name : c->c_name;
   
Line 278 
Line 287 
                 fatal("host_hash failed");                  fatal("host_hash failed");
   
         fprintf(stdout, "%s ", host);          fprintf(stdout, "%s ", host);
         key_write(key, stdout);          sshkey_write(key, stdout);
         fputs("\n", stdout);          fputs("\n", stdout);
 }  }
   
Line 366 
Line 375 
                 free(fdcon[s].c_data);                  free(fdcon[s].c_data);
         fdcon[s].c_status = CS_UNUSED;          fdcon[s].c_status = CS_UNUSED;
         fdcon[s].c_keytype = 0;          fdcon[s].c_keytype = 0;
           if (fdcon[s].c_ssh) {
                   ssh_packet_close(fdcon[s].c_ssh);
                   free(fdcon[s].c_ssh);
                   fdcon[s].c_ssh = NULL;
           }
         TAILQ_REMOVE(&tq, &fdcon[s], c_link);          TAILQ_REMOVE(&tq, &fdcon[s], c_link);
         FD_CLR(s, read_wait);          FD_CLR(s, read_wait);
         ncon--;          ncon--;
Line 433 
Line 447 
                 return;                  return;
         }          }
         *cp = '\0';          *cp = '\0';
           c->c_ssh = ssh_packet_set_connection(NULL, s, s);
           ssh_set_app_data(c->c_ssh, c);  /* back link */
         if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",          if (sscanf(buf, "SSH-%d.%d-%[^\n]\n",
             &remote_major, &remote_minor, remote_version) == 3)              &remote_major, &remote_minor, remote_version) == 3)
                 compat_datafellows(remote_version);                  c->c_ssh->compat = compat_datafellows(remote_version);
         else          else
                 datafellows = 0;                  c->c_ssh->compat = 0;
         if (c->c_keytype != KT_RSA1) {          if (c->c_keytype != KT_RSA1) {
                 if (!ssh2_capable(remote_major, remote_minor)) {                  if (!ssh2_capable(remote_major, remote_minor)) {
                         debug("%s doesn't support ssh2", c->c_name);                          debug("%s doesn't support ssh2", c->c_name);
Line 464 
Line 480 
                 return;                  return;
         }          }
         if (c->c_keytype != KT_RSA1) {          if (c->c_keytype != KT_RSA1) {
                 keyprint(c, keygrab_ssh2(c));                  keygrab_ssh2(c);
                 confree(s);                  confree(s);
                 return;                  return;
         }          }
Line 590 
Line 606 
         va_start(args, fmt);          va_start(args, fmt);
         do_log(SYSLOG_LEVEL_FATAL, fmt, args);          do_log(SYSLOG_LEVEL_FATAL, fmt, args);
         va_end(args);          va_end(args);
         if (nonfatal_fatal)          exit(255);
                 longjmp(kexjmp, -1);  
         else  
                 exit(255);  
 }  }
   
 static void  static void
Line 664 
Line 677 
                         get_keytypes = 0;                          get_keytypes = 0;
                         tname = strtok(optarg, ",");                          tname = strtok(optarg, ",");
                         while (tname) {                          while (tname) {
                                 int type = key_type_from_name(tname);                                  int type = sshkey_type_from_name(tname);
                                 switch (type) {                                  switch (type) {
                                 case KEY_RSA1:                                  case KEY_RSA1:
                                         get_keytypes |= KT_RSA1;                                          get_keytypes |= KT_RSA1;

Legend:
Removed from v.1.94  
changed lines
  Added in v.1.95