summaryrefslogtreecommitdiff
path: root/sshconnect2.c
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 /sshconnect2.c
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
Diffstat (limited to 'sshconnect2.c')
-rw-r--r--sshconnect2.c35
1 files changed, 20 insertions, 15 deletions
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;