summaryrefslogtreecommitdiff
path: root/monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c395
1 files changed, 143 insertions, 252 deletions
diff --git a/monitor.c b/monitor.c
index dbe29f128..bab6ce87e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: monitor.c,v 1.135 2014/07/15 15:54:14 millert Exp $ */ 1/* $OpenBSD: monitor.c,v 1.145 2015/02/20 22:17:21 djm Exp $ */
2/* 2/*
3 * Copyright 2002 Niels Provos <provos@citi.umich.edu> 3 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
4 * Copyright 2002 Markus Friedl <markus@openbsd.org> 4 * Copyright 2002 Markus Friedl <markus@openbsd.org>
@@ -28,7 +28,6 @@
28#include "includes.h" 28#include "includes.h"
29 29
30#include <sys/types.h> 30#include <sys/types.h>
31#include <sys/param.h>
32#include <sys/socket.h> 31#include <sys/socket.h>
33#include "openbsd-compat/sys-tree.h" 32#include "openbsd-compat/sys-tree.h"
34#include <sys/wait.h> 33#include <sys/wait.h>
@@ -40,6 +39,9 @@
40#endif 39#endif
41#include <pwd.h> 40#include <pwd.h>
42#include <signal.h> 41#include <signal.h>
42#ifdef HAVE_STDINT_H
43#include <stdint.h>
44#endif
43#include <stdlib.h> 45#include <stdlib.h>
44#include <string.h> 46#include <string.h>
45#include <stdarg.h> 47#include <stdarg.h>
@@ -100,6 +102,8 @@
100#include "ssh2.h" 102#include "ssh2.h"
101#include "roaming.h" 103#include "roaming.h"
102#include "authfd.h" 104#include "authfd.h"
105#include "match.h"
106#include "ssherr.h"
103 107
104#ifdef GSSAPI 108#ifdef GSSAPI
105static Gssctxt *gsscontext = NULL; 109static Gssctxt *gsscontext = NULL;
@@ -108,38 +112,13 @@ static Gssctxt *gsscontext = NULL;
108/* Imports */ 112/* Imports */
109extern ServerOptions options; 113extern ServerOptions options;
110extern u_int utmp_len; 114extern u_int utmp_len;
111extern Newkeys *current_keys[];
112extern z_stream incoming_stream;
113extern z_stream outgoing_stream;
114extern u_char session_id[]; 115extern u_char session_id[];
115extern Buffer auth_debug; 116extern Buffer auth_debug;
116extern int auth_debug_init; 117extern int auth_debug_init;
117extern Buffer loginmsg; 118extern Buffer loginmsg;
118 119
119/* State exported from the child */ 120/* State exported from the child */
120 121static struct sshbuf *child_state;
121struct {
122 z_stream incoming;
123 z_stream outgoing;
124 u_char *keyin;
125 u_int keyinlen;
126 u_char *keyout;
127 u_int keyoutlen;
128 u_char *ivin;
129 u_int ivinlen;
130 u_char *ivout;
131 u_int ivoutlen;
132 u_char *ssh1key;
133 u_int ssh1keylen;
134 int ssh1cipher;
135 int ssh1protoflags;
136 u_char *input;
137 u_int ilen;
138 u_char *output;
139 u_int olen;
140 u_int64_t sent_bytes;
141 u_int64_t recv_bytes;
142} child_state;
143 122
144/* Functions on the monitor that answer unprivileged requests */ 123/* Functions on the monitor that answer unprivileged requests */
145 124
@@ -504,6 +483,27 @@ monitor_sync(struct monitor *pmonitor)
504 } 483 }
505} 484}
506 485
486/* Allocation functions for zlib */
487static void *
488mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
489{
490 size_t len = (size_t) size * ncount;
491 void *address;
492
493 if (len == 0 || ncount > SIZE_MAX / size)
494 fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);
495
496 address = mm_malloc(mm, len);
497
498 return (address);
499}
500
501static void
502mm_zfree(struct mm_master *mm, void *address)
503{
504 mm_free(mm, address);
505}
506
507static int 507static int
508monitor_read_log(struct monitor *pmonitor) 508monitor_read_log(struct monitor *pmonitor)
509{ 509{
@@ -684,28 +684,60 @@ mm_answer_moduli(int sock, Buffer *m)
684} 684}
685#endif 685#endif
686 686
687extern AuthenticationConnection *auth_conn;
688
689int 687int
690mm_answer_sign(int sock, Buffer *m) 688mm_answer_sign(int sock, Buffer *m)
691{ 689{
692 Key *key; 690 struct ssh *ssh = active_state; /* XXX */
691 extern int auth_sock; /* XXX move to state struct? */
692 struct sshkey *key;
693 struct sshbuf *sigbuf;
693 u_char *p; 694 u_char *p;
694 u_char *signature; 695 u_char *signature;
695 u_int siglen, datlen; 696 size_t datlen, siglen;
696 int keyid; 697 int r, keyid, is_proof = 0;
698 const char proof_req[] = "hostkeys-prove-00@openssh.com";
697 699
698 debug3("%s", __func__); 700 debug3("%s", __func__);
699 701
700 keyid = buffer_get_int(m); 702 if ((r = sshbuf_get_u32(m, &keyid)) != 0 ||
701 p = buffer_get_string(m, &datlen); 703 (r = sshbuf_get_string(m, &p, &datlen)) != 0)
704 fatal("%s: buffer error: %s", __func__, ssh_err(r));
702 705
703 /* 706 /*
704 * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), 707 * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes),
705 * SHA384 (48 bytes) and SHA512 (64 bytes). 708 * SHA384 (48 bytes) and SHA512 (64 bytes).
709 *
710 * Otherwise, verify the signature request is for a hostkey
711 * proof.
712 *
713 * XXX perform similar check for KEX signature requests too?
714 * it's not trivial, since what is signed is the hash, rather
715 * than the full kex structure...
706 */ 716 */
707 if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) 717 if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) {
708 fatal("%s: data length incorrect: %u", __func__, datlen); 718 /*
719 * Construct expected hostkey proof and compare it to what
720 * the client sent us.
721 */
722 if (session_id2_len == 0) /* hostkeys is never first */
723 fatal("%s: bad data length: %zu", __func__, datlen);
724 if ((key = get_hostkey_public_by_index(keyid, ssh)) == NULL)
725 fatal("%s: no hostkey for index %d", __func__, keyid);
726 if ((sigbuf = sshbuf_new()) == NULL)
727 fatal("%s: sshbuf_new", __func__);
728 if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 ||
729 (r = sshbuf_put_string(sigbuf, session_id2,
730 session_id2_len) != 0) ||
731 (r = sshkey_puts(key, sigbuf)) != 0)
732 fatal("%s: couldn't prepare private key "
733 "proof buffer: %s", __func__, ssh_err(r));
734 if (datlen != sshbuf_len(sigbuf) ||
735 memcmp(p, sshbuf_ptr(sigbuf), sshbuf_len(sigbuf)) != 0)
736 fatal("%s: bad data length: %zu, hostkey proof len %zu",
737 __func__, datlen, sshbuf_len(sigbuf));
738 sshbuf_free(sigbuf);
739 is_proof = 1;
740 }
709 741
710 /* save session id, it will be passed on the first call */ 742 /* save session id, it will be passed on the first call */
711 if (session_id2_len == 0) { 743 if (session_id2_len == 0) {
@@ -715,20 +747,26 @@ mm_answer_sign(int sock, Buffer *m)
715 } 747 }
716 748
717 if ((key = get_hostkey_by_index(keyid)) != NULL) { 749 if ((key = get_hostkey_by_index(keyid)) != NULL) {
718 if (key_sign(key, &signature, &siglen, p, datlen) < 0) 750 if ((r = sshkey_sign(key, &signature, &siglen, p, datlen,
719 fatal("%s: key_sign failed", __func__); 751 datafellows)) != 0)
720 } else if ((key = get_hostkey_public_by_index(keyid)) != NULL && 752 fatal("%s: sshkey_sign failed: %s",
721 auth_conn != NULL) { 753 __func__, ssh_err(r));
722 if (ssh_agent_sign(auth_conn, key, &signature, &siglen, p, 754 } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
723 datlen) < 0) 755 auth_sock > 0) {
724 fatal("%s: ssh_agent_sign failed", __func__); 756 if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
757 p, datlen, datafellows)) != 0) {
758 fatal("%s: ssh_agent_sign failed: %s",
759 __func__, ssh_err(r));
760 }
725 } else 761 } else
726 fatal("%s: no hostkey from index %d", __func__, keyid); 762 fatal("%s: no hostkey from index %d", __func__, keyid);
727 763
728 debug3("%s: signature %p(%u)", __func__, signature, siglen); 764 debug3("%s: %s signature %p(%zu)", __func__,
765 is_proof ? "KEX" : "hostkey proof", signature, siglen);
729 766
730 buffer_clear(m); 767 sshbuf_reset(m);
731 buffer_put_string(m, signature, siglen); 768 if ((r = sshbuf_put_string(m, signature, siglen)) != 0)
769 fatal("%s: buffer error: %s", __func__, ssh_err(r));
732 770
733 free(p); 771 free(p);
734 free(signature); 772 free(signature);
@@ -1167,9 +1205,18 @@ mm_answer_keyallowed(int sock, Buffer *m)
1167 debug3("%s: key_from_blob: %p", __func__, key); 1205 debug3("%s: key_from_blob: %p", __func__, key);
1168 1206
1169 if (key != NULL && authctxt->valid) { 1207 if (key != NULL && authctxt->valid) {
1208 /* These should not make it past the privsep child */
1209 if (key_type_plain(key->type) == KEY_RSA &&
1210 (datafellows & SSH_BUG_RSASIGMD5) != 0)
1211 fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__);
1212
1170 switch (type) { 1213 switch (type) {
1171 case MM_USERKEY: 1214 case MM_USERKEY:
1172 allowed = options.pubkey_authentication && 1215 allowed = options.pubkey_authentication &&
1216 !auth2_userkey_already_used(authctxt, key) &&
1217 match_pattern_list(sshkey_ssh_name(key),
1218 options.pubkey_key_types,
1219 strlen(options.pubkey_key_types), 0) == 1 &&
1173 user_key_allowed(authctxt->pw, key); 1220 user_key_allowed(authctxt->pw, key);
1174 pubkey_auth_info(authctxt, key, NULL); 1221 pubkey_auth_info(authctxt, key, NULL);
1175 auth_method = "publickey"; 1222 auth_method = "publickey";
@@ -1178,6 +1225,9 @@ mm_answer_keyallowed(int sock, Buffer *m)
1178 break; 1225 break;
1179 case MM_HOSTKEY: 1226 case MM_HOSTKEY:
1180 allowed = options.hostbased_authentication && 1227 allowed = options.hostbased_authentication &&
1228 match_pattern_list(sshkey_ssh_name(key),
1229 options.hostbased_key_types,
1230 strlen(options.hostbased_key_types), 0) == 1 &&
1181 hostbased_key_allowed(authctxt->pw, 1231 hostbased_key_allowed(authctxt->pw,
1182 cuser, chost, key); 1232 cuser, chost, key);
1183 pubkey_auth_info(authctxt, key, 1233 pubkey_auth_info(authctxt, key,
@@ -1397,7 +1447,12 @@ mm_answer_keyverify(int sock, Buffer *m)
1397 debug3("%s: key %p signature %s", 1447 debug3("%s: key %p signature %s",
1398 __func__, key, (verified == 1) ? "verified" : "unverified"); 1448 __func__, key, (verified == 1) ? "verified" : "unverified");
1399 1449
1400 key_free(key); 1450 /* If auth was successful then record key to ensure it isn't reused */
1451 if (verified == 1)
1452 auth2_record_userkey(authctxt, key);
1453 else
1454 key_free(key);
1455
1401 free(blob); 1456 free(blob);
1402 free(signature); 1457 free(signature);
1403 free(data); 1458 free(data);
@@ -1783,105 +1838,40 @@ mm_answer_audit_command(int socket, Buffer *m)
1783void 1838void
1784monitor_apply_keystate(struct monitor *pmonitor) 1839monitor_apply_keystate(struct monitor *pmonitor)
1785{ 1840{
1786 if (compat20) { 1841 struct ssh *ssh = active_state; /* XXX */
1787 set_newkeys(MODE_IN); 1842 struct kex *kex;
1788 set_newkeys(MODE_OUT); 1843 int r;
1789 } else { 1844
1790 packet_set_protocol_flags(child_state.ssh1protoflags); 1845 debug3("%s: packet_set_state", __func__);
1791 packet_set_encryption_key(child_state.ssh1key, 1846 if ((r = ssh_packet_set_state(ssh, child_state)) != 0)
1792 child_state.ssh1keylen, child_state.ssh1cipher); 1847 fatal("%s: packet_set_state: %s", __func__, ssh_err(r));
1793 free(child_state.ssh1key); 1848 sshbuf_free(child_state);
1794 } 1849 child_state = NULL;
1795 1850
1796 /* for rc4 and other stateful ciphers */ 1851 if ((kex = ssh->kex) != 0) {
1797 packet_set_keycontext(MODE_OUT, child_state.keyout); 1852 /* XXX set callbacks */
1798 free(child_state.keyout); 1853#ifdef WITH_OPENSSL
1799 packet_set_keycontext(MODE_IN, child_state.keyin); 1854 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1800 free(child_state.keyin); 1855 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1801 1856 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1802 if (!compat20) { 1857 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1803 packet_set_iv(MODE_OUT, child_state.ivout); 1858# ifdef OPENSSL_HAS_ECC
1804 free(child_state.ivout); 1859 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
1805 packet_set_iv(MODE_IN, child_state.ivin); 1860# endif
1806 free(child_state.ivin); 1861#endif /* WITH_OPENSSL */
1862 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1863 kex->load_host_public_key=&get_hostkey_public_by_type;
1864 kex->load_host_private_key=&get_hostkey_private_by_type;
1865 kex->host_key_index=&get_hostkey_index;
1866 kex->sign = sshd_hostkey_sign;
1807 } 1867 }
1808 1868
1809 memcpy(&incoming_stream, &child_state.incoming,
1810 sizeof(incoming_stream));
1811 memcpy(&outgoing_stream, &child_state.outgoing,
1812 sizeof(outgoing_stream));
1813
1814 /* Update with new address */ 1869 /* Update with new address */
1815 if (options.compression) 1870 if (options.compression) {
1816 mm_init_compression(pmonitor->m_zlib); 1871 ssh_packet_set_compress_hooks(ssh, pmonitor->m_zlib,
1817 1872 (ssh_packet_comp_alloc_func *)mm_zalloc,
1818 packet_set_postauth(); 1873 (ssh_packet_comp_free_func *)mm_zfree);
1819 1874 }
1820 if (options.rekey_limit || options.rekey_interval)
1821 packet_set_rekey_limits((u_int32_t)options.rekey_limit,
1822 (time_t)options.rekey_interval);
1823
1824 /* Network I/O buffers */
1825 /* XXX inefficient for large buffers, need: buffer_init_from_string */
1826 buffer_clear(packet_get_input());
1827 buffer_append(packet_get_input(), child_state.input, child_state.ilen);
1828 explicit_bzero(child_state.input, child_state.ilen);
1829 free(child_state.input);
1830
1831 buffer_clear(packet_get_output());
1832 buffer_append(packet_get_output(), child_state.output,
1833 child_state.olen);
1834 explicit_bzero(child_state.output, child_state.olen);
1835 free(child_state.output);
1836
1837 /* Roaming */
1838 if (compat20)
1839 roam_set_bytes(child_state.sent_bytes, child_state.recv_bytes);
1840}
1841
1842static Kex *
1843mm_get_kex(Buffer *m)
1844{
1845 Kex *kex;
1846 void *blob;
1847 u_int bloblen;
1848
1849 kex = xcalloc(1, sizeof(*kex));
1850 kex->session_id = buffer_get_string(m, &kex->session_id_len);
1851 if (session_id2 == NULL ||
1852 kex->session_id_len != session_id2_len ||
1853 timingsafe_bcmp(kex->session_id, session_id2, session_id2_len) != 0)
1854 fatal("mm_get_get: internal error: bad session id");
1855 kex->we_need = buffer_get_int(m);
1856#ifdef WITH_OPENSSL
1857 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1858 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1859 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1860 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1861 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
1862#endif
1863 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1864 kex->server = 1;
1865 kex->hostkey_type = buffer_get_int(m);
1866 kex->kex_type = buffer_get_int(m);
1867 blob = buffer_get_string(m, &bloblen);
1868 buffer_init(&kex->my);
1869 buffer_append(&kex->my, blob, bloblen);
1870 free(blob);
1871 blob = buffer_get_string(m, &bloblen);
1872 buffer_init(&kex->peer);
1873 buffer_append(&kex->peer, blob, bloblen);
1874 free(blob);
1875 kex->done = 1;
1876 kex->flags = buffer_get_int(m);
1877 kex->client_version_string = buffer_get_string(m, NULL);
1878 kex->server_version_string = buffer_get_string(m, NULL);
1879 kex->load_host_public_key=&get_hostkey_public_by_type;
1880 kex->load_host_private_key=&get_hostkey_private_by_type;
1881 kex->host_key_index=&get_hostkey_index;
1882 kex->sign = sshd_hostkey_sign;
1883
1884 return (kex);
1885} 1875}
1886 1876
1887/* This function requries careful sanity checking */ 1877/* This function requries careful sanity checking */
@@ -1889,118 +1879,16 @@ mm_get_kex(Buffer *m)
1889void 1879void
1890mm_get_keystate(struct monitor *pmonitor) 1880mm_get_keystate(struct monitor *pmonitor)
1891{ 1881{
1892 Buffer m;
1893 u_char *blob, *p;
1894 u_int bloblen, plen;
1895 u_int32_t seqnr, packets;
1896 u_int64_t blocks, bytes;
1897
1898 debug3("%s: Waiting for new keys", __func__); 1882 debug3("%s: Waiting for new keys", __func__);
1899 1883
1900 buffer_init(&m); 1884 if ((child_state = sshbuf_new()) == NULL)
1901 mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m); 1885 fatal("%s: sshbuf_new failed", __func__);
1902 if (!compat20) { 1886 mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT,
1903 child_state.ssh1protoflags = buffer_get_int(&m); 1887 child_state);
1904 child_state.ssh1cipher = buffer_get_int(&m); 1888 debug3("%s: GOT new keys", __func__);
1905 child_state.ssh1key = buffer_get_string(&m,
1906 &child_state.ssh1keylen);
1907 child_state.ivout = buffer_get_string(&m,
1908 &child_state.ivoutlen);
1909 child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);
1910 goto skip;
1911 } else {
1912 /* Get the Kex for rekeying */
1913 *pmonitor->m_pkex = mm_get_kex(&m);
1914 }
1915
1916 blob = buffer_get_string(&m, &bloblen);
1917 current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
1918 free(blob);
1919
1920 debug3("%s: Waiting for second key", __func__);
1921 blob = buffer_get_string(&m, &bloblen);
1922 current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
1923 free(blob);
1924
1925 /* Now get sequence numbers for the packets */
1926 seqnr = buffer_get_int(&m);
1927 blocks = buffer_get_int64(&m);
1928 packets = buffer_get_int(&m);
1929 bytes = buffer_get_int64(&m);
1930 packet_set_state(MODE_OUT, seqnr, blocks, packets, bytes);
1931 seqnr = buffer_get_int(&m);
1932 blocks = buffer_get_int64(&m);
1933 packets = buffer_get_int(&m);
1934 bytes = buffer_get_int64(&m);
1935 packet_set_state(MODE_IN, seqnr, blocks, packets, bytes);
1936
1937 skip:
1938 /* Get the key context */
1939 child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);
1940 child_state.keyin = buffer_get_string(&m, &child_state.keyinlen);
1941
1942 debug3("%s: Getting compression state", __func__);
1943 /* Get compression state */
1944 p = buffer_get_string(&m, &plen);
1945 if (plen != sizeof(child_state.outgoing))
1946 fatal("%s: bad request size", __func__);
1947 memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));
1948 free(p);
1949
1950 p = buffer_get_string(&m, &plen);
1951 if (plen != sizeof(child_state.incoming))
1952 fatal("%s: bad request size", __func__);
1953 memcpy(&child_state.incoming, p, sizeof(child_state.incoming));
1954 free(p);
1955
1956 /* Network I/O buffers */
1957 debug3("%s: Getting Network I/O buffers", __func__);
1958 child_state.input = buffer_get_string(&m, &child_state.ilen);
1959 child_state.output = buffer_get_string(&m, &child_state.olen);
1960
1961 /* Roaming */
1962 if (compat20) {
1963 child_state.sent_bytes = buffer_get_int64(&m);
1964 child_state.recv_bytes = buffer_get_int64(&m);
1965 }
1966
1967 buffer_free(&m);
1968} 1889}
1969 1890
1970 1891
1971/* Allocation functions for zlib */
1972void *
1973mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
1974{
1975 size_t len = (size_t) size * ncount;
1976 void *address;
1977
1978 if (len == 0 || ncount > SIZE_T_MAX / size)
1979 fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);
1980
1981 address = mm_malloc(mm, len);
1982
1983 return (address);
1984}
1985
1986void
1987mm_zfree(struct mm_master *mm, void *address)
1988{
1989 mm_free(mm, address);
1990}
1991
1992void
1993mm_init_compression(struct mm_master *mm)
1994{
1995 outgoing_stream.zalloc = (alloc_func)mm_zalloc;
1996 outgoing_stream.zfree = (free_func)mm_zfree;
1997 outgoing_stream.opaque = mm;
1998
1999 incoming_stream.zalloc = (alloc_func)mm_zalloc;
2000 incoming_stream.zfree = (free_func)mm_zfree;
2001 incoming_stream.opaque = mm;
2002}
2003
2004/* XXX */ 1892/* XXX */
2005 1893
2006#define FD_CLOSEONEXEC(x) do { \ 1894#define FD_CLOSEONEXEC(x) do { \
@@ -2036,6 +1924,7 @@ monitor_openfds(struct monitor *mon, int do_logfds)
2036struct monitor * 1924struct monitor *
2037monitor_init(void) 1925monitor_init(void)
2038{ 1926{
1927 struct ssh *ssh = active_state; /* XXX */
2039 struct monitor *mon; 1928 struct monitor *mon;
2040 1929
2041 mon = xcalloc(1, sizeof(*mon)); 1930 mon = xcalloc(1, sizeof(*mon));
@@ -2048,7 +1937,9 @@ monitor_init(void)
2048 mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE); 1937 mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);
2049 1938
2050 /* Compression needs to share state across borders */ 1939 /* Compression needs to share state across borders */
2051 mm_init_compression(mon->m_zlib); 1940 ssh_packet_set_compress_hooks(ssh, mon->m_zlib,
1941 (ssh_packet_comp_alloc_func *)mm_zalloc,
1942 (ssh_packet_comp_free_func *)mm_zfree);
2052 } 1943 }
2053 1944
2054 return mon; 1945 return mon;