[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.250 and 1.251

version 1.250, 2019/11/19 16:02:32 version 1.251, 2019/12/13 19:09:10
Line 76 
Line 76 
 #include "ssherr.h"  #include "ssherr.h"
 #include "pathnames.h"  #include "pathnames.h"
 #include "ssh-pkcs11.h"  #include "ssh-pkcs11.h"
 #include "ssh-sk.h"  #include "sk-api.h"
   
 #ifndef DEFAULT_PROVIDER_WHITELIST  #ifndef DEFAULT_PROVIDER_WHITELIST
 # define DEFAULT_PROVIDER_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"  # define DEFAULT_PROVIDER_WHITELIST "/usr/lib*/*,/usr/local/lib*/*"
Line 268 
Line 268 
         return NULL;          return NULL;
 }  }
   
 static int  
 provider_sign(const char *provider, struct sshkey *key,  
     u_char **sigp, size_t *lenp,  
     const u_char *data, size_t datalen,  
     const char *alg, u_int compat)  
 {  
         int status, pair[2], r = SSH_ERR_INTERNAL_ERROR;  
         pid_t pid;  
         char *helper, *verbosity = NULL, *fp = NULL;  
         struct sshbuf *kbuf, *req, *resp;  
         u_char version;  
         struct notifier_ctx *notifier = NULL;  
   
         debug3("%s: start for provider %s", __func__, provider);  
   
         *sigp = NULL;  
         *lenp = 0;  
   
         helper = getenv("SSH_SK_HELPER");  
         if (helper == NULL || strlen(helper) == 0)  
                 helper = _PATH_SSH_SK_HELPER;  
         if (log_level_get() >= SYSLOG_LEVEL_DEBUG1)  
                 verbosity = "-vvv";  
   
         /* Start helper */  
         if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) {  
                 error("socketpair: %s", strerror(errno));  
                 return SSH_ERR_SYSTEM_ERROR;  
         }  
         if ((pid = fork()) == -1) {  
                 error("fork: %s", strerror(errno));  
                 close(pair[0]);  
                 close(pair[1]);  
                 return SSH_ERR_SYSTEM_ERROR;  
         }  
         if (pid == 0) {  
                 if ((dup2(pair[1], STDIN_FILENO) == -1) ||  
                     (dup2(pair[1], STDOUT_FILENO) == -1))  
                         fatal("%s: dup2: %s", __func__, ssh_err(r));  
                 close(pair[0]);  
                 close(pair[1]);  
                 closefrom(STDERR_FILENO + 1);  
                 debug("%s: starting %s %s", __func__, helper,  
                     verbosity == NULL ? "" : verbosity);  
                 execlp(helper, helper, verbosity, (char *)NULL);  
                 fatal("%s: execlp: %s", __func__, strerror(errno));  
         }  
         close(pair[1]);  
   
         if ((kbuf = sshbuf_new()) == NULL ||  
             (req = sshbuf_new()) == NULL ||  
             (resp = sshbuf_new()) == NULL)  
                 fatal("%s: sshbuf_new failed", __func__);  
   
         if ((r = sshkey_private_serialize(key, kbuf)) != 0 ||  
             (r = sshbuf_put_stringb(req, kbuf)) != 0 ||  
             (r = sshbuf_put_cstring(req, provider)) != 0 ||  
             (r = sshbuf_put_string(req, data, datalen)) != 0 ||  
             (r = sshbuf_put_u32(req, compat)) != 0)  
                 fatal("%s: compose: %s", __func__, ssh_err(r));  
   
         if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,  
             SSH_FP_DEFAULT)) == NULL)  
                 fatal("%s: sshkey_fingerprint failed", __func__);  
         notifier = notify_start(0,  
             "Confirm user presence for key %s %s", sshkey_type(key), fp);  
   
         if ((r = ssh_msg_send(pair[0], SSH_SK_HELPER_VERSION, req)) != 0) {  
                 error("%s: send: %s", __func__, ssh_err(r));  
                 goto out;  
         }  
         if ((r = ssh_msg_recv(pair[0], resp)) != 0) {  
                 error("%s: receive: %s", __func__, ssh_err(r));  
                 goto out;  
         }  
         if ((r = sshbuf_get_u8(resp, &version)) != 0) {  
                 error("%s: parse version: %s", __func__, ssh_err(r));  
                 goto out;  
         }  
         if (version != SSH_SK_HELPER_VERSION) {  
                 error("%s: unsupported version: got %u, expected %u",  
                     __func__, version, SSH_SK_HELPER_VERSION);  
                 r = SSH_ERR_INVALID_FORMAT;  
                 goto out;  
         }  
         if ((r = sshbuf_get_string(resp, sigp, lenp)) != 0) {  
                 error("%s: parse signature: %s", __func__, ssh_err(r));  
                 r = SSH_ERR_INVALID_FORMAT;  
                 goto out;  
         }  
         if (sshbuf_len(resp) != 0) {  
                 error("%s: trailing data in response", __func__);  
                 r = SSH_ERR_INVALID_FORMAT;  
                 goto out;  
         }  
         /* success */  
         r = 0;  
  out:  
         while (waitpid(pid, &status, 0) == -1) {  
                 if (errno != EINTR)  
                         fatal("%s: waitpid: %s", __func__, ssh_err(r));  
         }  
         notify_complete(notifier);  
         if (!WIFEXITED(status)) {  
                 error("%s: helper %s exited abnormally", __func__, helper);  
                 if (r == 0)  
                         r = SSH_ERR_SYSTEM_ERROR;  
         } else if (WEXITSTATUS(status) != 0) {  
                 error("%s: helper %s exited with non-zero exit status",  
                     __func__, helper);  
                 if (r == 0)  
                         r = SSH_ERR_SYSTEM_ERROR;  
         }  
         if (r != 0) {  
                 freezero(*sigp, *lenp);  
                 *sigp = NULL;  
                 *lenp = 0;  
         }  
         sshbuf_free(kbuf);  
         sshbuf_free(req);  
         sshbuf_free(resp);  
         return r;  
 }  
   
 /* ssh2 only */  /* ssh2 only */
 static void  static void
 process_sign_request2(SocketEntry *e)  process_sign_request2(SocketEntry *e)
