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

Diff for /src/usr.bin/ssh/ssh-agent.c between version 1.257 and 1.258

version 1.257, 2020/03/06 18:28:27 version 1.258, 2020/05/26 01:26:58
Line 63 
Line 63 
   
 #include "xmalloc.h"  #include "xmalloc.h"
 #include "ssh.h"  #include "ssh.h"
   #include "ssh2.h"
 #include "sshbuf.h"  #include "sshbuf.h"
 #include "sshkey.h"  #include "sshkey.h"
 #include "authfd.h"  #include "authfd.h"
Line 153 
Line 154 
   
 static int fingerprint_hash = SSH_FP_HASH_DEFAULT;  static int fingerprint_hash = SSH_FP_HASH_DEFAULT;
   
   /* Refuse signing of non-SSH messages for web-origin FIDO keys */
   static int restrict_websafe = 1;
   
 static void  static void
 close_socket(SocketEntry *e)  close_socket(SocketEntry *e)
 {  {
Line 268 
Line 272 
         return NULL;          return NULL;
 }  }
   
   /*
    * This function inspects a message to be signed by a FIDO key that has a
    * web-like application string (i.e. one that does not begin with "ssh:".
    * It checks that the message is one of those expected for SSH operations
    * (pubkey userauth, sshsig, CA key signing) to exclude signing challenges
    * for the web.
    */
   static int
   check_websafe_message_contents(struct sshkey *key,
       const u_char *msg, size_t len)
   {
           int matched = 0;
           struct sshbuf *b;
           u_char m, n;
           char *cp1 = NULL, *cp2 = NULL;
           int r;
           struct sshkey *mkey = NULL;
   
           if ((b = sshbuf_from(msg, len)) == NULL)
                   fatal("%s: sshbuf_new", __func__);
   
           /* SSH userauth request */
           if ((r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* sess_id */
               (r = sshbuf_get_u8(b, &m)) == 0 && /* SSH2_MSG_USERAUTH_REQUEST */
               (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* server user */
               (r = sshbuf_get_cstring(b, &cp1, NULL)) == 0 && /* service */
               (r = sshbuf_get_cstring(b, &cp2, NULL)) == 0 && /* method */
               (r = sshbuf_get_u8(b, &n)) == 0 && /* sig-follows */
               (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* alg */
               (r = sshkey_froms(b, &mkey)) == 0 && /* key */
               sshbuf_len(b) == 0) {
                   debug("%s: parsed userauth", __func__);
                   if (m == SSH2_MSG_USERAUTH_REQUEST && n == 1 &&
                       strcmp(cp1, "ssh-connection") == 0 &&
                       strcmp(cp2, "publickey") == 0 &&
                       sshkey_equal(key, mkey)) {
                           debug("%s: well formed userauth", __func__);
                           matched = 1;
                   }
           }
           free(cp1);
           free(cp2);
           sshkey_free(mkey);
           sshbuf_free(b);
           if (matched)
                   return 1;
   
           if ((b = sshbuf_from(msg, len)) == NULL)
                   fatal("%s: sshbuf_new", __func__);
           cp1 = cp2 = NULL;
           mkey = NULL;
   
           /* SSHSIG */
           if ((r = sshbuf_cmp(b, 0, "SSHSIG", 6)) == 0 &&
               (r = sshbuf_consume(b, 6)) == 0 &&
               (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* namespace */
               (r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* reserved */
               (r = sshbuf_get_cstring(b, NULL, NULL)) == 0 && /* hashalg */
               (r = sshbuf_get_string_direct(b, NULL, NULL)) == 0 && /* H(msg) */
               sshbuf_len(b) == 0) {
                   debug("%s: parsed sshsig", __func__);
                   matched = 1;
           }
   
           sshbuf_free(b);
           if (matched)
                   return 1;
   
           /* XXX CA signature operation */
   
           error("web-origin key attempting to sign non-SSH message");
           return 0;
   }
   
 /* ssh2 only */  /* ssh2 only */
 static void  static void
 process_sign_request2(SocketEntry *e)  process_sign_request2(SocketEntry *e)
Line 300 
Line 378 
                 verbose("%s: user refused key", __func__);                  verbose("%s: user refused key", __func__);
                 goto send;                  goto send;
         }          }
         if (sshkey_is_sk(id->key) &&          if (sshkey_is_sk(id->key)) {
             (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {                  if (strncmp(id->key->sk_application, "ssh:", 4) != 0 &&
                 if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,                      !check_websafe_message_contents(key, data, dlen)) {
                     SSH_FP_DEFAULT)) == NULL)                          /* error already logged */
                         fatal("%s: fingerprint failed", __func__);                          goto send;
                 notifier = notify_start(0,                  }
                     "Confirm user presence for key %s %s",                  if ((id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
                     sshkey_type(id->key), fp);                          if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
                               SSH_FP_DEFAULT)) == NULL)
                                   fatal("%s: fingerprint failed", __func__);
                           notifier = notify_start(0,
                               "Confirm user presence for key %s %s",
                               sshkey_type(id->key), fp);
                   }
         }          }
         if ((r = sshkey_sign(id->key, &signature, &slen,          if ((r = sshkey_sign(id->key, &signature, &slen,
             data, dlen, agent_decode_alg(key, flags),              data, dlen, agent_decode_alg(key, flags),
Line 1193 
Line 1277 
         OpenSSL_add_all_algorithms();          OpenSSL_add_all_algorithms();
 #endif  #endif
   
         while ((ch = getopt(ac, av, "cDdksE:a:P:t:")) != -1) {          while ((ch = getopt(ac, av, "cDdksE:a:O:P:t:")) != -1) {
                 switch (ch) {                  switch (ch) {
                 case 'E':                  case 'E':
                         fingerprint_hash = ssh_digest_alg_by_name(optarg);                          fingerprint_hash = ssh_digest_alg_by_name(optarg);
Line 1207 
Line 1291 
                         break;                          break;
                 case 'k':                  case 'k':
                         k_flag++;                          k_flag++;
                           break;
                   case 'O':
                           if (strcmp(optarg, "no-restrict-websafe") == 0)
                                   restrict_websafe  = 0;
                           else
                                   fatal("Unknown -O option");
                         break;                          break;
                 case 'P':                  case 'P':
                         if (provider_whitelist != NULL)                          if (provider_whitelist != NULL)

Legend:
Removed from v.1.257  
changed lines
  Added in v.1.258