packet.c revision 250739
1248619Sdes/* $OpenBSD: packet.c,v 1.181 2013/02/10 23:35:24 djm Exp $ */
2250739Sdes/* $OpenBSD: packet.c,v 1.182 2013/04/11 02:27:50 djm Exp $ */
357429Smarkm/*
457429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi>
557429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
657429Smarkm *                    All rights reserved
757429Smarkm * This file contains code implementing the packet protocol and communication
857429Smarkm * with the other side.  This same code is used both on client and server side.
960573Skris *
1065668Skris * As far as I am concerned, the code I have written for this software
1165668Skris * can be used freely for any purpose.  Any derived versions of this
1265668Skris * software must be clearly marked as such, and if the derived work is
1365668Skris * incompatible with the protocol description in the RFC file, it must be
1465668Skris * called by a name other than "ssh" or "Secure Shell".
1565668Skris *
1665668Skris *
1760573Skris * SSH2 packet format added by Markus Friedl.
1892555Sdes * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
1960573Skris *
2065668Skris * Redistribution and use in source and binary forms, with or without
2165668Skris * modification, are permitted provided that the following conditions
2265668Skris * are met:
2365668Skris * 1. Redistributions of source code must retain the above copyright
2465668Skris *    notice, this list of conditions and the following disclaimer.
2565668Skris * 2. Redistributions in binary form must reproduce the above copyright
2665668Skris *    notice, this list of conditions and the following disclaimer in the
2765668Skris *    documentation and/or other materials provided with the distribution.
2865668Skris *
2965668Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
3065668Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
3165668Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3265668Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3365668Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
3465668Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3565668Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3665668Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3765668Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
3865668Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3957429Smarkm */
4057429Smarkm
4157429Smarkm#include "includes.h"
42162852Sdes
43162852Sdes#include <sys/types.h>
44124208Sdes#include "openbsd-compat/sys-queue.h"
45162852Sdes#include <sys/param.h>
46162852Sdes#include <sys/socket.h>
47162852Sdes#ifdef HAVE_SYS_TIME_H
48162852Sdes# include <sys/time.h>
49162852Sdes#endif
50124208Sdes
51162852Sdes#include <netinet/in.h>
52162852Sdes#include <netinet/ip.h>
53162852Sdes#include <arpa/inet.h>
54162852Sdes
55162852Sdes#include <errno.h>
56162852Sdes#include <stdarg.h>
57162852Sdes#include <stdio.h>
58162852Sdes#include <stdlib.h>
59162852Sdes#include <string.h>
60162852Sdes#include <unistd.h>
61162852Sdes#include <signal.h>
62162852Sdes
6357429Smarkm#include "xmalloc.h"
6457429Smarkm#include "buffer.h"
6557429Smarkm#include "packet.h"
6657429Smarkm#include "crc32.h"
6757429Smarkm#include "compress.h"
6857429Smarkm#include "deattack.h"
6960573Skris#include "channels.h"
7060573Skris#include "compat.h"
7176259Sgreen#include "ssh1.h"
7260573Skris#include "ssh2.h"
7369587Sgreen#include "cipher.h"
74162852Sdes#include "key.h"
7560573Skris#include "kex.h"
7676259Sgreen#include "mac.h"
7776259Sgreen#include "log.h"
7876259Sgreen#include "canohost.h"
7992555Sdes#include "misc.h"
8098675Sdes#include "ssh.h"
81197679Sdes#include "roaming.h"
8260573Skris
8360573Skris#ifdef PACKET_DEBUG
8460573Skris#define DBG(x) x
8560573Skris#else
8660573Skris#define DBG(x)
8760573Skris#endif
8860573Skris
89192595Sdes#define PACKET_MAX_SIZE (256 * 1024)
90192595Sdes
91197679Sdesstruct packet_state {
92197679Sdes	u_int32_t seqnr;
93197679Sdes	u_int32_t packets;
94197679Sdes	u_int64_t blocks;
95197679Sdes	u_int64_t bytes;
96197679Sdes};
9757429Smarkm
98197679Sdesstruct packet {
99197679Sdes	TAILQ_ENTRY(packet) next;
100197679Sdes	u_char type;
101197679Sdes	Buffer payload;
102197679Sdes};
10357429Smarkm
104197679Sdesstruct session_state {
105197679Sdes	/*
106197679Sdes	 * This variable contains the file descriptors used for
107197679Sdes	 * communicating with the other side.  connection_in is used for
108197679Sdes	 * reading; connection_out for writing.  These can be the same
109197679Sdes	 * descriptor, in which case it is assumed to be a socket.
110197679Sdes	 */
111197679Sdes	int connection_in;
112197679Sdes	int connection_out;
11357429Smarkm
114197679Sdes	/* Protocol flags for the remote side. */
115197679Sdes	u_int remote_protocol_flags;
11657429Smarkm
117197679Sdes	/* Encryption context for receiving data.  Only used for decryption. */
118197679Sdes	CipherContext receive_context;
11957429Smarkm
120197679Sdes	/* Encryption context for sending data.  Only used for encryption. */
121197679Sdes	CipherContext send_context;
12257429Smarkm
123197679Sdes	/* Buffer for raw input data from the socket. */
124197679Sdes	Buffer input;
12557429Smarkm
126197679Sdes	/* Buffer for raw output data going to the socket. */
127197679Sdes	Buffer output;
12857429Smarkm
129197679Sdes	/* Buffer for the partial outgoing packet being constructed. */
130197679Sdes	Buffer outgoing_packet;
13157429Smarkm
132197679Sdes	/* Buffer for the incoming packet currently being processed. */
133197679Sdes	Buffer incoming_packet;
13457429Smarkm
135197679Sdes	/* Scratch buffer for packet compression/decompression. */
136197679Sdes	Buffer compression_buffer;
137197679Sdes	int compression_buffer_ready;
13857429Smarkm
139197679Sdes	/*
140197679Sdes	 * Flag indicating whether packet compression/decompression is
141197679Sdes	 * enabled.
142197679Sdes	 */
143197679Sdes	int packet_compression;
14457429Smarkm
145197679Sdes	/* default maximum packet size */
146197679Sdes	u_int max_packet_size;
14757429Smarkm
148197679Sdes	/* Flag indicating whether this module has been initialized. */
149197679Sdes	int initialized;
150149749Sdes
151197679Sdes	/* Set to true if the connection is interactive. */
152197679Sdes	int interactive_mode;
153149749Sdes
154197679Sdes	/* Set to true if we are the server side. */
155197679Sdes	int server_side;
156181111Sdes
157197679Sdes	/* Set to true if we are authenticated. */
158197679Sdes	int after_authentication;
159181111Sdes
160197679Sdes	int keep_alive_timeouts;
16160573Skris
162197679Sdes	/* The maximum time that we will wait to send or receive a packet */
163197679Sdes	int packet_timeout_ms;
164124208Sdes
165197679Sdes	/* Session key information for Encryption and MAC */
166197679Sdes	Newkeys *newkeys[MODE_MAX];
167197679Sdes	struct packet_state p_read, p_send;
16898675Sdes
169197679Sdes	u_int64_t max_blocks_in, max_blocks_out;
170197679Sdes	u_int32_t rekey_limit;
17160573Skris
172197679Sdes	/* Session key for protocol v1 */
173197679Sdes	u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
174197679Sdes	u_int ssh1_keylen;
175192595Sdes
176197679Sdes	/* roundup current message to extra_pad bytes */
177197679Sdes	u_char extra_pad;
178197679Sdes
179197679Sdes	/* XXX discard incoming data after MAC error */
180197679Sdes	u_int packet_discard;
181197679Sdes	Mac *packet_discard_mac;
182197679Sdes
183197679Sdes	/* Used in packet_read_poll2() */
184197679Sdes	u_int packlen;
185197679Sdes
186197679Sdes	/* Used in packet_send2 */
187197679Sdes	int rekeying;
188197679Sdes
189197679Sdes	/* Used in packet_set_interactive */
190197679Sdes	int set_interactive_called;
191197679Sdes
192197679Sdes	/* Used in packet_set_maxsize */
193197679Sdes	int set_maxsize_called;
194197679Sdes
195197679Sdes	TAILQ_HEAD(, packet) outgoing;
196124208Sdes};
197124208Sdes
198197679Sdesstatic struct session_state *active_state, *backup_state;
199224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
200224638Sbrooksstatic int rekey_requested = 0;
201224638Sbrooks#endif
202197679Sdes
203197679Sdesstatic struct session_state *
204197679Sdesalloc_session_state(void)
205197679Sdes{
206221420Sdes	struct session_state *s = xcalloc(1, sizeof(*s));
207197679Sdes
208221420Sdes	s->connection_in = -1;
209221420Sdes	s->connection_out = -1;
210221420Sdes	s->max_packet_size = 32768;
211221420Sdes	s->packet_timeout_ms = -1;
212221420Sdes	return s;
213197679Sdes}
214197679Sdes
21557429Smarkm/*
21657429Smarkm * Sets the descriptors used for communication.  Disables encryption until
21757429Smarkm * packet_set_encryption_key is called.
21857429Smarkm */
21957429Smarkmvoid
22057429Smarkmpacket_set_connection(int fd_in, int fd_out)
22157429Smarkm{
22269587Sgreen	Cipher *none = cipher_by_name("none");
223106121Sdes
22469587Sgreen	if (none == NULL)
22569587Sgreen		fatal("packet_set_connection: cannot load cipher 'none'");
226197679Sdes	if (active_state == NULL)
227197679Sdes		active_state = alloc_session_state();
228197679Sdes	active_state->connection_in = fd_in;
229197679Sdes	active_state->connection_out = fd_out;
230197679Sdes	cipher_init(&active_state->send_context, none, (const u_char *)"",
231137015Sdes	    0, NULL, 0, CIPHER_ENCRYPT);
232197679Sdes	cipher_init(&active_state->receive_context, none, (const u_char *)"",
233137015Sdes	    0, NULL, 0, CIPHER_DECRYPT);
234197679Sdes	active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL;
235197679Sdes	if (!active_state->initialized) {
236197679Sdes		active_state->initialized = 1;
237197679Sdes		buffer_init(&active_state->input);
238197679Sdes		buffer_init(&active_state->output);
239197679Sdes		buffer_init(&active_state->outgoing_packet);
240197679Sdes		buffer_init(&active_state->incoming_packet);
241197679Sdes		TAILQ_INIT(&active_state->outgoing);
242197679Sdes		active_state->p_send.packets = active_state->p_read.packets = 0;
24357429Smarkm	}
24457429Smarkm}
24557429Smarkm
246181111Sdesvoid
247181111Sdespacket_set_timeout(int timeout, int count)
248181111Sdes{
249240075Sdes	if (timeout <= 0 || count <= 0) {
250197679Sdes		active_state->packet_timeout_ms = -1;
251181111Sdes		return;
252181111Sdes	}
253181111Sdes	if ((INT_MAX / 1000) / count < timeout)
254197679Sdes		active_state->packet_timeout_ms = INT_MAX;
255181111Sdes	else
256197679Sdes		active_state->packet_timeout_ms = timeout * count * 1000;
257181111Sdes}
258181111Sdes
259192595Sdesstatic void
260192595Sdespacket_stop_discard(void)
261192595Sdes{
262197679Sdes	if (active_state->packet_discard_mac) {
263192595Sdes		char buf[1024];
264192595Sdes
265192595Sdes		memset(buf, 'a', sizeof(buf));
266197679Sdes		while (buffer_len(&active_state->incoming_packet) <
267197679Sdes		    PACKET_MAX_SIZE)
268197679Sdes			buffer_append(&active_state->incoming_packet, buf,
269197679Sdes			    sizeof(buf));
270197679Sdes		(void) mac_compute(active_state->packet_discard_mac,
271197679Sdes		    active_state->p_read.seqnr,
272197679Sdes		    buffer_ptr(&active_state->incoming_packet),
273192595Sdes		    PACKET_MAX_SIZE);
274192595Sdes	}
275192595Sdes	logit("Finished discarding for %.200s", get_remote_ipaddr());
276192595Sdes	cleanup_exit(255);
277192595Sdes}
278192595Sdes
279192595Sdesstatic void
280192595Sdespacket_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
281192595Sdes{
282248619Sdes	if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm))
283192595Sdes		packet_disconnect("Packet corrupt");
284192595Sdes	if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
285197679Sdes		active_state->packet_discard_mac = mac;
286197679Sdes	if (buffer_len(&active_state->input) >= discard)
287192595Sdes		packet_stop_discard();
288197679Sdes	active_state->packet_discard = discard -
289197679Sdes	    buffer_len(&active_state->input);
290192595Sdes}
291192595Sdes
29257429Smarkm/* Returns 1 if remote host is connected via socket, 0 if not. */
29357429Smarkm
29457429Smarkmint
29592555Sdespacket_connection_is_on_socket(void)
29657429Smarkm{
29757429Smarkm	struct sockaddr_storage from, to;
29857429Smarkm	socklen_t fromlen, tolen;
29957429Smarkm
30057429Smarkm	/* filedescriptors in and out are the same, so it's a socket */
301197679Sdes	if (active_state->connection_in == active_state->connection_out)
30257429Smarkm		return 1;
30357429Smarkm	fromlen = sizeof(from);
30457429Smarkm	memset(&from, 0, sizeof(from));
305197679Sdes	if (getpeername(active_state->connection_in, (struct sockaddr *)&from,
306197679Sdes	    &fromlen) < 0)
30757429Smarkm		return 0;
30857429Smarkm	tolen = sizeof(to);
30957429Smarkm	memset(&to, 0, sizeof(to));
310197679Sdes	if (getpeername(active_state->connection_out, (struct sockaddr *)&to,
311197679Sdes	    &tolen) < 0)
31257429Smarkm		return 0;
31357429Smarkm	if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
31457429Smarkm		return 0;
31557429Smarkm	if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
31657429Smarkm		return 0;
31757429Smarkm	return 1;
31857429Smarkm}
31957429Smarkm
32098675Sdes/*
32198675Sdes * Exports an IV from the CipherContext required to export the key
32298675Sdes * state back from the unprivileged child to the privileged parent
32398675Sdes * process.
32498675Sdes */
32598675Sdes
32698675Sdesvoid
32798675Sdespacket_get_keyiv(int mode, u_char *iv, u_int len)
32898675Sdes{
32998675Sdes	CipherContext *cc;
33098675Sdes
33198675Sdes	if (mode == MODE_OUT)
332197679Sdes		cc = &active_state->send_context;
33398675Sdes	else
334197679Sdes		cc = &active_state->receive_context;
33598675Sdes
33698675Sdes	cipher_get_keyiv(cc, iv, len);
33798675Sdes}
33898675Sdes
33998675Sdesint
34098675Sdespacket_get_keycontext(int mode, u_char *dat)
34198675Sdes{
34298675Sdes	CipherContext *cc;
34398675Sdes
34498675Sdes	if (mode == MODE_OUT)
345197679Sdes		cc = &active_state->send_context;
34698675Sdes	else
347197679Sdes		cc = &active_state->receive_context;
34898675Sdes
34998675Sdes	return (cipher_get_keycontext(cc, dat));
35098675Sdes}
35198675Sdes
35298675Sdesvoid
35398675Sdespacket_set_keycontext(int mode, u_char *dat)
35498675Sdes{
35598675Sdes	CipherContext *cc;
35698675Sdes
35798675Sdes	if (mode == MODE_OUT)
358197679Sdes		cc = &active_state->send_context;
35998675Sdes	else
360197679Sdes		cc = &active_state->receive_context;
36198675Sdes
36298675Sdes	cipher_set_keycontext(cc, dat);
36398675Sdes}
36498675Sdes
36598675Sdesint
36698675Sdespacket_get_keyiv_len(int mode)
36798675Sdes{
36898675Sdes	CipherContext *cc;
36998675Sdes
37098675Sdes	if (mode == MODE_OUT)
371197679Sdes		cc = &active_state->send_context;
37298675Sdes	else
373197679Sdes		cc = &active_state->receive_context;
37498675Sdes
37598675Sdes	return (cipher_get_keyiv_len(cc));
37698675Sdes}
377162852Sdes
37898675Sdesvoid
37998675Sdespacket_set_iv(int mode, u_char *dat)
38098675Sdes{
38198675Sdes	CipherContext *cc;
38298675Sdes
38398675Sdes	if (mode == MODE_OUT)
384197679Sdes		cc = &active_state->send_context;
38598675Sdes	else
386197679Sdes		cc = &active_state->receive_context;
38798675Sdes
38898675Sdes	cipher_set_keyiv(cc, dat);
38998675Sdes}
390162852Sdes
39198675Sdesint
392124208Sdespacket_get_ssh1_cipher(void)
39398675Sdes{
394197679Sdes	return (cipher_get_number(active_state->receive_context.cipher));
39598675Sdes}
39698675Sdes
397124208Sdesvoid
398221420Sdespacket_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks,
399221420Sdes    u_int32_t *packets, u_int64_t *bytes)
400124208Sdes{
401124208Sdes	struct packet_state *state;
40298675Sdes
403197679Sdes	state = (mode == MODE_IN) ?
404197679Sdes	    &active_state->p_read : &active_state->p_send;
405181111Sdes	if (seqnr)
406181111Sdes		*seqnr = state->seqnr;
407181111Sdes	if (blocks)
408181111Sdes		*blocks = state->blocks;
409181111Sdes	if (packets)
410181111Sdes		*packets = state->packets;
411181111Sdes	if (bytes)
412181111Sdes		*bytes = state->bytes;
41398675Sdes}
41498675Sdes
41598675Sdesvoid
416181111Sdespacket_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets,
417181111Sdes    u_int64_t bytes)
41898675Sdes{
419124208Sdes	struct packet_state *state;
420124208Sdes
421197679Sdes	state = (mode == MODE_IN) ?
422197679Sdes	    &active_state->p_read : &active_state->p_send;
423124208Sdes	state->seqnr = seqnr;
424124208Sdes	state->blocks = blocks;
425124208Sdes	state->packets = packets;
426181111Sdes	state->bytes = bytes;
42798675Sdes}
42898675Sdes
429226046Sdesstatic int
430226046Sdespacket_connection_af(void)
43157429Smarkm{
43257429Smarkm	struct sockaddr_storage to;
43357429Smarkm	socklen_t tolen = sizeof(to);
43457429Smarkm
43557429Smarkm	memset(&to, 0, sizeof(to));
436197679Sdes	if (getsockname(active_state->connection_out, (struct sockaddr *)&to,
437197679Sdes	    &tolen) < 0)
43857429Smarkm		return 0;
43998937Sdes#ifdef IPV4_IN_IPV6
440126274Sdes	if (to.ss_family == AF_INET6 &&
44198937Sdes	    IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))
442226046Sdes		return AF_INET;
44398937Sdes#endif
444226046Sdes	return to.ss_family;
44557429Smarkm}
44657429Smarkm
44757429Smarkm/* Sets the connection into non-blocking mode. */
44857429Smarkm
44957429Smarkmvoid
45092555Sdespacket_set_nonblocking(void)
45157429Smarkm{
45257429Smarkm	/* Set the socket into non-blocking mode. */
453197679Sdes	set_nonblock(active_state->connection_in);
45457429Smarkm
455197679Sdes	if (active_state->connection_out != active_state->connection_in)
456197679Sdes		set_nonblock(active_state->connection_out);
45757429Smarkm}
45857429Smarkm
45957429Smarkm/* Returns the socket used for reading. */
46057429Smarkm
46157429Smarkmint
46292555Sdespacket_get_connection_in(void)
46357429Smarkm{
464197679Sdes	return active_state->connection_in;
46557429Smarkm}
46657429Smarkm
46757429Smarkm/* Returns the descriptor used for writing. */
46857429Smarkm
46957429Smarkmint
47092555Sdespacket_get_connection_out(void)
47157429Smarkm{
472197679Sdes	return active_state->connection_out;
47357429Smarkm}
47457429Smarkm
47557429Smarkm/* Closes the connection and clears and frees internal data structures. */
47657429Smarkm
47757429Smarkmvoid
47892555Sdespacket_close(void)
47957429Smarkm{
480197679Sdes	if (!active_state->initialized)
48157429Smarkm		return;
482197679Sdes	active_state->initialized = 0;
483197679Sdes	if (active_state->connection_in == active_state->connection_out) {
484197679Sdes		shutdown(active_state->connection_out, SHUT_RDWR);
485197679Sdes		close(active_state->connection_out);
48657429Smarkm	} else {
487197679Sdes		close(active_state->connection_in);
488197679Sdes		close(active_state->connection_out);
48957429Smarkm	}
490197679Sdes	buffer_free(&active_state->input);
491197679Sdes	buffer_free(&active_state->output);
492197679Sdes	buffer_free(&active_state->outgoing_packet);
493197679Sdes	buffer_free(&active_state->incoming_packet);
494197679Sdes	if (active_state->compression_buffer_ready) {
495197679Sdes		buffer_free(&active_state->compression_buffer);
49657429Smarkm		buffer_compress_uninit();
49757429Smarkm	}
498197679Sdes	cipher_cleanup(&active_state->send_context);
499197679Sdes	cipher_cleanup(&active_state->receive_context);
50057429Smarkm}
50157429Smarkm
50257429Smarkm/* Sets remote side protocol flags. */
50357429Smarkm
50457429Smarkmvoid
50576259Sgreenpacket_set_protocol_flags(u_int protocol_flags)
50657429Smarkm{
507197679Sdes	active_state->remote_protocol_flags = protocol_flags;
50857429Smarkm}
50957429Smarkm
51057429Smarkm/* Returns the remote protocol flags set earlier by the above function. */
51157429Smarkm
51276259Sgreenu_int
51392555Sdespacket_get_protocol_flags(void)
51457429Smarkm{
515197679Sdes	return active_state->remote_protocol_flags;
51657429Smarkm}
51757429Smarkm
51857429Smarkm/*
51957429Smarkm * Starts packet compression from the next packet on in both directions.
52057429Smarkm * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip.
52157429Smarkm */
52257429Smarkm
52392555Sdesstatic void
52492555Sdespacket_init_compression(void)
52576259Sgreen{
526197679Sdes	if (active_state->compression_buffer_ready == 1)
52776259Sgreen		return;
528197679Sdes	active_state->compression_buffer_ready = 1;
529197679Sdes	buffer_init(&active_state->compression_buffer);
53076259Sgreen}
53176259Sgreen
53276259Sgreenvoid
53357429Smarkmpacket_start_compression(int level)
53457429Smarkm{
535197679Sdes	if (active_state->packet_compression && !compat20)
53657429Smarkm		fatal("Compression already enabled.");
537197679Sdes	active_state->packet_compression = 1;
53876259Sgreen	packet_init_compression();
53976259Sgreen	buffer_compress_init_send(level);
54076259Sgreen	buffer_compress_init_recv();
54157429Smarkm}
54257429Smarkm
54357429Smarkm/*
54457429Smarkm * Causes any further packets to be encrypted using the given key.  The same
54557429Smarkm * key is used for both sending and reception.  However, both directions are
54657429Smarkm * encrypted independently of each other.
54757429Smarkm */
54898675Sdes
54957429Smarkmvoid
550221420Sdespacket_set_encryption_key(const u_char *key, u_int keylen, int number)
55157429Smarkm{
55269587Sgreen	Cipher *cipher = cipher_by_number(number);
553106121Sdes
55469587Sgreen	if (cipher == NULL)
55569587Sgreen		fatal("packet_set_encryption_key: unknown cipher number %d", number);
55660573Skris	if (keylen < 20)
55769587Sgreen		fatal("packet_set_encryption_key: keylen too small: %d", keylen);
55898675Sdes	if (keylen > SSH_SESSION_KEY_LENGTH)
55998675Sdes		fatal("packet_set_encryption_key: keylen too big: %d", keylen);
560197679Sdes	memcpy(active_state->ssh1_key, key, keylen);
561197679Sdes	active_state->ssh1_keylen = keylen;
562197679Sdes	cipher_init(&active_state->send_context, cipher, key, keylen, NULL,
563197679Sdes	    0, CIPHER_ENCRYPT);
564197679Sdes	cipher_init(&active_state->receive_context, cipher, key, keylen, NULL,
565197679Sdes	    0, CIPHER_DECRYPT);
56657429Smarkm}
56757429Smarkm
56898675Sdesu_int
56998675Sdespacket_get_encryption_key(u_char *key)
57098675Sdes{
57198675Sdes	if (key == NULL)
572197679Sdes		return (active_state->ssh1_keylen);
573197679Sdes	memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen);
574197679Sdes	return (active_state->ssh1_keylen);
57598675Sdes}
57698675Sdes
57792555Sdes/* Start constructing a packet to send. */
57857429Smarkmvoid
57992555Sdespacket_start(u_char type)
58057429Smarkm{
58192555Sdes	u_char buf[9];
58292555Sdes	int len;
58357429Smarkm
58492555Sdes	DBG(debug("packet_start[%d]", type));
58592555Sdes	len = compat20 ? 6 : 9;
58692555Sdes	memset(buf, 0, len - 1);
58792555Sdes	buf[len - 1] = type;
588197679Sdes	buffer_clear(&active_state->outgoing_packet);
589197679Sdes	buffer_append(&active_state->outgoing_packet, buf, len);
59057429Smarkm}
59157429Smarkm
59292555Sdes/* Append payload. */
59360573Skrisvoid
59457429Smarkmpacket_put_char(int value)
59557429Smarkm{
59657429Smarkm	char ch = value;
597106121Sdes
598197679Sdes	buffer_append(&active_state->outgoing_packet, &ch, 1);
59957429Smarkm}
600162852Sdes
60157429Smarkmvoid
60276259Sgreenpacket_put_int(u_int value)
60357429Smarkm{
604197679Sdes	buffer_put_int(&active_state->outgoing_packet, value);
60557429Smarkm}
606162852Sdes
60757429Smarkmvoid
608197679Sdespacket_put_int64(u_int64_t value)
609197679Sdes{
610197679Sdes	buffer_put_int64(&active_state->outgoing_packet, value);
611197679Sdes}
612197679Sdes
613197679Sdesvoid
61492555Sdespacket_put_string(const void *buf, u_int len)
61557429Smarkm{
616197679Sdes	buffer_put_string(&active_state->outgoing_packet, buf, len);
61757429Smarkm}
618162852Sdes
61960573Skrisvoid
62060573Skrispacket_put_cstring(const char *str)
62160573Skris{
622197679Sdes	buffer_put_cstring(&active_state->outgoing_packet, str);
62360573Skris}
624162852Sdes
62560573Skrisvoid
62692555Sdespacket_put_raw(const void *buf, u_int len)
62760573Skris{
628197679Sdes	buffer_append(&active_state->outgoing_packet, buf, len);
62960573Skris}
630162852Sdes
63157429Smarkmvoid
63257429Smarkmpacket_put_bignum(BIGNUM * value)
63357429Smarkm{
634197679Sdes	buffer_put_bignum(&active_state->outgoing_packet, value);
63557429Smarkm}
636162852Sdes
63760573Skrisvoid
63860573Skrispacket_put_bignum2(BIGNUM * value)
63960573Skris{
640197679Sdes	buffer_put_bignum2(&active_state->outgoing_packet, value);
64160573Skris}
64257429Smarkm
643221420Sdes#ifdef OPENSSL_HAS_ECC
644221420Sdesvoid
645221420Sdespacket_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point)
646221420Sdes{
647221420Sdes	buffer_put_ecpoint(&active_state->outgoing_packet, curve, point);
648221420Sdes}
649221420Sdes#endif
650221420Sdes
65157429Smarkm/*
65257429Smarkm * Finalizes and sends the packet.  If the encryption key has been set,
65357429Smarkm * encrypts the packet before sending.
65457429Smarkm */
65557429Smarkm
65692555Sdesstatic void
65776259Sgreenpacket_send1(void)
65857429Smarkm{
65992555Sdes	u_char buf[8], *cp;
66057429Smarkm	int i, padding, len;
66176259Sgreen	u_int checksum;
662137015Sdes	u_int32_t rnd = 0;
66357429Smarkm
66457429Smarkm	/*
66557429Smarkm	 * If using packet compression, compress the payload of the outgoing
66657429Smarkm	 * packet.
66757429Smarkm	 */
668197679Sdes	if (active_state->packet_compression) {
669197679Sdes		buffer_clear(&active_state->compression_buffer);
67057429Smarkm		/* Skip padding. */
671197679Sdes		buffer_consume(&active_state->outgoing_packet, 8);
67257429Smarkm		/* padding */
673197679Sdes		buffer_append(&active_state->compression_buffer,
674197679Sdes		    "\0\0\0\0\0\0\0\0", 8);
675197679Sdes		buffer_compress(&active_state->outgoing_packet,
676197679Sdes		    &active_state->compression_buffer);
677197679Sdes		buffer_clear(&active_state->outgoing_packet);
678197679Sdes		buffer_append(&active_state->outgoing_packet,
679197679Sdes		    buffer_ptr(&active_state->compression_buffer),
680197679Sdes		    buffer_len(&active_state->compression_buffer));
68157429Smarkm	}
68257429Smarkm	/* Compute packet length without padding (add checksum, remove padding). */
683197679Sdes	len = buffer_len(&active_state->outgoing_packet) + 4 - 8;
68457429Smarkm
68560573Skris	/* Insert padding. Initialized to zero in packet_start1() */
68657429Smarkm	padding = 8 - len % 8;
687197679Sdes	if (!active_state->send_context.plaintext) {
688197679Sdes		cp = buffer_ptr(&active_state->outgoing_packet);
68957429Smarkm		for (i = 0; i < padding; i++) {
69057429Smarkm			if (i % 4 == 0)
691137015Sdes				rnd = arc4random();
692137015Sdes			cp[7 - i] = rnd & 0xff;
693137015Sdes			rnd >>= 8;
69457429Smarkm		}
69557429Smarkm	}
696197679Sdes	buffer_consume(&active_state->outgoing_packet, 8 - padding);
69757429Smarkm
69857429Smarkm	/* Add check bytes. */
699197679Sdes	checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet),
700197679Sdes	    buffer_len(&active_state->outgoing_packet));
701162852Sdes	put_u32(buf, checksum);
702197679Sdes	buffer_append(&active_state->outgoing_packet, buf, 4);
70357429Smarkm
70457429Smarkm#ifdef PACKET_DEBUG
70557429Smarkm	fprintf(stderr, "packet_send plain: ");
706197679Sdes	buffer_dump(&active_state->outgoing_packet);
70757429Smarkm#endif
70857429Smarkm
70957429Smarkm	/* Append to output. */
710162852Sdes	put_u32(buf, len);
711197679Sdes	buffer_append(&active_state->output, buf, 4);
712197679Sdes	cp = buffer_append_space(&active_state->output,
713197679Sdes	    buffer_len(&active_state->outgoing_packet));
714197679Sdes	cipher_crypt(&active_state->send_context, cp,
715197679Sdes	    buffer_ptr(&active_state->outgoing_packet),
716248619Sdes	    buffer_len(&active_state->outgoing_packet), 0, 0);
71757429Smarkm
71857429Smarkm#ifdef PACKET_DEBUG
71957429Smarkm	fprintf(stderr, "encrypted: ");
720197679Sdes	buffer_dump(&active_state->output);
72157429Smarkm#endif
722197679Sdes	active_state->p_send.packets++;
723197679Sdes	active_state->p_send.bytes += len +
724197679Sdes	    buffer_len(&active_state->outgoing_packet);
725197679Sdes	buffer_clear(&active_state->outgoing_packet);
72657429Smarkm
72757429Smarkm	/*
728157016Sdes	 * Note that the packet is now only buffered in output.  It won't be
72957429Smarkm	 * actually sent until packet_write_wait or packet_write_poll is
73057429Smarkm	 * called.
73157429Smarkm	 */
73257429Smarkm}
73357429Smarkm
73498675Sdesvoid
73576259Sgreenset_newkeys(int mode)
73676259Sgreen{
73776259Sgreen	Enc *enc;
73876259Sgreen	Mac *mac;
73976259Sgreen	Comp *comp;
74076259Sgreen	CipherContext *cc;
741124208Sdes	u_int64_t *max_blocks;
742137015Sdes	int crypt_type;
74376259Sgreen
744113908Sdes	debug2("set_newkeys: mode %d", mode);
74576259Sgreen
74692555Sdes	if (mode == MODE_OUT) {
747197679Sdes		cc = &active_state->send_context;
748137015Sdes		crypt_type = CIPHER_ENCRYPT;
749197679Sdes		active_state->p_send.packets = active_state->p_send.blocks = 0;
750197679Sdes		max_blocks = &active_state->max_blocks_out;
75192555Sdes	} else {
752197679Sdes		cc = &active_state->receive_context;
753137015Sdes		crypt_type = CIPHER_DECRYPT;
754197679Sdes		active_state->p_read.packets = active_state->p_read.blocks = 0;
755197679Sdes		max_blocks = &active_state->max_blocks_in;
75692555Sdes	}
757197679Sdes	if (active_state->newkeys[mode] != NULL) {
758113908Sdes		debug("set_newkeys: rekeying");
75992555Sdes		cipher_cleanup(cc);
760197679Sdes		enc  = &active_state->newkeys[mode]->enc;
761197679Sdes		mac  = &active_state->newkeys[mode]->mac;
762197679Sdes		comp = &active_state->newkeys[mode]->comp;
763181111Sdes		mac_clear(mac);
764248619Sdes		memset(enc->iv,  0, enc->iv_len);
765248619Sdes		memset(enc->key, 0, enc->key_len);
766248619Sdes		memset(mac->key, 0, mac->key_len);
76776259Sgreen		xfree(enc->name);
76876259Sgreen		xfree(enc->iv);
76976259Sgreen		xfree(enc->key);
77076259Sgreen		xfree(mac->name);
77176259Sgreen		xfree(mac->key);
77276259Sgreen		xfree(comp->name);
773197679Sdes		xfree(active_state->newkeys[mode]);
77476259Sgreen	}
775197679Sdes	active_state->newkeys[mode] = kex_get_newkeys(mode);
776197679Sdes	if (active_state->newkeys[mode] == NULL)
77776259Sgreen		fatal("newkeys: no keys for mode %d", mode);
778197679Sdes	enc  = &active_state->newkeys[mode]->enc;
779197679Sdes	mac  = &active_state->newkeys[mode]->mac;
780197679Sdes	comp = &active_state->newkeys[mode]->comp;
781248619Sdes	if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0)
78276259Sgreen		mac->enabled = 1;
78376259Sgreen	DBG(debug("cipher_init_context: %d", mode));
78492555Sdes	cipher_init(cc, enc->cipher, enc->key, enc->key_len,
785248619Sdes	    enc->iv, enc->iv_len, crypt_type);
78698675Sdes	/* Deleting the keys does not gain extra security */
78798675Sdes	/* memset(enc->iv,  0, enc->block_size);
788181111Sdes	   memset(enc->key, 0, enc->key_len);
789181111Sdes	   memset(mac->key, 0, mac->key_len); */
790149749Sdes	if ((comp->type == COMP_ZLIB ||
791197679Sdes	    (comp->type == COMP_DELAYED &&
792197679Sdes	     active_state->after_authentication)) && comp->enabled == 0) {
79376259Sgreen		packet_init_compression();
79476259Sgreen		if (mode == MODE_OUT)
79576259Sgreen			buffer_compress_init_send(6);
79676259Sgreen		else
79776259Sgreen			buffer_compress_init_recv();
79876259Sgreen		comp->enabled = 1;
79976259Sgreen	}
800124208Sdes	/*
801124208Sdes	 * The 2^(blocksize*2) limit is too expensive for 3DES,
802124208Sdes	 * blowfish, etc, so enforce a 1GB limit for small blocksizes.
803124208Sdes	 */
804124208Sdes	if (enc->block_size >= 16)
805124208Sdes		*max_blocks = (u_int64_t)1 << (enc->block_size*2);
806124208Sdes	else
807124208Sdes		*max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
808197679Sdes	if (active_state->rekey_limit)
809197679Sdes		*max_blocks = MIN(*max_blocks,
810197679Sdes		    active_state->rekey_limit / enc->block_size);
81176259Sgreen}
81276259Sgreen
81357429Smarkm/*
814149749Sdes * Delayed compression for SSH2 is enabled after authentication:
815162852Sdes * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
816149749Sdes * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received.
817149749Sdes */
818149749Sdesstatic void
819149749Sdespacket_enable_delayed_compress(void)
820149749Sdes{
821149749Sdes	Comp *comp = NULL;
822149749Sdes	int mode;
823149749Sdes
824149749Sdes	/*
825149749Sdes	 * Remember that we are past the authentication step, so rekeying
826149749Sdes	 * with COMP_DELAYED will turn on compression immediately.
827149749Sdes	 */
828197679Sdes	active_state->after_authentication = 1;
829149749Sdes	for (mode = 0; mode < MODE_MAX; mode++) {
830162852Sdes		/* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
831197679Sdes		if (active_state->newkeys[mode] == NULL)
832162852Sdes			continue;
833197679Sdes		comp = &active_state->newkeys[mode]->comp;
834149749Sdes		if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
835149749Sdes			packet_init_compression();
836149749Sdes			if (mode == MODE_OUT)
837149749Sdes				buffer_compress_init_send(6);
838149749Sdes			else
839149749Sdes				buffer_compress_init_recv();
840149749Sdes			comp->enabled = 1;
841149749Sdes		}
842149749Sdes	}
843149749Sdes}
844149749Sdes
845149749Sdes/*
84660573Skris * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
84760573Skris */
84892555Sdesstatic void
849124208Sdespacket_send2_wrapped(void)
85060573Skris{
85192555Sdes	u_char type, *cp, *macbuf = NULL;
852248619Sdes	u_char padlen, pad = 0;
853248619Sdes	u_int i, len, authlen = 0, aadlen = 0;
854137015Sdes	u_int32_t rnd = 0;
85560573Skris	Enc *enc   = NULL;
85660573Skris	Mac *mac   = NULL;
85760573Skris	Comp *comp = NULL;
85860573Skris	int block_size;
85960573Skris
860197679Sdes	if (active_state->newkeys[MODE_OUT] != NULL) {
861197679Sdes		enc  = &active_state->newkeys[MODE_OUT]->enc;
862197679Sdes		mac  = &active_state->newkeys[MODE_OUT]->mac;
863197679Sdes		comp = &active_state->newkeys[MODE_OUT]->comp;
864248619Sdes		/* disable mac for authenticated encryption */
865248619Sdes		if ((authlen = cipher_authlen(enc->cipher)) != 0)
866248619Sdes			mac = NULL;
86760573Skris	}
86892555Sdes	block_size = enc ? enc->block_size : 8;
869248619Sdes	aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
87060573Skris
871197679Sdes	cp = buffer_ptr(&active_state->outgoing_packet);
87292555Sdes	type = cp[5];
87360573Skris
87460573Skris#ifdef PACKET_DEBUG
87560573Skris	fprintf(stderr, "plain:     ");
876197679Sdes	buffer_dump(&active_state->outgoing_packet);
87760573Skris#endif
87860573Skris
87960573Skris	if (comp && comp->enabled) {
880197679Sdes		len = buffer_len(&active_state->outgoing_packet);
88160573Skris		/* skip header, compress only payload */
882197679Sdes		buffer_consume(&active_state->outgoing_packet, 5);
883197679Sdes		buffer_clear(&active_state->compression_buffer);
884197679Sdes		buffer_compress(&active_state->outgoing_packet,
885197679Sdes		    &active_state->compression_buffer);
886197679Sdes		buffer_clear(&active_state->outgoing_packet);
887197679Sdes		buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5);
888197679Sdes		buffer_append(&active_state->outgoing_packet,
889197679Sdes		    buffer_ptr(&active_state->compression_buffer),
890197679Sdes		    buffer_len(&active_state->compression_buffer));
89160573Skris		DBG(debug("compression: raw %d compressed %d", len,
892197679Sdes		    buffer_len(&active_state->outgoing_packet)));
89360573Skris	}
89460573Skris
89560573Skris	/* sizeof (packet_len + pad_len + payload) */
896197679Sdes	len = buffer_len(&active_state->outgoing_packet);
89760573Skris
89860573Skris	/*
89960573Skris	 * calc size of padding, alloc space, get random data,
90060573Skris	 * minimum padding is 4 bytes
90160573Skris	 */
902248619Sdes	len -= aadlen; /* packet length is not encrypted for EtM modes */
90360573Skris	padlen = block_size - (len % block_size);
90460573Skris	if (padlen < 4)
90560573Skris		padlen += block_size;
906197679Sdes	if (active_state->extra_pad) {
90792555Sdes		/* will wrap if extra_pad+padlen > 255 */
908197679Sdes		active_state->extra_pad =
909197679Sdes		    roundup(active_state->extra_pad, block_size);
910197679Sdes		pad = active_state->extra_pad -
911197679Sdes		    ((len + padlen) % active_state->extra_pad);
91298675Sdes		debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
913197679Sdes		    pad, len, padlen, active_state->extra_pad);
91492555Sdes		padlen += pad;
915197679Sdes		active_state->extra_pad = 0;
91692555Sdes	}
917197679Sdes	cp = buffer_append_space(&active_state->outgoing_packet, padlen);
918197679Sdes	if (enc && !active_state->send_context.plaintext) {
91960573Skris		/* random padding */
92060573Skris		for (i = 0; i < padlen; i++) {
92160573Skris			if (i % 4 == 0)
922137015Sdes				rnd = arc4random();
923137015Sdes			cp[i] = rnd & 0xff;
924137015Sdes			rnd >>= 8;
92560573Skris		}
92660573Skris	} else {
92760573Skris		/* clear padding */
92860573Skris		memset(cp, 0, padlen);
92960573Skris	}
930248619Sdes	/* sizeof (packet_len + pad_len + payload + padding) */
931248619Sdes	len = buffer_len(&active_state->outgoing_packet);
932248619Sdes	cp = buffer_ptr(&active_state->outgoing_packet);
93360573Skris	/* packet_length includes payload, padding and padding length field */
934248619Sdes	put_u32(cp, len - 4);
93592555Sdes	cp[4] = padlen;
936248619Sdes	DBG(debug("send: len %d (includes padlen %d, aadlen %d)",
937248619Sdes	    len, padlen, aadlen));
93860573Skris
93960573Skris	/* compute MAC over seqnr and packet(length fields, payload, padding) */
940248619Sdes	if (mac && mac->enabled && !mac->etm) {
941197679Sdes		macbuf = mac_compute(mac, active_state->p_send.seqnr,
942248619Sdes		    buffer_ptr(&active_state->outgoing_packet), len);
943197679Sdes		DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
94460573Skris	}
94560573Skris	/* encrypt packet and append to output buffer. */
946248619Sdes	cp = buffer_append_space(&active_state->output, len + authlen);
947197679Sdes	cipher_crypt(&active_state->send_context, cp,
948197679Sdes	    buffer_ptr(&active_state->outgoing_packet),
949248619Sdes	    len - aadlen, aadlen, authlen);
95060573Skris	/* append unencrypted MAC */
951248619Sdes	if (mac && mac->enabled) {
952248619Sdes		if (mac->etm) {
953248619Sdes			/* EtM: compute mac over aadlen + cipher text */
954248619Sdes			macbuf = mac_compute(mac,
955248619Sdes			    active_state->p_send.seqnr, cp, len);
956248619Sdes			DBG(debug("done calc MAC(EtM) out #%d",
957248619Sdes			    active_state->p_send.seqnr));
958248619Sdes		}
959197679Sdes		buffer_append(&active_state->output, macbuf, mac->mac_len);
960248619Sdes	}
96160573Skris#ifdef PACKET_DEBUG
96260573Skris	fprintf(stderr, "encrypted: ");
963197679Sdes	buffer_dump(&active_state->output);
96460573Skris#endif
96560573Skris	/* increment sequence number for outgoing packets */
966197679Sdes	if (++active_state->p_send.seqnr == 0)
967124208Sdes		logit("outgoing seqnr wraps around");
968197679Sdes	if (++active_state->p_send.packets == 0)
969124208Sdes		if (!(datafellows & SSH_BUG_NOREKEY))
970124208Sdes			fatal("XXX too many packets with same key");
971248619Sdes	active_state->p_send.blocks += len / block_size;
972248619Sdes	active_state->p_send.bytes += len;
973197679Sdes	buffer_clear(&active_state->outgoing_packet);
97460573Skris
97576259Sgreen	if (type == SSH2_MSG_NEWKEYS)
97676259Sgreen		set_newkeys(MODE_OUT);
977197679Sdes	else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
978149749Sdes		packet_enable_delayed_compress();
97960573Skris}
98060573Skris
981124208Sdesstatic void
982124208Sdespacket_send2(void)
983124208Sdes{
984124208Sdes	struct packet *p;
985124208Sdes	u_char type, *cp;
986124208Sdes
987197679Sdes	cp = buffer_ptr(&active_state->outgoing_packet);
988124208Sdes	type = cp[5];
989124208Sdes
990124208Sdes	/* during rekeying we can only send key exchange messages */
991197679Sdes	if (active_state->rekeying) {
992240075Sdes		if ((type < SSH2_MSG_TRANSPORT_MIN) ||
993240075Sdes		    (type > SSH2_MSG_TRANSPORT_MAX) ||
994240075Sdes		    (type == SSH2_MSG_SERVICE_REQUEST) ||
995240075Sdes		    (type == SSH2_MSG_SERVICE_ACCEPT)) {
996124208Sdes			debug("enqueue packet: %u", type);
997124208Sdes			p = xmalloc(sizeof(*p));
998124208Sdes			p->type = type;
999197679Sdes			memcpy(&p->payload, &active_state->outgoing_packet,
1000197679Sdes			    sizeof(Buffer));
1001197679Sdes			buffer_init(&active_state->outgoing_packet);
1002197679Sdes			TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
1003124208Sdes			return;
1004124208Sdes		}
1005124208Sdes	}
1006124208Sdes
1007124208Sdes	/* rekeying starts with sending KEXINIT */
1008124208Sdes	if (type == SSH2_MSG_KEXINIT)
1009197679Sdes		active_state->rekeying = 1;
1010124208Sdes
1011124208Sdes	packet_send2_wrapped();
1012124208Sdes
1013124208Sdes	/* after a NEWKEYS message we can send the complete queue */
1014124208Sdes	if (type == SSH2_MSG_NEWKEYS) {
1015197679Sdes		active_state->rekeying = 0;
1016197679Sdes		while ((p = TAILQ_FIRST(&active_state->outgoing))) {
1017124208Sdes			type = p->type;
1018124208Sdes			debug("dequeue packet: %u", type);
1019197679Sdes			buffer_free(&active_state->outgoing_packet);
1020197679Sdes			memcpy(&active_state->outgoing_packet, &p->payload,
1021124208Sdes			    sizeof(Buffer));
1022197679Sdes			TAILQ_REMOVE(&active_state->outgoing, p, next);
1023124208Sdes			xfree(p);
1024124208Sdes			packet_send2_wrapped();
1025124208Sdes		}
1026124208Sdes	}
1027124208Sdes}
1028124208Sdes
102960573Skrisvoid
103092555Sdespacket_send(void)
103160573Skris{
103292555Sdes	if (compat20)
103360573Skris		packet_send2();
103460573Skris	else
103560573Skris		packet_send1();
103660573Skris	DBG(debug("packet_send done"));
103760573Skris}
103860573Skris
103960573Skris/*
104057429Smarkm * Waits until a packet has been received, and returns its type.  Note that
104157429Smarkm * no other data is processed until this returns, so this function should not
104257429Smarkm * be used during the interactive session.
104357429Smarkm */
104457429Smarkm
104557429Smarkmint
104692555Sdespacket_read_seqnr(u_int32_t *seqnr_p)
104757429Smarkm{
1048197679Sdes	int type, len, ret, ms_remain, cont;
104976259Sgreen	fd_set *setp;
105057429Smarkm	char buf[8192];
1051181111Sdes	struct timeval timeout, start, *timeoutp = NULL;
1052181111Sdes
105360573Skris	DBG(debug("packet_read()"));
105457429Smarkm
1055197679Sdes	setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1,
1056197679Sdes	    NFDBITS), sizeof(fd_mask));
105776259Sgreen
105857429Smarkm	/* Since we are blocking, ensure that all written packets have been sent. */
105957429Smarkm	packet_write_wait();
106057429Smarkm
106157429Smarkm	/* Stay in the loop until we have received a complete packet. */
106257429Smarkm	for (;;) {
106357429Smarkm		/* Try to read a packet from the buffer. */
106492555Sdes		type = packet_read_poll_seqnr(seqnr_p);
106592555Sdes		if (!compat20 && (
106660573Skris		    type == SSH_SMSG_SUCCESS
106757429Smarkm		    || type == SSH_SMSG_FAILURE
106857429Smarkm		    || type == SSH_CMSG_EOF
106960573Skris		    || type == SSH_CMSG_EXIT_CONFIRMATION))
107092555Sdes			packet_check_eom();
107157429Smarkm		/* If we got a packet, return it. */
107276259Sgreen		if (type != SSH_MSG_NONE) {
107376259Sgreen			xfree(setp);
107457429Smarkm			return type;
107576259Sgreen		}
107657429Smarkm		/*
107757429Smarkm		 * Otherwise, wait for some data to arrive, add it to the
107857429Smarkm		 * buffer, and try again.
107957429Smarkm		 */
1080197679Sdes		memset(setp, 0, howmany(active_state->connection_in + 1,
1081197679Sdes		    NFDBITS) * sizeof(fd_mask));
1082197679Sdes		FD_SET(active_state->connection_in, setp);
108357429Smarkm
1084197679Sdes		if (active_state->packet_timeout_ms > 0) {
1085197679Sdes			ms_remain = active_state->packet_timeout_ms;
1086181111Sdes			timeoutp = &timeout;
1087181111Sdes		}
108857429Smarkm		/* Wait for some data to arrive. */
1089181111Sdes		for (;;) {
1090197679Sdes			if (active_state->packet_timeout_ms != -1) {
1091181111Sdes				ms_to_timeval(&timeout, ms_remain);
1092181111Sdes				gettimeofday(&start, NULL);
1093181111Sdes			}
1094197679Sdes			if ((ret = select(active_state->connection_in + 1, setp,
1095197679Sdes			    NULL, NULL, timeoutp)) >= 0)
1096181111Sdes				break;
1097197679Sdes			if (errno != EAGAIN && errno != EINTR &&
1098181111Sdes			    errno != EWOULDBLOCK)
1099181111Sdes				break;
1100197679Sdes			if (active_state->packet_timeout_ms == -1)
1101181111Sdes				continue;
1102181111Sdes			ms_subtract_diff(&start, &ms_remain);
1103181111Sdes			if (ms_remain <= 0) {
1104181111Sdes				ret = 0;
1105181111Sdes				break;
1106181111Sdes			}
1107181111Sdes		}
1108181111Sdes		if (ret == 0) {
1109181111Sdes			logit("Connection to %.200s timed out while "
1110181111Sdes			    "waiting to read", get_remote_ipaddr());
1111181111Sdes			cleanup_exit(255);
1112181111Sdes		}
111357429Smarkm		/* Read data from the socket. */
1114197679Sdes		do {
1115197679Sdes			cont = 0;
1116197679Sdes			len = roaming_read(active_state->connection_in, buf,
1117197679Sdes			    sizeof(buf), &cont);
1118197679Sdes		} while (len == 0 && cont);
111957429Smarkm		if (len == 0) {
1120124208Sdes			logit("Connection closed by %.200s", get_remote_ipaddr());
1121126274Sdes			cleanup_exit(255);
112257429Smarkm		}
112357429Smarkm		if (len < 0)
112457429Smarkm			fatal("Read from socket failed: %.100s", strerror(errno));
112557429Smarkm		/* Append it to the buffer. */
112657429Smarkm		packet_process_incoming(buf, len);
112757429Smarkm	}
112857429Smarkm	/* NOTREACHED */
112957429Smarkm}
113057429Smarkm
113192555Sdesint
113292555Sdespacket_read(void)
113392555Sdes{
113492555Sdes	return packet_read_seqnr(NULL);
113592555Sdes}
113692555Sdes
113757429Smarkm/*
113857429Smarkm * Waits until a packet has been received, verifies that its type matches
113957429Smarkm * that given, and gives a fatal error and exits if there is a mismatch.
114057429Smarkm */
114157429Smarkm
114257429Smarkmvoid
114392555Sdespacket_read_expect(int expected_type)
114457429Smarkm{
114557429Smarkm	int type;
114657429Smarkm
114792555Sdes	type = packet_read();
114857429Smarkm	if (type != expected_type)
114957429Smarkm		packet_disconnect("Protocol error: expected packet type %d, got %d",
115060573Skris		    expected_type, type);
115157429Smarkm}
115257429Smarkm
115357429Smarkm/* Checks if a full packet is available in the data received so far via
115457429Smarkm * packet_process_incoming.  If so, reads the packet; otherwise returns
115557429Smarkm * SSH_MSG_NONE.  This does not wait for data from the connection.
115657429Smarkm *
115757429Smarkm * SSH_MSG_DISCONNECT is handled specially here.  Also,
115857429Smarkm * SSH_MSG_IGNORE messages are skipped by this function and are never returned
115957429Smarkm * to higher levels.
116057429Smarkm */
116157429Smarkm
116292555Sdesstatic int
116392555Sdespacket_read_poll1(void)
116457429Smarkm{
116576259Sgreen	u_int len, padded_len;
116692555Sdes	u_char *cp, type;
116776259Sgreen	u_int checksum, stored_checksum;
116857429Smarkm
116957429Smarkm	/* Check if input size is less than minimum packet size. */
1170197679Sdes	if (buffer_len(&active_state->input) < 4 + 8)
117157429Smarkm		return SSH_MSG_NONE;
117257429Smarkm	/* Get length of incoming packet. */
1173197679Sdes	cp = buffer_ptr(&active_state->input);
1174162852Sdes	len = get_u32(cp);
117557429Smarkm	if (len < 1 + 2 + 2 || len > 256 * 1024)
1176113908Sdes		packet_disconnect("Bad packet length %u.", len);
117757429Smarkm	padded_len = (len + 8) & ~7;
117857429Smarkm
117957429Smarkm	/* Check if the packet has been entirely received. */
1180197679Sdes	if (buffer_len(&active_state->input) < 4 + padded_len)
118157429Smarkm		return SSH_MSG_NONE;
118257429Smarkm
118357429Smarkm	/* The entire packet is in buffer. */
118457429Smarkm
118557429Smarkm	/* Consume packet length. */
1186197679Sdes	buffer_consume(&active_state->input, 4);
118757429Smarkm
118892555Sdes	/*
118992555Sdes	 * Cryptographic attack detector for ssh
119092555Sdes	 * (C)1998 CORE-SDI, Buenos Aires Argentina
119192555Sdes	 * Ariel Futoransky(futo@core-sdi.com)
119292555Sdes	 */
1193197679Sdes	if (!active_state->receive_context.plaintext) {
1194197679Sdes		switch (detect_attack(buffer_ptr(&active_state->input),
1195197679Sdes		    padded_len)) {
1196162852Sdes		case DEATTACK_DETECTED:
1197162852Sdes			packet_disconnect("crc32 compensation attack: "
1198162852Sdes			    "network attack detected");
1199162852Sdes		case DEATTACK_DOS_DETECTED:
1200162852Sdes			packet_disconnect("deattack denial of "
1201162852Sdes			    "service detected");
1202162852Sdes		}
1203162852Sdes	}
120492555Sdes
120592555Sdes	/* Decrypt data to incoming_packet. */
1206197679Sdes	buffer_clear(&active_state->incoming_packet);
1207197679Sdes	cp = buffer_append_space(&active_state->incoming_packet, padded_len);
1208197679Sdes	cipher_crypt(&active_state->receive_context, cp,
1209248619Sdes	    buffer_ptr(&active_state->input), padded_len, 0, 0);
121092555Sdes
1211197679Sdes	buffer_consume(&active_state->input, padded_len);
121257429Smarkm
121357429Smarkm#ifdef PACKET_DEBUG
121457429Smarkm	fprintf(stderr, "read_poll plain: ");
1215197679Sdes	buffer_dump(&active_state->incoming_packet);
121657429Smarkm#endif
121757429Smarkm
121857429Smarkm	/* Compute packet checksum. */
1219197679Sdes	checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet),
1220197679Sdes	    buffer_len(&active_state->incoming_packet) - 4);
122157429Smarkm
122257429Smarkm	/* Skip padding. */
1223197679Sdes	buffer_consume(&active_state->incoming_packet, 8 - len % 8);
122457429Smarkm
122557429Smarkm	/* Test check bytes. */
1226197679Sdes	if (len != buffer_len(&active_state->incoming_packet))
122792555Sdes		packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
1228197679Sdes		    len, buffer_len(&active_state->incoming_packet));
122957429Smarkm
1230197679Sdes	cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4;
1231162852Sdes	stored_checksum = get_u32(cp);
123257429Smarkm	if (checksum != stored_checksum)
123357429Smarkm		packet_disconnect("Corrupted check bytes on input.");
1234197679Sdes	buffer_consume_end(&active_state->incoming_packet, 4);
123557429Smarkm
1236197679Sdes	if (active_state->packet_compression) {
1237197679Sdes		buffer_clear(&active_state->compression_buffer);
1238197679Sdes		buffer_uncompress(&active_state->incoming_packet,
1239197679Sdes		    &active_state->compression_buffer);
1240197679Sdes		buffer_clear(&active_state->incoming_packet);
1241197679Sdes		buffer_append(&active_state->incoming_packet,
1242197679Sdes		    buffer_ptr(&active_state->compression_buffer),
1243197679Sdes		    buffer_len(&active_state->compression_buffer));
124457429Smarkm	}
1245197679Sdes	active_state->p_read.packets++;
1246197679Sdes	active_state->p_read.bytes += padded_len + 4;
1247197679Sdes	type = buffer_get_char(&active_state->incoming_packet);
1248146998Sdes	if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
1249146998Sdes		packet_disconnect("Invalid ssh1 packet type: %d", type);
125092555Sdes	return type;
125160573Skris}
125257429Smarkm
125392555Sdesstatic int
125492555Sdespacket_read_poll2(u_int32_t *seqnr_p)
125560573Skris{
125676259Sgreen	u_int padlen, need;
1257248619Sdes	u_char *macbuf = NULL, *cp, type;
1258248619Sdes	u_int maclen, authlen = 0, aadlen = 0, block_size;
125960573Skris	Enc *enc   = NULL;
126060573Skris	Mac *mac   = NULL;
126160573Skris	Comp *comp = NULL;
126257429Smarkm
1263197679Sdes	if (active_state->packet_discard)
1264192595Sdes		return SSH_MSG_NONE;
1265192595Sdes
1266197679Sdes	if (active_state->newkeys[MODE_IN] != NULL) {
1267197679Sdes		enc  = &active_state->newkeys[MODE_IN]->enc;
1268197679Sdes		mac  = &active_state->newkeys[MODE_IN]->mac;
1269197679Sdes		comp = &active_state->newkeys[MODE_IN]->comp;
1270248619Sdes		/* disable mac for authenticated encryption */
1271248619Sdes		if ((authlen = cipher_authlen(enc->cipher)) != 0)
1272248619Sdes			mac = NULL;
127357429Smarkm	}
127460573Skris	maclen = mac && mac->enabled ? mac->mac_len : 0;
127592555Sdes	block_size = enc ? enc->block_size : 8;
1276248619Sdes	aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
127760573Skris
1278248619Sdes	if (aadlen && active_state->packlen == 0) {
1279248619Sdes		if (buffer_len(&active_state->input) < 4)
1280248619Sdes			return SSH_MSG_NONE;
1281248619Sdes		cp = buffer_ptr(&active_state->input);
1282248619Sdes		active_state->packlen = get_u32(cp);
1283248619Sdes		if (active_state->packlen < 1 + 4 ||
1284248619Sdes		    active_state->packlen > PACKET_MAX_SIZE) {
1285248619Sdes#ifdef PACKET_DEBUG
1286248619Sdes			buffer_dump(&active_state->input);
1287248619Sdes#endif
1288248619Sdes			logit("Bad packet length %u.", active_state->packlen);
1289248619Sdes			packet_disconnect("Packet corrupt");
1290248619Sdes		}
1291248619Sdes		buffer_clear(&active_state->incoming_packet);
1292248619Sdes	} else if (active_state->packlen == 0) {
129360573Skris		/*
129460573Skris		 * check if input size is less than the cipher block size,
129560573Skris		 * decrypt first block and extract length of incoming packet
129660573Skris		 */
1297197679Sdes		if (buffer_len(&active_state->input) < block_size)
129860573Skris			return SSH_MSG_NONE;
1299197679Sdes		buffer_clear(&active_state->incoming_packet);
1300197679Sdes		cp = buffer_append_space(&active_state->incoming_packet,
130160573Skris		    block_size);
1302197679Sdes		cipher_crypt(&active_state->receive_context, cp,
1303248619Sdes		    buffer_ptr(&active_state->input), block_size, 0, 0);
1304197679Sdes		cp = buffer_ptr(&active_state->incoming_packet);
1305240075Sdes
1306197679Sdes		active_state->packlen = get_u32(cp);
1307197679Sdes		if (active_state->packlen < 1 + 4 ||
1308197679Sdes		    active_state->packlen > PACKET_MAX_SIZE) {
1309124208Sdes#ifdef PACKET_DEBUG
1310197679Sdes			buffer_dump(&active_state->incoming_packet);
1311124208Sdes#endif
1312197679Sdes			logit("Bad packet length %u.", active_state->packlen);
1313197679Sdes			packet_start_discard(enc, mac, active_state->packlen,
1314192595Sdes			    PACKET_MAX_SIZE);
1315192595Sdes			return SSH_MSG_NONE;
131660573Skris		}
1317197679Sdes		buffer_consume(&active_state->input, block_size);
131860573Skris	}
1319248619Sdes	DBG(debug("input: packet len %u", active_state->packlen+4));
1320248619Sdes	if (aadlen) {
1321248619Sdes		/* only the payload is encrypted */
1322248619Sdes		need = active_state->packlen;
1323248619Sdes	} else {
1324248619Sdes		/*
1325248619Sdes		 * the payload size and the payload are encrypted, but we
1326248619Sdes		 * have a partial packet of block_size bytes
1327248619Sdes		 */
1328248619Sdes		need = 4 + active_state->packlen - block_size;
1329248619Sdes	}
1330248619Sdes	DBG(debug("partial packet: block %d, need %d, maclen %d, authlen %d,"
1331248619Sdes	    " aadlen %d", block_size, need, maclen, authlen, aadlen));
1332192595Sdes	if (need % block_size != 0) {
1333192595Sdes		logit("padding error: need %d block %d mod %d",
133460573Skris		    need, block_size, need % block_size);
1335197679Sdes		packet_start_discard(enc, mac, active_state->packlen,
1336192595Sdes		    PACKET_MAX_SIZE - block_size);
1337192595Sdes		return SSH_MSG_NONE;
1338192595Sdes	}
133960573Skris	/*
134060573Skris	 * check if the entire packet has been received and
1341248619Sdes	 * decrypt into incoming_packet:
1342248619Sdes	 * 'aadlen' bytes are unencrypted, but authenticated.
1343248619Sdes	 * 'need' bytes are encrypted, followed by either
1344248619Sdes	 * 'authlen' bytes of authentication tag or
1345248619Sdes	 * 'maclen' bytes of message authentication code.
134660573Skris	 */
1347248619Sdes	if (buffer_len(&active_state->input) < aadlen + need + authlen + maclen)
134860573Skris		return SSH_MSG_NONE;
134960573Skris#ifdef PACKET_DEBUG
135060573Skris	fprintf(stderr, "read_poll enc/full: ");
1351197679Sdes	buffer_dump(&active_state->input);
135260573Skris#endif
1353248619Sdes	/* EtM: compute mac over encrypted input */
1354248619Sdes	if (mac && mac->enabled && mac->etm)
1355248619Sdes		macbuf = mac_compute(mac, active_state->p_read.seqnr,
1356248619Sdes		    buffer_ptr(&active_state->input), aadlen + need);
1357248619Sdes	cp = buffer_append_space(&active_state->incoming_packet, aadlen + need);
1358197679Sdes	cipher_crypt(&active_state->receive_context, cp,
1359248619Sdes	    buffer_ptr(&active_state->input), need, aadlen, authlen);
1360248619Sdes	buffer_consume(&active_state->input, aadlen + need + authlen);
136160573Skris	/*
136260573Skris	 * compute MAC over seqnr and packet,
136360573Skris	 * increment sequence number for incoming packet
136460573Skris	 */
136560573Skris	if (mac && mac->enabled) {
1366248619Sdes		if (!mac->etm)
1367248619Sdes			macbuf = mac_compute(mac, active_state->p_read.seqnr,
1368248619Sdes			    buffer_ptr(&active_state->incoming_packet),
1369248619Sdes			    buffer_len(&active_state->incoming_packet));
1370215116Sdes		if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input),
1371197679Sdes		    mac->mac_len) != 0) {
1372192595Sdes			logit("Corrupted MAC on input.");
1373192595Sdes			if (need > PACKET_MAX_SIZE)
1374192595Sdes				fatal("internal error need %d", need);
1375197679Sdes			packet_start_discard(enc, mac, active_state->packlen,
1376192595Sdes			    PACKET_MAX_SIZE - need);
1377192595Sdes			return SSH_MSG_NONE;
1378192595Sdes		}
1379192595Sdes
1380197679Sdes		DBG(debug("MAC #%d ok", active_state->p_read.seqnr));
1381197679Sdes		buffer_consume(&active_state->input, mac->mac_len);
138260573Skris	}
1383192595Sdes	/* XXX now it's safe to use fatal/packet_disconnect */
138492555Sdes	if (seqnr_p != NULL)
1385197679Sdes		*seqnr_p = active_state->p_read.seqnr;
1386197679Sdes	if (++active_state->p_read.seqnr == 0)
1387124208Sdes		logit("incoming seqnr wraps around");
1388197679Sdes	if (++active_state->p_read.packets == 0)
1389124208Sdes		if (!(datafellows & SSH_BUG_NOREKEY))
1390124208Sdes			fatal("XXX too many packets with same key");
1391197679Sdes	active_state->p_read.blocks += (active_state->packlen + 4) / block_size;
1392197679Sdes	active_state->p_read.bytes += active_state->packlen + 4;
139360573Skris
139460573Skris	/* get padlen */
1395197679Sdes	cp = buffer_ptr(&active_state->incoming_packet);
139692555Sdes	padlen = cp[4];
139760573Skris	DBG(debug("input: padlen %d", padlen));
139860573Skris	if (padlen < 4)
139960573Skris		packet_disconnect("Corrupted padlen %d on input.", padlen);
140060573Skris
140160573Skris	/* skip packet size + padlen, discard padding */
1402197679Sdes	buffer_consume(&active_state->incoming_packet, 4 + 1);
1403197679Sdes	buffer_consume_end(&active_state->incoming_packet, padlen);
140460573Skris
1405197679Sdes	DBG(debug("input: len before de-compress %d",
1406197679Sdes	    buffer_len(&active_state->incoming_packet)));
140760573Skris	if (comp && comp->enabled) {
1408197679Sdes		buffer_clear(&active_state->compression_buffer);
1409197679Sdes		buffer_uncompress(&active_state->incoming_packet,
1410197679Sdes		    &active_state->compression_buffer);
1411197679Sdes		buffer_clear(&active_state->incoming_packet);
1412197679Sdes		buffer_append(&active_state->incoming_packet,
1413197679Sdes		    buffer_ptr(&active_state->compression_buffer),
1414197679Sdes		    buffer_len(&active_state->compression_buffer));
1415106121Sdes		DBG(debug("input: len after de-compress %d",
1416197679Sdes		    buffer_len(&active_state->incoming_packet)));
141760573Skris	}
141860573Skris	/*
141960573Skris	 * get packet type, implies consume.
142060573Skris	 * return length of payload (without type field)
142160573Skris	 */
1422197679Sdes	type = buffer_get_char(&active_state->incoming_packet);
1423146998Sdes	if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
1424146998Sdes		packet_disconnect("Invalid ssh2 packet type: %d", type);
142576259Sgreen	if (type == SSH2_MSG_NEWKEYS)
142676259Sgreen		set_newkeys(MODE_IN);
1427197679Sdes	else if (type == SSH2_MSG_USERAUTH_SUCCESS &&
1428197679Sdes	    !active_state->server_side)
1429149749Sdes		packet_enable_delayed_compress();
143060573Skris#ifdef PACKET_DEBUG
143176259Sgreen	fprintf(stderr, "read/plain[%d]:\r\n", type);
1432197679Sdes	buffer_dump(&active_state->incoming_packet);
143360573Skris#endif
143492555Sdes	/* reset for next packet */
1435197679Sdes	active_state->packlen = 0;
143692555Sdes	return type;
143757429Smarkm}
143857429Smarkm
143960573Skrisint
144092555Sdespacket_read_poll_seqnr(u_int32_t *seqnr_p)
144160573Skris{
144299060Sdes	u_int reason, seqnr;
144392555Sdes	u_char type;
144460573Skris	char *msg;
144592555Sdes
144660573Skris	for (;;) {
144792555Sdes		if (compat20) {
144892555Sdes			type = packet_read_poll2(seqnr_p);
1449181111Sdes			if (type) {
1450197679Sdes				active_state->keep_alive_timeouts = 0;
145160573Skris				DBG(debug("received packet type %d", type));
1452181111Sdes			}
145392555Sdes			switch (type) {
145460573Skris			case SSH2_MSG_IGNORE:
1455181111Sdes				debug3("Received SSH2_MSG_IGNORE");
145660573Skris				break;
145760573Skris			case SSH2_MSG_DEBUG:
145860573Skris				packet_get_char();
145960573Skris				msg = packet_get_string(NULL);
146060573Skris				debug("Remote: %.900s", msg);
146160573Skris				xfree(msg);
146260573Skris				msg = packet_get_string(NULL);
146360573Skris				xfree(msg);
146460573Skris				break;
146560573Skris			case SSH2_MSG_DISCONNECT:
146660573Skris				reason = packet_get_int();
146760573Skris				msg = packet_get_string(NULL);
1468249475Sdes				/* Ignore normal client exit notifications */
1469249475Sdes				do_log2(active_state->server_side &&
1470249475Sdes				    reason == SSH2_DISCONNECT_BY_APPLICATION ?
1471250739Sdes				    SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
1472249475Sdes				    "Received disconnect from %s: %u: %.400s",
147399060Sdes				    get_remote_ipaddr(), reason, msg);
147460573Skris				xfree(msg);
1475126274Sdes				cleanup_exit(255);
147660573Skris				break;
147792555Sdes			case SSH2_MSG_UNIMPLEMENTED:
147892555Sdes				seqnr = packet_get_int();
147999060Sdes				debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
148099060Sdes				    seqnr);
148192555Sdes				break;
148260573Skris			default:
148360573Skris				return type;
148476259Sgreen			}
148560573Skris		} else {
148692555Sdes			type = packet_read_poll1();
148792555Sdes			switch (type) {
148860573Skris			case SSH_MSG_IGNORE:
148960573Skris				break;
149060573Skris			case SSH_MSG_DEBUG:
149160573Skris				msg = packet_get_string(NULL);
149260573Skris				debug("Remote: %.900s", msg);
149360573Skris				xfree(msg);
149460573Skris				break;
149560573Skris			case SSH_MSG_DISCONNECT:
149660573Skris				msg = packet_get_string(NULL);
1497249475Sdes				logit("Received disconnect from %s: %.400s",
149899060Sdes				    get_remote_ipaddr(), msg);
1499126274Sdes				cleanup_exit(255);
150060573Skris				break;
150160573Skris			default:
150292555Sdes				if (type)
150360573Skris					DBG(debug("received packet type %d", type));
150460573Skris				return type;
150576259Sgreen			}
150660573Skris		}
150760573Skris	}
150860573Skris}
150960573Skris
151057429Smarkm/*
151157429Smarkm * Buffers the given amount of input characters.  This is intended to be used
151257429Smarkm * together with packet_read_poll.
151357429Smarkm */
151457429Smarkm
151557429Smarkmvoid
151676259Sgreenpacket_process_incoming(const char *buf, u_int len)
151757429Smarkm{
1518197679Sdes	if (active_state->packet_discard) {
1519197679Sdes		active_state->keep_alive_timeouts = 0; /* ?? */
1520197679Sdes		if (len >= active_state->packet_discard)
1521192595Sdes			packet_stop_discard();
1522197679Sdes		active_state->packet_discard -= len;
1523192595Sdes		return;
1524192595Sdes	}
1525197679Sdes	buffer_append(&active_state->input, buf, len);
152657429Smarkm}
152757429Smarkm
152857429Smarkm/* Returns a character from the packet. */
152957429Smarkm
153076259Sgreenu_int
153192555Sdespacket_get_char(void)
153257429Smarkm{
153357429Smarkm	char ch;
1534106121Sdes
1535197679Sdes	buffer_get(&active_state->incoming_packet, &ch, 1);
153676259Sgreen	return (u_char) ch;
153757429Smarkm}
153857429Smarkm
153957429Smarkm/* Returns an integer from the packet data. */
154057429Smarkm
154176259Sgreenu_int
154292555Sdespacket_get_int(void)
154357429Smarkm{
1544197679Sdes	return buffer_get_int(&active_state->incoming_packet);
154557429Smarkm}
154657429Smarkm
1547197679Sdes/* Returns an 64 bit integer from the packet data. */
1548197679Sdes
1549197679Sdesu_int64_t
1550197679Sdespacket_get_int64(void)
1551197679Sdes{
1552197679Sdes	return buffer_get_int64(&active_state->incoming_packet);
1553197679Sdes}
1554197679Sdes
155557429Smarkm/*
155657429Smarkm * Returns an arbitrary precision integer from the packet data.  The integer
155757429Smarkm * must have been initialized before this call.
155857429Smarkm */
155957429Smarkm
156057429Smarkmvoid
156192555Sdespacket_get_bignum(BIGNUM * value)
156257429Smarkm{
1563197679Sdes	buffer_get_bignum(&active_state->incoming_packet, value);
156457429Smarkm}
156557429Smarkm
156660573Skrisvoid
156792555Sdespacket_get_bignum2(BIGNUM * value)
156860573Skris{
1569197679Sdes	buffer_get_bignum2(&active_state->incoming_packet, value);
157060573Skris}
157160573Skris
1572221420Sdes#ifdef OPENSSL_HAS_ECC
1573221420Sdesvoid
1574221420Sdespacket_get_ecpoint(const EC_GROUP *curve, EC_POINT *point)
1575221420Sdes{
1576221420Sdes	buffer_get_ecpoint(&active_state->incoming_packet, curve, point);
1577221420Sdes}
1578221420Sdes#endif
1579221420Sdes
158092555Sdesvoid *
1581149749Sdespacket_get_raw(u_int *length_ptr)
158260573Skris{
1583197679Sdes	u_int bytes = buffer_len(&active_state->incoming_packet);
1584106121Sdes
158560573Skris	if (length_ptr != NULL)
158660573Skris		*length_ptr = bytes;
1587197679Sdes	return buffer_ptr(&active_state->incoming_packet);
158860573Skris}
158960573Skris
159060573Skrisint
159160573Skrispacket_remaining(void)
159260573Skris{
1593197679Sdes	return buffer_len(&active_state->incoming_packet);
159460573Skris}
159560573Skris
159657429Smarkm/*
159757429Smarkm * Returns a string from the packet data.  The string is allocated using
159857429Smarkm * xmalloc; it is the responsibility of the calling program to free it when
159957429Smarkm * no longer needed.  The length_ptr argument may be NULL, or point to an
160057429Smarkm * integer into which the length of the string is stored.
160157429Smarkm */
160257429Smarkm
160392555Sdesvoid *
160476259Sgreenpacket_get_string(u_int *length_ptr)
160557429Smarkm{
1606197679Sdes	return buffer_get_string(&active_state->incoming_packet, length_ptr);
160757429Smarkm}
160857429Smarkm
1609181111Sdesvoid *
1610181111Sdespacket_get_string_ptr(u_int *length_ptr)
1611181111Sdes{
1612197679Sdes	return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
1613181111Sdes}
1614181111Sdes
1615221420Sdes/* Ensures the returned string has no embedded \0 characters in it. */
1616221420Sdeschar *
1617221420Sdespacket_get_cstring(u_int *length_ptr)
1618221420Sdes{
1619221420Sdes	return buffer_get_cstring(&active_state->incoming_packet, length_ptr);
1620221420Sdes}
1621221420Sdes
162257429Smarkm/*
162357429Smarkm * Sends a diagnostic message from the server to the client.  This message
162457429Smarkm * can be sent at any time (but not while constructing another message). The
162557429Smarkm * message is printed immediately, but only if the client is being executed
162657429Smarkm * in verbose mode.  These messages are primarily intended to ease debugging
162757429Smarkm * authentication problems.   The length of the formatted message must not
162857429Smarkm * exceed 1024 bytes.  This will automatically call packet_write_wait.
162957429Smarkm */
163057429Smarkm
163157429Smarkmvoid
163257429Smarkmpacket_send_debug(const char *fmt,...)
163357429Smarkm{
163457429Smarkm	char buf[1024];
163557429Smarkm	va_list args;
163657429Smarkm
163776259Sgreen	if (compat20 && (datafellows & SSH_BUG_DEBUG))
163876259Sgreen		return;
163976259Sgreen
164057429Smarkm	va_start(args, fmt);
164157429Smarkm	vsnprintf(buf, sizeof(buf), fmt, args);
164257429Smarkm	va_end(args);
164357429Smarkm
164460573Skris	if (compat20) {
164560573Skris		packet_start(SSH2_MSG_DEBUG);
164660573Skris		packet_put_char(0);	/* bool: always display */
164760573Skris		packet_put_cstring(buf);
164860573Skris		packet_put_cstring("");
164960573Skris	} else {
165060573Skris		packet_start(SSH_MSG_DEBUG);
165160573Skris		packet_put_cstring(buf);
165260573Skris	}
165357429Smarkm	packet_send();
165457429Smarkm	packet_write_wait();
165557429Smarkm}
165657429Smarkm
165757429Smarkm/*
165857429Smarkm * Logs the error plus constructs and sends a disconnect packet, closes the
165957429Smarkm * connection, and exits.  This function never returns. The error message
166057429Smarkm * should not contain a newline.  The length of the formatted message must
166157429Smarkm * not exceed 1024 bytes.
166257429Smarkm */
166357429Smarkm
166457429Smarkmvoid
166557429Smarkmpacket_disconnect(const char *fmt,...)
166657429Smarkm{
166757429Smarkm	char buf[1024];
166857429Smarkm	va_list args;
166957429Smarkm	static int disconnecting = 0;
1670106121Sdes
167157429Smarkm	if (disconnecting)	/* Guard against recursive invocations. */
167257429Smarkm		fatal("packet_disconnect called recursively.");
167357429Smarkm	disconnecting = 1;
167457429Smarkm
167557429Smarkm	/*
167657429Smarkm	 * Format the message.  Note that the caller must make sure the
167757429Smarkm	 * message is of limited size.
167857429Smarkm	 */
167957429Smarkm	va_start(args, fmt);
168057429Smarkm	vsnprintf(buf, sizeof(buf), fmt, args);
168157429Smarkm	va_end(args);
168257429Smarkm
1683113908Sdes	/* Display the error locally */
1684124208Sdes	logit("Disconnecting: %.100s", buf);
1685113908Sdes
168657429Smarkm	/* Send the disconnect message to the other side, and wait for it to get sent. */
168760573Skris	if (compat20) {
168860573Skris		packet_start(SSH2_MSG_DISCONNECT);
168960573Skris		packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR);
169060573Skris		packet_put_cstring(buf);
169160573Skris		packet_put_cstring("");
169260573Skris	} else {
169360573Skris		packet_start(SSH_MSG_DISCONNECT);
169492555Sdes		packet_put_cstring(buf);
169560573Skris	}
169657429Smarkm	packet_send();
169757429Smarkm	packet_write_wait();
169857429Smarkm
169957429Smarkm	/* Stop listening for connections. */
170092555Sdes	channel_close_all();
170157429Smarkm
170257429Smarkm	/* Close the connection. */
170357429Smarkm	packet_close();
1704126274Sdes	cleanup_exit(255);
170557429Smarkm}
170657429Smarkm
170757429Smarkm/* Checks if there is any buffered output, and tries to write some of the output. */
170857429Smarkm
170957429Smarkmvoid
171092555Sdespacket_write_poll(void)
171157429Smarkm{
1712197679Sdes	int len = buffer_len(&active_state->output);
1713197679Sdes	int cont;
1714106121Sdes
171557429Smarkm	if (len > 0) {
1716197679Sdes		cont = 0;
1717197679Sdes		len = roaming_write(active_state->connection_out,
1718197679Sdes		    buffer_ptr(&active_state->output), len, &cont);
1719181111Sdes		if (len == -1) {
1720181111Sdes			if (errno == EINTR || errno == EAGAIN ||
1721181111Sdes			    errno == EWOULDBLOCK)
172257429Smarkm				return;
1723181111Sdes			fatal("Write failed: %.100s", strerror(errno));
172457429Smarkm		}
1725197679Sdes		if (len == 0 && !cont)
1726181111Sdes			fatal("Write connection closed");
1727197679Sdes		buffer_consume(&active_state->output, len);
172857429Smarkm	}
172957429Smarkm}
173057429Smarkm
173157429Smarkm/*
173257429Smarkm * Calls packet_write_poll repeatedly until all pending output data has been
173357429Smarkm * written.
173457429Smarkm */
173557429Smarkm
173657429Smarkmvoid
173792555Sdespacket_write_wait(void)
173857429Smarkm{
173976259Sgreen	fd_set *setp;
1740181111Sdes	int ret, ms_remain;
1741181111Sdes	struct timeval start, timeout, *timeoutp = NULL;
174276259Sgreen
1743197679Sdes	setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
1744197679Sdes	    NFDBITS), sizeof(fd_mask));
174557429Smarkm	packet_write_poll();
174657429Smarkm	while (packet_have_data_to_write()) {
1747197679Sdes		memset(setp, 0, howmany(active_state->connection_out + 1,
1748197679Sdes		    NFDBITS) * sizeof(fd_mask));
1749197679Sdes		FD_SET(active_state->connection_out, setp);
1750181111Sdes
1751197679Sdes		if (active_state->packet_timeout_ms > 0) {
1752197679Sdes			ms_remain = active_state->packet_timeout_ms;
1753181111Sdes			timeoutp = &timeout;
1754181111Sdes		}
1755181111Sdes		for (;;) {
1756197679Sdes			if (active_state->packet_timeout_ms != -1) {
1757181111Sdes				ms_to_timeval(&timeout, ms_remain);
1758181111Sdes				gettimeofday(&start, NULL);
1759181111Sdes			}
1760197679Sdes			if ((ret = select(active_state->connection_out + 1,
1761197679Sdes			    NULL, setp, NULL, timeoutp)) >= 0)
1762181111Sdes				break;
1763197679Sdes			if (errno != EAGAIN && errno != EINTR &&
1764181111Sdes			    errno != EWOULDBLOCK)
1765181111Sdes				break;
1766197679Sdes			if (active_state->packet_timeout_ms == -1)
1767181111Sdes				continue;
1768181111Sdes			ms_subtract_diff(&start, &ms_remain);
1769181111Sdes			if (ms_remain <= 0) {
1770181111Sdes				ret = 0;
1771181111Sdes				break;
1772181111Sdes			}
1773181111Sdes		}
1774181111Sdes		if (ret == 0) {
1775181111Sdes			logit("Connection to %.200s timed out while "
1776181111Sdes			    "waiting to write", get_remote_ipaddr());
1777181111Sdes			cleanup_exit(255);
1778181111Sdes		}
177957429Smarkm		packet_write_poll();
178057429Smarkm	}
178176259Sgreen	xfree(setp);
178257429Smarkm}
178357429Smarkm
178457429Smarkm/* Returns true if there is buffered data to write to the connection. */
178557429Smarkm
178657429Smarkmint
178792555Sdespacket_have_data_to_write(void)
178857429Smarkm{
1789197679Sdes	return buffer_len(&active_state->output) != 0;
179057429Smarkm}
179157429Smarkm
179257429Smarkm/* Returns true if there is not too much data to write to the connection. */
179357429Smarkm
179457429Smarkmint
179592555Sdespacket_not_very_much_data_to_write(void)
179657429Smarkm{
1797197679Sdes	if (active_state->interactive_mode)
1798197679Sdes		return buffer_len(&active_state->output) < 16384;
179957429Smarkm	else
1800197679Sdes		return buffer_len(&active_state->output) < 128 * 1024;
180157429Smarkm}
180257429Smarkm
1803113908Sdesstatic void
1804221420Sdespacket_set_tos(int tos)
1805113908Sdes{
1806226046Sdes#ifndef IP_TOS_IS_BROKEN
1807226046Sdes	if (!packet_connection_is_on_socket())
1808113908Sdes		return;
1809226046Sdes	switch (packet_connection_af()) {
1810226046Sdes# ifdef IP_TOS
1811226046Sdes	case AF_INET:
1812226046Sdes		debug3("%s: set IP_TOS 0x%02x", __func__, tos);
1813226046Sdes		if (setsockopt(active_state->connection_in,
1814226046Sdes		    IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
1815226046Sdes			error("setsockopt IP_TOS %d: %.100s:",
1816226046Sdes			    tos, strerror(errno));
1817226046Sdes		break;
1818226046Sdes# endif /* IP_TOS */
1819226046Sdes# ifdef IPV6_TCLASS
1820226046Sdes	case AF_INET6:
1821226046Sdes		debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos);
1822226046Sdes		if (setsockopt(active_state->connection_in,
1823226046Sdes		    IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0)
1824226046Sdes			error("setsockopt IPV6_TCLASS %d: %.100s:",
1825226046Sdes			    tos, strerror(errno));
1826226046Sdes		break;
1827226046Sdes# endif /* IPV6_TCLASS */
1828226046Sdes	}
1829226046Sdes#endif /* IP_TOS_IS_BROKEN */
1830113908Sdes}
1831113908Sdes
183257429Smarkm/* Informs that the current session is interactive.  Sets IP flags for that. */
183357429Smarkm
183457429Smarkmvoid
1835221420Sdespacket_set_interactive(int interactive, int qos_interactive, int qos_bulk)
183657429Smarkm{
1837197679Sdes	if (active_state->set_interactive_called)
183876259Sgreen		return;
1839197679Sdes	active_state->set_interactive_called = 1;
184076259Sgreen
184157429Smarkm	/* Record that we are in interactive mode. */
1842197679Sdes	active_state->interactive_mode = interactive;
184357429Smarkm
184457429Smarkm	/* Only set socket options if using a socket.  */
184557429Smarkm	if (!packet_connection_is_on_socket())
1846116791Sdes		return;
1847197679Sdes	set_nodelay(active_state->connection_in);
1848221420Sdes	packet_set_tos(interactive ? qos_interactive : qos_bulk);
184957429Smarkm}
185057429Smarkm
185157429Smarkm/* Returns true if the current connection is interactive. */
185257429Smarkm
185357429Smarkmint
185492555Sdespacket_is_interactive(void)
185557429Smarkm{
1856197679Sdes	return active_state->interactive_mode;
185757429Smarkm}
185857429Smarkm
1859137015Sdesint
1860124208Sdespacket_set_maxsize(u_int s)
186157429Smarkm{
1862197679Sdes	if (active_state->set_maxsize_called) {
1863124208Sdes		logit("packet_set_maxsize: called twice: old %d new %d",
1864197679Sdes		    active_state->max_packet_size, s);
186557429Smarkm		return -1;
186657429Smarkm	}
186757429Smarkm	if (s < 4 * 1024 || s > 1024 * 1024) {
1868124208Sdes		logit("packet_set_maxsize: bad size %d", s);
186957429Smarkm		return -1;
187057429Smarkm	}
1871197679Sdes	active_state->set_maxsize_called = 1;
187292555Sdes	debug("packet_set_maxsize: setting to %d", s);
1873197679Sdes	active_state->max_packet_size = s;
187457429Smarkm	return s;
187557429Smarkm}
187676259Sgreen
1877197679Sdesint
1878197679Sdespacket_inc_alive_timeouts(void)
1879197679Sdes{
1880197679Sdes	return ++active_state->keep_alive_timeouts;
1881197679Sdes}
1882197679Sdes
1883197679Sdesvoid
1884197679Sdespacket_set_alive_timeouts(int ka)
1885197679Sdes{
1886197679Sdes	active_state->keep_alive_timeouts = ka;
1887197679Sdes}
1888197679Sdes
1889197679Sdesu_int
1890197679Sdespacket_get_maxsize(void)
1891197679Sdes{
1892197679Sdes	return active_state->max_packet_size;
1893197679Sdes}
1894197679Sdes
189592555Sdes/* roundup current message to pad bytes */
189692555Sdesvoid
189792555Sdespacket_add_padding(u_char pad)
189892555Sdes{
1899197679Sdes	active_state->extra_pad = pad;
190092555Sdes}
190192555Sdes
190276259Sgreen/*
190376259Sgreen * 9.2.  Ignored Data Message
190476259Sgreen *
190576259Sgreen *   byte      SSH_MSG_IGNORE
190676259Sgreen *   string    data
190776259Sgreen *
190876259Sgreen * All implementations MUST understand (and ignore) this message at any
190976259Sgreen * time (after receiving the protocol version). No implementation is
191076259Sgreen * required to send them. This message can be used as an additional
191176259Sgreen * protection measure against advanced traffic analysis techniques.
191276259Sgreen */
191376259Sgreenvoid
191476259Sgreenpacket_send_ignore(int nbytes)
191576259Sgreen{
1916137015Sdes	u_int32_t rnd = 0;
191776259Sgreen	int i;
191876259Sgreen
191976259Sgreen	packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE);
192076259Sgreen	packet_put_int(nbytes);
192192555Sdes	for (i = 0; i < nbytes; i++) {
192276259Sgreen		if (i % 4 == 0)
1923137015Sdes			rnd = arc4random();
1924162852Sdes		packet_put_char((u_char)rnd & 0xff);
1925137015Sdes		rnd >>= 8;
192676259Sgreen	}
192776259Sgreen}
1928124208Sdes
1929224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
1930224638Sbrooksvoid
1931224638Sbrookspacket_request_rekeying(void)
1932224638Sbrooks{
1933224638Sbrooks	rekey_requested = 1;
1934224638Sbrooks}
1935224638Sbrooks#endif
1936224638Sbrooks
1937137015Sdes#define MAX_PACKETS	(1U<<31)
1938124208Sdesint
1939124208Sdespacket_need_rekeying(void)
1940124208Sdes{
1941124208Sdes	if (datafellows & SSH_BUG_NOREKEY)
1942124208Sdes		return 0;
1943224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
1944224638Sbrooks	if (rekey_requested == 1) {
1945224638Sbrooks		rekey_requested = 0;
1946224638Sbrooks		return 1;
1947224638Sbrooks	}
1948224638Sbrooks#endif
1949124208Sdes	return
1950197679Sdes	    (active_state->p_send.packets > MAX_PACKETS) ||
1951197679Sdes	    (active_state->p_read.packets > MAX_PACKETS) ||
1952197679Sdes	    (active_state->max_blocks_out &&
1953197679Sdes	        (active_state->p_send.blocks > active_state->max_blocks_out)) ||
1954197679Sdes	    (active_state->max_blocks_in &&
1955197679Sdes	        (active_state->p_read.blocks > active_state->max_blocks_in));
1956124208Sdes}
1957124208Sdes
1958124208Sdesvoid
1959124208Sdespacket_set_rekey_limit(u_int32_t bytes)
1960124208Sdes{
1961197679Sdes	active_state->rekey_limit = bytes;
1962124208Sdes}
1963149749Sdes
1964149749Sdesvoid
1965149749Sdespacket_set_server(void)
1966149749Sdes{
1967197679Sdes	active_state->server_side = 1;
1968149749Sdes}
1969149749Sdes
1970149749Sdesvoid
1971149749Sdespacket_set_authenticated(void)
1972149749Sdes{
1973197679Sdes	active_state->after_authentication = 1;
1974149749Sdes}
1975197679Sdes
1976197679Sdesvoid *
1977197679Sdespacket_get_input(void)
1978197679Sdes{
1979197679Sdes	return (void *)&active_state->input;
1980197679Sdes}
1981197679Sdes
1982197679Sdesvoid *
1983197679Sdespacket_get_output(void)
1984197679Sdes{
1985197679Sdes	return (void *)&active_state->output;
1986197679Sdes}
1987197679Sdes
1988197679Sdesvoid *
1989197679Sdespacket_get_newkeys(int mode)
1990197679Sdes{
1991197679Sdes	return (void *)active_state->newkeys[mode];
1992197679Sdes}
1993197679Sdes
1994197679Sdes/*
1995197679Sdes * Save the state for the real connection, and use a separate state when
1996197679Sdes * resuming a suspended connection.
1997197679Sdes */
1998197679Sdesvoid
1999197679Sdespacket_backup_state(void)
2000197679Sdes{
2001197679Sdes	struct session_state *tmp;
2002197679Sdes
2003197679Sdes	close(active_state->connection_in);
2004197679Sdes	active_state->connection_in = -1;
2005197679Sdes	close(active_state->connection_out);
2006197679Sdes	active_state->connection_out = -1;
2007197679Sdes	if (backup_state)
2008197679Sdes		tmp = backup_state;
2009197679Sdes	else
2010197679Sdes		tmp = alloc_session_state();
2011197679Sdes	backup_state = active_state;
2012197679Sdes	active_state = tmp;
2013197679Sdes}
2014197679Sdes
2015197679Sdes/*
2016197679Sdes * Swap in the old state when resuming a connecion.
2017197679Sdes */
2018197679Sdesvoid
2019197679Sdespacket_restore_state(void)
2020197679Sdes{
2021197679Sdes	struct session_state *tmp;
2022197679Sdes	void *buf;
2023197679Sdes	u_int len;
2024197679Sdes
2025197679Sdes	tmp = backup_state;
2026197679Sdes	backup_state = active_state;
2027197679Sdes	active_state = tmp;
2028197679Sdes	active_state->connection_in = backup_state->connection_in;
2029197679Sdes	backup_state->connection_in = -1;
2030197679Sdes	active_state->connection_out = backup_state->connection_out;
2031197679Sdes	backup_state->connection_out = -1;
2032197679Sdes	len = buffer_len(&backup_state->input);
2033197679Sdes	if (len > 0) {
2034197679Sdes		buf = buffer_ptr(&backup_state->input);
2035197679Sdes		buffer_append(&active_state->input, buf, len);
2036197679Sdes		buffer_clear(&backup_state->input);
2037197679Sdes		add_recv_bytes(len);
2038197679Sdes	}
2039197679Sdes}
2040224638Sbrooks
2041224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
2042224638Sbrooksint
2043224638Sbrookspacket_get_authentication_state(void)
2044224638Sbrooks{
2045224638Sbrooks	return (active_state->after_authentication);
2046224638Sbrooks}
2047224638Sbrooks#endif
2048