=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/ssh/ssh-agent.c,v retrieving revision 1.250 retrieving revision 1.251 diff -u -r1.250 -r1.251 --- src/usr.bin/ssh/ssh-agent.c 2019/11/19 16:02:32 1.250 +++ src/usr.bin/ssh/ssh-agent.c 2019/12/13 19:09:10 1.251 @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh-agent.c,v 1.250 2019/11/19 16:02:32 jmc Exp $ */ +/* $OpenBSD: ssh-agent.c,v 1.251 2019/12/13 19:09:10 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -76,7 +76,7 @@ #include "ssherr.h" #include "pathnames.h" #include "ssh-pkcs11.h" -#include "ssh-sk.h" +#include "sk-api.h" #ifndef DEFAULT_PROVIDER_WHITELIST # define DEFAULT_PROVIDER_WHITELIST "/usr/lib*/*,/usr/local/lib*/*" @@ -268,130 +268,6 @@ 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 */ static void process_sign_request2(SocketEntry *e) @@ -401,9 +277,11 @@ size_t dlen, slen = 0; u_int compat = 0, flags; int r, ok = -1; + char *fp = NULL; struct sshbuf *msg; struct sshkey *key = NULL; struct identity *id; + struct notifier_ctx *notifier = NULL; if ((msg = sshbuf_new()) == NULL) fatal("%s: sshbuf_new failed", __func__); @@ -422,25 +300,27 @@ verbose("%s: user refused key", __func__); goto send; } - if (id->sk_provider != NULL) { - if ((r = provider_sign(id->sk_provider, id->key, &signature, - &slen, data, dlen, agent_decode_alg(key, flags), - compat)) != 0) { - error("%s: sign: %s", __func__, ssh_err(r)); - goto send; - } - } else { - 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 (sshkey_is_sk(id->key) && + (id->key->sk_flags & SSH_SK_USER_PRESENCE_REQD)) { + 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, + data, dlen, agent_decode_alg(key, flags), + id->sk_provider, compat)) != 0) { + error("%s: sshkey_sign: %s", __func__, ssh_err(r)); + goto send; + } /* Success */ ok = 0; send: + notify_complete(notifier); sshkey_free(key); + free(fp); if (ok == 0) { if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 || (r = sshbuf_put_string(msg, signature, slen)) != 0)