diff options
author | Colin Watson <cjwatson@debian.org> | 2013-09-14 15:43:03 +0100 |
---|---|---|
committer | Colin Watson <cjwatson@debian.org> | 2013-09-14 15:43:03 +0100 |
commit | 8faf8c84430cf3c19705b1d9f8889d256e7fd1fd (patch) | |
tree | e6cb74192adb00fda5e4d1457547851d7e0d86af /sshd.c | |
parent | 328b60656f29db6306994d7498dede386ec2d1c3 (diff) | |
parent | c41345ad7ee5a22689e2c009595e85fa27b4b39a (diff) |
merge 6.3p1
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 125 |
1 files changed, 104 insertions, 21 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.397 2013/02/11 21:21:58 dtucker Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.404 2013/07/19 07:37:48 markus 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 |
@@ -106,6 +106,7 @@ | |||
106 | #include "canohost.h" | 106 | #include "canohost.h" |
107 | #include "hostfile.h" | 107 | #include "hostfile.h" |
108 | #include "auth.h" | 108 | #include "auth.h" |
109 | #include "authfd.h" | ||
109 | #include "misc.h" | 110 | #include "misc.h" |
110 | #include "msg.h" | 111 | #include "msg.h" |
111 | #include "dispatch.h" | 112 | #include "dispatch.h" |
@@ -198,6 +199,10 @@ char *server_version_string = NULL; | |||
198 | /* for rekeying XXX fixme */ | 199 | /* for rekeying XXX fixme */ |
199 | Kex *xxx_kex; | 200 | Kex *xxx_kex; |
200 | 201 | ||
202 | /* Daemon's agent connection */ | ||
203 | AuthenticationConnection *auth_conn = NULL; | ||
204 | int have_agent = 0; | ||
205 | |||
201 | /* | 206 | /* |
202 | * Any really sensitive data in the application is contained in this | 207 | * Any really sensitive data in the application is contained in this |
203 | * structure. The idea is that this structure could be locked into memory so | 208 | * structure. The idea is that this structure could be locked into memory so |
@@ -210,6 +215,7 @@ struct { | |||
210 | Key *server_key; /* ephemeral server key */ | 215 | Key *server_key; /* ephemeral server key */ |
211 | Key *ssh1_host_key; /* ssh1 host key */ | 216 | Key *ssh1_host_key; /* ssh1 host key */ |
212 | Key **host_keys; /* all private host keys */ | 217 | Key **host_keys; /* all private host keys */ |
218 | Key **host_pubkeys; /* all public host keys */ | ||
213 | Key **host_certificates; /* all public host certificates */ | 219 | Key **host_certificates; /* all public host certificates */ |
214 | int have_ssh1_key; | 220 | int have_ssh1_key; |
215 | int have_ssh2_key; | 221 | int have_ssh2_key; |
@@ -657,6 +663,8 @@ privsep_preauth(Authctxt *authctxt) | |||
657 | debug2("Network child is on pid %ld", (long)pid); | 663 | debug2("Network child is on pid %ld", (long)pid); |
658 | 664 | ||
659 | pmonitor->m_pid = pid; | 665 | pmonitor->m_pid = pid; |
666 | if (have_agent) | ||
667 | auth_conn = ssh_get_authentication_connection(); | ||
660 | if (box != NULL) | 668 | if (box != NULL) |
661 | ssh_sandbox_parent_preauth(box, pid); | 669 | ssh_sandbox_parent_preauth(box, pid); |
662 | monitor_child_preauth(authctxt, pmonitor); | 670 | monitor_child_preauth(authctxt, pmonitor); |
@@ -771,6 +779,8 @@ list_hostkey_types(void) | |||
771 | for (i = 0; i < options.num_host_key_files; i++) { | 779 | for (i = 0; i < options.num_host_key_files; i++) { |
772 | key = sensitive_data.host_keys[i]; | 780 | key = sensitive_data.host_keys[i]; |
773 | if (key == NULL) | 781 | if (key == NULL) |
782 | key = sensitive_data.host_pubkeys[i]; | ||
783 | if (key == NULL) | ||
774 | continue; | 784 | continue; |
775 | switch (key->type) { | 785 | switch (key->type) { |
776 | case KEY_RSA: | 786 | case KEY_RSA: |
@@ -823,6 +833,8 @@ get_hostkey_by_type(int type, int need_private) | |||
823 | break; | 833 | break; |
824 | default: | 834 | default: |
825 | key = sensitive_data.host_keys[i]; | 835 | key = sensitive_data.host_keys[i]; |
836 | if (key == NULL && !need_private) | ||
837 | key = sensitive_data.host_pubkeys[i]; | ||
826 | break; | 838 | break; |
827 | } | 839 | } |
828 | if (key != NULL && key->type == type) | 840 | if (key != NULL && key->type == type) |
@@ -852,6 +864,14 @@ get_hostkey_by_index(int ind) | |||
852 | return (sensitive_data.host_keys[ind]); | 864 | return (sensitive_data.host_keys[ind]); |
853 | } | 865 | } |
854 | 866 | ||
867 | Key * | ||
868 | get_hostkey_public_by_index(int ind) | ||
869 | { | ||
870 | if (ind < 0 || ind >= options.num_host_key_files) | ||
871 | return (NULL); | ||
872 | return (sensitive_data.host_pubkeys[ind]); | ||
873 | } | ||
874 | |||
855 | int | 875 | int |
856 | get_hostkey_index(Key *key) | 876 | get_hostkey_index(Key *key) |
857 | { | 877 | { |
@@ -864,6 +884,8 @@ get_hostkey_index(Key *key) | |||
864 | } else { | 884 | } else { |
865 | if (key == sensitive_data.host_keys[i]) | 885 | if (key == sensitive_data.host_keys[i]) |
866 | return (i); | 886 | return (i); |
887 | if (key == sensitive_data.host_pubkeys[i]) | ||
888 | return (i); | ||
867 | } | 889 | } |
868 | } | 890 | } |
869 | return (-1); | 891 | return (-1); |
@@ -904,8 +926,9 @@ usage(void) | |||
904 | SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); | 926 | SSH_RELEASE, SSLeay_version(SSLEAY_VERSION)); |
905 | fprintf(stderr, | 927 | fprintf(stderr, |
906 | "usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" | 928 | "usage: sshd [-46DdeiqTt] [-b bits] [-C connection_spec] [-c host_cert_file]\n" |
907 | " [-f config_file] [-g login_grace_time] [-h host_key_file]\n" | 929 | " [-E log_file] [-f config_file] [-g login_grace_time]\n" |
908 | " [-k key_gen_time] [-o option] [-p port] [-u len]\n" | 930 | " [-h host_key_file] [-k key_gen_time] [-o option] [-p port]\n" |
931 | " [-u len]\n" | ||
909 | ); | 932 | ); |
910 | exit(1); | 933 | exit(1); |
911 | } | 934 | } |
@@ -976,7 +999,7 @@ recv_rexec_state(int fd, Buffer *conf) | |||
976 | cp = buffer_get_string(&m, &len); | 999 | cp = buffer_get_string(&m, &len); |
977 | if (conf != NULL) | 1000 | if (conf != NULL) |
978 | buffer_append(conf, cp, len + 1); | 1001 | buffer_append(conf, cp, len + 1); |
979 | xfree(cp); | 1002 | free(cp); |
980 | 1003 | ||
981 | if (buffer_get_int(&m)) { | 1004 | if (buffer_get_int(&m)) { |
982 | if (sensitive_data.server_key != NULL) | 1005 | if (sensitive_data.server_key != NULL) |
@@ -1027,7 +1050,9 @@ server_accept_inetd(int *sock_in, int *sock_out) | |||
1027 | if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { | 1050 | if ((fd = open(_PATH_DEVNULL, O_RDWR, 0)) != -1) { |
1028 | dup2(fd, STDIN_FILENO); | 1051 | dup2(fd, STDIN_FILENO); |
1029 | dup2(fd, STDOUT_FILENO); | 1052 | dup2(fd, STDOUT_FILENO); |
1030 | if (fd > STDOUT_FILENO) | 1053 | if (!log_stderr) |
1054 | dup2(fd, STDERR_FILENO); | ||
1055 | if (fd > (log_stderr ? STDERR_FILENO : STDOUT_FILENO)) | ||
1031 | close(fd); | 1056 | close(fd); |
1032 | } | 1057 | } |
1033 | debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out); | 1058 | debug("inetd sockets after dupping: %d, %d", *sock_in, *sock_out); |
@@ -1138,7 +1163,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1138 | if (received_sighup) | 1163 | if (received_sighup) |
1139 | sighup_restart(); | 1164 | sighup_restart(); |
1140 | if (fdset != NULL) | 1165 | if (fdset != NULL) |
1141 | xfree(fdset); | 1166 | free(fdset); |
1142 | fdset = (fd_set *)xcalloc(howmany(maxfd + 1, NFDBITS), | 1167 | fdset = (fd_set *)xcalloc(howmany(maxfd + 1, NFDBITS), |
1143 | sizeof(fd_mask)); | 1168 | sizeof(fd_mask)); |
1144 | 1169 | ||
@@ -1187,8 +1212,8 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1187 | *newsock = accept(listen_socks[i], | 1212 | *newsock = accept(listen_socks[i], |
1188 | (struct sockaddr *)&from, &fromlen); | 1213 | (struct sockaddr *)&from, &fromlen); |
1189 | if (*newsock < 0) { | 1214 | if (*newsock < 0) { |
1190 | if (errno != EINTR && errno != EAGAIN && | 1215 | if (errno != EINTR && errno != EWOULDBLOCK && |
1191 | errno != EWOULDBLOCK) | 1216 | errno != ECONNABORTED && errno != EAGAIN) |
1192 | error("accept: %.100s", | 1217 | error("accept: %.100s", |
1193 | strerror(errno)); | 1218 | strerror(errno)); |
1194 | if (errno == EMFILE || errno == ENFILE) | 1219 | if (errno == EMFILE || errno == ENFILE) |
@@ -1339,12 +1364,14 @@ main(int ac, char **av) | |||
1339 | int sock_in = -1, sock_out = -1, newsock = -1; | 1364 | int sock_in = -1, sock_out = -1, newsock = -1; |
1340 | const char *remote_ip; | 1365 | const char *remote_ip; |
1341 | int remote_port; | 1366 | int remote_port; |
1342 | char *line; | 1367 | char *line, *logfile = NULL; |
1343 | int config_s[2] = { -1 , -1 }; | 1368 | int config_s[2] = { -1 , -1 }; |
1344 | u_int n; | 1369 | u_int n; |
1345 | u_int64_t ibytes, obytes; | 1370 | u_int64_t ibytes, obytes; |
1346 | mode_t new_umask; | 1371 | mode_t new_umask; |
1347 | Key *key; | 1372 | Key *key; |
1373 | Key *pubkey; | ||
1374 | int keytype; | ||
1348 | Authctxt *authctxt; | 1375 | Authctxt *authctxt; |
1349 | struct connection_info *connection_info = get_connection_info(0, 0); | 1376 | struct connection_info *connection_info = get_connection_info(0, 0); |
1350 | 1377 | ||
@@ -1377,7 +1404,7 @@ main(int ac, char **av) | |||
1377 | initialize_server_options(&options); | 1404 | initialize_server_options(&options); |
1378 | 1405 | ||
1379 | /* Parse command-line arguments. */ | 1406 | /* Parse command-line arguments. */ |
1380 | while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeiqrtQRT46")) != -1) { | 1407 | while ((opt = getopt(ac, av, "f:p:b:k:h:g:u:o:C:dDeE:iqrtQRT46")) != -1) { |
1381 | switch (opt) { | 1408 | switch (opt) { |
1382 | case '4': | 1409 | case '4': |
1383 | options.address_family = AF_INET; | 1410 | options.address_family = AF_INET; |
@@ -1406,6 +1433,9 @@ main(int ac, char **av) | |||
1406 | case 'D': | 1433 | case 'D': |
1407 | no_daemon_flag = 1; | 1434 | no_daemon_flag = 1; |
1408 | break; | 1435 | break; |
1436 | case 'E': | ||
1437 | logfile = xstrdup(optarg); | ||
1438 | /* FALLTHROUGH */ | ||
1409 | case 'e': | 1439 | case 'e': |
1410 | log_stderr = 1; | 1440 | log_stderr = 1; |
1411 | break; | 1441 | break; |
@@ -1484,7 +1514,7 @@ main(int ac, char **av) | |||
1484 | if (process_server_config_line(&options, line, | 1514 | if (process_server_config_line(&options, line, |
1485 | "command-line", 0, NULL, NULL) != 0) | 1515 | "command-line", 0, NULL, NULL) != 0) |
1486 | exit(1); | 1516 | exit(1); |
1487 | xfree(line); | 1517 | free(line); |
1488 | break; | 1518 | break; |
1489 | case '?': | 1519 | case '?': |
1490 | default: | 1520 | default: |
@@ -1503,6 +1533,11 @@ main(int ac, char **av) | |||
1503 | 1533 | ||
1504 | OpenSSL_add_all_algorithms(); | 1534 | OpenSSL_add_all_algorithms(); |
1505 | 1535 | ||
1536 | /* If requested, redirect the logs to the specified logfile. */ | ||
1537 | if (logfile != NULL) { | ||
1538 | log_redirect_stderr_to(logfile); | ||
1539 | free(logfile); | ||
1540 | } | ||
1506 | /* | 1541 | /* |
1507 | * Force logging to stderr until we have loaded the private host | 1542 | * Force logging to stderr until we have loaded the private host |
1508 | * key (unless started from inetd) | 1543 | * key (unless started from inetd) |
@@ -1611,27 +1646,50 @@ main(int ac, char **av) | |||
1611 | } else { | 1646 | } else { |
1612 | memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd)); | 1647 | memset(privsep_pw->pw_passwd, 0, strlen(privsep_pw->pw_passwd)); |
1613 | privsep_pw = pwcopy(privsep_pw); | 1648 | privsep_pw = pwcopy(privsep_pw); |
1614 | xfree(privsep_pw->pw_passwd); | 1649 | free(privsep_pw->pw_passwd); |
1615 | privsep_pw->pw_passwd = xstrdup("*"); | 1650 | privsep_pw->pw_passwd = xstrdup("*"); |
1616 | } | 1651 | } |
1617 | endpwent(); | 1652 | endpwent(); |
1618 | 1653 | ||
1619 | /* load private host keys */ | 1654 | /* load host keys */ |
1620 | sensitive_data.host_keys = xcalloc(options.num_host_key_files, | 1655 | sensitive_data.host_keys = xcalloc(options.num_host_key_files, |
1621 | sizeof(Key *)); | 1656 | sizeof(Key *)); |
1622 | for (i = 0; i < options.num_host_key_files; i++) | 1657 | sensitive_data.host_pubkeys = xcalloc(options.num_host_key_files, |
1658 | sizeof(Key *)); | ||
1659 | for (i = 0; i < options.num_host_key_files; i++) { | ||
1623 | sensitive_data.host_keys[i] = NULL; | 1660 | sensitive_data.host_keys[i] = NULL; |
1661 | sensitive_data.host_pubkeys[i] = NULL; | ||
1662 | } | ||
1663 | |||
1664 | if (options.host_key_agent) { | ||
1665 | if (strcmp(options.host_key_agent, SSH_AUTHSOCKET_ENV_NAME)) | ||
1666 | setenv(SSH_AUTHSOCKET_ENV_NAME, | ||
1667 | options.host_key_agent, 1); | ||
1668 | have_agent = ssh_agent_present(); | ||
1669 | } | ||
1624 | 1670 | ||
1625 | for (i = 0; i < options.num_host_key_files; i++) { | 1671 | for (i = 0; i < options.num_host_key_files; i++) { |
1626 | key = key_load_private(options.host_key_files[i], "", NULL); | 1672 | key = key_load_private(options.host_key_files[i], "", NULL); |
1673 | pubkey = key_load_public(options.host_key_files[i], NULL); | ||
1627 | sensitive_data.host_keys[i] = key; | 1674 | sensitive_data.host_keys[i] = key; |
1628 | if (key == NULL) { | 1675 | sensitive_data.host_pubkeys[i] = pubkey; |
1676 | |||
1677 | if (key == NULL && pubkey != NULL && pubkey->type != KEY_RSA1 && | ||
1678 | have_agent) { | ||
1679 | debug("will rely on agent for hostkey %s", | ||
1680 | options.host_key_files[i]); | ||
1681 | keytype = pubkey->type; | ||
1682 | } else if (key != NULL) { | ||
1683 | keytype = key->type; | ||
1684 | } else { | ||
1629 | error("Could not load host key: %s", | 1685 | error("Could not load host key: %s", |
1630 | options.host_key_files[i]); | 1686 | options.host_key_files[i]); |
1631 | sensitive_data.host_keys[i] = NULL; | 1687 | sensitive_data.host_keys[i] = NULL; |
1688 | sensitive_data.host_pubkeys[i] = NULL; | ||
1632 | continue; | 1689 | continue; |
1633 | } | 1690 | } |
1634 | switch (key->type) { | 1691 | |
1692 | switch (keytype) { | ||
1635 | case KEY_RSA1: | 1693 | case KEY_RSA1: |
1636 | sensitive_data.ssh1_host_key = key; | 1694 | sensitive_data.ssh1_host_key = key; |
1637 | sensitive_data.have_ssh1_key = 1; | 1695 | sensitive_data.have_ssh1_key = 1; |
@@ -1642,8 +1700,8 @@ main(int ac, char **av) | |||
1642 | sensitive_data.have_ssh2_key = 1; | 1700 | sensitive_data.have_ssh2_key = 1; |
1643 | break; | 1701 | break; |
1644 | } | 1702 | } |
1645 | debug("private host key: #%d type %d %s", i, key->type, | 1703 | debug("private host key: #%d type %d %s", i, keytype, |
1646 | key_type(key)); | 1704 | key_type(key ? key : pubkey)); |
1647 | } | 1705 | } |
1648 | if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { | 1706 | if ((options.protocol & SSH_PROTO_1) && !sensitive_data.have_ssh1_key) { |
1649 | logit("Disabling protocol version 1. Could not load host key"); | 1707 | logit("Disabling protocol version 1. Could not load host key"); |
@@ -1813,7 +1871,8 @@ main(int ac, char **av) | |||
1813 | 1871 | ||
1814 | /* Chdir to the root directory so that the current disk can be | 1872 | /* Chdir to the root directory so that the current disk can be |
1815 | unmounted if desired. */ | 1873 | unmounted if desired. */ |
1816 | chdir("/"); | 1874 | if (chdir("/") == -1) |
1875 | error("chdir(\"/\"): %s", strerror(errno)); | ||
1817 | 1876 | ||
1818 | /* ignore SIGPIPE */ | 1877 | /* ignore SIGPIPE */ |
1819 | signal(SIGPIPE, SIG_IGN); | 1878 | signal(SIGPIPE, SIG_IGN); |
@@ -2069,9 +2128,11 @@ main(int ac, char **av) | |||
2069 | buffer_init(&loginmsg); | 2128 | buffer_init(&loginmsg); |
2070 | auth_debug_reset(); | 2129 | auth_debug_reset(); |
2071 | 2130 | ||
2072 | if (use_privsep) | 2131 | if (use_privsep) { |
2073 | if (privsep_preauth(authctxt) == 1) | 2132 | if (privsep_preauth(authctxt) == 1) |
2074 | goto authenticated; | 2133 | goto authenticated; |
2134 | } else if (compat20 && have_agent) | ||
2135 | auth_conn = ssh_get_authentication_connection(); | ||
2075 | 2136 | ||
2076 | /* perform the key exchange */ | 2137 | /* perform the key exchange */ |
2077 | /* authenticate user and start session */ | 2138 | /* authenticate user and start session */ |
@@ -2358,7 +2419,7 @@ do_ssh1_kex(void) | |||
2358 | MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); | 2419 | MD5_Update(&md, sensitive_data.ssh1_cookie, SSH_SESSION_KEY_LENGTH); |
2359 | MD5_Final(session_key + 16, &md); | 2420 | MD5_Final(session_key + 16, &md); |
2360 | memset(buf, 0, bytes); | 2421 | memset(buf, 0, bytes); |
2361 | xfree(buf); | 2422 | free(buf); |
2362 | for (i = 0; i < 16; i++) | 2423 | for (i = 0; i < 16; i++) |
2363 | session_id[i] = session_key[i] ^ session_key[i + 16]; | 2424 | session_id[i] = session_key[i] ^ session_key[i + 16]; |
2364 | } | 2425 | } |
@@ -2385,6 +2446,23 @@ do_ssh1_kex(void) | |||
2385 | packet_write_wait(); | 2446 | packet_write_wait(); |
2386 | } | 2447 | } |
2387 | 2448 | ||
2449 | void | ||
2450 | sshd_hostkey_sign(Key *privkey, Key *pubkey, u_char **signature, u_int *slen, | ||
2451 | u_char *data, u_int dlen) | ||
2452 | { | ||
2453 | if (privkey) { | ||
2454 | if (PRIVSEP(key_sign(privkey, signature, slen, data, dlen) < 0)) | ||
2455 | fatal("%s: key_sign failed", __func__); | ||
2456 | } else if (use_privsep) { | ||
2457 | if (mm_key_sign(pubkey, signature, slen, data, dlen) < 0) | ||
2458 | fatal("%s: pubkey_sign failed", __func__); | ||
2459 | } else { | ||
2460 | if (ssh_agent_sign(auth_conn, pubkey, signature, slen, data, | ||
2461 | dlen)) | ||
2462 | fatal("%s: ssh_agent_sign failed", __func__); | ||
2463 | } | ||
2464 | } | ||
2465 | |||
2388 | /* | 2466 | /* |
2389 | * SSH2 key exchange: diffie-hellman-group1-sha1 | 2467 | * SSH2 key exchange: diffie-hellman-group1-sha1 |
2390 | */ | 2468 | */ |
@@ -2416,6 +2494,10 @@ do_ssh2_kex(void) | |||
2416 | if (options.kex_algorithms != NULL) | 2494 | if (options.kex_algorithms != NULL) |
2417 | myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; | 2495 | myproposal[PROPOSAL_KEX_ALGS] = options.kex_algorithms; |
2418 | 2496 | ||
2497 | if (options.rekey_limit || options.rekey_interval) | ||
2498 | packet_set_rekey_limits((u_int32_t)options.rekey_limit, | ||
2499 | (time_t)options.rekey_interval); | ||
2500 | |||
2419 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); | 2501 | myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = list_hostkey_types(); |
2420 | 2502 | ||
2421 | #ifdef GSSAPI | 2503 | #ifdef GSSAPI |
@@ -2480,6 +2562,7 @@ do_ssh2_kex(void) | |||
2480 | kex->load_host_public_key=&get_hostkey_public_by_type; | 2562 | kex->load_host_public_key=&get_hostkey_public_by_type; |
2481 | kex->load_host_private_key=&get_hostkey_private_by_type; | 2563 | kex->load_host_private_key=&get_hostkey_private_by_type; |
2482 | kex->host_key_index=&get_hostkey_index; | 2564 | kex->host_key_index=&get_hostkey_index; |
2565 | kex->sign = sshd_hostkey_sign; | ||
2483 | 2566 | ||
2484 | xxx_kex = kex; | 2567 | xxx_kex = kex; |
2485 | 2568 | ||