summaryrefslogtreecommitdiff
path: root/monitor.c
diff options
context:
space:
mode:
Diffstat (limited to 'monitor.c')
-rw-r--r--monitor.c407
1 files changed, 149 insertions, 258 deletions
diff --git a/monitor.c b/monitor.c
index cc15ce486..ce7ba079c 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#ifdef USE_CONSOLEKIT 107#ifdef USE_CONSOLEKIT
104#include "consolekit.h" 108#include "consolekit.h"
105#endif 109#endif
@@ -111,38 +115,13 @@ static Gssctxt *gsscontext = NULL;
111/* Imports */ 115/* Imports */
112extern ServerOptions options; 116extern ServerOptions options;
113extern u_int utmp_len; 117extern u_int utmp_len;
114extern Newkeys *current_keys[];
115extern z_stream incoming_stream;
116extern z_stream outgoing_stream;
117extern u_char session_id[]; 118extern u_char session_id[];
118extern Buffer auth_debug; 119extern Buffer auth_debug;
119extern int auth_debug_init; 120extern int auth_debug_init;
120extern Buffer loginmsg; 121extern Buffer loginmsg;
121 122
122/* State exported from the child */ 123/* State exported from the child */
123 124static struct sshbuf *child_state;
124struct {
125 z_stream incoming;
126 z_stream outgoing;
127 u_char *keyin;
128 u_int keyinlen;
129 u_char *keyout;
130 u_int keyoutlen;
131 u_char *ivin;
132 u_int ivinlen;
133 u_char *ivout;
134 u_int ivoutlen;
135 u_char *ssh1key;
136 u_int ssh1keylen;
137 int ssh1cipher;
138 int ssh1protoflags;
139 u_char *input;
140 u_int ilen;
141 u_char *output;
142 u_int olen;
143 u_int64_t sent_bytes;
144 u_int64_t recv_bytes;
145} child_state;
146 125
147/* Functions on the monitor that answer unprivileged requests */ 126/* Functions on the monitor that answer unprivileged requests */
148 127
@@ -539,6 +518,27 @@ monitor_sync(struct monitor *pmonitor)
539 } 518 }
540} 519}
541 520
521/* Allocation functions for zlib */
522static void *
523mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
524{
525 size_t len = (size_t) size * ncount;
526 void *address;
527
528 if (len == 0 || ncount > SIZE_MAX / size)
529 fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);
530
531 address = mm_malloc(mm, len);
532
533 return (address);
534}
535
536static void
537mm_zfree(struct mm_master *mm, void *address)
538{
539 mm_free(mm, address);
540}
541
542static int 542static int
543monitor_read_log(struct monitor *pmonitor) 543monitor_read_log(struct monitor *pmonitor)
544{ 544{
@@ -719,28 +719,60 @@ mm_answer_moduli(int sock, Buffer *m)
719} 719}
720#endif 720#endif
721 721
722extern AuthenticationConnection *auth_conn;
723
724int 722int
725mm_answer_sign(int sock, Buffer *m) 723mm_answer_sign(int sock, Buffer *m)
726{ 724{
727 Key *key; 725 struct ssh *ssh = active_state; /* XXX */
726 extern int auth_sock; /* XXX move to state struct? */
727 struct sshkey *key;
728 struct sshbuf *sigbuf;
728 u_char *p; 729 u_char *p;
729 u_char *signature; 730 u_char *signature;
730 u_int siglen, datlen; 731 size_t datlen, siglen;
731 int keyid; 732 int r, keyid, is_proof = 0;
733 const char proof_req[] = "hostkeys-prove-00@openssh.com";
732 734
733 debug3("%s", __func__); 735 debug3("%s", __func__);
734 736
735 keyid = buffer_get_int(m); 737 if ((r = sshbuf_get_u32(m, &keyid)) != 0 ||
736 p = buffer_get_string(m, &datlen); 738 (r = sshbuf_get_string(m, &p, &datlen)) != 0)
739 fatal("%s: buffer error: %s", __func__, ssh_err(r));
737 740
738 /* 741 /*
739 * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes), 742 * Supported KEX types use SHA1 (20 bytes), SHA256 (32 bytes),
740 * SHA384 (48 bytes) and SHA512 (64 bytes). 743 * SHA384 (48 bytes) and SHA512 (64 bytes).
744 *
745 * Otherwise, verify the signature request is for a hostkey
746 * proof.
747 *
748 * XXX perform similar check for KEX signature requests too?
749 * it's not trivial, since what is signed is the hash, rather
750 * than the full kex structure...
741 */ 751 */
742 if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) 752 if (datlen != 20 && datlen != 32 && datlen != 48 && datlen != 64) {
743 fatal("%s: data length incorrect: %u", __func__, datlen); 753 /*
754 * Construct expected hostkey proof and compare it to what
755 * the client sent us.
756 */
757 if (session_id2_len == 0) /* hostkeys is never first */
758 fatal("%s: bad data length: %zu", __func__, datlen);
759 if ((key = get_hostkey_public_by_index(keyid, ssh)) == NULL)
760 fatal("%s: no hostkey for index %d", __func__, keyid);
761 if ((sigbuf = sshbuf_new()) == NULL)
762 fatal("%s: sshbuf_new", __func__);
763 if ((r = sshbuf_put_cstring(sigbuf, proof_req)) != 0 ||
764 (r = sshbuf_put_string(sigbuf, session_id2,
765 session_id2_len) != 0) ||
766 (r = sshkey_puts(key, sigbuf)) != 0)
767 fatal("%s: couldn't prepare private key "
768 "proof buffer: %s", __func__, ssh_err(r));
769 if (datlen != sshbuf_len(sigbuf) ||
770 memcmp(p, sshbuf_ptr(sigbuf), sshbuf_len(sigbuf)) != 0)
771 fatal("%s: bad data length: %zu, hostkey proof len %zu",
772 __func__, datlen, sshbuf_len(sigbuf));
773 sshbuf_free(sigbuf);
774 is_proof = 1;
775 }
744 776
745 /* save session id, it will be passed on the first call */ 777 /* save session id, it will be passed on the first call */
746 if (session_id2_len == 0) { 778 if (session_id2_len == 0) {
@@ -750,20 +782,26 @@ mm_answer_sign(int sock, Buffer *m)
750 } 782 }
751 783
752 if ((key = get_hostkey_by_index(keyid)) != NULL) { 784 if ((key = get_hostkey_by_index(keyid)) != NULL) {
753 if (key_sign(key, &signature, &siglen, p, datlen) < 0) 785 if ((r = sshkey_sign(key, &signature, &siglen, p, datlen,
754 fatal("%s: key_sign failed", __func__); 786 datafellows)) != 0)
755 } else if ((key = get_hostkey_public_by_index(keyid)) != NULL && 787 fatal("%s: sshkey_sign failed: %s",
756 auth_conn != NULL) { 788 __func__, ssh_err(r));
757 if (ssh_agent_sign(auth_conn, key, &signature, &siglen, p, 789 } else if ((key = get_hostkey_public_by_index(keyid, ssh)) != NULL &&
758 datlen) < 0) 790 auth_sock > 0) {
759 fatal("%s: ssh_agent_sign failed", __func__); 791 if ((r = ssh_agent_sign(auth_sock, key, &signature, &siglen,
792 p, datlen, datafellows)) != 0) {
793 fatal("%s: ssh_agent_sign failed: %s",
794 __func__, ssh_err(r));
795 }
760 } else 796 } else
761 fatal("%s: no hostkey from index %d", __func__, keyid); 797 fatal("%s: no hostkey from index %d", __func__, keyid);
762 798
763 debug3("%s: signature %p(%u)", __func__, signature, siglen); 799 debug3("%s: %s signature %p(%zu)", __func__,
800 is_proof ? "KEX" : "hostkey proof", signature, siglen);
764 801
765 buffer_clear(m); 802 sshbuf_reset(m);
766 buffer_put_string(m, signature, siglen); 803 if ((r = sshbuf_put_string(m, signature, siglen)) != 0)
804 fatal("%s: buffer error: %s", __func__, ssh_err(r));
767 805
768 free(p); 806 free(p);
769 free(signature); 807 free(signature);
@@ -1226,9 +1264,18 @@ mm_answer_keyallowed(int sock, Buffer *m)
1226 debug3("%s: key_from_blob: %p", __func__, key); 1264 debug3("%s: key_from_blob: %p", __func__, key);
1227 1265
1228 if (key != NULL && authctxt->valid) { 1266 if (key != NULL && authctxt->valid) {
1267 /* These should not make it past the privsep child */
1268 if (key_type_plain(key->type) == KEY_RSA &&
1269 (datafellows & SSH_BUG_RSASIGMD5) != 0)
1270 fatal("%s: passed a SSH_BUG_RSASIGMD5 key", __func__);
1271
1229 switch (type) { 1272 switch (type) {
1230 case MM_USERKEY: 1273 case MM_USERKEY:
1231 allowed = options.pubkey_authentication && 1274 allowed = options.pubkey_authentication &&
1275 !auth2_userkey_already_used(authctxt, key) &&
1276 match_pattern_list(sshkey_ssh_name(key),
1277 options.pubkey_key_types,
1278 strlen(options.pubkey_key_types), 0) == 1 &&
1232 user_key_allowed(authctxt->pw, key); 1279 user_key_allowed(authctxt->pw, key);
1233 pubkey_auth_info(authctxt, key, NULL); 1280 pubkey_auth_info(authctxt, key, NULL);
1234 auth_method = "publickey"; 1281 auth_method = "publickey";
@@ -1237,6 +1284,9 @@ mm_answer_keyallowed(int sock, Buffer *m)
1237 break; 1284 break;
1238 case MM_HOSTKEY: 1285 case MM_HOSTKEY:
1239 allowed = options.hostbased_authentication && 1286 allowed = options.hostbased_authentication &&
1287 match_pattern_list(sshkey_ssh_name(key),
1288 options.hostbased_key_types,
1289 strlen(options.hostbased_key_types), 0) == 1 &&
1240 hostbased_key_allowed(authctxt->pw, 1290 hostbased_key_allowed(authctxt->pw,
1241 cuser, chost, key); 1291 cuser, chost, key);
1242 pubkey_auth_info(authctxt, key, 1292 pubkey_auth_info(authctxt, key,
@@ -1456,7 +1506,12 @@ mm_answer_keyverify(int sock, Buffer *m)
1456 debug3("%s: key %p signature %s", 1506 debug3("%s: key %p signature %s",
1457 __func__, key, (verified == 1) ? "verified" : "unverified"); 1507 __func__, key, (verified == 1) ? "verified" : "unverified");
1458 1508
1459 key_free(key); 1509 /* If auth was successful then record key to ensure it isn't reused */
1510 if (verified == 1)
1511 auth2_record_userkey(authctxt, key);
1512 else
1513 key_free(key);
1514
1460 free(blob); 1515 free(blob);
1461 free(signature); 1516 free(signature);
1462 free(data); 1517 free(data);
@@ -1842,112 +1897,47 @@ mm_answer_audit_command(int socket, Buffer *m)
1842void 1897void
1843monitor_apply_keystate(struct monitor *pmonitor) 1898monitor_apply_keystate(struct monitor *pmonitor)
1844{ 1899{
1845 if (compat20) { 1900 struct ssh *ssh = active_state; /* XXX */
1846 set_newkeys(MODE_IN); 1901 struct kex *kex;
1847 set_newkeys(MODE_OUT); 1902 int r;
1848 } else { 1903
1849 packet_set_protocol_flags(child_state.ssh1protoflags); 1904 debug3("%s: packet_set_state", __func__);
1850 packet_set_encryption_key(child_state.ssh1key, 1905 if ((r = ssh_packet_set_state(ssh, child_state)) != 0)
1851 child_state.ssh1keylen, child_state.ssh1cipher); 1906 fatal("%s: packet_set_state: %s", __func__, ssh_err(r));
1852 free(child_state.ssh1key); 1907 sshbuf_free(child_state);
1853 } 1908 child_state = NULL;
1854 1909
1855 /* for rc4 and other stateful ciphers */ 1910 if ((kex = ssh->kex) != 0) {
1856 packet_set_keycontext(MODE_OUT, child_state.keyout); 1911 /* XXX set callbacks */
1857 free(child_state.keyout); 1912#ifdef WITH_OPENSSL
1858 packet_set_keycontext(MODE_IN, child_state.keyin); 1913 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1859 free(child_state.keyin); 1914 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1860 1915 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1861 if (!compat20) { 1916 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1862 packet_set_iv(MODE_OUT, child_state.ivout); 1917# ifdef OPENSSL_HAS_ECC
1863 free(child_state.ivout); 1918 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
1864 packet_set_iv(MODE_IN, child_state.ivin); 1919# endif
1865 free(child_state.ivin); 1920#endif /* WITH_OPENSSL */
1921 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1922#ifdef GSSAPI
1923 if (options.gss_keyex) {
1924 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1925 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1926 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1927 }
1928#endif
1929 kex->load_host_public_key=&get_hostkey_public_by_type;
1930 kex->load_host_private_key=&get_hostkey_private_by_type;
1931 kex->host_key_index=&get_hostkey_index;
1932 kex->sign = sshd_hostkey_sign;
1866 } 1933 }
1867 1934
1868 memcpy(&incoming_stream, &child_state.incoming,
1869 sizeof(incoming_stream));
1870 memcpy(&outgoing_stream, &child_state.outgoing,
1871 sizeof(outgoing_stream));
1872
1873 /* Update with new address */ 1935 /* Update with new address */
1874 if (options.compression) 1936 if (options.compression) {
1875 mm_init_compression(pmonitor->m_zlib); 1937 ssh_packet_set_compress_hooks(ssh, pmonitor->m_zlib,
1876 1938 (ssh_packet_comp_alloc_func *)mm_zalloc,
1877 packet_set_postauth(); 1939 (ssh_packet_comp_free_func *)mm_zfree);
1878
1879 if (options.rekey_limit || options.rekey_interval)
1880 packet_set_rekey_limits((u_int32_t)options.rekey_limit,
1881 (time_t)options.rekey_interval);
1882
1883 /* Network I/O buffers */
1884 /* XXX inefficient for large buffers, need: buffer_init_from_string */
1885 buffer_clear(packet_get_input());
1886 buffer_append(packet_get_input(), child_state.input, child_state.ilen);
1887 explicit_bzero(child_state.input, child_state.ilen);
1888 free(child_state.input);
1889
1890 buffer_clear(packet_get_output());
1891 buffer_append(packet_get_output(), child_state.output,
1892 child_state.olen);
1893 explicit_bzero(child_state.output, child_state.olen);
1894 free(child_state.output);
1895
1896 /* Roaming */
1897 if (compat20)
1898 roam_set_bytes(child_state.sent_bytes, child_state.recv_bytes);
1899}
1900
1901static Kex *
1902mm_get_kex(Buffer *m)
1903{
1904 Kex *kex;
1905 void *blob;
1906 u_int bloblen;
1907
1908 kex = xcalloc(1, sizeof(*kex));
1909 kex->session_id = buffer_get_string(m, &kex->session_id_len);
1910 if (session_id2 == NULL ||
1911 kex->session_id_len != session_id2_len ||
1912 timingsafe_bcmp(kex->session_id, session_id2, session_id2_len) != 0)
1913 fatal("mm_get_get: internal error: bad session id");
1914 kex->we_need = buffer_get_int(m);
1915#ifdef WITH_OPENSSL
1916 kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1917 kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1918 kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1919 kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1920 kex->kex[KEX_ECDH_SHA2] = kexecdh_server;
1921#endif
1922 kex->kex[KEX_C25519_SHA256] = kexc25519_server;
1923#ifdef GSSAPI
1924 if (options.gss_keyex) {
1925 kex->kex[KEX_GSS_GRP1_SHA1] = kexgss_server;
1926 kex->kex[KEX_GSS_GRP14_SHA1] = kexgss_server;
1927 kex->kex[KEX_GSS_GEX_SHA1] = kexgss_server;
1928 } 1940 }
1929#endif
1930 kex->server = 1;
1931 kex->hostkey_type = buffer_get_int(m);
1932 kex->kex_type = buffer_get_int(m);
1933 blob = buffer_get_string(m, &bloblen);
1934 buffer_init(&kex->my);
1935 buffer_append(&kex->my, blob, bloblen);
1936 free(blob);
1937 blob = buffer_get_string(m, &bloblen);
1938 buffer_init(&kex->peer);
1939 buffer_append(&kex->peer, blob, bloblen);
1940 free(blob);
1941 kex->done = 1;
1942 kex->flags = buffer_get_int(m);
1943 kex->client_version_string = buffer_get_string(m, NULL);
1944 kex->server_version_string = buffer_get_string(m, NULL);
1945 kex->load_host_public_key=&get_hostkey_public_by_type;
1946 kex->load_host_private_key=&get_hostkey_private_by_type;
1947 kex->host_key_index=&get_hostkey_index;
1948 kex->sign = sshd_hostkey_sign;
1949
1950 return (kex);
1951} 1941}
1952 1942
1953/* This function requries careful sanity checking */ 1943/* This function requries careful sanity checking */
@@ -1955,118 +1945,16 @@ mm_get_kex(Buffer *m)
1955void 1945void
1956mm_get_keystate(struct monitor *pmonitor) 1946mm_get_keystate(struct monitor *pmonitor)
1957{ 1947{
1958 Buffer m;
1959 u_char *blob, *p;
1960 u_int bloblen, plen;
1961 u_int32_t seqnr, packets;
1962 u_int64_t blocks, bytes;
1963
1964 debug3("%s: Waiting for new keys", __func__); 1948 debug3("%s: Waiting for new keys", __func__);
1965 1949
1966 buffer_init(&m); 1950 if ((child_state = sshbuf_new()) == NULL)
1967 mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m); 1951 fatal("%s: sshbuf_new failed", __func__);
1968 if (!compat20) { 1952 mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT,
1969 child_state.ssh1protoflags = buffer_get_int(&m); 1953 child_state);
1970 child_state.ssh1cipher = buffer_get_int(&m); 1954 debug3("%s: GOT new keys", __func__);
1971 child_state.ssh1key = buffer_get_string(&m,
1972 &child_state.ssh1keylen);
1973 child_state.ivout = buffer_get_string(&m,
1974 &child_state.ivoutlen);
1975 child_state.ivin = buffer_get_string(&m, &child_state.ivinlen);
1976 goto skip;
1977 } else {
1978 /* Get the Kex for rekeying */
1979 *pmonitor->m_pkex = mm_get_kex(&m);
1980 }
1981
1982 blob = buffer_get_string(&m, &bloblen);
1983 current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
1984 free(blob);
1985
1986 debug3("%s: Waiting for second key", __func__);
1987 blob = buffer_get_string(&m, &bloblen);
1988 current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
1989 free(blob);
1990
1991 /* Now get sequence numbers for the packets */
1992 seqnr = buffer_get_int(&m);
1993 blocks = buffer_get_int64(&m);
1994 packets = buffer_get_int(&m);
1995 bytes = buffer_get_int64(&m);
1996 packet_set_state(MODE_OUT, seqnr, blocks, packets, bytes);
1997 seqnr = buffer_get_int(&m);
1998 blocks = buffer_get_int64(&m);
1999 packets = buffer_get_int(&m);
2000 bytes = buffer_get_int64(&m);
2001 packet_set_state(MODE_IN, seqnr, blocks, packets, bytes);
2002
2003 skip:
2004 /* Get the key context */
2005 child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);
2006 child_state.keyin = buffer_get_string(&m, &child_state.keyinlen);
2007
2008 debug3("%s: Getting compression state", __func__);
2009 /* Get compression state */
2010 p = buffer_get_string(&m, &plen);
2011 if (plen != sizeof(child_state.outgoing))
2012 fatal("%s: bad request size", __func__);
2013 memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));
2014 free(p);
2015
2016 p = buffer_get_string(&m, &plen);
2017 if (plen != sizeof(child_state.incoming))
2018 fatal("%s: bad request size", __func__);
2019 memcpy(&child_state.incoming, p, sizeof(child_state.incoming));
2020 free(p);
2021
2022 /* Network I/O buffers */
2023 debug3("%s: Getting Network I/O buffers", __func__);
2024 child_state.input = buffer_get_string(&m, &child_state.ilen);
2025 child_state.output = buffer_get_string(&m, &child_state.olen);
2026
2027 /* Roaming */
2028 if (compat20) {
2029 child_state.sent_bytes = buffer_get_int64(&m);
2030 child_state.recv_bytes = buffer_get_int64(&m);
2031 }
2032
2033 buffer_free(&m);
2034} 1955}
2035 1956
2036 1957
2037/* Allocation functions for zlib */
2038void *
2039mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
2040{
2041 size_t len = (size_t) size * ncount;
2042 void *address;
2043
2044 if (len == 0 || ncount > SIZE_T_MAX / size)
2045 fatal("%s: mm_zalloc(%u, %u)", __func__, ncount, size);
2046
2047 address = mm_malloc(mm, len);
2048
2049 return (address);
2050}
2051
2052void
2053mm_zfree(struct mm_master *mm, void *address)
2054{
2055 mm_free(mm, address);
2056}
2057
2058void
2059mm_init_compression(struct mm_master *mm)
2060{
2061 outgoing_stream.zalloc = (alloc_func)mm_zalloc;
2062 outgoing_stream.zfree = (free_func)mm_zfree;
2063 outgoing_stream.opaque = mm;
2064
2065 incoming_stream.zalloc = (alloc_func)mm_zalloc;
2066 incoming_stream.zfree = (free_func)mm_zfree;
2067 incoming_stream.opaque = mm;
2068}
2069
2070/* XXX */ 1958/* XXX */
2071 1959
2072#define FD_CLOSEONEXEC(x) do { \ 1960#define FD_CLOSEONEXEC(x) do { \
@@ -2102,6 +1990,7 @@ monitor_openfds(struct monitor *mon, int do_logfds)
2102struct monitor * 1990struct monitor *
2103monitor_init(void) 1991monitor_init(void)
2104{ 1992{
1993 struct ssh *ssh = active_state; /* XXX */
2105 struct monitor *mon; 1994 struct monitor *mon;
2106 1995
2107 mon = xcalloc(1, sizeof(*mon)); 1996 mon = xcalloc(1, sizeof(*mon));
@@ -2114,7 +2003,9 @@ monitor_init(void)
2114 mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE); 2003 mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE);
2115 2004
2116 /* Compression needs to share state across borders */ 2005 /* Compression needs to share state across borders */
2117 mm_init_compression(mon->m_zlib); 2006 ssh_packet_set_compress_hooks(ssh, mon->m_zlib,
2007 (ssh_packet_comp_alloc_func *)mm_zalloc,
2008 (ssh_packet_comp_free_func *)mm_zfree);
2118 } 2009 }
2119 2010
2120 return mon; 2011 return mon;