diff options
author | Colin Watson <cjwatson@debian.org> | 2015-08-19 14:23:51 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2015-08-19 16:48:11 +0100 |
commit | 0f0841b2d28b7463267d4d91577e72e3340a1d3a (patch) | |
tree | ba55fcd2b6e2cc22b30f5afb561dbb3da4c8b6c7 /ssh.c | |
parent | f2a5f5dae656759efb0b76c3d94890b65c197a02 (diff) | |
parent | 8698446b972003b63dfe5dcbdb86acfe986afb85 (diff) |
New upstream release (6.8p1).
Diffstat (limited to 'ssh.c')
-rw-r--r-- | ssh.c | 221 |
1 files changed, 175 insertions, 46 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: ssh.c,v 1.407 2014/07/17 07:22:19 djm Exp $ */ | 1 | /* $OpenBSD: ssh.c,v 1.416 2015/03/03 06:48:58 djm 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 |
@@ -48,7 +48,6 @@ | |||
48 | #endif | 48 | #endif |
49 | #include <sys/resource.h> | 49 | #include <sys/resource.h> |
50 | #include <sys/ioctl.h> | 50 | #include <sys/ioctl.h> |
51 | #include <sys/param.h> | ||
52 | #include <sys/socket.h> | 51 | #include <sys/socket.h> |
53 | #include <sys/wait.h> | 52 | #include <sys/wait.h> |
54 | 53 | ||
@@ -67,6 +66,7 @@ | |||
67 | #include <stdlib.h> | 66 | #include <stdlib.h> |
68 | #include <string.h> | 67 | #include <string.h> |
69 | #include <unistd.h> | 68 | #include <unistd.h> |
69 | #include <limits.h> | ||
70 | 70 | ||
71 | #include <netinet/in.h> | 71 | #include <netinet/in.h> |
72 | #include <arpa/inet.h> | 72 | #include <arpa/inet.h> |
@@ -107,6 +107,7 @@ | |||
107 | #include "uidswap.h" | 107 | #include "uidswap.h" |
108 | #include "roaming.h" | 108 | #include "roaming.h" |
109 | #include "version.h" | 109 | #include "version.h" |
110 | #include "ssherr.h" | ||
110 | 111 | ||
111 | #ifdef ENABLE_PKCS11 | 112 | #ifdef ENABLE_PKCS11 |
112 | #include "ssh-pkcs11.h" | 113 | #include "ssh-pkcs11.h" |
@@ -199,7 +200,7 @@ static void | |||
199 | usage(void) | 200 | usage(void) |
200 | { | 201 | { |
201 | fprintf(stderr, | 202 | fprintf(stderr, |
202 | "usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" | 203 | "usage: ssh [-1246AaCfGgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]\n" |
203 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" | 204 | " [-D [bind_address:]port] [-E log_file] [-e escape_char]\n" |
204 | " [-F configfile] [-I pkcs11] [-i identity_file]\n" | 205 | " [-F configfile] [-I pkcs11] [-i identity_file]\n" |
205 | " [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]\n" | 206 | " [-L [bind_address:]port:host:hostport] [-l login_name] [-m mac_spec]\n" |
@@ -276,6 +277,60 @@ resolve_host(const char *name, int port, int logerr, char *cname, size_t clen) | |||
276 | } | 277 | } |
277 | 278 | ||
278 | /* | 279 | /* |
280 | * Attempt to resolve a numeric host address / port to a single address. | ||
281 | * Returns a canonical address string. | ||
282 | * Returns NULL on failure. | ||
283 | * NB. this function must operate with a options having undefined members. | ||
284 | */ | ||
285 | static struct addrinfo * | ||
286 | resolve_addr(const char *name, int port, char *caddr, size_t clen) | ||
287 | { | ||
288 | char addr[NI_MAXHOST], strport[NI_MAXSERV]; | ||
289 | struct addrinfo hints, *res; | ||
290 | int gaierr; | ||
291 | |||
292 | if (port <= 0) | ||
293 | port = default_ssh_port(); | ||
294 | snprintf(strport, sizeof strport, "%u", port); | ||
295 | memset(&hints, 0, sizeof(hints)); | ||
296 | hints.ai_family = options.address_family == -1 ? | ||
297 | AF_UNSPEC : options.address_family; | ||
298 | hints.ai_socktype = SOCK_STREAM; | ||
299 | hints.ai_flags = AI_NUMERICHOST|AI_NUMERICSERV; | ||
300 | if ((gaierr = getaddrinfo(name, strport, &hints, &res)) != 0) { | ||
301 | debug2("%s: could not resolve name %.100s as address: %s", | ||
302 | __func__, name, ssh_gai_strerror(gaierr)); | ||
303 | return NULL; | ||
304 | } | ||
305 | if (res == NULL) { | ||
306 | debug("%s: getaddrinfo %.100s returned no addresses", | ||
307 | __func__, name); | ||
308 | return NULL; | ||
309 | } | ||
310 | if (res->ai_next != NULL) { | ||
311 | debug("%s: getaddrinfo %.100s returned multiple addresses", | ||
312 | __func__, name); | ||
313 | goto fail; | ||
314 | } | ||
315 | if ((gaierr = getnameinfo(res->ai_addr, res->ai_addrlen, | ||
316 | addr, sizeof(addr), NULL, 0, NI_NUMERICHOST)) != 0) { | ||
317 | debug("%s: Could not format address for name %.100s: %s", | ||
318 | __func__, name, ssh_gai_strerror(gaierr)); | ||
319 | goto fail; | ||
320 | } | ||
321 | if (strlcpy(caddr, addr, clen) >= clen) { | ||
322 | error("%s: host \"%s\" addr \"%s\" too long (max %lu)", | ||
323 | __func__, name, addr, (u_long)clen); | ||
324 | if (clen > 0) | ||
325 | *caddr = '\0'; | ||
326 | fail: | ||
327 | freeaddrinfo(res); | ||
328 | return NULL; | ||
329 | } | ||
330 | return res; | ||
331 | } | ||
332 | |||
333 | /* | ||
279 | * Check whether the cname is a permitted replacement for the hostname | 334 | * Check whether the cname is a permitted replacement for the hostname |
280 | * and perform the replacement if it is. | 335 | * and perform the replacement if it is. |
281 | * NB. this function must operate with a options having undefined members. | 336 | * NB. this function must operate with a options having undefined members. |
@@ -325,7 +380,7 @@ static struct addrinfo * | |||
325 | resolve_canonicalize(char **hostp, int port) | 380 | resolve_canonicalize(char **hostp, int port) |
326 | { | 381 | { |
327 | int i, ndots; | 382 | int i, ndots; |
328 | char *cp, *fullhost, cname_target[NI_MAXHOST]; | 383 | char *cp, *fullhost, newname[NI_MAXHOST]; |
329 | struct addrinfo *addrs; | 384 | struct addrinfo *addrs; |
330 | 385 | ||
331 | if (options.canonicalize_hostname == SSH_CANONICALISE_NO) | 386 | if (options.canonicalize_hostname == SSH_CANONICALISE_NO) |
@@ -339,6 +394,19 @@ resolve_canonicalize(char **hostp, int port) | |||
339 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) | 394 | options.canonicalize_hostname != SSH_CANONICALISE_ALWAYS) |
340 | return NULL; | 395 | return NULL; |
341 | 396 | ||
397 | /* Try numeric hostnames first */ | ||
398 | if ((addrs = resolve_addr(*hostp, port, | ||
399 | newname, sizeof(newname))) != NULL) { | ||
400 | debug2("%s: hostname %.100s is address", __func__, *hostp); | ||
401 | if (strcasecmp(*hostp, newname) != 0) { | ||
402 | debug2("%s: canonicalised address \"%s\" => \"%s\"", | ||
403 | __func__, *hostp, newname); | ||
404 | free(*hostp); | ||
405 | *hostp = xstrdup(newname); | ||
406 | } | ||
407 | return addrs; | ||
408 | } | ||
409 | |||
342 | /* Don't apply canonicalization to sufficiently-qualified hostnames */ | 410 | /* Don't apply canonicalization to sufficiently-qualified hostnames */ |
343 | ndots = 0; | 411 | ndots = 0; |
344 | for (cp = *hostp; *cp != '\0'; cp++) { | 412 | for (cp = *hostp; *cp != '\0'; cp++) { |
@@ -352,20 +420,20 @@ resolve_canonicalize(char **hostp, int port) | |||
352 | } | 420 | } |
353 | /* Attempt each supplied suffix */ | 421 | /* Attempt each supplied suffix */ |
354 | for (i = 0; i < options.num_canonical_domains; i++) { | 422 | for (i = 0; i < options.num_canonical_domains; i++) { |
355 | *cname_target = '\0'; | 423 | *newname = '\0'; |
356 | xasprintf(&fullhost, "%s.%s.", *hostp, | 424 | xasprintf(&fullhost, "%s.%s.", *hostp, |
357 | options.canonical_domains[i]); | 425 | options.canonical_domains[i]); |
358 | debug3("%s: attempting \"%s\" => \"%s\"", __func__, | 426 | debug3("%s: attempting \"%s\" => \"%s\"", __func__, |
359 | *hostp, fullhost); | 427 | *hostp, fullhost); |
360 | if ((addrs = resolve_host(fullhost, port, 0, | 428 | if ((addrs = resolve_host(fullhost, port, 0, |
361 | cname_target, sizeof(cname_target))) == NULL) { | 429 | newname, sizeof(newname))) == NULL) { |
362 | free(fullhost); | 430 | free(fullhost); |
363 | continue; | 431 | continue; |
364 | } | 432 | } |
365 | /* Remove trailing '.' */ | 433 | /* Remove trailing '.' */ |
366 | fullhost[strlen(fullhost) - 1] = '\0'; | 434 | fullhost[strlen(fullhost) - 1] = '\0'; |
367 | /* Follow CNAME if requested */ | 435 | /* Follow CNAME if requested */ |
368 | if (!check_follow_cname(&fullhost, cname_target)) { | 436 | if (!check_follow_cname(&fullhost, newname)) { |
369 | debug("Canonicalized hostname \"%s\" => \"%s\"", | 437 | debug("Canonicalized hostname \"%s\" => \"%s\"", |
370 | *hostp, fullhost); | 438 | *hostp, fullhost); |
371 | } | 439 | } |
@@ -384,27 +452,49 @@ resolve_canonicalize(char **hostp, int port) | |||
384 | * file if the user specifies a config file on the command line. | 452 | * file if the user specifies a config file on the command line. |
385 | */ | 453 | */ |
386 | static void | 454 | static void |
387 | process_config_files(struct passwd *pw) | 455 | process_config_files(const char *host_arg, struct passwd *pw, int post_canon) |
388 | { | 456 | { |
389 | char buf[MAXPATHLEN]; | 457 | char buf[PATH_MAX]; |
390 | int r; | 458 | int r; |
391 | 459 | ||
392 | if (config != NULL) { | 460 | if (config != NULL) { |
393 | if (strcasecmp(config, "none") != 0 && | 461 | if (strcasecmp(config, "none") != 0 && |
394 | !read_config_file(config, pw, host, &options, | 462 | !read_config_file(config, pw, host, host_arg, &options, |
395 | SSHCONF_USERCONF)) | 463 | SSHCONF_USERCONF | (post_canon ? SSHCONF_POSTCANON : 0))) |
396 | fatal("Can't open user config file %.100s: " | 464 | fatal("Can't open user config file %.100s: " |
397 | "%.100s", config, strerror(errno)); | 465 | "%.100s", config, strerror(errno)); |
398 | } else { | 466 | } else { |
399 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, | 467 | r = snprintf(buf, sizeof buf, "%s/%s", pw->pw_dir, |
400 | _PATH_SSH_USER_CONFFILE); | 468 | _PATH_SSH_USER_CONFFILE); |
401 | if (r > 0 && (size_t)r < sizeof(buf)) | 469 | if (r > 0 && (size_t)r < sizeof(buf)) |
402 | (void)read_config_file(buf, pw, host, &options, | 470 | (void)read_config_file(buf, pw, host, host_arg, |
403 | SSHCONF_CHECKPERM|SSHCONF_USERCONF); | 471 | &options, SSHCONF_CHECKPERM | SSHCONF_USERCONF | |
472 | (post_canon ? SSHCONF_POSTCANON : 0)); | ||
404 | 473 | ||
405 | /* Read systemwide configuration file after user config. */ | 474 | /* Read systemwide configuration file after user config. */ |
406 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, host, | 475 | (void)read_config_file(_PATH_HOST_CONFIG_FILE, pw, |
407 | &options, 0); | 476 | host, host_arg, &options, |
477 | post_canon ? SSHCONF_POSTCANON : 0); | ||
478 | } | ||
479 | } | ||
480 | |||
481 | /* Rewrite the port number in an addrinfo list of addresses */ | ||
482 | static void | ||
483 | set_addrinfo_port(struct addrinfo *addrs, int port) | ||
484 | { | ||
485 | struct addrinfo *addr; | ||
486 | |||
487 | for (addr = addrs; addr != NULL; addr = addr->ai_next) { | ||
488 | switch (addr->ai_family) { | ||
489 | case AF_INET: | ||
490 | ((struct sockaddr_in *)addr->ai_addr)-> | ||
491 | sin_port = htons(port); | ||
492 | break; | ||
493 | case AF_INET6: | ||
494 | ((struct sockaddr_in6 *)addr->ai_addr)-> | ||
495 | sin6_port = htons(port); | ||
496 | break; | ||
497 | } | ||
408 | } | 498 | } |
409 | } | 499 | } |
410 | 500 | ||
@@ -414,8 +504,8 @@ process_config_files(struct passwd *pw) | |||
414 | int | 504 | int |
415 | main(int ac, char **av) | 505 | main(int ac, char **av) |
416 | { | 506 | { |
417 | int i, r, opt, exit_status, use_syslog; | 507 | int i, r, opt, exit_status, use_syslog, config_test = 0; |
418 | char *p, *cp, *line, *argv0, buf[MAXPATHLEN], *host_arg, *logfile; | 508 | char *p, *cp, *line, *argv0, buf[PATH_MAX], *host_arg, *logfile; |
419 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; | 509 | char thishost[NI_MAXHOST], shorthost[NI_MAXHOST], portstr[NI_MAXSERV]; |
420 | char cname[NI_MAXHOST]; | 510 | char cname[NI_MAXHOST]; |
421 | struct stat st; | 511 | struct stat st; |
@@ -507,7 +597,7 @@ main(int ac, char **av) | |||
507 | 597 | ||
508 | again: | 598 | again: |
509 | while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" | 599 | while ((opt = getopt(ac, av, "1246ab:c:e:fgi:kl:m:no:p:qstvx" |
510 | "ACD:E:F:I:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { | 600 | "ACD:E:F:GI:KL:MNO:PQ:R:S:TVw:W:XYy")) != -1) { |
511 | switch (opt) { | 601 | switch (opt) { |
512 | case '1': | 602 | case '1': |
513 | options.protocol = SSH_PROTO_1; | 603 | options.protocol = SSH_PROTO_1; |
@@ -540,6 +630,9 @@ main(int ac, char **av) | |||
540 | case 'E': | 630 | case 'E': |
541 | logfile = xstrdup(optarg); | 631 | logfile = xstrdup(optarg); |
542 | break; | 632 | break; |
633 | case 'G': | ||
634 | config_test = 1; | ||
635 | break; | ||
543 | case 'Y': | 636 | case 'Y': |
544 | options.forward_x11 = 1; | 637 | options.forward_x11 = 1; |
545 | options.forward_x11_trusted = 1; | 638 | options.forward_x11_trusted = 1; |
@@ -585,6 +678,13 @@ main(int ac, char **av) | |||
585 | cp = key_alg_list(1, 0); | 678 | cp = key_alg_list(1, 0); |
586 | else if (strcmp(optarg, "key-plain") == 0) | 679 | else if (strcmp(optarg, "key-plain") == 0) |
587 | cp = key_alg_list(0, 1); | 680 | cp = key_alg_list(0, 1); |
681 | else if (strcmp(optarg, "protocol-version") == 0) { | ||
682 | #ifdef WITH_SSH1 | ||
683 | cp = xstrdup("1\n2"); | ||
684 | #else | ||
685 | cp = xstrdup("2"); | ||
686 | #endif | ||
687 | } | ||
588 | if (cp == NULL) | 688 | if (cp == NULL) |
589 | fatal("Unsupported query \"%s\"", optarg); | 689 | fatal("Unsupported query \"%s\"", optarg); |
590 | printf("%s\n", cp); | 690 | printf("%s\n", cp); |
@@ -788,9 +888,9 @@ main(int ac, char **av) | |||
788 | break; | 888 | break; |
789 | case 'o': | 889 | case 'o': |
790 | line = xstrdup(optarg); | 890 | line = xstrdup(optarg); |
791 | if (process_config_line(&options, pw, host ? host : "", | 891 | if (process_config_line(&options, pw, |
792 | line, "command-line", 0, NULL, SSHCONF_USERCONF) | 892 | host ? host : "", host ? host : "", line, |
793 | != 0) | 893 | "command-line", 0, NULL, SSHCONF_USERCONF) != 0) |
794 | exit(255); | 894 | exit(255); |
795 | free(line); | 895 | free(line); |
796 | break; | 896 | break; |
@@ -899,7 +999,7 @@ main(int ac, char **av) | |||
899 | ); | 999 | ); |
900 | 1000 | ||
901 | /* Parse the configuration files */ | 1001 | /* Parse the configuration files */ |
902 | process_config_files(pw); | 1002 | process_config_files(host_arg, pw, 0); |
903 | 1003 | ||
904 | /* Hostname canonicalisation needs a few options filled. */ | 1004 | /* Hostname canonicalisation needs a few options filled. */ |
905 | fill_default_options_for_canonicalization(&options); | 1005 | fill_default_options_for_canonicalization(&options); |
@@ -911,6 +1011,8 @@ main(int ac, char **av) | |||
911 | "h", host, (char *)NULL); | 1011 | "h", host, (char *)NULL); |
912 | free(host); | 1012 | free(host); |
913 | host = cp; | 1013 | host = cp; |
1014 | free(options.hostname); | ||
1015 | options.hostname = xstrdup(host); | ||
914 | } | 1016 | } |
915 | 1017 | ||
916 | /* If canonicalization requested then try to apply it */ | 1018 | /* If canonicalization requested then try to apply it */ |
@@ -945,12 +1047,22 @@ main(int ac, char **av) | |||
945 | } | 1047 | } |
946 | 1048 | ||
947 | /* | 1049 | /* |
948 | * If the target hostname has changed as a result of canonicalisation | 1050 | * If canonicalisation is enabled then re-parse the configuration |
949 | * then re-parse the configuration files as new stanzas may match. | 1051 | * files as new stanzas may match. |
950 | */ | 1052 | */ |
951 | if (strcasecmp(host_arg, host) != 0) { | 1053 | if (options.canonicalize_hostname != 0) { |
952 | debug("Hostname has changed; re-reading configuration"); | 1054 | debug("Re-reading configuration after hostname " |
953 | process_config_files(pw); | 1055 | "canonicalisation"); |
1056 | free(options.hostname); | ||
1057 | options.hostname = xstrdup(host); | ||
1058 | process_config_files(host_arg, pw, 1); | ||
1059 | /* | ||
1060 | * Address resolution happens early with canonicalisation | ||
1061 | * enabled and the port number may have changed since, so | ||
1062 | * reset it in address list | ||
1063 | */ | ||
1064 | if (addrs != NULL && options.port > 0) | ||
1065 | set_addrinfo_port(addrs, options.port); | ||
954 | } | 1066 | } |
955 | 1067 | ||
956 | /* Fill configuration defaults. */ | 1068 | /* Fill configuration defaults. */ |
@@ -967,6 +1079,12 @@ main(int ac, char **av) | |||
967 | strcmp(options.proxy_command, "-") == 0 && | 1079 | strcmp(options.proxy_command, "-") == 0 && |
968 | options.proxy_use_fdpass) | 1080 | options.proxy_use_fdpass) |
969 | fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); | 1081 | fatal("ProxyCommand=- and ProxyUseFDPass are incompatible"); |
1082 | if (options.control_persist && | ||
1083 | options.update_hostkeys == SSH_UPDATE_HOSTKEYS_ASK) { | ||
1084 | debug("UpdateHostKeys=ask is incompatible with ControlPersist; " | ||
1085 | "disabling"); | ||
1086 | options.update_hostkeys = 0; | ||
1087 | } | ||
970 | #ifndef HAVE_CYGWIN | 1088 | #ifndef HAVE_CYGWIN |
971 | if (original_effective_uid != 0) | 1089 | if (original_effective_uid != 0) |
972 | options.use_privileged_port = 0; | 1090 | options.use_privileged_port = 0; |
@@ -1052,6 +1170,11 @@ main(int ac, char **av) | |||
1052 | } | 1170 | } |
1053 | free(conn_hash_hex); | 1171 | free(conn_hash_hex); |
1054 | 1172 | ||
1173 | if (config_test) { | ||
1174 | dump_client_config(&options, host); | ||
1175 | exit(0); | ||
1176 | } | ||
1177 | |||
1055 | if (muxclient_command != 0 && options.control_path == NULL) | 1178 | if (muxclient_command != 0 && options.control_path == NULL) |
1056 | fatal("No ControlPath specified for \"-O\" command"); | 1179 | fatal("No ControlPath specified for \"-O\" command"); |
1057 | if (options.control_path != NULL) | 1180 | if (options.control_path != NULL) |
@@ -1107,26 +1230,26 @@ main(int ac, char **av) | |||
1107 | PRIV_START; | 1230 | PRIV_START; |
1108 | sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, | 1231 | sensitive_data.keys[0] = key_load_private_type(KEY_RSA1, |
1109 | _PATH_HOST_KEY_FILE, "", NULL, NULL); | 1232 | _PATH_HOST_KEY_FILE, "", NULL, NULL); |
1110 | sensitive_data.keys[1] = key_load_private_cert(KEY_DSA, | ||
1111 | _PATH_HOST_DSA_KEY_FILE, "", NULL); | ||
1112 | #ifdef OPENSSL_HAS_ECC | 1233 | #ifdef OPENSSL_HAS_ECC |
1113 | sensitive_data.keys[2] = key_load_private_cert(KEY_ECDSA, | 1234 | sensitive_data.keys[1] = key_load_private_cert(KEY_ECDSA, |
1114 | _PATH_HOST_ECDSA_KEY_FILE, "", NULL); | 1235 | _PATH_HOST_ECDSA_KEY_FILE, "", NULL); |
1115 | #endif | 1236 | #endif |
1237 | sensitive_data.keys[2] = key_load_private_cert(KEY_ED25519, | ||
1238 | _PATH_HOST_ED25519_KEY_FILE, "", NULL); | ||
1116 | sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, | 1239 | sensitive_data.keys[3] = key_load_private_cert(KEY_RSA, |
1117 | _PATH_HOST_RSA_KEY_FILE, "", NULL); | 1240 | _PATH_HOST_RSA_KEY_FILE, "", NULL); |
1118 | sensitive_data.keys[4] = key_load_private_cert(KEY_ED25519, | 1241 | sensitive_data.keys[4] = key_load_private_cert(KEY_DSA, |
1119 | _PATH_HOST_ED25519_KEY_FILE, "", NULL); | 1242 | _PATH_HOST_DSA_KEY_FILE, "", NULL); |
1120 | sensitive_data.keys[5] = key_load_private_type(KEY_DSA, | ||
1121 | _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); | ||
1122 | #ifdef OPENSSL_HAS_ECC | 1243 | #ifdef OPENSSL_HAS_ECC |
1123 | sensitive_data.keys[6] = key_load_private_type(KEY_ECDSA, | 1244 | sensitive_data.keys[5] = key_load_private_type(KEY_ECDSA, |
1124 | _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); | 1245 | _PATH_HOST_ECDSA_KEY_FILE, "", NULL, NULL); |
1125 | #endif | 1246 | #endif |
1247 | sensitive_data.keys[6] = key_load_private_type(KEY_ED25519, | ||
1248 | _PATH_HOST_ED25519_KEY_FILE, "", NULL, NULL); | ||
1126 | sensitive_data.keys[7] = key_load_private_type(KEY_RSA, | 1249 | sensitive_data.keys[7] = key_load_private_type(KEY_RSA, |
1127 | _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); | 1250 | _PATH_HOST_RSA_KEY_FILE, "", NULL, NULL); |
1128 | sensitive_data.keys[8] = key_load_private_type(KEY_ED25519, | 1251 | sensitive_data.keys[8] = key_load_private_type(KEY_DSA, |
1129 | _PATH_HOST_ED25519_KEY_FILE, "", NULL, NULL); | 1252 | _PATH_HOST_DSA_KEY_FILE, "", NULL, NULL); |
1130 | PRIV_END; | 1253 | PRIV_END; |
1131 | 1254 | ||
1132 | if (options.hostbased_authentication == 1 && | 1255 | if (options.hostbased_authentication == 1 && |
@@ -1135,26 +1258,26 @@ main(int ac, char **av) | |||
1135 | sensitive_data.keys[6] == NULL && | 1258 | sensitive_data.keys[6] == NULL && |
1136 | sensitive_data.keys[7] == NULL && | 1259 | sensitive_data.keys[7] == NULL && |
1137 | sensitive_data.keys[8] == NULL) { | 1260 | sensitive_data.keys[8] == NULL) { |
1138 | sensitive_data.keys[1] = key_load_cert( | ||
1139 | _PATH_HOST_DSA_KEY_FILE); | ||
1140 | #ifdef OPENSSL_HAS_ECC | 1261 | #ifdef OPENSSL_HAS_ECC |
1141 | sensitive_data.keys[2] = key_load_cert( | 1262 | sensitive_data.keys[1] = key_load_cert( |
1142 | _PATH_HOST_ECDSA_KEY_FILE); | 1263 | _PATH_HOST_ECDSA_KEY_FILE); |
1143 | #endif | 1264 | #endif |
1265 | sensitive_data.keys[2] = key_load_cert( | ||
1266 | _PATH_HOST_ED25519_KEY_FILE); | ||
1144 | sensitive_data.keys[3] = key_load_cert( | 1267 | sensitive_data.keys[3] = key_load_cert( |
1145 | _PATH_HOST_RSA_KEY_FILE); | 1268 | _PATH_HOST_RSA_KEY_FILE); |
1146 | sensitive_data.keys[4] = key_load_cert( | 1269 | sensitive_data.keys[4] = key_load_cert( |
1147 | _PATH_HOST_ED25519_KEY_FILE); | 1270 | _PATH_HOST_DSA_KEY_FILE); |
1148 | sensitive_data.keys[5] = key_load_public( | ||
1149 | _PATH_HOST_DSA_KEY_FILE, NULL); | ||
1150 | #ifdef OPENSSL_HAS_ECC | 1271 | #ifdef OPENSSL_HAS_ECC |
1151 | sensitive_data.keys[6] = key_load_public( | 1272 | sensitive_data.keys[5] = key_load_public( |
1152 | _PATH_HOST_ECDSA_KEY_FILE, NULL); | 1273 | _PATH_HOST_ECDSA_KEY_FILE, NULL); |
1153 | #endif | 1274 | #endif |
1275 | sensitive_data.keys[6] = key_load_public( | ||
1276 | _PATH_HOST_ED25519_KEY_FILE, NULL); | ||
1154 | sensitive_data.keys[7] = key_load_public( | 1277 | sensitive_data.keys[7] = key_load_public( |
1155 | _PATH_HOST_RSA_KEY_FILE, NULL); | 1278 | _PATH_HOST_RSA_KEY_FILE, NULL); |
1156 | sensitive_data.keys[8] = key_load_public( | 1279 | sensitive_data.keys[8] = key_load_public( |
1157 | _PATH_HOST_ED25519_KEY_FILE, NULL); | 1280 | _PATH_HOST_DSA_KEY_FILE, NULL); |
1158 | sensitive_data.external_keysign = 1; | 1281 | sensitive_data.external_keysign = 1; |
1159 | } | 1282 | } |
1160 | } | 1283 | } |
@@ -1460,10 +1583,16 @@ ssh_init_forwarding(void) | |||
1460 | static void | 1583 | static void |
1461 | check_agent_present(void) | 1584 | check_agent_present(void) |
1462 | { | 1585 | { |
1586 | int r; | ||
1587 | |||
1463 | if (options.forward_agent) { | 1588 | if (options.forward_agent) { |
1464 | /* Clear agent forwarding if we don't have an agent. */ | 1589 | /* Clear agent forwarding if we don't have an agent. */ |
1465 | if (!ssh_agent_present()) | 1590 | if ((r = ssh_get_authentication_socket(NULL)) != 0) { |
1466 | options.forward_agent = 0; | 1591 | options.forward_agent = 0; |
1592 | if (r != SSH_ERR_AGENT_NOT_PRESENT) | ||
1593 | debug("ssh_get_authentication_socket: %s", | ||
1594 | ssh_err(r)); | ||
1595 | } | ||
1467 | } | 1596 | } |
1468 | } | 1597 | } |
1469 | 1598 | ||