diff options
Diffstat (limited to 'sshd.c')
-rw-r--r-- | sshd.c | 232 |
1 files changed, 143 insertions, 89 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshd.c,v 1.506 2018/03/03 03:15:51 djm Exp $ */ | 1 | /* $OpenBSD: sshd.c,v 1.514 2018/08/13 02:41:05 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 |
@@ -91,7 +91,7 @@ | |||
91 | #include "sshpty.h" | 91 | #include "sshpty.h" |
92 | #include "packet.h" | 92 | #include "packet.h" |
93 | #include "log.h" | 93 | #include "log.h" |
94 | #include "buffer.h" | 94 | #include "sshbuf.h" |
95 | #include "misc.h" | 95 | #include "misc.h" |
96 | #include "match.h" | 96 | #include "match.h" |
97 | #include "servconf.h" | 97 | #include "servconf.h" |
@@ -99,7 +99,7 @@ | |||
99 | #include "compat.h" | 99 | #include "compat.h" |
100 | #include "cipher.h" | 100 | #include "cipher.h" |
101 | #include "digest.h" | 101 | #include "digest.h" |
102 | #include "key.h" | 102 | #include "sshkey.h" |
103 | #include "kex.h" | 103 | #include "kex.h" |
104 | #include "myproposal.h" | 104 | #include "myproposal.h" |
105 | #include "authfile.h" | 105 | #include "authfile.h" |
@@ -237,10 +237,10 @@ Authctxt *the_authctxt = NULL; | |||
237 | struct sshauthopt *auth_opts = NULL; | 237 | struct sshauthopt *auth_opts = NULL; |
238 | 238 | ||
239 | /* sshd_config buffer */ | 239 | /* sshd_config buffer */ |
240 | Buffer cfg; | 240 | struct sshbuf *cfg; |
241 | 241 | ||
242 | /* message to be displayed after login */ | 242 | /* message to be displayed after login */ |
243 | Buffer loginmsg; | 243 | struct sshbuf *loginmsg; |
244 | 244 | ||
245 | /* Unprivileged user */ | 245 | /* Unprivileged user */ |
246 | struct passwd *privsep_pw = NULL; | 246 | struct passwd *privsep_pw = NULL; |
@@ -473,11 +473,11 @@ destroy_sensitive_data(void) | |||
473 | 473 | ||
474 | for (i = 0; i < options.num_host_key_files; i++) { | 474 | for (i = 0; i < options.num_host_key_files; i++) { |
475 | if (sensitive_data.host_keys[i]) { | 475 | if (sensitive_data.host_keys[i]) { |
476 | key_free(sensitive_data.host_keys[i]); | 476 | sshkey_free(sensitive_data.host_keys[i]); |
477 | sensitive_data.host_keys[i] = NULL; | 477 | sensitive_data.host_keys[i] = NULL; |
478 | } | 478 | } |
479 | if (sensitive_data.host_certificates[i]) { | 479 | if (sensitive_data.host_certificates[i]) { |
480 | key_free(sensitive_data.host_certificates[i]); | 480 | sshkey_free(sensitive_data.host_certificates[i]); |
481 | sensitive_data.host_certificates[i] = NULL; | 481 | sensitive_data.host_certificates[i] = NULL; |
482 | } | 482 | } |
483 | } | 483 | } |
@@ -489,11 +489,16 @@ demote_sensitive_data(void) | |||
489 | { | 489 | { |
490 | struct sshkey *tmp; | 490 | struct sshkey *tmp; |
491 | u_int i; | 491 | u_int i; |
492 | int r; | ||
492 | 493 | ||
493 | for (i = 0; i < options.num_host_key_files; i++) { | 494 | for (i = 0; i < options.num_host_key_files; i++) { |
494 | if (sensitive_data.host_keys[i]) { | 495 | if (sensitive_data.host_keys[i]) { |
495 | tmp = key_demote(sensitive_data.host_keys[i]); | 496 | if ((r = sshkey_demote(sensitive_data.host_keys[i], |
496 | key_free(sensitive_data.host_keys[i]); | 497 | &tmp)) != 0) |
498 | fatal("could not demote host %s key: %s", | ||
499 | sshkey_type(sensitive_data.host_keys[i]), | ||
500 | ssh_err(r)); | ||
501 | sshkey_free(sensitive_data.host_keys[i]); | ||
497 | sensitive_data.host_keys[i] = tmp; | 502 | sensitive_data.host_keys[i] = tmp; |
498 | } | 503 | } |
499 | /* Certs do not need demotion */ | 504 | /* Certs do not need demotion */ |
@@ -649,7 +654,7 @@ privsep_postauth(Authctxt *authctxt) | |||
649 | fatal("fork of unprivileged child failed"); | 654 | fatal("fork of unprivileged child failed"); |
650 | else if (pmonitor->m_pid != 0) { | 655 | else if (pmonitor->m_pid != 0) { |
651 | verbose("User child is on pid %ld", (long)pmonitor->m_pid); | 656 | verbose("User child is on pid %ld", (long)pmonitor->m_pid); |
652 | buffer_clear(&loginmsg); | 657 | sshbuf_reset(loginmsg); |
653 | monitor_clear_keystate(pmonitor); | 658 | monitor_clear_keystate(pmonitor); |
654 | monitor_child_postauth(pmonitor); | 659 | monitor_child_postauth(pmonitor); |
655 | 660 | ||
@@ -681,45 +686,47 @@ privsep_postauth(Authctxt *authctxt) | |||
681 | packet_set_authenticated(); | 686 | packet_set_authenticated(); |
682 | } | 687 | } |
683 | 688 | ||
689 | static void | ||
690 | append_hostkey_type(struct sshbuf *b, const char *s) | ||
691 | { | ||
692 | int r; | ||
693 | |||
694 | if (match_pattern_list(s, options.hostkeyalgorithms, 0) != 1) { | ||
695 | debug3("%s: %s key not permitted by HostkeyAlgorithms", | ||
696 | __func__, s); | ||
697 | return; | ||
698 | } | ||
699 | if ((r = sshbuf_putf(b, "%s%s", sshbuf_len(b) > 0 ? "," : "", s)) != 0) | ||
700 | fatal("%s: sshbuf_putf: %s", __func__, ssh_err(r)); | ||
701 | } | ||
702 | |||
684 | static char * | 703 | static char * |
685 | list_hostkey_types(void) | 704 | list_hostkey_types(void) |
686 | { | 705 | { |
687 | Buffer b; | 706 | struct sshbuf *b; |
688 | const char *p; | 707 | struct sshkey *key; |
689 | char *ret; | 708 | char *ret; |
690 | u_int i; | 709 | u_int i; |
691 | struct sshkey *key; | ||
692 | 710 | ||
693 | buffer_init(&b); | 711 | if ((b = sshbuf_new()) == NULL) |
712 | fatal("%s: sshbuf_new failed", __func__); | ||
694 | for (i = 0; i < options.num_host_key_files; i++) { | 713 | for (i = 0; i < options.num_host_key_files; i++) { |
695 | key = sensitive_data.host_keys[i]; | 714 | key = sensitive_data.host_keys[i]; |
696 | if (key == NULL) | 715 | if (key == NULL) |
697 | key = sensitive_data.host_pubkeys[i]; | 716 | key = sensitive_data.host_pubkeys[i]; |
698 | if (key == NULL) | 717 | if (key == NULL) |
699 | continue; | 718 | continue; |
700 | /* Check that the key is accepted in HostkeyAlgorithms */ | ||
701 | if (match_pattern_list(sshkey_ssh_name(key), | ||
702 | options.hostkeyalgorithms, 0) != 1) { | ||
703 | debug3("%s: %s key not permitted by HostkeyAlgorithms", | ||
704 | __func__, sshkey_ssh_name(key)); | ||
705 | continue; | ||
706 | } | ||
707 | switch (key->type) { | 719 | switch (key->type) { |
708 | case KEY_RSA: | 720 | case KEY_RSA: |
721 | /* for RSA we also support SHA2 signatures */ | ||
722 | append_hostkey_type(b, "rsa-sha2-512"); | ||
723 | append_hostkey_type(b, "rsa-sha2-256"); | ||
724 | /* FALLTHROUGH */ | ||
709 | case KEY_DSA: | 725 | case KEY_DSA: |
710 | case KEY_ECDSA: | 726 | case KEY_ECDSA: |
711 | case KEY_ED25519: | 727 | case KEY_ED25519: |
712 | case KEY_XMSS: | 728 | case KEY_XMSS: |
713 | if (buffer_len(&b) > 0) | 729 | append_hostkey_type(b, sshkey_ssh_name(key)); |
714 | buffer_append(&b, ",", 1); | ||
715 | p = key_ssh_name(key); | ||
716 | buffer_append(&b, p, strlen(p)); | ||
717 | |||
718 | /* for RSA we also support SHA2 signatures */ | ||
719 | if (key->type == KEY_RSA) { | ||
720 | p = ",rsa-sha2-512,rsa-sha2-256"; | ||
721 | buffer_append(&b, p, strlen(p)); | ||
722 | } | ||
723 | break; | 730 | break; |
724 | } | 731 | } |
725 | /* If the private key has a cert peer, then list that too */ | 732 | /* If the private key has a cert peer, then list that too */ |
@@ -728,21 +735,24 @@ list_hostkey_types(void) | |||
728 | continue; | 735 | continue; |
729 | switch (key->type) { | 736 | switch (key->type) { |
730 | case KEY_RSA_CERT: | 737 | case KEY_RSA_CERT: |
738 | /* for RSA we also support SHA2 signatures */ | ||
739 | append_hostkey_type(b, | ||
740 | "rsa-sha2-512-cert-v01@openssh.com"); | ||
741 | append_hostkey_type(b, | ||
742 | "rsa-sha2-256-cert-v01@openssh.com"); | ||
743 | /* FALLTHROUGH */ | ||
731 | case KEY_DSA_CERT: | 744 | case KEY_DSA_CERT: |
732 | case KEY_ECDSA_CERT: | 745 | case KEY_ECDSA_CERT: |
733 | case KEY_ED25519_CERT: | 746 | case KEY_ED25519_CERT: |
734 | case KEY_XMSS_CERT: | 747 | case KEY_XMSS_CERT: |
735 | if (buffer_len(&b) > 0) | 748 | append_hostkey_type(b, sshkey_ssh_name(key)); |
736 | buffer_append(&b, ",", 1); | ||
737 | p = key_ssh_name(key); | ||
738 | buffer_append(&b, p, strlen(p)); | ||
739 | break; | 749 | break; |
740 | } | 750 | } |
741 | } | 751 | } |
742 | if ((ret = sshbuf_dup_string(&b)) == NULL) | 752 | if ((ret = sshbuf_dup_string(b)) == NULL) |
743 | fatal("%s: sshbuf_dup_string failed", __func__); | 753 | fatal("%s: sshbuf_dup_string failed", __func__); |
744 | buffer_free(&b); | 754 | sshbuf_free(b); |
745 | debug("list_hostkey_types: %s", ret); | 755 | debug("%s: %s", __func__, ret); |
746 | return ret; | 756 | return ret; |
747 | } | 757 | } |
748 | 758 | ||
@@ -809,7 +819,7 @@ get_hostkey_index(struct sshkey *key, int compare, struct ssh *ssh) | |||
809 | u_int i; | 819 | u_int i; |
810 | 820 | ||
811 | for (i = 0; i < options.num_host_key_files; i++) { | 821 | for (i = 0; i < options.num_host_key_files; i++) { |
812 | if (key_is_cert(key)) { | 822 | if (sshkey_is_cert(key)) { |
813 | if (key == sensitive_data.host_certificates[i] || | 823 | if (key == sensitive_data.host_certificates[i] || |
814 | (compare && sensitive_data.host_certificates[i] && | 824 | (compare && sensitive_data.host_certificates[i] && |
815 | sshkey_equal(key, | 825 | sshkey_equal(key, |
@@ -953,31 +963,33 @@ send_rexec_state(int fd, struct sshbuf *conf) | |||
953 | } | 963 | } |
954 | 964 | ||
955 | static void | 965 | static void |
956 | recv_rexec_state(int fd, Buffer *conf) | 966 | recv_rexec_state(int fd, struct sshbuf *conf) |
957 | { | 967 | { |
958 | Buffer m; | 968 | struct sshbuf *m; |
959 | char *cp; | 969 | u_char *cp, ver; |
960 | u_int len; | 970 | size_t len; |
971 | int r; | ||
961 | 972 | ||
962 | debug3("%s: entering fd = %d", __func__, fd); | 973 | debug3("%s: entering fd = %d", __func__, fd); |
963 | 974 | ||
964 | buffer_init(&m); | 975 | if ((m = sshbuf_new()) == NULL) |
965 | 976 | fatal("%s: sshbuf_new failed", __func__); | |
966 | if (ssh_msg_recv(fd, &m) == -1) | 977 | if (ssh_msg_recv(fd, m) == -1) |
967 | fatal("%s: ssh_msg_recv failed", __func__); | 978 | fatal("%s: ssh_msg_recv failed", __func__); |
968 | if (buffer_get_char(&m) != 0) | 979 | if ((r = sshbuf_get_u8(m, &ver)) != 0) |
980 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
981 | if (ver != 0) | ||
969 | fatal("%s: rexec version mismatch", __func__); | 982 | fatal("%s: rexec version mismatch", __func__); |
970 | 983 | if ((r = sshbuf_get_string(m, &cp, &len)) != 0) | |
971 | cp = buffer_get_string(&m, &len); | 984 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
972 | if (conf != NULL) | 985 | if (conf != NULL && (r = sshbuf_put(conf, cp, len))) |
973 | buffer_append(conf, cp, len); | 986 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
974 | free(cp); | ||
975 | |||
976 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) | 987 | #if defined(WITH_OPENSSL) && !defined(OPENSSL_PRNG_ONLY) |
977 | rexec_recv_rng_seed(&m); | 988 | rexec_recv_rng_seed(m); |
978 | #endif | 989 | #endif |
979 | 990 | ||
980 | buffer_free(&m); | 991 | free(cp); |
992 | sshbuf_free(m); | ||
981 | 993 | ||
982 | debug3("%s: done", __func__); | 994 | debug3("%s: done", __func__); |
983 | } | 995 | } |
@@ -1258,8 +1270,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1258 | startup_pipe = -1; | 1270 | startup_pipe = -1; |
1259 | pid = getpid(); | 1271 | pid = getpid(); |
1260 | if (rexec_flag) { | 1272 | if (rexec_flag) { |
1261 | send_rexec_state(config_s[0], | 1273 | send_rexec_state(config_s[0], cfg); |
1262 | &cfg); | ||
1263 | close(config_s[0]); | 1274 | close(config_s[0]); |
1264 | } | 1275 | } |
1265 | break; | 1276 | break; |
@@ -1305,7 +1316,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1305 | close(startup_p[1]); | 1316 | close(startup_p[1]); |
1306 | 1317 | ||
1307 | if (rexec_flag) { | 1318 | if (rexec_flag) { |
1308 | send_rexec_state(config_s[0], &cfg); | 1319 | send_rexec_state(config_s[0], cfg); |
1309 | close(config_s[0]); | 1320 | close(config_s[0]); |
1310 | close(config_s[1]); | 1321 | close(config_s[1]); |
1311 | } | 1322 | } |
@@ -1336,7 +1347,7 @@ server_accept_loop(int *sock_in, int *sock_out, int *newsock, int *config_s) | |||
1336 | * return an error if any are found). Basically we are worried about | 1347 | * return an error if any are found). Basically we are worried about |
1337 | * source routing; it can be used to pretend you are somebody | 1348 | * source routing; it can be used to pretend you are somebody |
1338 | * (ip-address) you are not. That itself may be "almost acceptable" | 1349 | * (ip-address) you are not. That itself may be "almost acceptable" |
1339 | * under certain circumstances, but rhosts autentication is useless | 1350 | * under certain circumstances, but rhosts authentication is useless |
1340 | * if source routing is accepted. Notice also that if we just dropped | 1351 | * if source routing is accepted. Notice also that if we just dropped |
1341 | * source routing here, the other side could use IP spoofing to do | 1352 | * source routing here, the other side could use IP spoofing to do |
1342 | * rest of the interaction and could still bypass security. So we | 1353 | * rest of the interaction and could still bypass security. So we |
@@ -1413,6 +1424,43 @@ set_process_rdomain(struct ssh *ssh, const char *name) | |||
1413 | #endif | 1424 | #endif |
1414 | } | 1425 | } |
1415 | 1426 | ||
1427 | static void | ||
1428 | accumulate_host_timing_secret(struct sshbuf *server_cfg, | ||
1429 | const struct sshkey *key) | ||
1430 | { | ||
1431 | static struct ssh_digest_ctx *ctx; | ||
1432 | u_char *hash; | ||
1433 | size_t len; | ||
1434 | struct sshbuf *buf; | ||
1435 | int r; | ||
1436 | |||
1437 | if (ctx == NULL && (ctx = ssh_digest_start(SSH_DIGEST_SHA512)) == NULL) | ||
1438 | fatal("%s: ssh_digest_start", __func__); | ||
1439 | if (key == NULL) { /* finalize */ | ||
1440 | /* add server config in case we are using agent for host keys */ | ||
1441 | if (ssh_digest_update(ctx, sshbuf_ptr(server_cfg), | ||
1442 | sshbuf_len(server_cfg)) != 0) | ||
1443 | fatal("%s: ssh_digest_update", __func__); | ||
1444 | len = ssh_digest_bytes(SSH_DIGEST_SHA512); | ||
1445 | hash = xmalloc(len); | ||
1446 | if (ssh_digest_final(ctx, hash, len) != 0) | ||
1447 | fatal("%s: ssh_digest_final", __func__); | ||
1448 | options.timing_secret = PEEK_U64(hash); | ||
1449 | freezero(hash, len); | ||
1450 | ssh_digest_free(ctx); | ||
1451 | ctx = NULL; | ||
1452 | return; | ||
1453 | } | ||
1454 | if ((buf = sshbuf_new()) == NULL) | ||
1455 | fatal("%s could not allocate buffer", __func__); | ||
1456 | if ((r = sshkey_private_serialize(key, buf)) != 0) | ||
1457 | fatal("sshkey_private_serialize: %s", ssh_err(r)); | ||
1458 | if (ssh_digest_update(ctx, sshbuf_ptr(buf), sshbuf_len(buf)) != 0) | ||
1459 | fatal("%s: ssh_digest_update", __func__); | ||
1460 | sshbuf_reset(buf); | ||
1461 | sshbuf_free(buf); | ||
1462 | } | ||
1463 | |||
1416 | /* | 1464 | /* |
1417 | * Main program for the daemon. | 1465 | * Main program for the daemon. |
1418 | */ | 1466 | */ |
@@ -1620,14 +1668,15 @@ main(int ac, char **av) | |||
1620 | "test mode (-T)"); | 1668 | "test mode (-T)"); |
1621 | 1669 | ||
1622 | /* Fetch our configuration */ | 1670 | /* Fetch our configuration */ |
1623 | buffer_init(&cfg); | 1671 | if ((cfg = sshbuf_new()) == NULL) |
1672 | fatal("%s: sshbuf_new failed", __func__); | ||
1624 | if (rexeced_flag) | 1673 | if (rexeced_flag) |
1625 | recv_rexec_state(REEXEC_CONFIG_PASS_FD, &cfg); | 1674 | recv_rexec_state(REEXEC_CONFIG_PASS_FD, cfg); |
1626 | else if (strcasecmp(config_file_name, "none") != 0) | 1675 | else if (strcasecmp(config_file_name, "none") != 0) |
1627 | load_server_config(config_file_name, &cfg); | 1676 | load_server_config(config_file_name, cfg); |
1628 | 1677 | ||
1629 | parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, | 1678 | parse_server_config(&options, rexeced_flag ? "rexec" : config_file_name, |
1630 | &cfg, NULL); | 1679 | cfg, NULL); |
1631 | 1680 | ||
1632 | seed_rng(); | 1681 | seed_rng(); |
1633 | 1682 | ||
@@ -1714,11 +1763,18 @@ main(int ac, char **av) | |||
1714 | for (i = 0; i < options.num_host_key_files; i++) { | 1763 | for (i = 0; i < options.num_host_key_files; i++) { |
1715 | if (options.host_key_files[i] == NULL) | 1764 | if (options.host_key_files[i] == NULL) |
1716 | continue; | 1765 | continue; |
1717 | key = key_load_private(options.host_key_files[i], "", NULL); | 1766 | if ((r = sshkey_load_private(options.host_key_files[i], "", |
1718 | pubkey = key_load_public(options.host_key_files[i], NULL); | 1767 | &key, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) |
1719 | 1768 | error("Error loading host key \"%s\": %s", | |
1769 | options.host_key_files[i], ssh_err(r)); | ||
1770 | if ((r = sshkey_load_public(options.host_key_files[i], | ||
1771 | &pubkey, NULL)) != 0 && r != SSH_ERR_SYSTEM_ERROR) | ||
1772 | error("Error loading host key \"%s\": %s", | ||
1773 | options.host_key_files[i], ssh_err(r)); | ||
1720 | if (pubkey == NULL && key != NULL) | 1774 | if (pubkey == NULL && key != NULL) |
1721 | pubkey = key_demote(key); | 1775 | if ((r = sshkey_demote(key, &pubkey)) != 0) |
1776 | fatal("Could not demote key: \"%s\": %s", | ||
1777 | options.host_key_files[i], ssh_err(r)); | ||
1722 | sensitive_data.host_keys[i] = key; | 1778 | sensitive_data.host_keys[i] = key; |
1723 | sensitive_data.host_pubkeys[i] = pubkey; | 1779 | sensitive_data.host_pubkeys[i] = pubkey; |
1724 | 1780 | ||
@@ -1728,6 +1784,7 @@ main(int ac, char **av) | |||
1728 | keytype = pubkey->type; | 1784 | keytype = pubkey->type; |
1729 | } else if (key != NULL) { | 1785 | } else if (key != NULL) { |
1730 | keytype = key->type; | 1786 | keytype = key->type; |
1787 | accumulate_host_timing_secret(cfg, key); | ||
1731 | } else { | 1788 | } else { |
1732 | error("Could not load host key: %s", | 1789 | error("Could not load host key: %s", |
1733 | options.host_key_files[i]); | 1790 | options.host_key_files[i]); |
@@ -1753,6 +1810,7 @@ main(int ac, char **av) | |||
1753 | key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); | 1810 | key ? "private" : "agent", i, sshkey_ssh_name(pubkey), fp); |
1754 | free(fp); | 1811 | free(fp); |
1755 | } | 1812 | } |
1813 | accumulate_host_timing_secret(cfg, NULL); | ||
1756 | if (!sensitive_data.have_ssh2_key) { | 1814 | if (!sensitive_data.have_ssh2_key) { |
1757 | logit("sshd: no hostkeys available -- exiting."); | 1815 | logit("sshd: no hostkeys available -- exiting."); |
1758 | exit(1); | 1816 | exit(1); |
@@ -1770,21 +1828,21 @@ main(int ac, char **av) | |||
1770 | for (i = 0; i < options.num_host_cert_files; i++) { | 1828 | for (i = 0; i < options.num_host_cert_files; i++) { |
1771 | if (options.host_cert_files[i] == NULL) | 1829 | if (options.host_cert_files[i] == NULL) |
1772 | continue; | 1830 | continue; |
1773 | key = key_load_public(options.host_cert_files[i], NULL); | 1831 | if ((r = sshkey_load_public(options.host_cert_files[i], |
1774 | if (key == NULL) { | 1832 | &key, NULL)) != 0) { |
1775 | error("Could not load host certificate: %s", | 1833 | error("Could not load host certificate \"%s\": %s", |
1776 | options.host_cert_files[i]); | 1834 | options.host_cert_files[i], ssh_err(r)); |
1777 | continue; | 1835 | continue; |
1778 | } | 1836 | } |
1779 | if (!key_is_cert(key)) { | 1837 | if (!sshkey_is_cert(key)) { |
1780 | error("Certificate file is not a certificate: %s", | 1838 | error("Certificate file is not a certificate: %s", |
1781 | options.host_cert_files[i]); | 1839 | options.host_cert_files[i]); |
1782 | key_free(key); | 1840 | sshkey_free(key); |
1783 | continue; | 1841 | continue; |
1784 | } | 1842 | } |
1785 | /* Find matching private key */ | 1843 | /* Find matching private key */ |
1786 | for (j = 0; j < options.num_host_key_files; j++) { | 1844 | for (j = 0; j < options.num_host_key_files; j++) { |
1787 | if (key_equal_public(key, | 1845 | if (sshkey_equal_public(key, |
1788 | sensitive_data.host_keys[j])) { | 1846 | sensitive_data.host_keys[j])) { |
1789 | sensitive_data.host_certificates[j] = key; | 1847 | sensitive_data.host_certificates[j] = key; |
1790 | break; | 1848 | break; |
@@ -1793,12 +1851,12 @@ main(int ac, char **av) | |||
1793 | if (j >= options.num_host_key_files) { | 1851 | if (j >= options.num_host_key_files) { |
1794 | error("No matching private key for certificate: %s", | 1852 | error("No matching private key for certificate: %s", |
1795 | options.host_cert_files[i]); | 1853 | options.host_cert_files[i]); |
1796 | key_free(key); | 1854 | sshkey_free(key); |
1797 | continue; | 1855 | continue; |
1798 | } | 1856 | } |
1799 | sensitive_data.host_certificates[j] = key; | 1857 | sensitive_data.host_certificates[j] = key; |
1800 | debug("host certificate: #%u type %d %s", j, key->type, | 1858 | debug("host certificate: #%u type %d %s", j, key->type, |
1801 | key_type(key)); | 1859 | sshkey_type(key)); |
1802 | } | 1860 | } |
1803 | 1861 | ||
1804 | if (privsep_chroot) { | 1862 | if (privsep_chroot) { |
@@ -2065,7 +2123,7 @@ main(int ac, char **av) | |||
2065 | /* allocate authentication context */ | 2123 | /* allocate authentication context */ |
2066 | authctxt = xcalloc(1, sizeof(*authctxt)); | 2124 | authctxt = xcalloc(1, sizeof(*authctxt)); |
2067 | 2125 | ||
2068 | authctxt->loginmsg = &loginmsg; | 2126 | authctxt->loginmsg = loginmsg; |
2069 | 2127 | ||
2070 | /* XXX global for cleanup, access from other modules */ | 2128 | /* XXX global for cleanup, access from other modules */ |
2071 | the_authctxt = authctxt; | 2129 | the_authctxt = authctxt; |
@@ -2075,7 +2133,8 @@ main(int ac, char **av) | |||
2075 | fatal("allocation failed"); | 2133 | fatal("allocation failed"); |
2076 | 2134 | ||
2077 | /* prepare buffer to collect messages to display to user after login */ | 2135 | /* prepare buffer to collect messages to display to user after login */ |
2078 | buffer_init(&loginmsg); | 2136 | if ((loginmsg = sshbuf_new()) == NULL) |
2137 | fatal("%s: sshbuf_new failed", __func__); | ||
2079 | auth_debug_reset(); | 2138 | auth_debug_reset(); |
2080 | 2139 | ||
2081 | if (use_privsep) { | 2140 | if (use_privsep) { |
@@ -2178,26 +2237,21 @@ main(int ac, char **av) | |||
2178 | 2237 | ||
2179 | int | 2238 | int |
2180 | sshd_hostkey_sign(struct sshkey *privkey, struct sshkey *pubkey, | 2239 | sshd_hostkey_sign(struct sshkey *privkey, struct sshkey *pubkey, |
2181 | u_char **signature, size_t *slen, const u_char *data, size_t dlen, | 2240 | u_char **signature, size_t *slenp, const u_char *data, size_t dlen, |
2182 | const char *alg, u_int flag) | 2241 | const char *alg, u_int flag) |
2183 | { | 2242 | { |
2184 | int r; | 2243 | int r; |
2185 | u_int xxx_slen, xxx_dlen = dlen; | ||
2186 | 2244 | ||
2187 | if (privkey) { | 2245 | if (privkey) { |
2188 | if (PRIVSEP(key_sign(privkey, signature, &xxx_slen, data, xxx_dlen, | 2246 | if (PRIVSEP(sshkey_sign(privkey, signature, slenp, data, dlen, |
2189 | alg) < 0)) | 2247 | alg, datafellows)) < 0) |
2190 | fatal("%s: key_sign failed", __func__); | 2248 | fatal("%s: key_sign failed", __func__); |
2191 | if (slen) | ||
2192 | *slen = xxx_slen; | ||
2193 | } else if (use_privsep) { | 2249 | } else if (use_privsep) { |
2194 | if (mm_key_sign(pubkey, signature, &xxx_slen, data, xxx_dlen, | 2250 | if (mm_sshkey_sign(pubkey, signature, slenp, data, dlen, |
2195 | alg) < 0) | 2251 | alg, datafellows) < 0) |
2196 | fatal("%s: pubkey_sign failed", __func__); | 2252 | fatal("%s: pubkey_sign failed", __func__); |
2197 | if (slen) | ||
2198 | *slen = xxx_slen; | ||
2199 | } else { | 2253 | } else { |
2200 | if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slen, | 2254 | if ((r = ssh_agent_sign(auth_sock, pubkey, signature, slenp, |
2201 | data, dlen, alg, datafellows)) != 0) | 2255 | data, dlen, alg, datafellows)) != 0) |
2202 | fatal("%s: ssh_agent_sign failed: %s", | 2256 | fatal("%s: ssh_agent_sign failed: %s", |
2203 | __func__, ssh_err(r)); | 2257 | __func__, ssh_err(r)); |