View | Details | Raw Unified | Return to bug 1699
Collapse All | Expand All

(-)readconf.c (-3 / +31 lines)
Lines 128-134 typedef enum { Link Here
128
	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
128
	oSendEnv, oControlPath, oControlMaster, oHashKnownHosts,
129
	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
129
	oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
130
	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
130
	oVisualHostKey, oUseRoaming, oZeroKnowledgePasswordAuthentication,
131
	oDeprecated, oUnsupported
131
	oAddKeysToAgent, oDeprecated, oUnsupported
132
} OpCodes;
132
} OpCodes;
133
133
134
/* Textual representations of the tokens. */
134
/* Textual representations of the tokens. */
Lines 232-237 static struct { Link Here
232
#else
232
#else
233
	{ "zeroknowledgepasswordauthentication", oUnsupported },
233
	{ "zeroknowledgepasswordauthentication", oUnsupported },
234
#endif
234
#endif
235
	{ "addkeystoagent", oAddKeysToAgent },
235
236
236
	{ NULL, oBadOption }
237
	{ NULL, oBadOption }
237
};
238
};
Lines 914-919 parse_int: Link Here
914
		intptr = &options->use_roaming;
915
		intptr = &options->use_roaming;
915
		goto parse_flag;
916
		goto parse_flag;
916
917
918
	case oAddKeysToAgent:
919
		intptr = &options->add_keys_to_agent;
920
		arg = strdelim(&s);
921
		if (!arg || *arg == '\0')
922
			fatal("%.200s line %d: Missing yes/no/confirm/ask "
923
			    "argument.", filename, linenum);
924
		value = 0;	/* To avoid compiler warning... */
925
		if (strcmp(arg, "yes") == 0 || strcmp(arg, "true") == 0)
926
			value = 1;
927
		else if (strcmp(arg, "no") == 0 || strcmp(arg, "false") == 0)
928
			value = 0;
929
		else if (strcmp(arg, "ask") == 0)
930
			value = 2;
931
		else if (strcmp(arg, "confirm") == 0)
932
			value = 3;
933
		else
934
			fatal("%.200s line %d: Bad yes/no/confirm/ask "
935
			    "argument.", filename, linenum);
936
		if (*activep && *intptr == -1)
937
			*intptr = value;
938
		break;
939
917
	case oDeprecated:
940
	case oDeprecated:
918
		debug("%s line %d: Deprecated option \"%s\"",
941
		debug("%s line %d: Deprecated option \"%s\"",
919
		    filename, linenum, keyword);
942
		    filename, linenum, keyword);
Lines 1064-1069 initialize_options(Options * options) Link Here
1064
	options->local_command = NULL;
1087
	options->local_command = NULL;
1065
	options->permit_local_command = -1;
1088
	options->permit_local_command = -1;
1066
	options->use_roaming = -1;
1089
	options->use_roaming = -1;
1090
	options->add_keys_to_agent = -1;
1067
	options->visual_host_key = -1;
1091
	options->visual_host_key = -1;
1068
	options->zero_knowledge_password_authentication = -1;
1092
	options->zero_knowledge_password_authentication = -1;
1069
}
1093
}
Lines 1138-1152 fill_default_options(Options * options) Link Here
1138
	/* options->hostkeyalgorithms, default set in myproposals.h */
1162
	/* options->hostkeyalgorithms, default set in myproposals.h */
1139
	if (options->protocol == SSH_PROTO_UNKNOWN)
1163
	if (options->protocol == SSH_PROTO_UNKNOWN)
1140
		options->protocol = SSH_PROTO_2;
1164
		options->protocol = SSH_PROTO_2;
1165
	if (options->add_keys_to_agent == -1)
1166
		options->add_keys_to_agent = 0;