Line 401 
Line 277 
         size_t dlen, slen = 0;          size_t dlen, slen = 0;
         u_int compat = 0, flags;          u_int compat = 0, flags;
         int r, ok = -1;          int r, ok = -1;
           char *fp = NULL;
         struct sshbuf *msg;          struct sshbuf *msg;
         struct sshkey *key = NULL;          struct sshkey *key = NULL;
         struct identity *id;          struct identity *id;
           struct notifier_ctx *notifier = NULL;
   
         if ((msg = sshbuf_new()) == NULL)          if ((msg = sshbuf_new()) == NULL)
                 fatal("%s: sshbuf_new failed", __func__);                  fatal("%s: sshbuf_new failed", __func__);
Line 422 
Line 300 
                 verbose("%s: user refused key", __func__);                  verbose("%s: user refused key", __func__);
                 goto send;                  goto send;
         }          }
         if (id->sk_provider != NULL) {          if (sshkey_is_sk(id->key) &&
                 if ((r = provider_sign(id->sk_provider, id->key, &signature,              (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) {
                     &slen, data, dlen, agent_decode_alg(key, flags),                  if ((fp = sshkey_fingerprint(key, SSH_FP_HASH_DEFAULT,
                     compat)) != 0) {                      SSH_FP_DEFAULT)) == NULL)
                         error("%s: sign: %s", __func__, ssh_err(r));                          fatal("%s: fingerprint failed", __func__);
                         goto send;                  notifier = notify_start(0,
                 }                      "Confirm user presence for key %s %s",
         } else {                      sshkey_type(id->key), fp);
                 if ((r = sshkey_sign(id->key, &signature, &slen,  
                     data, dlen, agent_decode_alg(key, flags),  
                     NULL, compat)) != 0) {  
                         error("%s: sshkey_sign: %s", __func__, ssh_err(r));  
                         goto send;  
                 }  
         }          }
           if ((r = sshkey_sign(id->key, &signature, &slen,
               data, dlen, agent_decode_alg(key, flags),
               id->sk_provider, compat)) != 0) {
                   error("%s: sshkey_sign: %s", __func__, ssh_err(r));
                   goto send;
           }
         /* Success */          /* Success */
         ok = 0;          ok = 0;
  send:   send:
           notify_complete(notifier);
         sshkey_free(key);          sshkey_free(key);
           free(fp);
         if (ok == 0) {          if (ok == 0) {
                 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||                  if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
                     (r = sshbuf_put_string(msg, signature, slen)) != 0)                      (r = sshbuf_put_string(msg, signature, slen)) != 0)

Legend:
Removed from v.1.250  
changed lines
  Added in v.1.251