summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjcs@openbsd.org <jcs@openbsd.org>2015-11-15 22:26:49 +0000
committerDamien Miller <djm@mindrot.org>2015-11-16 11:31:39 +1100
commitf361df474c49a097bfcf16d1b7b5c36fcd844b4b (patch)
tree493beb15e73f9b57f42244e8c927bdf75480188f
parentd87063d9baf5479b6e813d47dfb694a97df6f6f5 (diff)
upstream commit
Add an AddKeysToAgent client option which can be set to 'yes', 'no', 'ask', or 'confirm', and defaults to 'no'. When enabled, a private key that is used during authentication will be added to ssh-agent if it is running (with confirmation enabled if set to 'confirm'). Initial version from Joachim Schipper many years ago. ok markus@ Upstream-ID: a680db2248e8064ec55f8be72d539458c987d5f4
-rw-r--r--readconf.c22
-rw-r--r--readconf.h4
-rw-r--r--ssh-agent.111
-rw-r--r--ssh.19
-rw-r--r--ssh_config.537
-rw-r--r--sshconnect.c30
-rw-r--r--sshconnect.h4
-rw-r--r--sshconnect1.c15
-rw-r--r--sshconnect2.c35
9 files changed, 137 insertions, 30 deletions
diff --git a/readconf.c b/readconf.c
index c062433ce..0a380913f 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.245 2015/10/27 08:54:52 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.246 2015/11/15 22:26:49 jcs Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -135,7 +135,7 @@ typedef enum {
135 oPasswordAuthentication, oRSAAuthentication, 135 oPasswordAuthentication, oRSAAuthentication,
136 oChallengeResponseAuthentication, oXAuthLocation, 136 oChallengeResponseAuthentication, oXAuthLocation,
137 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 137 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
138 oCertificateFile, 138 oCertificateFile, oAddKeysToAgent,
139 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 139 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
140 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 140 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
141 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 141 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
@@ -204,6 +204,7 @@ static struct {
204 { "identityfile2", oIdentityFile }, /* obsolete */ 204 { "identityfile2", oIdentityFile }, /* obsolete */
205 { "identitiesonly", oIdentitiesOnly }, 205 { "identitiesonly", oIdentitiesOnly },
206 { "certificatefile", oCertificateFile }, 206 { "certificatefile", oCertificateFile },
207 { "addkeystoagent", oAddKeysToAgent },
207 { "hostname", oHostName }, 208 { "hostname", oHostName },
208 { "hostkeyalias", oHostKeyAlias }, 209 { "hostkeyalias", oHostKeyAlias },
209 { "proxycommand", oProxyCommand }, 210 { "proxycommand", oProxyCommand },
@@ -712,6 +713,15 @@ static const struct multistate multistate_yesnoask[] = {
712 { "ask", 2 }, 713 { "ask", 2 },
713 { NULL, -1 } 714 { NULL, -1 }
714}; 715};
716static const struct multistate multistate_yesnoaskconfirm[] = {
717 { "true", 1 },
718 { "false", 0 },
719 { "yes", 1 },
720 { "no", 0 },
721 { "ask", 2 },
722 { "confirm", 3 },
723 { NULL, -1 }
724};
715static const struct multistate multistate_addressfamily[] = { 725static const struct multistate multistate_addressfamily[] = {
716 { "inet", AF_INET }, 726 { "inet", AF_INET },
717 { "inet6", AF_INET6 }, 727 { "inet6", AF_INET6 },
@@ -1533,6 +1543,11 @@ parse_keytypes:
1533 charptr = &options->pubkey_key_types; 1543 charptr = &options->pubkey_key_types;
1534 goto parse_keytypes; 1544 goto parse_keytypes;
1535 1545
1546 case oAddKeysToAgent:
1547 intptr = &options->add_keys_to_agent;
1548 multistate_ptr = multistate_yesnoaskconfirm;
1549 goto parse_multistate;
1550
1536 case oDeprecated: 1551 case oDeprecated:
1537 debug("%s line %d: Deprecated option \"%s\"", 1552 debug("%s line %d: Deprecated option \"%s\"",
1538 filename, linenum, keyword); 1553 filename, linenum, keyword);
@@ -1699,6 +1714,7 @@ initialize_options(Options * options)
1699 options->local_command = NULL; 1714 options->local_command = NULL;
1700 options->permit_local_command = -1; 1715 options->permit_local_command = -1;
1701 options->use_roaming = -1; 1716 options->use_roaming = -1;
1717 options->add_keys_to_agent = -1;
1702 options->visual_host_key = -1; 1718 options->visual_host_key = -1;
1703 options->ip_qos_interactive = -1; 1719 options->ip_qos_interactive = -1;
1704 options->ip_qos_bulk = -1; 1720 options->ip_qos_bulk = -1;
@@ -1803,6 +1819,8 @@ fill_default_options(Options * options)
1803 /* options->hostkeyalgorithms, default set in myproposals.h */ 1819 /* options->hostkeyalgorithms, default set in myproposals.h */
1804 if (options->protocol == SSH_PROTO_UNKNOWN) 1820 if (options->protocol == SSH_PROTO_UNKNOWN)
1805 options->protocol = SSH_PROTO_2; 1821 options->protocol = SSH_PROTO_2;
1822 if (options->add_keys_to_agent == -1)
1823 options->add_keys_to_agent = 0;
1806 if (options->num_identity_files == 0) { 1824 if (options->num_identity_files == 0) {
1807 if (options->protocol & SSH_PROTO_1) { 1825 if (options->protocol & SSH_PROTO_1) {
1808 add_identity_file(options, "~/", 1826 add_identity_file(options, "~/",
diff --git a/readconf.h b/readconf.h
index 6d6927f06..2034bfd9d 100644
--- a/readconf.h
+++ b/readconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.h,v 1.111 2015/09/24 06:15:11 djm Exp $ */ 1/* $OpenBSD: readconf.h,v 1.112 2015/11/15 22:26:49 jcs Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -100,6 +100,8 @@ typedef struct {
100 int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES]; 100 int certificate_file_userprovided[SSH_MAX_CERTIFICATE_FILES];
101 struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES]; 101 struct sshkey *certificates[SSH_MAX_CERTIFICATE_FILES];
102 102
103 int add_keys_to_agent;
104
103 /* Local TCP/IP forward requests. */ 105 /* Local TCP/IP forward requests. */
104 int num_local_forwards; 106 int num_local_forwards;
105 struct Forward *local_forwards; 107 struct Forward *local_forwards;
diff --git a/ssh-agent.1 b/ssh-agent.1
index 5a521cb56..dabc5c46b 100644
--- a/ssh-agent.1
+++ b/ssh-agent.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: ssh-agent.1,v 1.60 2015/11/05 09:48:05 jmc Exp $ 1.\" $OpenBSD: ssh-agent.1,v 1.61 2015/11/15 22:26:49 jcs Exp $
2.\" 2.\"
3.\" Author: Tatu Ylonen <ylo@cs.hut.fi> 3.\" Author: Tatu Ylonen <ylo@cs.hut.fi>
4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4.\" Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -34,7 +34,7 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.Dd $Mdocdate: November 5 2015 $ 37.Dd $Mdocdate: November 15 2015 $
38.Dt SSH-AGENT 1 38.Dt SSH-AGENT 1
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -66,6 +66,13 @@ machines using
66.Pp 66.Pp
67The agent initially does not have any private keys. 67The agent initially does not have any private keys.
68Keys are added using 68Keys are added using
69.Xr ssh 1
70(see
71.Cm AddKeysToAgent
72in
73.Xr ssh_config 5
74for details)
75or
69.Xr ssh-add 1 . 76.Xr ssh-add 1 .
70Multiple identities may be stored in 77Multiple identities may be stored in
71.Nm 78.Nm
diff --git a/ssh.1 b/ssh.1
index c4b7250a5..5b35b6cc0 100644
--- a/ssh.1
+++ b/ssh.1
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh.1,v 1.365 2015/11/06 00:31:41 mmcc Exp $ 36.\" $OpenBSD: ssh.1,v 1.366 2015/11/15 22:26:49 jcs Exp $
37.Dd $Mdocdate: November 6 2015 $ 37.Dd $Mdocdate: November 15 2015 $
38.Dt SSH 1 38.Dt SSH 1
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -462,6 +462,7 @@ For full details of the options listed below, and their possible values, see
462.Xr ssh_config 5 . 462.Xr ssh_config 5 .
463.Pp 463.Pp
464.Bl -tag -width Ds -offset indent -compact 464.Bl -tag -width Ds -offset indent -compact
465.It AddKeysToAgent
465.It AddressFamily 466.It AddressFamily
466.It BatchMode 467.It BatchMode
467.It BindAddress 468.It BindAddress
@@ -926,6 +927,10 @@ The most convenient way to use public key or certificate authentication
926may be with an authentication agent. 927may be with an authentication agent.
927See 928See
928.Xr ssh-agent 1 929.Xr ssh-agent 1
930and (optionally) the
931.Cm AddKeysToAgent
932directive in
933.Xr ssh_config 5
929for more information. 934for more information.
930.Pp 935.Pp
931Challenge-response authentication works as follows: 936Challenge-response authentication works as follows:
diff --git a/ssh_config.5 b/ssh_config.5
index 39cf932d3..e6673b103 100644
--- a/ssh_config.5
+++ b/ssh_config.5
@@ -33,8 +33,8 @@
33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 33.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 34.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35.\" 35.\"
36.\" $OpenBSD: ssh_config.5,v 1.221 2015/09/24 06:15:11 djm Exp $ 36.\" $OpenBSD: ssh_config.5,v 1.222 2015/11/15 22:26:49 jcs Exp $
37.Dd $Mdocdate: September 24 2015 $ 37.Dd $Mdocdate: November 15 2015 $
38.Dt SSH_CONFIG 5 38.Dt SSH_CONFIG 5
39.Os 39.Os
40.Sh NAME 40.Sh NAME
@@ -221,6 +221,39 @@ keyword matches against the name of the local user running
221(this keyword may be useful in system-wide 221(this keyword may be useful in system-wide
222.Nm 222.Nm
223files). 223files).
224.It Cm AddKeysToAgent
225Specifies whether keys should be automatically added to a running
226.Xr ssh-agent 5 .
227If this option is set to
228.Dq yes
229and a key is loaded from a file, the key and its passphrase are added to
230the agent with the default lifetime, as if by
231.Xr ssh-add 1 .
232If this option is set to
233.Dq ask ,
234.Nm ssh
235will require confirmation using the
236.Ev SSH_ASKPASS
237program before adding a key (see
238.Xr ssh-add 1
239for details).
240If this option is set to
241.Dq confirm ,
242each use of the key must be confirmed, as if the
243.Fl c
244option was specified to
245.Xr ssh-add 1 .
246If this option is set to
247.Dq no ,
248no keys are added to the agent.
249The argument must be
250.Dq yes ,
251.Dq confirm ,
252.Dq ask ,
253or
254.Dq no .
255The default is
256.Dq no .
224.It Cm AddressFamily 257.It Cm AddressFamily
225Specifies which address family to use when connecting. 258Specifies which address family to use when connecting.
226Valid arguments are 259Valid arguments are
diff --git a/sshconnect.c b/sshconnect.c
index c9f88e035..19d393f7b 100644
--- a/sshconnect.c
+++ b/sshconnect.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.c,v 1.265 2015/09/04 04:55:24 djm Exp $ */ 1/* $OpenBSD: sshconnect.c,v 1.266 2015/11/15 22:26:49 jcs Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -65,6 +65,7 @@
65#include "version.h" 65#include "version.h"
66#include "authfile.h" 66#include "authfile.h"
67#include "ssherr.h" 67#include "ssherr.h"
68#include "authfd.h"
68 69
69char *client_version_string = NULL; 70char *client_version_string = NULL;
70char *server_version_string = NULL; 71char *server_version_string = NULL;
@@ -1487,3 +1488,30 @@ ssh_local_cmd(const char *args)
1487 1488
1488 return (WEXITSTATUS(status)); 1489 return (WEXITSTATUS(status));
1489} 1490}
1491
1492void
1493maybe_add_key_to_agent(char *authfile, Key *private, char *comment,
1494 char *passphrase)
1495{
1496 int auth_sock = -1, r;
1497
1498 if (options.add_keys_to_agent == 0)
1499 return;
1500
1501 if ((r = ssh_get_authentication_socket(&auth_sock)) != 0) {
1502 debug3("no authentication agent, not adding key");
1503 return;
1504 }
1505
1506 if (options.add_keys_to_agent == 2 &&
1507 !ask_permission("Add key %s (%s) to agent?", authfile, comment)) {
1508 debug3("user denied adding this key");
1509 return;
1510 }
1511
1512 if ((r = ssh_add_identity_constrained(auth_sock, private, comment, 0,
1513 (options.add_keys_to_agent == 3))) == 0)
1514 debug("identity added to agent: %s", authfile);
1515 else
1516 debug("could not add identity to agent: %s (%d)", authfile, r);
1517}
diff --git a/sshconnect.h b/sshconnect.h
index 0ea6e99f6..cf1851a95 100644
--- a/sshconnect.h
+++ b/sshconnect.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect.h,v 1.28 2013/10/16 02:31:47 djm Exp $ */ 1/* $OpenBSD: sshconnect.h,v 1.29 2015/11/15 22:26:49 jcs Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -55,6 +55,8 @@ void ssh_userauth2(const char *, const char *, char *, Sensitive *);
55void ssh_put_password(char *); 55void ssh_put_password(char *);
56int ssh_local_cmd(const char *); 56int ssh_local_cmd(const char *);
57 57
58void maybe_add_key_to_agent(char *, Key *, char *, char *);
59
58/* 60/*
59 * Macros to raise/lower permissions. 61 * Macros to raise/lower permissions.
60 */ 62 */
diff --git a/sshconnect1.c b/sshconnect1.c
index 016abbce5..bfc523bde 100644
--- a/sshconnect1.c
+++ b/sshconnect1.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect1.c,v 1.77 2015/01/14 20:05:27 djm Exp $ */ 1/* $OpenBSD: sshconnect1.c,v 1.78 2015/11/15 22:26:49 jcs Exp $ */
2/* 2/*
3 * Author: Tatu Ylonen <ylo@cs.hut.fi> 3 * Author: Tatu Ylonen <ylo@cs.hut.fi>
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -221,7 +221,7 @@ try_rsa_authentication(int idx)
221{ 221{
222 BIGNUM *challenge; 222 BIGNUM *challenge;
223 Key *public, *private; 223 Key *public, *private;
224 char buf[300], *passphrase, *comment, *authfile; 224 char buf[300], *passphrase = NULL, *comment, *authfile;
225 int i, perm_ok = 1, type, quit; 225 int i, perm_ok = 1, type, quit;
226 226
227 public = options.identity_keys[idx]; 227 public = options.identity_keys[idx];
@@ -283,13 +283,20 @@ try_rsa_authentication(int idx)
283 debug2("no passphrase given, try next key"); 283 debug2("no passphrase given, try next key");
284 quit = 1; 284 quit = 1;
285 } 285 }
286 explicit_bzero(passphrase, strlen(passphrase));
287 free(passphrase);
288 if (private != NULL || quit) 286 if (private != NULL || quit)
289 break; 287 break;
290 debug2("bad passphrase given, try again..."); 288 debug2("bad passphrase given, try again...");
291 } 289 }
292 } 290 }
291
292 if (private != NULL)
293 maybe_add_key_to_agent(authfile, private, comment, passphrase);
294
295 if (passphrase != NULL) {
296 explicit_bzero(passphrase, strlen(passphrase));
297 free(passphrase);
298 }
299
293 /* We no longer need the comment. */ 300 /* We no longer need the comment. */
294 free(comment); 301 free(comment);
295 302
diff --git a/sshconnect2.c b/sshconnect2.c
index 3ab686e86..69d0bee4e 100644
--- a/sshconnect2.c
+++ b/sshconnect2.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: sshconnect2.c,v 1.228 2015/10/13 16:15:21 djm Exp $ */ 1/* $OpenBSD: sshconnect2.c,v 1.229 2015/11/15 22:26:49 jcs Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2008 Damien Miller. All rights reserved. 4 * Copyright (c) 2008 Damien Miller. All rights reserved.
@@ -313,7 +313,7 @@ void userauth(Authctxt *, char *);
313static int sign_and_send_pubkey(Authctxt *, Identity *); 313static int sign_and_send_pubkey(Authctxt *, Identity *);
314static void pubkey_prepare(Authctxt *); 314static void pubkey_prepare(Authctxt *);
315static void pubkey_cleanup(Authctxt *); 315static void pubkey_cleanup(Authctxt *);
316static Key *load_identity_file(char *, int); 316static Key *load_identity_file(Identity *);
317 317
318static Authmethod *authmethod_get(char *authlist); 318static Authmethod *authmethod_get(char *authlist);
319static Authmethod *authmethod_lookup(const char *name); 319static Authmethod *authmethod_lookup(const char *name);
@@ -990,7 +990,7 @@ identity_sign(struct identity *id, u_char **sigp, size_t *lenp,
990 return (sshkey_sign(id->key, sigp, lenp, data, datalen, 990 return (sshkey_sign(id->key, sigp, lenp, data, datalen,
991 compat)); 991 compat));
992 /* load the private key from the file */ 992 /* load the private key from the file */
993 if ((prv = load_identity_file(id->filename, id->userprovided)) == NULL) 993 if ((prv = load_identity_file(id)) == NULL)
994 return (-1); /* XXX return decent error code */ 994 return (-1); /* XXX return decent error code */
995 ret = sshkey_sign(prv, sigp, lenp, data, datalen, compat); 995 ret = sshkey_sign(prv, sigp, lenp, data, datalen, compat);
996 sshkey_free(prv); 996 sshkey_free(prv);
@@ -1147,20 +1147,20 @@ send_pubkey_test(Authctxt *authctxt, Identity *id)
1147} 1147}
1148 1148
1149static Key * 1149static Key *
1150load_identity_file(char *filename, int userprovided) 1150load_identity_file(Identity *id)
1151{ 1151{
1152 Key *private; 1152 Key *private;
1153 char prompt[300], *passphrase; 1153 char prompt[300], *passphrase, *comment;
1154 int r, perm_ok = 0, quit = 0, i; 1154 int r, perm_ok = 0, quit = 0, i;
1155 struct stat st; 1155 struct stat st;
1156 1156
1157 if (stat(filename, &st) < 0) { 1157 if (stat(id->filename, &st) < 0) {
1158 (userprovided ? logit : debug3)("no such identity: %s: %s", 1158 (id->userprovided ? logit : debug3)("no such identity: %s: %s",
1159 filename, strerror(errno)); 1159 id->filename, strerror(errno));
1160 return NULL; 1160 return NULL;
1161 } 1161 }
1162 snprintf(prompt, sizeof prompt, 1162 snprintf(prompt, sizeof prompt,
1163 "Enter passphrase for key '%.100s': ", filename); 1163 "Enter passphrase for key '%.100s': ", id->filename);
1164 for (i = 0; i <= options.number_of_password_prompts; i++) { 1164 for (i = 0; i <= options.number_of_password_prompts; i++) {
1165 if (i == 0) 1165 if (i == 0)
1166 passphrase = ""; 1166 passphrase = "";
@@ -1172,8 +1172,8 @@ load_identity_file(char *filename, int userprovided)
1172 break; 1172 break;
1173 } 1173 }
1174 } 1174 }
1175 switch ((r = sshkey_load_private_type(KEY_UNSPEC, filename, 1175 switch ((r = sshkey_load_private_type(KEY_UNSPEC, id->filename,
1176 passphrase, &private, NULL, &perm_ok))) { 1176 passphrase, &private, &comment, &perm_ok))) {
1177 case 0: 1177 case 0:
1178 break; 1178 break;
1179 case SSH_ERR_KEY_WRONG_PASSPHRASE: 1179 case SSH_ERR_KEY_WRONG_PASSPHRASE:
@@ -1187,20 +1187,26 @@ load_identity_file(char *filename, int userprovided)
1187 case SSH_ERR_SYSTEM_ERROR: 1187 case SSH_ERR_SYSTEM_ERROR:
1188 if (errno == ENOENT) { 1188 if (errno == ENOENT) {
1189 debug2("Load key \"%s\": %s", 1189 debug2("Load key \"%s\": %s",
1190 filename, ssh_err(r)); 1190 id->filename, ssh_err(r));
1191 quit = 1; 1191 quit = 1;
1192 break; 1192 break;
1193 } 1193 }
1194 /* FALLTHROUGH */ 1194 /* FALLTHROUGH */
1195 default: 1195 default:
1196 error("Load key \"%s\": %s", filename, ssh_err(r)); 1196 error("Load key \"%s\": %s", id->filename, ssh_err(r));
1197 quit = 1; 1197 quit = 1;
1198 break; 1198 break;
1199 } 1199 }
1200 if (!quit && private != NULL && !id->agent_fd &&
1201 !(id->key && id->isprivate))
1202 maybe_add_key_to_agent(id->filename, private, comment,
1203 passphrase);
1200 if (i > 0) { 1204 if (i > 0) {
1201 explicit_bzero(passphrase, strlen(passphrase)); 1205 explicit_bzero(passphrase, strlen(passphrase));
1202 free(passphrase); 1206 free(passphrase);
1203 } 1207 }
1208 if (comment)
1209 free(comment);
1204 if (private != NULL || quit) 1210 if (private != NULL || quit)
1205 break; 1211 break;
1206 } 1212 }
@@ -1403,8 +1409,7 @@ userauth_pubkey(Authctxt *authctxt)
1403 } 1409 }
1404 } else { 1410 } else {
1405 debug("Trying private key: %s", id->filename); 1411 debug("Trying private key: %s", id->filename);
1406 id->key = load_identity_file(id->filename, 1412 id->key = load_identity_file(id);
1407 id->userprovided);
1408 if (id->key != NULL) { 1413 if (id->key != NULL) {
1409 if (try_identity(id)) { 1414 if (try_identity(id)) {
1410 id->isprivate = 1; 1415 id->isprivate = 1;