1141
	if (options->num_identity_files == 0) {
1167
	if (options->num_identity_files == 0) {
1142
		if (options->protocol & SSH_PROTO_1) {
1168
		if (options->protocol & SSH_PROTO_1 ||
1169
		    options->add_keys_to_agent != 0) {
1143
			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1170
			len = 2 + strlen(_PATH_SSH_CLIENT_IDENTITY) + 1;
1144
			options->identity_files[options->num_identity_files] =
1171
			options->identity_files[options->num_identity_files] =
1145
			    xmalloc(len);
1172
			    xmalloc(len);
1146
			snprintf(options->identity_files[options->num_identity_files++],
1173
			snprintf(options->identity_files[options->num_identity_files++],
1147
			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1174
			    len, "~/%.100s", _PATH_SSH_CLIENT_IDENTITY);
1148
		}
1175
		}
1149
		if (options->protocol & SSH_PROTO_2) {
1176
		if (options->protocol & SSH_PROTO_2 ||
1177
		    options->add_keys_to_agent != 0) {
1150
			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1178
			len = 2 + strlen(_PATH_SSH_CLIENT_ID_RSA) + 1;
1151
			options->identity_files[options->num_identity_files] =
1179
			options->identity_files[options->num_identity_files] =
1152
			    xmalloc(len);
1180
			    xmalloc(len);
(-)readconf.h (+2 lines)
Lines 125-130 typedef struct { Link Here
125
125
126
	int	use_roaming;
126
	int	use_roaming;
127
127
128
	int	add_keys_to_agent;
129
128
}       Options;
130
}       Options;
129
131
130
#define SSHCTL_MASTER_NO	0
132
#define SSHCTL_MASTER_NO	0
(-)sshconnect2.c (-50 / +135 lines)
Lines 178-183 struct identity { Link Here
178
	AuthenticationConnection *ac;	/* set if agent supports key */
178
	AuthenticationConnection *ac;	/* set if agent supports key */
179
	Key	*key;			/* public/private key */
179
	Key	*key;			/* public/private key */
180
	char	*filename;		/* comment for agent-only keys */
180
	char	*filename;		/* comment for agent-only keys */
181
	char	*comment;		/* comment for other keys */
181
	int	tried;
182
	int	tried;
182
	int	isprivate;		/* key points to the private key */
183
	int	isprivate;		/* key points to the private key */
183
};
184
};
Lines 244-250 void userauth(Authctxt *, char *); Link Here
244
static int sign_and_send_pubkey(Authctxt *, Identity *);
245
static int sign_and_send_pubkey(Authctxt *, Identity *);
245
static void pubkey_prepare(Authctxt *);
246
static void pubkey_prepare(Authctxt *);
246
static void pubkey_cleanup(Authctxt *);
247
static void pubkey_cleanup(Authctxt *);
247
static Key *load_identity_file(char *);
248
static Key *load_identity_file(Identity *, char **);
249
static void add_keys_to_agent(Authctxt *, char *);
248
250
249
static Authmethod *authmethod_get(char *authlist);
251
static Authmethod *authmethod_get(char *authlist);
250
static Authmethod *authmethod_lookup(const char *name);
252
static Authmethod *authmethod_lookup(const char *name);
Lines 1101-1139 input_userauth_jpake_server_confirm(int Link Here
1101
#endif /* JPAKE */
1103
#endif /* JPAKE */
1102
1104
1103
static int
1105
static int
1104
identity_sign(Identity *id, u_char **sigp, u_int *lenp,
1105
    u_char *data, u_int datalen)
1106
{
1107
	Key *prv;
1108
	int ret;
1109
1110
	/* the agent supports this key */
1111
	if (id->ac)
1112
		return (ssh_agent_sign(id->ac, id->key, sigp, lenp,
1113
		    data, datalen));
1114
	/*
1115
	 * we have already loaded the private key or
1116
	 * the private key is stored in external hardware
1117
	 */
1118
	if (id->isprivate || (id->key->flags & KEY_FLAG_EXT))
1119
		return (key_sign(id->key, sigp, lenp, data, datalen));
1120
	/* load the private key from the file */
1121
	if ((prv = load_identity_file(id->filename)) == NULL)
1122
		return (-1);
1123
	ret = key_sign(prv, sigp, lenp, data, datalen);
1124
	key_free(prv);
1125
	return (ret);
1126
}
1127
1128
static int
1129
sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1106
sign_and_send_pubkey(Authctxt *authctxt, Identity *id)
1130
{
1107
{
1131
	Buffer b;
1108
	Buffer b;
1132
	u_char *blob, *signature;
1109
	u_char *blob, *signature;
1133
	u_int bloblen, slen;
1110
	u_int bloblen, slen;
1134
	u_int skip = 0;
1111
	u_int skip = 0;
1135
	int ret = -1;
1112
	int sign_ok = -1, have_sig = 1;
1136
	int have_sig = 1;
1113
	Key *private;
1114
	char *passphrase;
1137
1115
1138
	debug3("sign_and_send_pubkey");
1116
	debug3("sign_and_send_pubkey");
1139
1117
Lines 1167-1175 sign_and_send_pubkey(Authctxt *authctxt, Link Here
1167
	buffer_put_string(&b, blob, bloblen);
1145
	buffer_put_string(&b, blob, bloblen);
1168
1146
1169
	/* generate signature */
1147
	/* generate signature */
1170
	ret = identity_sign(id, &signature, &slen,
1148
	if (id->ac) {
1171
	    buffer_ptr(&b), buffer_len(&b));
1149
		/* the agent supports this key */
1172
	if (ret == -1) {
1150
		sign_ok = ssh_agent_sign(id->ac, id->key, &signature, &slen,
1151
		    buffer_ptr(&b), buffer_len(&b));
1152
	} else if (id->isprivate || (id->key->flags & KEY_FLAG_EXT)) {
1153
		/*
1154
		 * we have already loaded the private key or the private key is
1155
		 * stored in external hardware
1156
		 */
1157
		sign_ok = key_sign(id->key, &signature, &slen, buffer_ptr(&b),
1158
		    buffer_len(&b));
1159
	} else {
1160
		/* load the private key from the file */
1161
		private = load_identity_file(id, &passphrase);
1162
		if (private == NULL)
1163
			sign_ok = -1;
1164
		else {
1165
			sign_ok = key_sign(private, &signature, &slen,
1166
			    buffer_ptr(&b), buffer_len(&b));
1167
1168
			key_free(private);
1169
1170
			add_keys_to_agent(authctxt, passphrase);
1171
		}
1172
	}
1173
1174
	if (sign_ok == -1) {
1173
		xfree(blob);
1175
		xfree(blob);
1174
		buffer_free(&b);
1176
		buffer_free(&b);
1175
		return 0;
1177
		return 0;
Lines 1240-1277 send_pubkey_test(Authctxt *authctxt, Ide Link Here
1240
}
1242
}
1241
1243
1242
static Key *
1244
static Key *
1243
load_identity_file(char *filename)
1245
load_identity_file(Identity *id, char **passphrase)
1244
{
1246
{
1245
	Key *private;
1247
	Key *private;
1246
	char prompt[300], *passphrase;
1248
	char prompt[300];
1247
	int perm_ok = 0, quit, i;
1249
	int perm_ok = 0, quit, i;
1248
	struct stat st;
1250
	struct stat st;
1249
1251
1250
	if (stat(filename, &st) < 0) {
1252
	if (stat(id->filename, &st) < 0) {
1251
		debug3("no such identity: %s", filename);
1253
		debug3("no such identity: %s", id->filename);
1252
		return NULL;
1254
		return NULL;
1253
	}
1255
	}
1254
	private = key_load_private_type(KEY_UNSPEC, filename, "", NULL, &perm_ok);
1256
	*passphrase = NULL;
1257
	private = key_load_private_type(KEY_UNSPEC, id->filename, "",
1258
	    &id->comment, &perm_ok);
1255
	if (!perm_ok)
1259
	if (!perm_ok)
1256
		return NULL;
1260
		return NULL;
1257
	if (private == NULL) {
1261
	if (private == NULL) {
1258
		if (options.batch_mode)
1262
		if (options.batch_mode)
1259
			return NULL;
1263
			return NULL;
1260
		snprintf(prompt, sizeof prompt,
1264
		snprintf(prompt, sizeof prompt,
1261
		    "Enter passphrase for key '%.100s': ", filename);
1265
		    "Enter passphrase for key '%.100s': ", id->filename);
1262
		for (i = 0; i < options.number_of_password_prompts; i++) {
1266
		for (i = 0; i < options.number_of_password_prompts; i++) {
1263
			passphrase = read_passphrase(prompt, 0);
1267
			*passphrase = read_passphrase(prompt, 0);
1264
			if (strcmp(passphrase, "") != 0) {
1268
			if (strcmp(*passphrase, "") != 0) {
1265
				private = key_load_private_type(KEY_UNSPEC,
1269
				private = key_load_private_type(KEY_UNSPEC,
1266
				    filename, passphrase, NULL, NULL);
1270
				    id->filename, *passphrase, &id->comment,
1271
				    NULL);
1267
				quit = 0;
1272
				quit = 0;
1268
			} else {
1273
			} else {
1269
				debug2("no passphrase given, try next key");
1274
				debug2("no passphrase given, try next key");
1270
				quit = 1;
1275
				quit = 1;
1271
			}
1276
			}
1272
			memset(passphrase, 0, strlen(passphrase));
1277
			if (private != NULL)
1273
			xfree(passphrase);
1278
				break;
1274
			if (private != NULL || quit)
1279
			memset(*passphrase, 0, strlen(*passphrase));
1280
			xfree(*passphrase);
1281
			*passphrase = NULL;
1282
			if (quit)
1275
				break;
1283
				break;
1276
			debug2("bad passphrase given, try again...");
1284
			debug2("bad passphrase given, try again...");
1277
		}
1285
		}
Lines 1293-1299 pubkey_prepare(Authctxt *authctxt) Link Here
1293
	Key *key;
1301
	Key *key;
1294
	AuthenticationConnection *ac;
1302
	AuthenticationConnection *ac;
1295
	char *comment;
1303
	char *comment;
1296
	int i, found;
1304
	int i, found, protocol;
1297
1305
1298
	TAILQ_INIT(&agent);	/* keys from the agent */
1306
	TAILQ_INIT(&agent);	/* keys from the agent */
1299
	TAILQ_INIT(&files);	/* keys from the config file */
1307
	TAILQ_INIT(&files);	/* keys from the config file */
Lines 1303-1310 pubkey_prepare(Authctxt *authctxt) Link Here
1303
	/* list of keys stored in the filesystem */
1311
	/* list of keys stored in the filesystem */
1304
	for (i = 0; i < options.num_identity_files; i++) {
1312
	for (i = 0; i < options.num_identity_files; i++) {
1305
		key = options.identity_keys[i];
1313
		key = options.identity_keys[i];
1306
		if (key && key->type == KEY_RSA1)
1307
			continue;
1308
		options.identity_keys[i] = NULL;
1314
		options.identity_keys[i] = NULL;
1309
		id = xcalloc(1, sizeof(*id));
1315
		id = xcalloc(1, sizeof(*id));
1310
		id->key = key;
1316
		id->key = key;
Lines 1313-1321 pubkey_prepare(Authctxt *authctxt) Link Here
1313
	}
1319
	}
1314
	/* list of keys supported by the agent */
1320
	/* list of keys supported by the agent */
1315
	if ((ac = ssh_get_authentication_connection())) {
1321
	if ((ac = ssh_get_authentication_connection())) {
1316
		for (key = ssh_get_first_identity(ac, &comment, 2);
1322
		for (key = ssh_get_first_identity(ac, &comment, protocol = 2);
1317
		    key != NULL;
1323
		    key != NULL || protocol == 2;
1318
		    key = ssh_get_next_identity(ac, &comment, 2)) {
1324
		    key = ssh_get_next_identity(ac, &comment, protocol)) {
1325
			if (key == NULL && options.add_keys_to_agent != 0) {
1326
				protocol = 1;
1327
				key = ssh_get_first_identity(ac, &comment, protocol);
1328
			}
1329
			if (key == NULL)
1330
				break;
1319
			found = 0;
1331
			found = 0;
1320
			TAILQ_FOREACH(id, &files, next) {
1332
			TAILQ_FOREACH(id, &files, next) {
1321
				/* agent keys from the config file are preferred */
1333
				/* agent keys from the config file are preferred */
Lines 1368-1382 pubkey_cleanup(Authctxt *authctxt) Link Here
1368
			key_free(id->key);
1380
			key_free(id->key);
1369
		if (id->filename)
1381
		if (id->filename)
1370
			xfree(id->filename);
1382
			xfree(id->filename);
1383
		if (id->comment)
1384
			xfree(id->comment);
1371
		xfree(id);
1385
		xfree(id);
1372
	}
1386
	}
1373
}
1387
}
1374
1388
1389
static void
1390
add_keys_to_agent(Authctxt *authctxt, char *passphrase)
1391
{
1392
	Identity	*id;
1393
	Key		*private;
1394
	int		 perm_ok;
1395
	struct stat	 st;
1396
1397
	if (options.add_keys_to_agent == 0)
1398
		goto done;
1399
1400
	if (authctxt->agent == NULL) {
1401
		debug3("no connection to agent, not adding keys");
1402
		goto done;
1403
	}
1404
1405
	TAILQ_FOREACH(id, &authctxt->keys, next) {
1406
		if (id->ac) {
1407
			debug3("key already in agent: %s", id->filename);
1408
			continue;
1409
		}
1410
1411
		if (id->key && id->isprivate) {
1412
			debug3("using private key loaded previously");
1413
			private = id->key;
1414
		} else {
1415
			/* Try loading key */
1416
			if (stat(id->filename, &st) < 0) {
1417
				debug3("no such identity to add to agent: %s",
1418
				    id->filename);
1419
				continue;
1420
			}
1421
			private = key_load_private(id->filename, "",
1422
			    &id->comment);
1423
			if (private == NULL && passphrase != NULL)
1424
				private = key_load_private(id->filename,
1425
				    passphrase, &id->comment);
1426
			if (private == NULL) {
1427
				debug3("bad passphrase for identity: %s", id->filename);
1428
				continue;
1429
			}
1430
		}
1431
1432
		if (options.add_keys_to_agent == 2 &&
1433
		    !ask_permission("Add key %s (%s) to agent?", id->filename,
1434
		      id->comment)) {
1435
			debug3("user did not confirm adding this key");
1436
			key_free(private);
1437
			continue;
1438
		}
1439
1440
		if (ssh_add_identity_constrained(authctxt->agent, private,
1441
		    id->comment, 0, options.add_keys_to_agent == 3))
1442
			debug("Identity added to agent: %s (%s)",
1443
			    id->filename, id->comment);
1444
		else
1445
			debug("Could not add identity: %s", id->filename);
1446
1447
		if (!id->isprivate || private != id->key)
1448
			key_free(private);
1449
	}
1450
1451
done:
1452
	if (passphrase != NULL) {
1453
		memset(passphrase, 0, strlen(passphrase));
1454
		xfree(passphrase);
1455
	}
1456
}
1457
1375
int
1458
int
1376
userauth_pubkey(Authctxt *authctxt)
1459
userauth_pubkey(Authctxt *authctxt)
1377
{
1460
{
1378
	Identity *id;
1461
	Identity *id;
1379
	int sent = 0;
1462
	int sent = 0;
1463
	char *passphrase;
1380
1464
1381
	while ((id = TAILQ_FIRST(&authctxt->keys))) {
1465
	while ((id = TAILQ_FIRST(&authctxt->keys))) {
1382
		if (id->tried++)
1466
		if (id->tried++)
Lines 1394-1402 userauth_pubkey(Authctxt *authctxt) Link Here
1394
			sent = send_pubkey_test(authctxt, id);
1478
			sent = send_pubkey_test(authctxt, id);
1395
		} else if (id->key == NULL) {
1479
		} else if (id->key == NULL) {
1396
			debug("Trying private key: %s", id->filename);
1480
			debug("Trying private key: %s", id->filename);
1397
			id->key = load_identity_file(id->filename);
1481
			id->key = load_identity_file(id, &passphrase);
1398
			if (id->key != NULL) {
1482
			if (id->key != NULL) {
1399
				id->isprivate = 1;
1483
				id->isprivate = 1;
1484
				add_keys_to_agent(authctxt, passphrase);
1400
				sent = sign_and_send_pubkey(authctxt, id);
1485
				sent = sign_and_send_pubkey(authctxt, id);
1401
				key_free(id->key);
1486
				key_free(id->key);
1402
				id->key = NULL;
1487
				id->key = NULL;
(-)sshconnect1.c (-22 / +106 lines)
Lines 15-20 Link Here
15
15
16
#include <sys/types.h>
16
#include <sys/types.h>
17
#include <sys/socket.h>
17
#include <sys/socket.h>
18
#include <sys/stat.h>
18
19
19
#include <openssl/bn.h>
20
#include <openssl/bn.h>
20
#include <openssl/md5.h>
21
#include <openssl/md5.h>
Lines 57-77 extern char *__progname; Link Here
57
 * authenticate using the agent.
58
 * authenticate using the agent.
58
 */
59
 */
59
static int
60
static int
60
try_agent_authentication(void)
61
try_agent_authentication(AuthenticationConnection *auth)
61
{
62
{
62
	int type;
63
	int type;
63
	char *comment;
64
	char *comment;
64
	AuthenticationConnection *auth;
65
	u_char response[16];
65
	u_char response[16];
66
	u_int i;
66
	u_int i;
67
	Key *key;
67
	Key *key;
68
	BIGNUM *challenge;
68
	BIGNUM *challenge;
69
69
70
	/* Get connection to the agent. */
71
	auth = ssh_get_authentication_connection();
72
	if (!auth)
73
		return 0;
74
75
	if ((challenge = BN_new()) == NULL)
70
	if ((challenge = BN_new()) == NULL)
76
		fatal("try_agent_authentication: BN_new failed");
71
		fatal("try_agent_authentication: BN_new failed");
77
	/* Loop through identities served by the agent. */
72
	/* Loop through identities served by the agent. */
Lines 134-140 try_agent_authentication(void) Link Here
134
129
135
		/* The server returns success if it accepted the authentication. */
130
		/* The server returns success if it accepted the authentication. */
136
		if (type == SSH_SMSG_SUCCESS) {
131
		if (type == SSH_SMSG_SUCCESS) {
137
			ssh_close_authentication_connection(auth);
138
			BN_clear_free(challenge);
132
			BN_clear_free(challenge);
139
			debug("RSA authentication accepted by server.");
133
			debug("RSA authentication accepted by server.");
140
			return 1;
134
			return 1;
Lines 144-150 try_agent_authentication(void) Link Here
144
			packet_disconnect("Protocol error waiting RSA auth response: %d",
138
			packet_disconnect("Protocol error waiting RSA auth response: %d",
145
					  type);
139
					  type);
146
	}
140
	}
147
	ssh_close_authentication_connection(auth);
148
	BN_clear_free(challenge);
141
	BN_clear_free(challenge);
149
	debug("RSA authentication using agent refused.");
142
	debug("RSA authentication using agent refused.");
150
	return 0;
143
	return 0;
Lines 200-210 respond_to_rsa_challenge(BIGNUM * challe Link Here
200
 * the user using it.
193
 * the user using it.
201
 */
194
 */
202
static int
195
static int
203
try_rsa_authentication(int idx)
196
try_rsa_authentication(int idx, char **passphrase)
204
{
197
{
205
	BIGNUM *challenge;
198
	BIGNUM *challenge;
206
	Key *public, *private;
199
	Key *public, *private;
207
	char buf[300], *passphrase, *comment, *authfile;
200
	char buf[300], *comment, *authfile;
208
	int i, perm_ok = 1, type, quit;
201
	int i, perm_ok = 1, type, quit;
209
202
210
	public = options.identity_keys[idx];
203
	public = options.identity_keys[idx];
Lines 248-253 try_rsa_authentication(int idx) Link Here
248
	 * load the private key.  Try first with empty passphrase; if it
241
	 * load the private key.  Try first with empty passphrase; if it
249
	 * fails, ask for a passphrase.
242
	 * fails, ask for a passphrase.
250
	 */
243
	 */
244
	*passphrase = NULL;
251
	if (public->flags & KEY_FLAG_EXT)
245
	if (public->flags & KEY_FLAG_EXT)
252
		private = public;
246
		private = public;
253
	else
247
	else
Lines 257-274 try_rsa_authentication(int idx) Link Here
257
		snprintf(buf, sizeof(buf),
251
		snprintf(buf, sizeof(buf),
258
		    "Enter passphrase for RSA key '%.100s': ", comment);
252
		    "Enter passphrase for RSA key '%.100s': ", comment);
259
		for (i = 0; i < options.number_of_password_prompts; i++) {
253
		for (i = 0; i < options.number_of_password_prompts; i++) {
260
			passphrase = read_passphrase(buf, 0);
254
			*passphrase = read_passphrase(buf, 0);
261
			if (strcmp(passphrase, "") != 0) {
255
			if (strcmp(*passphrase, "") != 0) {
262
				private = key_load_private_type(KEY_RSA1,
256
				private = key_load_private_type(KEY_RSA1,
263
				    authfile, passphrase, NULL, NULL);
257
				    authfile, *passphrase, NULL, NULL);
264
				quit = 0;
258
				quit = 0;
265
			} else {
259
			} else {
266
				debug2("no passphrase given, try next key");
260
				debug2("no passphrase given, try next key");
267
				quit = 1;
261
				quit = 1;
268
			}
262
			}
269
			memset(passphrase, 0, strlen(passphrase));
263
			if (private != NULL)
270
			xfree(passphrase);
264
				break;
271
			if (private != NULL || quit)
265
			memset(*passphrase, 0, strlen(*passphrase));
266
			xfree(*passphrase);
267
			if (quit)
272
				break;
268
				break;
273
			debug2("bad passphrase given, try again...");
269
			debug2("bad passphrase given, try again...");
274
		}
270
		}
Lines 669-675 void Link Here
669
ssh_userauth1(const char *local_user, const char *server_user, char *host,
665
ssh_userauth1(const char *local_user, const char *server_user, char *host,
670
    Sensitive *sensitive)
666
    Sensitive *sensitive)
671
{
667
{
672
	int i, type;
668
	int i, type, protocol;
669
	AuthenticationConnection *auth = NULL;
670
	char *passphrase, *comment;
671
	struct stat st;
672
	Key *private, *key;
673
673
674
	if (supported_authentications == 0)
674
	if (supported_authentications == 0)
675
		fatal("ssh_userauth1: server supports no auth methods");
675
		fatal("ssh_userauth1: server supports no auth methods");
Lines 715-730 ssh_userauth1(const char *local_user, co Link Here
715
		 * agent is tried first because no passphrase is needed for
715
		 * agent is tried first because no passphrase is needed for
716
		 * it, whereas identity files may require passphrases.
716
		 * it, whereas identity files may require passphrases.
717
		 */
717
		 */
718
		if (try_agent_authentication())
718
		auth = ssh_get_authentication_connection();
719
		if (auth != NULL && try_agent_authentication(auth))
719
			goto success;
720
			goto success;
720
721
721
		/* Try RSA authentication for each identity. */
722
		/* Try RSA authentication for each identity. */
722
		for (i = 0; i < options.num_identity_files; i++)
723
		for (i = 0; i < options.num_identity_files; i++)
723
			if (options.identity_keys[i] != NULL &&
724
			if (options.identity_keys[i] != NULL &&
724
			    options.identity_keys[i]->type == KEY_RSA1 &&
725
			    options.identity_keys[i]->type == KEY_RSA1 &&
725
			    try_rsa_authentication(i))
726
			    try_rsa_authentication(i, &passphrase))
726
				goto success;
727
				break;
728
729
		if (i == options.num_identity_files)
730
			goto try_next_method;
731
732
		if (options.add_keys_to_agent == 0)
733
			goto clear_passphrase;
734
735
		if (auth == NULL) {
736
			debug3("no connection to agent, not adding keys");
737
			goto clear_passphrase;
738
		}
739
740
		for (i = 0;
741
		     i < options.num_identity_files;
742
		     i++) {
743
			/* Try loading key */
744
			if (stat(options.identity_files[i], &st) < 0) {
745
				debug3("no such identity to add to agent: %s",
746
				    options.identity_files[i]);
747
				continue;
748
			}
749
			private = key_load_private(options.identity_files[i],
750
			    "", &comment);
751
			if (private == NULL && passphrase != NULL)
752
				private = key_load_private(
753
				    options.identity_files[i], passphrase,
754
				    &comment);
755
			if (private == NULL) {
756
				debug3("bad passphrase for identity: %s",
757
				    options.identity_files[i]);
758
				continue;
759
			}
760
761
			/* Check whether key is already in agent */
762
			for (key = ssh_get_first_identity(auth, &comment,
763
			      protocol = 2);
764
			    key != NULL || protocol == 2;
765
			    key = ssh_get_next_identity(auth, &comment,
766
			      protocol)) {
767
				if (key == NULL) {
768
					protocol = 1;
769
					key = ssh_get_first_identity(auth,
770
					    &comment, protocol);
771
					if (key == NULL)
772
						break;
773
				}
774
				if (key_equal(private, key))
775
					break;
776
			}
777
			if (key != NULL) {
778
				debug3("key already in agent: %s",
779
				    options.identity_files[i]);
780
				continue;
781
			}
782
783
			if (options.add_keys_to_agent == 2 &&
784
			    !ask_permission("Add key %s (%s) to agent?",
785
			      options.identity_files[i], comment)) {
786
				debug3("user did not confirm adding this key");
787
				key_free(private);
788
				continue;
789
			}
790
791
			if (ssh_add_identity_constrained(auth, private, comment,
792
			     0, options.add_keys_to_agent == 3))
793
				debug("Identity now in agent: %s (%s)",
794
				    options.identity_files[i], comment);
795
			else
796
				debug("Could not add identity: %s",
797
				    options.identity_files[i]);
798
799
			key_free(private);
800
		}
801
802
clear_passphrase:
803
		if (passphrase != NULL) {
804
			memset(passphrase, 0, strlen(passphrase));
805
			xfree(passphrase);
806
		}
807
808
		goto success;
727
	}
809
	}
810
try_next_method:
728
	/* Try challenge response authentication if the server supports it. */
811
	/* Try challenge response authentication if the server supports it. */
729
	if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
812
	if ((supported_authentications & (1 << SSH_AUTH_TIS)) &&
730
	    options.challenge_response_authentication && !options.batch_mode) {
813
	    options.challenge_response_authentication && !options.batch_mode) {
Lines 746-750 ssh_userauth1(const char *local_user, co Link Here
746
	/* NOTREACHED */
829
	/* NOTREACHED */
747
830
748
 success:
831
 success:
749
	return;	/* need statement after label */
832
	if (auth)
833
		ssh_close_authentication_connection(auth);
750
}
834
}
(-)ssh-agent.1 (+7 lines)
Lines 109-114 When the command dies, so does the agent Link Here
109
.Pp
109
.Pp
110
The agent initially does not have any private keys.
110
The agent initially does not have any private keys.
111
Keys are added using
111
Keys are added using
112
.Xr ssh 1
113
(see
114
.Cm AddKeysToAgent
115
in
116
.Xr ssh_config 5
117
for details)
118
or
112
.Xr ssh-add 1 .
119
.Xr ssh-add 1 .
113
When executed without arguments,
120
When executed without arguments,
114
.Xr ssh-add 1
121
.Xr ssh-add 1
(-)ssh.1 (+5 lines)
Lines 428-433 For full details of the options listed b Link Here
428
.Xr ssh_config 5 .
428
.Xr ssh_config 5 .
429
.Pp
429
.Pp
430
.Bl -tag -width Ds -offset indent -compact
430
.Bl -tag -width Ds -offset indent -compact
431
.It AddKeysToAgent
431
.It AddressFamily
432
.It AddressFamily
432
.It BatchMode
433
.It BatchMode
433
.It BindAddress
434
.It BindAddress
Lines 803-808 The most convenient way to use public ke Link Here
803
authentication agent.
804
authentication agent.
804
See
805
See
805
.Xr ssh-agent 1
806
.Xr ssh-agent 1
807
and (optionally) the
808
.Cm AddKeysToAgent
809
directive in
810
.Xr ssh_config 5
806
for more information.
811
for more information.
807
.Pp
812
.Pp
808
Challenge-response authentication works as follows:
813
Challenge-response authentication works as follows:
(-)ssh_config.5 (+34 lines)
Lines 116-121 a canonicalized host name before matchin Link Here
116
See
116
See
117
.Sx PATTERNS
117
.Sx PATTERNS
118
for more information on patterns.
118
for more information on patterns.
119
.It Cm AddKeysToAgent
120
Specifies whether keys should be automatically added to 
121
.Xr ssh-agent 5
122
(if running).
123
If this option is set to
124
.Dq yes
125
and a key is loaded from a file, this key and all keys with either the same or
126
an empty passphrase are added to the agent (with the default lifetime), as if by
127
.Xr ssh-add 1 .
128
If this option is set to
129
.Dq ask ,
130
.Nm ssh
131
will require confirmation using the
132
.Ev SSH_ASKPASS
133
program before adding a key (see
134
.Xr ssh-add 1
135
for details).
136
If this option is set to
137
.Dq confirm ,
138
each use of the key must be confirmed, exactly as if the
139
.Fl c
140
option was specified to
141
.Xr ssh-add 1 .
142
If this option is set to
143
.Dq no ,
144
no keys are added to the agent.
145
The argument must be
146
.Dq yes ,
147
.Dq confirm ,
148
.Dq ask ,
149
or
150
.Dq no .
151
The default is
152
.Dq no .
119
.It Cm AddressFamily
153
.It Cm AddressFamily
120
Specifies which address family to use when connecting.
154
Specifies which address family to use when connecting.
121
Valid arguments are
155
Valid arguments are

Return to bug 1699