1263970Sdes/* $OpenBSD: packet.c,v 1.192 2014/02/02 03:44:31 djm Exp $ */
2263970Sdes/* $FreeBSD$ */
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"
42263970Sdes__RCSID("$FreeBSD$");
43162852Sdes
44162852Sdes#include <sys/types.h>
45124208Sdes#include "openbsd-compat/sys-queue.h"
46162852Sdes#include <sys/param.h>
47162852Sdes#include <sys/socket.h>
48162852Sdes#ifdef HAVE_SYS_TIME_H
49162852Sdes# include <sys/time.h>
50162852Sdes#endif
51124208Sdes
52162852Sdes#include <netinet/in.h>
53162852Sdes#include <netinet/ip.h>
54162852Sdes#include <arpa/inet.h>
55162852Sdes
56162852Sdes#include <errno.h>
57162852Sdes#include <stdarg.h>
58162852Sdes#include <stdio.h>
59162852Sdes#include <stdlib.h>
60162852Sdes#include <string.h>
61162852Sdes#include <unistd.h>
62162852Sdes#include <signal.h>
63263970Sdes#include <time.h>
64162852Sdes
6557429Smarkm#include "xmalloc.h"
6657429Smarkm#include "buffer.h"
6757429Smarkm#include "packet.h"
6857429Smarkm#include "crc32.h"
6957429Smarkm#include "compress.h"
7057429Smarkm#include "deattack.h"
7160573Skris#include "channels.h"
7260573Skris#include "compat.h"
7376259Sgreen#include "ssh1.h"
7460573Skris#include "ssh2.h"
7569587Sgreen#include "cipher.h"
76162852Sdes#include "key.h"
7760573Skris#include "kex.h"
7876259Sgreen#include "mac.h"
7976259Sgreen#include "log.h"
8076259Sgreen#include "canohost.h"
8192555Sdes#include "misc.h"
8298675Sdes#include "ssh.h"
83197679Sdes#include "roaming.h"
8460573Skris
8560573Skris#ifdef PACKET_DEBUG
8660573Skris#define DBG(x) x
8760573Skris#else
8860573Skris#define DBG(x)
8960573Skris#endif
9060573Skris
91192595Sdes#define PACKET_MAX_SIZE (256 * 1024)
92192595Sdes
93197679Sdesstruct packet_state {
94197679Sdes	u_int32_t seqnr;
95197679Sdes	u_int32_t packets;
96197679Sdes	u_int64_t blocks;
97197679Sdes	u_int64_t bytes;
98197679Sdes};
9957429Smarkm
100197679Sdesstruct packet {
101197679Sdes	TAILQ_ENTRY(packet) next;
102197679Sdes	u_char type;
103197679Sdes	Buffer payload;
104197679Sdes};
10557429Smarkm
106197679Sdesstruct session_state {
107197679Sdes	/*
108197679Sdes	 * This variable contains the file descriptors used for
109197679Sdes	 * communicating with the other side.  connection_in is used for
110197679Sdes	 * reading; connection_out for writing.  These can be the same
111197679Sdes	 * descriptor, in which case it is assumed to be a socket.
112197679Sdes	 */
113197679Sdes	int connection_in;
114197679Sdes	int connection_out;
11557429Smarkm
116197679Sdes	/* Protocol flags for the remote side. */
117197679Sdes	u_int remote_protocol_flags;
11857429Smarkm
119197679Sdes	/* Encryption context for receiving data.  Only used for decryption. */
120197679Sdes	CipherContext receive_context;
12157429Smarkm
122197679Sdes	/* Encryption context for sending data.  Only used for encryption. */
123197679Sdes	CipherContext send_context;
12457429Smarkm
125197679Sdes	/* Buffer for raw input data from the socket. */
126197679Sdes	Buffer input;
12757429Smarkm
128197679Sdes	/* Buffer for raw output data going to the socket. */
129197679Sdes	Buffer output;
13057429Smarkm
131197679Sdes	/* Buffer for the partial outgoing packet being constructed. */
132197679Sdes	Buffer outgoing_packet;
13357429Smarkm
134197679Sdes	/* Buffer for the incoming packet currently being processed. */
135197679Sdes	Buffer incoming_packet;
13657429Smarkm
137197679Sdes	/* Scratch buffer for packet compression/decompression. */
138197679Sdes	Buffer compression_buffer;
139197679Sdes	int compression_buffer_ready;
14057429Smarkm
141197679Sdes	/*
142197679Sdes	 * Flag indicating whether packet compression/decompression is
143197679Sdes	 * enabled.
144197679Sdes	 */
145197679Sdes	int packet_compression;
14657429Smarkm
147197679Sdes	/* default maximum packet size */
148197679Sdes	u_int max_packet_size;
14957429Smarkm
150197679Sdes	/* Flag indicating whether this module has been initialized. */
151197679Sdes	int initialized;
152149749Sdes
153197679Sdes	/* Set to true if the connection is interactive. */
154197679Sdes	int interactive_mode;
155149749Sdes
156197679Sdes	/* Set to true if we are the server side. */
157197679Sdes	int server_side;
158181111Sdes
159197679Sdes	/* Set to true if we are authenticated. */
160197679Sdes	int after_authentication;
161181111Sdes
162197679Sdes	int keep_alive_timeouts;
16360573Skris
164197679Sdes	/* The maximum time that we will wait to send or receive a packet */
165197679Sdes	int packet_timeout_ms;
166124208Sdes
167197679Sdes	/* Session key information for Encryption and MAC */
168197679Sdes	Newkeys *newkeys[MODE_MAX];
169197679Sdes	struct packet_state p_read, p_send;
17098675Sdes
171263970Sdes	/* Volume-based rekeying */
172197679Sdes	u_int64_t max_blocks_in, max_blocks_out;
173197679Sdes	u_int32_t rekey_limit;
17460573Skris
175263970Sdes	/* Time-based rekeying */
176263970Sdes	time_t rekey_interval;	/* how often in seconds */
177263970Sdes	time_t rekey_time;	/* time of last rekeying */
178263970Sdes
179197679Sdes	/* Session key for protocol v1 */
180197679Sdes	u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
181197679Sdes	u_int ssh1_keylen;
182192595Sdes
183197679Sdes	/* roundup current message to extra_pad bytes */
184197679Sdes	u_char extra_pad;
185197679Sdes
186197679Sdes	/* XXX discard incoming data after MAC error */
187197679Sdes	u_int packet_discard;
188197679Sdes	Mac *packet_discard_mac;
189197679Sdes
190197679Sdes	/* Used in packet_read_poll2() */
191197679Sdes	u_int packlen;
192197679Sdes
193197679Sdes	/* Used in packet_send2 */
194197679Sdes	int rekeying;
195197679Sdes
196197679Sdes	/* Used in packet_set_interactive */
197197679Sdes	int set_interactive_called;
198197679Sdes
199197679Sdes	/* Used in packet_set_maxsize */
200197679Sdes	int set_maxsize_called;
201197679Sdes
202197679Sdes	TAILQ_HEAD(, packet) outgoing;
203124208Sdes};
204124208Sdes
205197679Sdesstatic struct session_state *active_state, *backup_state;
206224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
207224638Sbrooksstatic int rekey_requested = 0;
208224638Sbrooks#endif
209197679Sdes
210197679Sdesstatic struct session_state *
211197679Sdesalloc_session_state(void)
212197679Sdes{
213221420Sdes	struct session_state *s = xcalloc(1, sizeof(*s));
214197679Sdes
215221420Sdes	s->connection_in = -1;
216221420Sdes	s->connection_out = -1;
217221420Sdes	s->max_packet_size = 32768;
218221420Sdes	s->packet_timeout_ms = -1;
219221420Sdes	return s;
220197679Sdes}
221197679Sdes
22257429Smarkm/*
22357429Smarkm * Sets the descriptors used for communication.  Disables encryption until
22457429Smarkm * packet_set_encryption_key is called.
22557429Smarkm */
22657429Smarkmvoid
22757429Smarkmpacket_set_connection(int fd_in, int fd_out)
22857429Smarkm{
229263970Sdes	const Cipher *none = cipher_by_name("none");
230106121Sdes
23169587Sgreen	if (none == NULL)
23269587Sgreen		fatal("packet_set_connection: cannot load cipher 'none'");
233197679Sdes	if (active_state == NULL)
234197679Sdes		active_state = alloc_session_state();
235197679Sdes	active_state->connection_in = fd_in;
236197679Sdes	active_state->connection_out = fd_out;
237197679Sdes	cipher_init(&active_state->send_context, none, (const u_char *)"",
238137015Sdes	    0, NULL, 0, CIPHER_ENCRYPT);
239197679Sdes	cipher_init(&active_state->receive_context, none, (const u_char *)"",
240137015Sdes	    0, NULL, 0, CIPHER_DECRYPT);
241197679Sdes	active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL;
242197679Sdes	if (!active_state->initialized) {
243197679Sdes		active_state->initialized = 1;
244197679Sdes		buffer_init(&active_state->input);
245197679Sdes		buffer_init(&active_state->output);
246197679Sdes		buffer_init(&active_state->outgoing_packet);
247197679Sdes		buffer_init(&active_state->incoming_packet);
248197679Sdes		TAILQ_INIT(&active_state->outgoing);
249197679Sdes		active_state->p_send.packets = active_state->p_read.packets = 0;
25057429Smarkm	}
25157429Smarkm}
25257429Smarkm
253181111Sdesvoid
254181111Sdespacket_set_timeout(int timeout, int count)
255181111Sdes{
256247485Sdes	if (timeout <= 0 || count <= 0) {
257197679Sdes		active_state->packet_timeout_ms = -1;
258181111Sdes		return;
259181111Sdes	}
260181111Sdes	if ((INT_MAX / 1000) / count < timeout)
261197679Sdes		active_state->packet_timeout_ms = INT_MAX;
262181111Sdes	else
263197679Sdes		active_state->packet_timeout_ms = timeout * count * 1000;
264181111Sdes}
265181111Sdes
266192595Sdesstatic void
267192595Sdespacket_stop_discard(void)
268192595Sdes{
269197679Sdes	if (active_state->packet_discard_mac) {
270192595Sdes		char buf[1024];
271192595Sdes
272192595Sdes		memset(buf, 'a', sizeof(buf));
273197679Sdes		while (buffer_len(&active_state->incoming_packet) <
274197679Sdes		    PACKET_MAX_SIZE)
275197679Sdes			buffer_append(&active_state->incoming_packet, buf,
276197679Sdes			    sizeof(buf));
277197679Sdes		(void) mac_compute(active_state->packet_discard_mac,
278197679Sdes		    active_state->p_read.seqnr,
279197679Sdes		    buffer_ptr(&active_state->incoming_packet),
280192595Sdes		    PACKET_MAX_SIZE);
281192595Sdes	}
282192595Sdes	logit("Finished discarding for %.200s", get_remote_ipaddr());
283192595Sdes	cleanup_exit(255);
284192595Sdes}
285192595Sdes
286192595Sdesstatic void
287192595Sdespacket_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
288192595Sdes{
289251135Sdes	if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm))
290192595Sdes		packet_disconnect("Packet corrupt");
291192595Sdes	if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
292197679Sdes		active_state->packet_discard_mac = mac;
293197679Sdes	if (buffer_len(&active_state->input) >= discard)
294192595Sdes		packet_stop_discard();
295197679Sdes	active_state->packet_discard = discard -
296197679Sdes	    buffer_len(&active_state->input);
297192595Sdes}
298192595Sdes
29957429Smarkm/* Returns 1 if remote host is connected via socket, 0 if not. */
30057429Smarkm
30157429Smarkmint
30292555Sdespacket_connection_is_on_socket(void)
30357429Smarkm{
30457429Smarkm	struct sockaddr_storage from, to;
30557429Smarkm	socklen_t fromlen, tolen;
30657429Smarkm
30757429Smarkm	/* filedescriptors in and out are the same, so it's a socket */
308197679Sdes	if (active_state->connection_in == active_state->connection_out)
30957429Smarkm		return 1;
31057429Smarkm	fromlen = sizeof(from);
31157429Smarkm	memset(&from, 0, sizeof(from));
312197679Sdes	if (getpeername(active_state->connection_in, (struct sockaddr *)&from,
313197679Sdes	    &fromlen) < 0)
31457429Smarkm		return 0;
31557429Smarkm	tolen = sizeof(to);
31657429Smarkm	memset(&to, 0, sizeof(to));
317197679Sdes	if (getpeername(active_state->connection_out, (struct sockaddr *)&to,
318197679Sdes	    &tolen) < 0)
31957429Smarkm		return 0;
32057429Smarkm	if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
32157429Smarkm		return 0;
32257429Smarkm	if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
32357429Smarkm		return 0;
32457429Smarkm	return 1;
32557429Smarkm}
32657429Smarkm
32798675Sdes/*
32898675Sdes * Exports an IV from the CipherContext required to export the key
32998675Sdes * state back from the unprivileged child to the privileged parent
33098675Sdes * process.
33198675Sdes */
33298675Sdes
33398675Sdesvoid
33498675Sdespacket_get_keyiv(int mode, u_char *iv, u_int len)
33598675Sdes{
33698675Sdes	CipherContext *cc;
33798675Sdes
33898675Sdes	if (mode == MODE_OUT)
339197679Sdes		cc = &active_state->send_context;
34098675Sdes	else
341197679Sdes		cc = &active_state->receive_context;
34298675Sdes
34398675Sdes	cipher_get_keyiv(cc, iv, len);
34498675Sdes}
34598675Sdes
34698675Sdesint
34798675Sdespacket_get_keycontext(int mode, u_char *dat)
34898675Sdes{
34998675Sdes	CipherContext *cc;
35098675Sdes
35198675Sdes	if (mode == MODE_OUT)
352197679Sdes		cc = &active_state->send_context;
35398675Sdes	else
354197679Sdes		cc = &active_state->receive_context;
35598675Sdes
35698675Sdes	return (cipher_get_keycontext(cc, dat));
35798675Sdes}
35898675Sdes
35998675Sdesvoid
36098675Sdespacket_set_keycontext(int mode, u_char *dat)
36198675Sdes{
36298675Sdes	CipherContext *cc;
36398675Sdes
36498675Sdes	if (mode == MODE_OUT)
365197679Sdes		cc = &active_state->send_context;
36698675Sdes	else
367197679Sdes		cc = &active_state->receive_context;
36898675Sdes
36998675Sdes	cipher_set_keycontext(cc, dat);
37098675Sdes}
37198675Sdes
37298675Sdesint
37398675Sdespacket_get_keyiv_len(int mode)
37498675Sdes{
37598675Sdes	CipherContext *cc;
37698675Sdes
37798675Sdes	if (mode == MODE_OUT)
378197679Sdes		cc = &active_state->send_context;
37998675Sdes	else
380197679Sdes		cc = &active_state->receive_context;
38198675Sdes
38298675Sdes	return (cipher_get_keyiv_len(cc));
38398675Sdes}
384162852Sdes
38598675Sdesvoid
38698675Sdespacket_set_iv(int mode, u_char *dat)
38798675Sdes{
38898675Sdes	CipherContext *cc;
38998675Sdes
39098675Sdes	if (mode == MODE_OUT)
391197679Sdes		cc = &active_state->send_context;
39298675Sdes	else
393197679Sdes		cc = &active_state->receive_context;
39498675Sdes
39598675Sdes	cipher_set_keyiv(cc, dat);
39698675Sdes}
397162852Sdes
39898675Sdesint
399124208Sdespacket_get_ssh1_cipher(void)
40098675Sdes{
401197679Sdes	return (cipher_get_number(active_state->receive_context.cipher));
40298675Sdes}
40398675Sdes
404124208Sdesvoid
405221420Sdespacket_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks,
406221420Sdes    u_int32_t *packets, u_int64_t *bytes)
407124208Sdes{
408124208Sdes	struct packet_state *state;
40998675Sdes
410197679Sdes	state = (mode == MODE_IN) ?
411197679Sdes	    &active_state->p_read : &active_state->p_send;
412181111Sdes	if (seqnr)
413181111Sdes		*seqnr = state->seqnr;
414181111Sdes	if (blocks)
415181111Sdes		*blocks = state->blocks;
416181111Sdes	if (packets)
417181111Sdes		*packets = state->packets;
418181111Sdes	if (bytes)
419181111Sdes		*bytes = state->bytes;
42098675Sdes}
42198675Sdes
42298675Sdesvoid
423181111Sdespacket_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets,
424181111Sdes    u_int64_t bytes)
42598675Sdes{
426124208Sdes	struct packet_state *state;
427124208Sdes
428197679Sdes	state = (mode == MODE_IN) ?
429197679Sdes	    &active_state->p_read : &active_state->p_send;
430124208Sdes	state->seqnr = seqnr;
431124208Sdes	state->blocks = blocks;
432124208Sdes	state->packets = packets;
433181111Sdes	state->bytes = bytes;
43498675Sdes}
43598675Sdes
436247485Sdesstatic int
437247485Sdespacket_connection_af(void)
43857429Smarkm{
43957429Smarkm	struct sockaddr_storage to;
44057429Smarkm	socklen_t tolen = sizeof(to);
44157429Smarkm
44257429Smarkm	memset(&to, 0, sizeof(to));
443197679Sdes	if (getsockname(active_state->connection_out, (struct sockaddr *)&to,
444197679Sdes	    &tolen) < 0)
44557429Smarkm		return 0;
44698937Sdes#ifdef IPV4_IN_IPV6
447126274Sdes	if (to.ss_family == AF_INET6 &&
44898937Sdes	    IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))
449247485Sdes		return AF_INET;
45098937Sdes#endif
451247485Sdes	return to.ss_family;
45257429Smarkm}
45357429Smarkm
45457429Smarkm/* Sets the connection into non-blocking mode. */
45557429Smarkm
45657429Smarkmvoid
45792555Sdespacket_set_nonblocking(void)
45857429Smarkm{
45957429Smarkm	/* Set the socket into non-blocking mode. */
460197679Sdes	set_nonblock(active_state->connection_in);
46157429Smarkm
462197679Sdes	if (active_state->connection_out != active_state->connection_in)
463197679Sdes		set_nonblock(active_state->connection_out);
46457429Smarkm}
46557429Smarkm
46657429Smarkm/* Returns the socket used for reading. */
46757429Smarkm
46857429Smarkmint
46992555Sdespacket_get_connection_in(void)
47057429Smarkm{
471197679Sdes	return active_state->connection_in;
47257429Smarkm}
47357429Smarkm
47457429Smarkm/* Returns the descriptor used for writing. */
47557429Smarkm
47657429Smarkmint
47792555Sdespacket_get_connection_out(void)
47857429Smarkm{
479197679Sdes	return active_state->connection_out;
48057429Smarkm}
48157429Smarkm
48257429Smarkm/* Closes the connection and clears and frees internal data structures. */
48357429Smarkm
48457429Smarkmvoid
48592555Sdespacket_close(void)
48657429Smarkm{
487197679Sdes	if (!active_state->initialized)
48857429Smarkm		return;
489197679Sdes	active_state->initialized = 0;
490197679Sdes	if (active_state->connection_in == active_state->connection_out) {
491197679Sdes		shutdown(active_state->connection_out, SHUT_RDWR);
492197679Sdes		close(active_state->connection_out);
49357429Smarkm	} else {
494197679Sdes		close(active_state->connection_in);
495197679Sdes		close(active_state->connection_out);
49657429Smarkm	}
497197679Sdes	buffer_free(&active_state->input);
498197679Sdes	buffer_free(&active_state->output);
499197679Sdes	buffer_free(&active_state->outgoing_packet);
500197679Sdes	buffer_free(&active_state->incoming_packet);
501197679Sdes	if (active_state->compression_buffer_ready) {
502197679Sdes		buffer_free(&active_state->compression_buffer);
50357429Smarkm		buffer_compress_uninit();
50457429Smarkm	}
505197679Sdes	cipher_cleanup(&active_state->send_context);
506197679Sdes	cipher_cleanup(&active_state->receive_context);
50757429Smarkm}
50857429Smarkm
50957429Smarkm/* Sets remote side protocol flags. */
51057429Smarkm
51157429Smarkmvoid
51276259Sgreenpacket_set_protocol_flags(u_int protocol_flags)
51357429Smarkm{
514197679Sdes	active_state->remote_protocol_flags = protocol_flags;
51557429Smarkm}
51657429Smarkm
51757429Smarkm/* Returns the remote protocol flags set earlier by the above function. */
51857429Smarkm
51976259Sgreenu_int
52092555Sdespacket_get_protocol_flags(void)
52157429Smarkm{
522197679Sdes	return active_state->remote_protocol_flags;
52357429Smarkm}
52457429Smarkm
52557429Smarkm/*
52657429Smarkm * Starts packet compression from the next packet on in both directions.
52757429Smarkm * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip.
52857429Smarkm */
52957429Smarkm
53092555Sdesstatic void
53192555Sdespacket_init_compression(void)
53276259Sgreen{
533197679Sdes	if (active_state->compression_buffer_ready == 1)
53476259Sgreen		return;
535197679Sdes	active_state->compression_buffer_ready = 1;
536197679Sdes	buffer_init(&active_state->compression_buffer);
53776259Sgreen}
53876259Sgreen
53976259Sgreenvoid
54057429Smarkmpacket_start_compression(int level)
54157429Smarkm{
542197679Sdes	if (active_state->packet_compression && !compat20)
54357429Smarkm		fatal("Compression already enabled.");
544197679Sdes	active_state->packet_compression = 1;
54576259Sgreen	packet_init_compression();
54676259Sgreen	buffer_compress_init_send(level);
54776259Sgreen	buffer_compress_init_recv();
54857429Smarkm}
54957429Smarkm
55057429Smarkm/*
55157429Smarkm * Causes any further packets to be encrypted using the given key.  The same
55257429Smarkm * key is used for both sending and reception.  However, both directions are
55357429Smarkm * encrypted independently of each other.
55457429Smarkm */
55598675Sdes
55657429Smarkmvoid
557221420Sdespacket_set_encryption_key(const u_char *key, u_int keylen, int number)
55857429Smarkm{
559263970Sdes	const Cipher *cipher = cipher_by_number(number);
560106121Sdes
56169587Sgreen	if (cipher == NULL)
56269587Sgreen		fatal("packet_set_encryption_key: unknown cipher number %d", number);
56360573Skris	if (keylen < 20)
56469587Sgreen		fatal("packet_set_encryption_key: keylen too small: %d", keylen);
56598675Sdes	if (keylen > SSH_SESSION_KEY_LENGTH)
56698675Sdes		fatal("packet_set_encryption_key: keylen too big: %d", keylen);
567197679Sdes	memcpy(active_state->ssh1_key, key, keylen);
568197679Sdes	active_state->ssh1_keylen = keylen;
569197679Sdes	cipher_init(&active_state->send_context, cipher, key, keylen, NULL,
570197679Sdes	    0, CIPHER_ENCRYPT);
571197679Sdes	cipher_init(&active_state->receive_context, cipher, key, keylen, NULL,
572197679Sdes	    0, CIPHER_DECRYPT);
57357429Smarkm}
57457429Smarkm
57598675Sdesu_int
57698675Sdespacket_get_encryption_key(u_char *key)
57798675Sdes{
57898675Sdes	if (key == NULL)
579197679Sdes		return (active_state->ssh1_keylen);
580197679Sdes	memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen);
581197679Sdes	return (active_state->ssh1_keylen);
58298675Sdes}
58398675Sdes
58492555Sdes/* Start constructing a packet to send. */
58557429Smarkmvoid
58692555Sdespacket_start(u_char type)
58757429Smarkm{
58892555Sdes	u_char buf[9];
58992555Sdes	int len;
59057429Smarkm
59192555Sdes	DBG(debug("packet_start[%d]", type));
59292555Sdes	len = compat20 ? 6 : 9;
59392555Sdes	memset(buf, 0, len - 1);
59492555Sdes	buf[len - 1] = type;
595197679Sdes	buffer_clear(&active_state->outgoing_packet);
596197679Sdes	buffer_append(&active_state->outgoing_packet, buf, len);
59757429Smarkm}
59857429Smarkm
59992555Sdes/* Append payload. */
60060573Skrisvoid
60157429Smarkmpacket_put_char(int value)
60257429Smarkm{
60357429Smarkm	char ch = value;
604106121Sdes
605197679Sdes	buffer_append(&active_state->outgoing_packet, &ch, 1);
60657429Smarkm}
607162852Sdes
60857429Smarkmvoid
60976259Sgreenpacket_put_int(u_int value)
61057429Smarkm{
611197679Sdes	buffer_put_int(&active_state->outgoing_packet, value);
61257429Smarkm}
613162852Sdes
61457429Smarkmvoid
615197679Sdespacket_put_int64(u_int64_t value)
616197679Sdes{
617197679Sdes	buffer_put_int64(&active_state->outgoing_packet, value);
618197679Sdes}
619197679Sdes
620197679Sdesvoid
62192555Sdespacket_put_string(const void *buf, u_int len)
62257429Smarkm{
623197679Sdes	buffer_put_string(&active_state->outgoing_packet, buf, len);
62457429Smarkm}
625162852Sdes
62660573Skrisvoid
62760573Skrispacket_put_cstring(const char *str)
62860573Skris{
629197679Sdes	buffer_put_cstring(&active_state->outgoing_packet, str);
63060573Skris}
631162852Sdes
63260573Skrisvoid
63392555Sdespacket_put_raw(const void *buf, u_int len)
63460573Skris{
635197679Sdes	buffer_append(&active_state->outgoing_packet, buf, len);
63660573Skris}
637162852Sdes
63857429Smarkmvoid
63957429Smarkmpacket_put_bignum(BIGNUM * value)
64057429Smarkm{
641197679Sdes	buffer_put_bignum(&active_state->outgoing_packet, value);
64257429Smarkm}
643162852Sdes
64460573Skrisvoid
64560573Skrispacket_put_bignum2(BIGNUM * value)
64660573Skris{
647197679Sdes	buffer_put_bignum2(&active_state->outgoing_packet, value);
64860573Skris}
64957429Smarkm
650221420Sdes#ifdef OPENSSL_HAS_ECC
651221420Sdesvoid
652221420Sdespacket_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point)
653221420Sdes{
654221420Sdes	buffer_put_ecpoint(&active_state->outgoing_packet, curve, point);
655221420Sdes}
656221420Sdes#endif
657221420Sdes
65857429Smarkm/*
65957429Smarkm * Finalizes and sends the packet.  If the encryption key has been set,
66057429Smarkm * encrypts the packet before sending.
66157429Smarkm */
66257429Smarkm
66392555Sdesstatic void
66476259Sgreenpacket_send1(void)
66557429Smarkm{
66692555Sdes	u_char buf[8], *cp;
66757429Smarkm	int i, padding, len;
66876259Sgreen	u_int checksum;
669137015Sdes	u_int32_t rnd = 0;
67057429Smarkm
67157429Smarkm	/*
67257429Smarkm	 * If using packet compression, compress the payload of the outgoing
67357429Smarkm	 * packet.
67457429Smarkm	 */
675197679Sdes	if (active_state->packet_compression) {
676197679Sdes		buffer_clear(&active_state->compression_buffer);
67757429Smarkm		/* Skip padding. */
678197679Sdes		buffer_consume(&active_state->outgoing_packet, 8);
67957429Smarkm		/* padding */
680197679Sdes		buffer_append(&active_state->compression_buffer,
681197679Sdes		    "\0\0\0\0\0\0\0\0", 8);
682197679Sdes		buffer_compress(&active_state->outgoing_packet,
683197679Sdes		    &active_state->compression_buffer);
684197679Sdes		buffer_clear(&active_state->outgoing_packet);
685197679Sdes		buffer_append(&active_state->outgoing_packet,
686197679Sdes		    buffer_ptr(&active_state->compression_buffer),
687197679Sdes		    buffer_len(&active_state->compression_buffer));
68857429Smarkm	}
68957429Smarkm	/* Compute packet length without padding (add checksum, remove padding). */
690197679Sdes	len = buffer_len(&active_state->outgoing_packet) + 4 - 8;
69157429Smarkm
69260573Skris	/* Insert padding. Initialized to zero in packet_start1() */
69357429Smarkm	padding = 8 - len % 8;
694197679Sdes	if (!active_state->send_context.plaintext) {
695197679Sdes		cp = buffer_ptr(&active_state->outgoing_packet);
69657429Smarkm		for (i = 0; i < padding; i++) {
69757429Smarkm			if (i % 4 == 0)
698137015Sdes				rnd = arc4random();
699137015Sdes			cp[7 - i] = rnd & 0xff;
700137015Sdes			rnd >>= 8;
70157429Smarkm		}
70257429Smarkm	}
703197679Sdes	buffer_consume(&active_state->outgoing_packet, 8 - padding);
70457429Smarkm
70557429Smarkm	/* Add check bytes. */
706197679Sdes	checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet),
707197679Sdes	    buffer_len(&active_state->outgoing_packet));
708162852Sdes	put_u32(buf, checksum);
709197679Sdes	buffer_append(&active_state->outgoing_packet, buf, 4);
71057429Smarkm
71157429Smarkm#ifdef PACKET_DEBUG
71257429Smarkm	fprintf(stderr, "packet_send plain: ");
713197679Sdes	buffer_dump(&active_state->outgoing_packet);
71457429Smarkm#endif
71557429Smarkm
71657429Smarkm	/* Append to output. */
717162852Sdes	put_u32(buf, len);
718197679Sdes	buffer_append(&active_state->output, buf, 4);
719197679Sdes	cp = buffer_append_space(&active_state->output,
720197679Sdes	    buffer_len(&active_state->outgoing_packet));
721263970Sdes	if (cipher_crypt(&active_state->send_context, 0, cp,
722197679Sdes	    buffer_ptr(&active_state->outgoing_packet),
723263970Sdes	    buffer_len(&active_state->outgoing_packet), 0, 0) != 0)
724263970Sdes		fatal("%s: cipher_crypt failed", __func__);
72557429Smarkm
72657429Smarkm#ifdef PACKET_DEBUG
72757429Smarkm	fprintf(stderr, "encrypted: ");
728197679Sdes	buffer_dump(&active_state->output);
72957429Smarkm#endif
730197679Sdes	active_state->p_send.packets++;
731197679Sdes	active_state->p_send.bytes += len +
732197679Sdes	    buffer_len(&active_state->outgoing_packet);
733197679Sdes	buffer_clear(&active_state->outgoing_packet);
73457429Smarkm
73557429Smarkm	/*
736157016Sdes	 * Note that the packet is now only buffered in output.  It won't be
73757429Smarkm	 * actually sent until packet_write_wait or packet_write_poll is
73857429Smarkm	 * called.
73957429Smarkm	 */
74057429Smarkm}
74157429Smarkm
74298675Sdesvoid
74376259Sgreenset_newkeys(int mode)
74476259Sgreen{
74576259Sgreen	Enc *enc;
74676259Sgreen	Mac *mac;
74776259Sgreen	Comp *comp;
74876259Sgreen	CipherContext *cc;
749124208Sdes	u_int64_t *max_blocks;
750137015Sdes	int crypt_type;
75176259Sgreen
752113908Sdes	debug2("set_newkeys: mode %d", mode);
75376259Sgreen
75492555Sdes	if (mode == MODE_OUT) {
755197679Sdes		cc = &active_state->send_context;
756137015Sdes		crypt_type = CIPHER_ENCRYPT;
757197679Sdes		active_state->p_send.packets = active_state->p_send.blocks = 0;
758197679Sdes		max_blocks = &active_state->max_blocks_out;
75992555Sdes	} else {
760197679Sdes		cc = &active_state->receive_context;
761137015Sdes		crypt_type = CIPHER_DECRYPT;
762197679Sdes		active_state->p_read.packets = active_state->p_read.blocks = 0;
763197679Sdes		max_blocks = &active_state->max_blocks_in;
76492555Sdes	}
765197679Sdes	if (active_state->newkeys[mode] != NULL) {
766113908Sdes		debug("set_newkeys: rekeying");
76792555Sdes		cipher_cleanup(cc);
768197679Sdes		enc  = &active_state->newkeys[mode]->enc;
769197679Sdes		mac  = &active_state->newkeys[mode]->mac;
770197679Sdes		comp = &active_state->newkeys[mode]->comp;
771181111Sdes		mac_clear(mac);
772263970Sdes		explicit_bzero(enc->iv,  enc->iv_len);
773263970Sdes		explicit_bzero(enc->key, enc->key_len);
774263970Sdes		explicit_bzero(mac->key, mac->key_len);
775263970Sdes		free(enc->name);
776263970Sdes		free(enc->iv);
777263970Sdes		free(enc->key);
778263970Sdes		free(mac->name);
779263970Sdes		free(mac->key);
780263970Sdes		free(comp->name);
781263970Sdes		free(active_state->newkeys[mode]);
78276259Sgreen	}
783197679Sdes	active_state->newkeys[mode] = kex_get_newkeys(mode);
784197679Sdes	if (active_state->newkeys[mode] == NULL)
78576259Sgreen		fatal("newkeys: no keys for mode %d", mode);
786197679Sdes	enc  = &active_state->newkeys[mode]->enc;
787197679Sdes	mac  = &active_state->newkeys[mode]->mac;
788197679Sdes	comp = &active_state->newkeys[mode]->comp;
789251135Sdes	if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0)
79076259Sgreen		mac->enabled = 1;
79176259Sgreen	DBG(debug("cipher_init_context: %d", mode));
79292555Sdes	cipher_init(cc, enc->cipher, enc->key, enc->key_len,
793251135Sdes	    enc->iv, enc->iv_len, crypt_type);
79498675Sdes	/* Deleting the keys does not gain extra security */
795263970Sdes	/* explicit_bzero(enc->iv,  enc->block_size);
796263970Sdes	   explicit_bzero(enc->key, enc->key_len);
797263970Sdes	   explicit_bzero(mac->key, mac->key_len); */
798149749Sdes	if ((comp->type == COMP_ZLIB ||
799197679Sdes	    (comp->type == COMP_DELAYED &&
800197679Sdes	     active_state->after_authentication)) && comp->enabled == 0) {
80176259Sgreen		packet_init_compression();
80276259Sgreen		if (mode == MODE_OUT)
80376259Sgreen			buffer_compress_init_send(6);
80476259Sgreen		else
80576259Sgreen			buffer_compress_init_recv();
80676259Sgreen		comp->enabled = 1;
80776259Sgreen	}
808124208Sdes	/*
809124208Sdes	 * The 2^(blocksize*2) limit is too expensive for 3DES,
810124208Sdes	 * blowfish, etc, so enforce a 1GB limit for small blocksizes.
811124208Sdes	 */
812124208Sdes	if (enc->block_size >= 16)
813124208Sdes		*max_blocks = (u_int64_t)1 << (enc->block_size*2);
814124208Sdes	else
815124208Sdes		*max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
816197679Sdes	if (active_state->rekey_limit)
817197679Sdes		*max_blocks = MIN(*max_blocks,
818197679Sdes		    active_state->rekey_limit / enc->block_size);
81976259Sgreen}
82076259Sgreen
82157429Smarkm/*
822149749Sdes * Delayed compression for SSH2 is enabled after authentication:
823162852Sdes * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
824149749Sdes * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received.
825149749Sdes */
826149749Sdesstatic void
827149749Sdespacket_enable_delayed_compress(void)
828149749Sdes{
829149749Sdes	Comp *comp = NULL;
830149749Sdes	int mode;
831149749Sdes
832149749Sdes	/*
833149749Sdes	 * Remember that we are past the authentication step, so rekeying
834149749Sdes	 * with COMP_DELAYED will turn on compression immediately.
835149749Sdes	 */
836197679Sdes	active_state->after_authentication = 1;
837149749Sdes	for (mode = 0; mode < MODE_MAX; mode++) {
838162852Sdes		/* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
839197679Sdes		if (active_state->newkeys[mode] == NULL)
840162852Sdes			continue;
841197679Sdes		comp = &active_state->newkeys[mode]->comp;
842149749Sdes		if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
843149749Sdes			packet_init_compression();
844149749Sdes			if (mode == MODE_OUT)
845149749Sdes				buffer_compress_init_send(6);
846149749Sdes			else
847149749Sdes				buffer_compress_init_recv();
848149749Sdes			comp->enabled = 1;
849149749Sdes		}
850149749Sdes	}
851149749Sdes}
852149749Sdes
853149749Sdes/*
85460573Skris * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
85560573Skris */
85692555Sdesstatic void
857124208Sdespacket_send2_wrapped(void)
85860573Skris{
85992555Sdes	u_char type, *cp, *macbuf = NULL;
860251135Sdes	u_char padlen, pad = 0;
861251135Sdes	u_int i, len, authlen = 0, aadlen = 0;
862137015Sdes	u_int32_t rnd = 0;
86360573Skris	Enc *enc   = NULL;
86460573Skris	Mac *mac   = NULL;
86560573Skris	Comp *comp = NULL;
86660573Skris	int block_size;
86760573Skris
868197679Sdes	if (active_state->newkeys[MODE_OUT] != NULL) {
869197679Sdes		enc  = &active_state->newkeys[MODE_OUT]->enc;
870197679Sdes		mac  = &active_state->newkeys[MODE_OUT]->mac;
871197679Sdes		comp = &active_state->newkeys[MODE_OUT]->comp;
872251135Sdes		/* disable mac for authenticated encryption */
873251135Sdes		if ((authlen = cipher_authlen(enc->cipher)) != 0)
874251135Sdes			mac = NULL;
87560573Skris	}
87692555Sdes	block_size = enc ? enc->block_size : 8;
877251135Sdes	aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
87860573Skris
879197679Sdes	cp = buffer_ptr(&active_state->outgoing_packet);
88092555Sdes	type = cp[5];
88160573Skris
88260573Skris#ifdef PACKET_DEBUG
88360573Skris	fprintf(stderr, "plain:     ");
884197679Sdes	buffer_dump(&active_state->outgoing_packet);
88560573Skris#endif
88660573Skris
88760573Skris	if (comp && comp->enabled) {
888197679Sdes		len = buffer_len(&active_state->outgoing_packet);
88960573Skris		/* skip header, compress only payload */
890197679Sdes		buffer_consume(&active_state->outgoing_packet, 5);
891197679Sdes		buffer_clear(&active_state->compression_buffer);
892197679Sdes		buffer_compress(&active_state->outgoing_packet,
893197679Sdes		    &active_state->compression_buffer);
894197679Sdes		buffer_clear(&active_state->outgoing_packet);
895197679Sdes		buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5);
896197679Sdes		buffer_append(&active_state->outgoing_packet,
897197679Sdes		    buffer_ptr(&active_state->compression_buffer),
898197679Sdes		    buffer_len(&active_state->compression_buffer));
89960573Skris		DBG(debug("compression: raw %d compressed %d", len,
900197679Sdes		    buffer_len(&active_state->outgoing_packet)));
90160573Skris	}
90260573Skris
90360573Skris	/* sizeof (packet_len + pad_len + payload) */
904197679Sdes	len = buffer_len(&active_state->outgoing_packet);
90560573Skris
90660573Skris	/*
90760573Skris	 * calc size of padding, alloc space, get random data,
90860573Skris	 * minimum padding is 4 bytes
90960573Skris	 */
910251135Sdes	len -= aadlen; /* packet length is not encrypted for EtM modes */
91160573Skris	padlen = block_size - (len % block_size);
91260573Skris	if (padlen < 4)
91360573Skris		padlen += block_size;
914197679Sdes	if (active_state->extra_pad) {
91592555Sdes		/* will wrap if extra_pad+padlen > 255 */
916197679Sdes		active_state->extra_pad =
917197679Sdes		    roundup(active_state->extra_pad, block_size);
918197679Sdes		pad = active_state->extra_pad -
919197679Sdes		    ((len + padlen) % active_state->extra_pad);
92098675Sdes		debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
921197679Sdes		    pad, len, padlen, active_state->extra_pad);
92292555Sdes		padlen += pad;
923197679Sdes		active_state->extra_pad = 0;
92492555Sdes	}
925197679Sdes	cp = buffer_append_space(&active_state->outgoing_packet, padlen);
926197679Sdes	if (enc && !active_state->send_context.plaintext) {
92760573Skris		/* random padding */
92860573Skris		for (i = 0; i < padlen; i++) {
92960573Skris			if (i % 4 == 0)
930137015Sdes				rnd = arc4random();
931137015Sdes			cp[i] = rnd & 0xff;
932137015Sdes			rnd >>= 8;
93360573Skris		}
93460573Skris	} else {
93560573Skris		/* clear padding */
936263970Sdes		explicit_bzero(cp, padlen);
93760573Skris	}
938251135Sdes	/* sizeof (packet_len + pad_len + payload + padding) */
939251135Sdes	len = buffer_len(&active_state->outgoing_packet);
940251135Sdes	cp = buffer_ptr(&active_state->outgoing_packet);
94160573Skris	/* packet_length includes payload, padding and padding length field */
942251135Sdes	put_u32(cp, len - 4);
94392555Sdes	cp[4] = padlen;
944251135Sdes	DBG(debug("send: len %d (includes padlen %d, aadlen %d)",
945251135Sdes	    len, padlen, aadlen));
94660573Skris
94760573Skris	/* compute MAC over seqnr and packet(length fields, payload, padding) */
948251135Sdes	if (mac && mac->enabled && !mac->etm) {
949197679Sdes		macbuf = mac_compute(mac, active_state->p_send.seqnr,
950251135Sdes		    buffer_ptr(&active_state->outgoing_packet), len);
951197679Sdes		DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
95260573Skris	}
95360573Skris	/* encrypt packet and append to output buffer. */
954251135Sdes	cp = buffer_append_space(&active_state->output, len + authlen);
955263970Sdes	if (cipher_crypt(&active_state->send_context, active_state->p_send.seqnr,
956263970Sdes	    cp, buffer_ptr(&active_state->outgoing_packet),
957263970Sdes	    len - aadlen, aadlen, authlen) != 0)
958263970Sdes		fatal("%s: cipher_crypt failed", __func__);
95960573Skris	/* append unencrypted MAC */
960251135Sdes	if (mac && mac->enabled) {
961251135Sdes		if (mac->etm) {
962251135Sdes			/* EtM: compute mac over aadlen + cipher text */
963251135Sdes			macbuf = mac_compute(mac,
964251135Sdes			    active_state->p_send.seqnr, cp, len);
965251135Sdes			DBG(debug("done calc MAC(EtM) out #%d",
966251135Sdes			    active_state->p_send.seqnr));
967251135Sdes		}
968197679Sdes		buffer_append(&active_state->output, macbuf, mac->mac_len);
969251135Sdes	}
97060573Skris#ifdef PACKET_DEBUG
97160573Skris	fprintf(stderr, "encrypted: ");
972197679Sdes	buffer_dump(&active_state->output);
97360573Skris#endif
97460573Skris	/* increment sequence number for outgoing packets */
975197679Sdes	if (++active_state->p_send.seqnr == 0)
976124208Sdes		logit("outgoing seqnr wraps around");
977197679Sdes	if (++active_state->p_send.packets == 0)
978124208Sdes		if (!(datafellows & SSH_BUG_NOREKEY))
979124208Sdes			fatal("XXX too many packets with same key");
980251135Sdes	active_state->p_send.blocks += len / block_size;
981251135Sdes	active_state->p_send.bytes += len;
982197679Sdes	buffer_clear(&active_state->outgoing_packet);
98360573Skris
98476259Sgreen	if (type == SSH2_MSG_NEWKEYS)
98576259Sgreen		set_newkeys(MODE_OUT);
986197679Sdes	else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
987149749Sdes		packet_enable_delayed_compress();
98860573Skris}
98960573Skris
990124208Sdesstatic void
991124208Sdespacket_send2(void)
992124208Sdes{
993124208Sdes	struct packet *p;
994124208Sdes	u_char type, *cp;
995124208Sdes
996197679Sdes	cp = buffer_ptr(&active_state->outgoing_packet);
997124208Sdes	type = cp[5];
998124208Sdes
999124208Sdes	/* during rekeying we can only send key exchange messages */
1000197679Sdes	if (active_state->rekeying) {
1001247485Sdes		if ((type < SSH2_MSG_TRANSPORT_MIN) ||
1002247485Sdes		    (type > SSH2_MSG_TRANSPORT_MAX) ||
1003247485Sdes		    (type == SSH2_MSG_SERVICE_REQUEST) ||
1004247485Sdes		    (type == SSH2_MSG_SERVICE_ACCEPT)) {
1005124208Sdes			debug("enqueue packet: %u", type);
1006263970Sdes			p = xcalloc(1, sizeof(*p));
1007124208Sdes			p->type = type;
1008197679Sdes			memcpy(&p->payload, &active_state->outgoing_packet,
1009197679Sdes			    sizeof(Buffer));
1010197679Sdes			buffer_init(&active_state->outgoing_packet);
1011197679Sdes			TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
1012124208Sdes			return;
1013124208Sdes		}
1014124208Sdes	}
1015124208Sdes
1016124208Sdes	/* rekeying starts with sending KEXINIT */
1017124208Sdes	if (type == SSH2_MSG_KEXINIT)
1018197679Sdes		active_state->rekeying = 1;
1019124208Sdes
1020124208Sdes	packet_send2_wrapped();
1021124208Sdes
1022124208Sdes	/* after a NEWKEYS message we can send the complete queue */
1023124208Sdes	if (type == SSH2_MSG_NEWKEYS) {
1024197679Sdes		active_state->rekeying = 0;
1025263970Sdes		active_state->rekey_time = monotime();
1026197679Sdes		while ((p = TAILQ_FIRST(&active_state->outgoing))) {
1027124208Sdes			type = p->type;
1028124208Sdes			debug("dequeue packet: %u", type);
1029197679Sdes			buffer_free(&active_state->outgoing_packet);
1030197679Sdes			memcpy(&active_state->outgoing_packet, &p->payload,
1031124208Sdes			    sizeof(Buffer));
1032197679Sdes			TAILQ_REMOVE(&active_state->outgoing, p, next);
1033263970Sdes			free(p);
1034124208Sdes			packet_send2_wrapped();
1035124208Sdes		}
1036124208Sdes	}
1037124208Sdes}
1038124208Sdes
103960573Skrisvoid
104092555Sdespacket_send(void)
104160573Skris{
104292555Sdes	if (compat20)
104360573Skris		packet_send2();
104460573Skris	else
104560573Skris		packet_send1();
104660573Skris	DBG(debug("packet_send done"));
104760573Skris}
104860573Skris
104960573Skris/*
105057429Smarkm * Waits until a packet has been received, and returns its type.  Note that
105157429Smarkm * no other data is processed until this returns, so this function should not
105257429Smarkm * be used during the interactive session.
105357429Smarkm */
105457429Smarkm
105557429Smarkmint
105692555Sdespacket_read_seqnr(u_int32_t *seqnr_p)
105757429Smarkm{
1058263970Sdes	int type, len, ret, cont, ms_remain = 0;
105976259Sgreen	fd_set *setp;
106057429Smarkm	char buf[8192];
1061181111Sdes	struct timeval timeout, start, *timeoutp = NULL;
1062181111Sdes
106360573Skris	DBG(debug("packet_read()"));
106457429Smarkm
1065197679Sdes	setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1,
1066197679Sdes	    NFDBITS), sizeof(fd_mask));
106776259Sgreen
106857429Smarkm	/* Since we are blocking, ensure that all written packets have been sent. */
106957429Smarkm	packet_write_wait();
107057429Smarkm
107157429Smarkm	/* Stay in the loop until we have received a complete packet. */
107257429Smarkm	for (;;) {
107357429Smarkm		/* Try to read a packet from the buffer. */
107492555Sdes		type = packet_read_poll_seqnr(seqnr_p);
107592555Sdes		if (!compat20 && (
107660573Skris		    type == SSH_SMSG_SUCCESS
107757429Smarkm		    || type == SSH_SMSG_FAILURE
107857429Smarkm		    || type == SSH_CMSG_EOF
107960573Skris		    || type == SSH_CMSG_EXIT_CONFIRMATION))
108092555Sdes			packet_check_eom();
108157429Smarkm		/* If we got a packet, return it. */
108276259Sgreen		if (type != SSH_MSG_NONE) {
1083263970Sdes			free(setp);
108457429Smarkm			return type;
108576259Sgreen		}
108657429Smarkm		/*
108757429Smarkm		 * Otherwise, wait for some data to arrive, add it to the
108857429Smarkm		 * buffer, and try again.
108957429Smarkm		 */
1090197679Sdes		memset(setp, 0, howmany(active_state->connection_in + 1,
1091197679Sdes		    NFDBITS) * sizeof(fd_mask));
1092197679Sdes		FD_SET(active_state->connection_in, setp);
109357429Smarkm
1094197679Sdes		if (active_state->packet_timeout_ms > 0) {
1095197679Sdes			ms_remain = active_state->packet_timeout_ms;
1096181111Sdes			timeoutp = &timeout;
1097181111Sdes		}
109857429Smarkm		/* Wait for some data to arrive. */
1099181111Sdes		for (;;) {
1100197679Sdes			if (active_state->packet_timeout_ms != -1) {
1101181111Sdes				ms_to_timeval(&timeout, ms_remain);
1102181111Sdes				gettimeofday(&start, NULL);
1103181111Sdes			}
1104197679Sdes			if ((ret = select(active_state->connection_in + 1, setp,
1105197679Sdes			    NULL, NULL, timeoutp)) >= 0)
1106181111Sdes				break;
1107197679Sdes			if (errno != EAGAIN && errno != EINTR &&
1108181111Sdes			    errno != EWOULDBLOCK)
1109181111Sdes				break;
1110197679Sdes			if (active_state->packet_timeout_ms == -1)
1111181111Sdes				continue;
1112181111Sdes			ms_subtract_diff(&start, &ms_remain);
1113181111Sdes			if (ms_remain <= 0) {
1114181111Sdes				ret = 0;
1115181111Sdes				break;
1116181111Sdes			}
1117181111Sdes		}
1118181111Sdes		if (ret == 0) {
1119181111Sdes			logit("Connection to %.200s timed out while "
1120181111Sdes			    "waiting to read", get_remote_ipaddr());
1121181111Sdes			cleanup_exit(255);
1122181111Sdes		}
112357429Smarkm		/* Read data from the socket. */
1124197679Sdes		do {
1125197679Sdes			cont = 0;
1126197679Sdes			len = roaming_read(active_state->connection_in, buf,
1127197679Sdes			    sizeof(buf), &cont);
1128197679Sdes		} while (len == 0 && cont);
112957429Smarkm		if (len == 0) {
1130124208Sdes			logit("Connection closed by %.200s", get_remote_ipaddr());
1131126274Sdes			cleanup_exit(255);
113257429Smarkm		}
113357429Smarkm		if (len < 0)
113457429Smarkm			fatal("Read from socket failed: %.100s", strerror(errno));
113557429Smarkm		/* Append it to the buffer. */
113657429Smarkm		packet_process_incoming(buf, len);
113757429Smarkm	}
113857429Smarkm	/* NOTREACHED */
113957429Smarkm}
114057429Smarkm
114192555Sdesint
114292555Sdespacket_read(void)
114392555Sdes{
114492555Sdes	return packet_read_seqnr(NULL);
114592555Sdes}
114692555Sdes
114757429Smarkm/*
114857429Smarkm * Waits until a packet has been received, verifies that its type matches
114957429Smarkm * that given, and gives a fatal error and exits if there is a mismatch.
115057429Smarkm */
115157429Smarkm
115257429Smarkmvoid
115392555Sdespacket_read_expect(int expected_type)
115457429Smarkm{
115557429Smarkm	int type;
115657429Smarkm
115792555Sdes	type = packet_read();
115857429Smarkm	if (type != expected_type)
115957429Smarkm		packet_disconnect("Protocol error: expected packet type %d, got %d",
116060573Skris		    expected_type, type);
116157429Smarkm}
116257429Smarkm
116357429Smarkm/* Checks if a full packet is available in the data received so far via
116457429Smarkm * packet_process_incoming.  If so, reads the packet; otherwise returns
116557429Smarkm * SSH_MSG_NONE.  This does not wait for data from the connection.
116657429Smarkm *
116757429Smarkm * SSH_MSG_DISCONNECT is handled specially here.  Also,
116857429Smarkm * SSH_MSG_IGNORE messages are skipped by this function and are never returned
116957429Smarkm * to higher levels.
117057429Smarkm */
117157429Smarkm
117292555Sdesstatic int
117392555Sdespacket_read_poll1(void)
117457429Smarkm{
117576259Sgreen	u_int len, padded_len;
117692555Sdes	u_char *cp, type;
117776259Sgreen	u_int checksum, stored_checksum;
117857429Smarkm
117957429Smarkm	/* Check if input size is less than minimum packet size. */
1180197679Sdes	if (buffer_len(&active_state->input) < 4 + 8)
118157429Smarkm		return SSH_MSG_NONE;
118257429Smarkm	/* Get length of incoming packet. */
1183197679Sdes	cp = buffer_ptr(&active_state->input);
1184162852Sdes	len = get_u32(cp);
118557429Smarkm	if (len < 1 + 2 + 2 || len > 256 * 1024)
1186113908Sdes		packet_disconnect("Bad packet length %u.", len);
118757429Smarkm	padded_len = (len + 8) & ~7;
118857429Smarkm
118957429Smarkm	/* Check if the packet has been entirely received. */
1190197679Sdes	if (buffer_len(&active_state->input) < 4 + padded_len)
119157429Smarkm		return SSH_MSG_NONE;
119257429Smarkm
119357429Smarkm	/* The entire packet is in buffer. */
119457429Smarkm
119557429Smarkm	/* Consume packet length. */
1196197679Sdes	buffer_consume(&active_state->input, 4);
119757429Smarkm
119892555Sdes	/*
119992555Sdes	 * Cryptographic attack detector for ssh
120092555Sdes	 * (C)1998 CORE-SDI, Buenos Aires Argentina
120192555Sdes	 * Ariel Futoransky(futo@core-sdi.com)
120292555Sdes	 */
1203197679Sdes	if (!active_state->receive_context.plaintext) {
1204197679Sdes		switch (detect_attack(buffer_ptr(&active_state->input),
1205197679Sdes		    padded_len)) {
1206162852Sdes		case DEATTACK_DETECTED:
1207162852Sdes			packet_disconnect("crc32 compensation attack: "
1208162852Sdes			    "network attack detected");
1209162852Sdes		case DEATTACK_DOS_DETECTED:
1210162852Sdes			packet_disconnect("deattack denial of "
1211162852Sdes			    "service detected");
1212162852Sdes		}
1213162852Sdes	}
121492555Sdes
121592555Sdes	/* Decrypt data to incoming_packet. */
1216197679Sdes	buffer_clear(&active_state->incoming_packet);
1217197679Sdes	cp = buffer_append_space(&active_state->incoming_packet, padded_len);
1218263970Sdes	if (cipher_crypt(&active_state->receive_context, 0, cp,
1219263970Sdes	    buffer_ptr(&active_state->input), padded_len, 0, 0) != 0)
1220263970Sdes		fatal("%s: cipher_crypt failed", __func__);
122192555Sdes
1222197679Sdes	buffer_consume(&active_state->input, padded_len);
122357429Smarkm
122457429Smarkm#ifdef PACKET_DEBUG
122557429Smarkm	fprintf(stderr, "read_poll plain: ");
1226197679Sdes	buffer_dump(&active_state->incoming_packet);
122757429Smarkm#endif
122857429Smarkm
122957429Smarkm	/* Compute packet checksum. */
1230197679Sdes	checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet),
1231197679Sdes	    buffer_len(&active_state->incoming_packet) - 4);
123257429Smarkm
123357429Smarkm	/* Skip padding. */
1234197679Sdes	buffer_consume(&active_state->incoming_packet, 8 - len % 8);
123557429Smarkm
123657429Smarkm	/* Test check bytes. */
1237197679Sdes	if (len != buffer_len(&active_state->incoming_packet))
123892555Sdes		packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
1239197679Sdes		    len, buffer_len(&active_state->incoming_packet));
124057429Smarkm
1241197679Sdes	cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4;
1242162852Sdes	stored_checksum = get_u32(cp);
124357429Smarkm	if (checksum != stored_checksum)
124457429Smarkm		packet_disconnect("Corrupted check bytes on input.");
1245197679Sdes	buffer_consume_end(&active_state->incoming_packet, 4);
124657429Smarkm
1247197679Sdes	if (active_state->packet_compression) {
1248197679Sdes		buffer_clear(&active_state->compression_buffer);
1249197679Sdes		buffer_uncompress(&active_state->incoming_packet,
1250197679Sdes		    &active_state->compression_buffer);
1251197679Sdes		buffer_clear(&active_state->incoming_packet);
1252197679Sdes		buffer_append(&active_state->incoming_packet,
1253197679Sdes		    buffer_ptr(&active_state->compression_buffer),
1254197679Sdes		    buffer_len(&active_state->compression_buffer));
125557429Smarkm	}
1256197679Sdes	active_state->p_read.packets++;
1257197679Sdes	active_state->p_read.bytes += padded_len + 4;
1258197679Sdes	type = buffer_get_char(&active_state->incoming_packet);
1259146998Sdes	if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
1260146998Sdes		packet_disconnect("Invalid ssh1 packet type: %d", type);
126192555Sdes	return type;
126260573Skris}
126357429Smarkm
126492555Sdesstatic int
126592555Sdespacket_read_poll2(u_int32_t *seqnr_p)
126660573Skris{
126776259Sgreen	u_int padlen, need;
1268251135Sdes	u_char *macbuf = NULL, *cp, type;
1269251135Sdes	u_int maclen, authlen = 0, aadlen = 0, block_size;
127060573Skris	Enc *enc   = NULL;
127160573Skris	Mac *mac   = NULL;
127260573Skris	Comp *comp = NULL;
127357429Smarkm
1274197679Sdes	if (active_state->packet_discard)
1275192595Sdes		return SSH_MSG_NONE;
1276192595Sdes
1277197679Sdes	if (active_state->newkeys[MODE_IN] != NULL) {
1278197679Sdes		enc  = &active_state->newkeys[MODE_IN]->enc;
1279197679Sdes		mac  = &active_state->newkeys[MODE_IN]->mac;
1280197679Sdes		comp = &active_state->newkeys[MODE_IN]->comp;
1281251135Sdes		/* disable mac for authenticated encryption */
1282251135Sdes		if ((authlen = cipher_authlen(enc->cipher)) != 0)
1283251135Sdes			mac = NULL;
128457429Smarkm	}
128560573Skris	maclen = mac && mac->enabled ? mac->mac_len : 0;
128692555Sdes	block_size = enc ? enc->block_size : 8;
1287251135Sdes	aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0;
128860573Skris
1289251135Sdes	if (aadlen && active_state->packlen == 0) {
1290263970Sdes		if (cipher_get_length(&active_state->receive_context,
1291263970Sdes		    &active_state->packlen,
1292263970Sdes		    active_state->p_read.seqnr,
1293263970Sdes		    buffer_ptr(&active_state->input),
1294263970Sdes		    buffer_len(&active_state->input)) != 0)
1295251135Sdes			return SSH_MSG_NONE;
1296251135Sdes		if (active_state->packlen < 1 + 4 ||
1297251135Sdes		    active_state->packlen > PACKET_MAX_SIZE) {
1298251135Sdes#ifdef PACKET_DEBUG
1299251135Sdes			buffer_dump(&active_state->input);
1300251135Sdes#endif
1301251135Sdes			logit("Bad packet length %u.", active_state->packlen);
1302251135Sdes			packet_disconnect("Packet corrupt");
1303251135Sdes		}
1304251135Sdes		buffer_clear(&active_state->incoming_packet);
1305251135Sdes	} else if (active_state->packlen == 0) {
130660573Skris		/*
130760573Skris		 * check if input size is less than the cipher block size,
130860573Skris		 * decrypt first block and extract length of incoming packet
130960573Skris		 */
1310197679Sdes		if (buffer_len(&active_state->input) < block_size)
131160573Skris			return SSH_MSG_NONE;
1312197679Sdes		buffer_clear(&active_state->incoming_packet);
1313197679Sdes		cp = buffer_append_space(&active_state->incoming_packet,
131460573Skris		    block_size);
1315263970Sdes		if (cipher_crypt(&active_state->receive_context,
1316263970Sdes		    active_state->p_read.seqnr, cp,
1317263970Sdes		    buffer_ptr(&active_state->input), block_size, 0, 0) != 0)
1318263970Sdes			fatal("Decryption integrity check failed");
1319197679Sdes		cp = buffer_ptr(&active_state->incoming_packet);
1320247485Sdes
1321197679Sdes		active_state->packlen = get_u32(cp);
1322197679Sdes		if (active_state->packlen < 1 + 4 ||
1323197679Sdes		    active_state->packlen > PACKET_MAX_SIZE) {
1324124208Sdes#ifdef PACKET_DEBUG
1325197679Sdes			buffer_dump(&active_state->incoming_packet);
1326124208Sdes#endif
1327197679Sdes			logit("Bad packet length %u.", active_state->packlen);
1328197679Sdes			packet_start_discard(enc, mac, active_state->packlen,
1329192595Sdes			    PACKET_MAX_SIZE);
1330192595Sdes			return SSH_MSG_NONE;
133160573Skris		}
1332197679Sdes		buffer_consume(&active_state->input, block_size);
133360573Skris	}
1334251135Sdes	DBG(debug("input: packet len %u", active_state->packlen+4));
1335251135Sdes	if (aadlen) {
1336251135Sdes		/* only the payload is encrypted */
1337251135Sdes		need = active_state->packlen;
1338251135Sdes	} else {
1339251135Sdes		/*
1340251135Sdes		 * the payload size and the payload are encrypted, but we
1341251135Sdes		 * have a partial packet of block_size bytes
1342251135Sdes		 */
1343251135Sdes		need = 4 + active_state->packlen - block_size;
1344251135Sdes	}
1345251135Sdes	DBG(debug("partial packet: block %d, need %d, maclen %d, authlen %d,"
1346251135Sdes	    " aadlen %d", block_size, need, maclen, authlen, aadlen));
1347192595Sdes	if (need % block_size != 0) {
1348192595Sdes		logit("padding error: need %d block %d mod %d",
134960573Skris		    need, block_size, need % block_size);
1350197679Sdes		packet_start_discard(enc, mac, active_state->packlen,
1351192595Sdes		    PACKET_MAX_SIZE - block_size);
1352192595Sdes		return SSH_MSG_NONE;
1353192595Sdes	}
135460573Skris	/*
135560573Skris	 * check if the entire packet has been received and
1356251135Sdes	 * decrypt into incoming_packet:
1357251135Sdes	 * 'aadlen' bytes are unencrypted, but authenticated.
1358251135Sdes	 * 'need' bytes are encrypted, followed by either
1359251135Sdes	 * 'authlen' bytes of authentication tag or
1360251135Sdes	 * 'maclen' bytes of message authentication code.
136160573Skris	 */
1362251135Sdes	if (buffer_len(&active_state->input) < aadlen + need + authlen + maclen)
136360573Skris		return SSH_MSG_NONE;
136460573Skris#ifdef PACKET_DEBUG
136560573Skris	fprintf(stderr, "read_poll enc/full: ");
1366197679Sdes	buffer_dump(&active_state->input);
136760573Skris#endif
1368251135Sdes	/* EtM: compute mac over encrypted input */
1369251135Sdes	if (mac && mac->enabled && mac->etm)
1370251135Sdes		macbuf = mac_compute(mac, active_state->p_read.seqnr,
1371251135Sdes		    buffer_ptr(&active_state->input), aadlen + need);
1372251135Sdes	cp = buffer_append_space(&active_state->incoming_packet, aadlen + need);
1373263970Sdes	if (cipher_crypt(&active_state->receive_context,
1374263970Sdes	    active_state->p_read.seqnr, cp,
1375263970Sdes	    buffer_ptr(&active_state->input), need, aadlen, authlen) != 0)
1376263970Sdes		fatal("Decryption integrity check failed");
1377251135Sdes	buffer_consume(&active_state->input, aadlen + need + authlen);
137860573Skris	/*
137960573Skris	 * compute MAC over seqnr and packet,
138060573Skris	 * increment sequence number for incoming packet
138160573Skris	 */
138260573Skris	if (mac && mac->enabled) {
1383251135Sdes		if (!mac->etm)
1384251135Sdes			macbuf = mac_compute(mac, active_state->p_read.seqnr,
1385251135Sdes			    buffer_ptr(&active_state->incoming_packet),
1386251135Sdes			    buffer_len(&active_state->incoming_packet));
1387215116Sdes		if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input),
1388197679Sdes		    mac->mac_len) != 0) {
1389192595Sdes			logit("Corrupted MAC on input.");
1390192595Sdes			if (need > PACKET_MAX_SIZE)
1391192595Sdes				fatal("internal error need %d", need);
1392197679Sdes			packet_start_discard(enc, mac, active_state->packlen,
1393192595Sdes			    PACKET_MAX_SIZE - need);
1394192595Sdes			return SSH_MSG_NONE;
1395192595Sdes		}
1396192595Sdes
1397197679Sdes		DBG(debug("MAC #%d ok", active_state->p_read.seqnr));
1398197679Sdes		buffer_consume(&active_state->input, mac->mac_len);
139960573Skris	}
1400192595Sdes	/* XXX now it's safe to use fatal/packet_disconnect */
140192555Sdes	if (seqnr_p != NULL)
1402197679Sdes		*seqnr_p = active_state->p_read.seqnr;
1403197679Sdes	if (++active_state->p_read.seqnr == 0)
1404124208Sdes		logit("incoming seqnr wraps around");
1405197679Sdes	if (++active_state->p_read.packets == 0)
1406124208Sdes		if (!(datafellows & SSH_BUG_NOREKEY))
1407124208Sdes			fatal("XXX too many packets with same key");
1408197679Sdes	active_state->p_read.blocks += (active_state->packlen + 4) / block_size;
1409197679Sdes	active_state->p_read.bytes += active_state->packlen + 4;
141060573Skris
141160573Skris	/* get padlen */
1412197679Sdes	cp = buffer_ptr(&active_state->incoming_packet);
141392555Sdes	padlen = cp[4];
141460573Skris	DBG(debug("input: padlen %d", padlen));
141560573Skris	if (padlen < 4)
141660573Skris		packet_disconnect("Corrupted padlen %d on input.", padlen);
141760573Skris
141860573Skris	/* skip packet size + padlen, discard padding */
1419197679Sdes	buffer_consume(&active_state->incoming_packet, 4 + 1);
1420197679Sdes	buffer_consume_end(&active_state->incoming_packet, padlen);
142160573Skris
1422197679Sdes	DBG(debug("input: len before de-compress %d",
1423197679Sdes	    buffer_len(&active_state->incoming_packet)));
142460573Skris	if (comp && comp->enabled) {
1425197679Sdes		buffer_clear(&active_state->compression_buffer);
1426197679Sdes		buffer_uncompress(&active_state->incoming_packet,
1427197679Sdes		    &active_state->compression_buffer);
1428197679Sdes		buffer_clear(&active_state->incoming_packet);
1429197679Sdes		buffer_append(&active_state->incoming_packet,
1430197679Sdes		    buffer_ptr(&active_state->compression_buffer),
1431197679Sdes		    buffer_len(&active_state->compression_buffer));
1432106121Sdes		DBG(debug("input: len after de-compress %d",
1433197679Sdes		    buffer_len(&active_state->incoming_packet)));
143460573Skris	}
143560573Skris	/*
143660573Skris	 * get packet type, implies consume.
143760573Skris	 * return length of payload (without type field)
143860573Skris	 */
1439197679Sdes	type = buffer_get_char(&active_state->incoming_packet);
1440146998Sdes	if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
1441146998Sdes		packet_disconnect("Invalid ssh2 packet type: %d", type);
144276259Sgreen	if (type == SSH2_MSG_NEWKEYS)
144376259Sgreen		set_newkeys(MODE_IN);
1444197679Sdes	else if (type == SSH2_MSG_USERAUTH_SUCCESS &&
1445197679Sdes	    !active_state->server_side)
1446149749Sdes		packet_enable_delayed_compress();
144760573Skris#ifdef PACKET_DEBUG
144876259Sgreen	fprintf(stderr, "read/plain[%d]:\r\n", type);
1449197679Sdes	buffer_dump(&active_state->incoming_packet);
145060573Skris#endif
145192555Sdes	/* reset for next packet */
1452197679Sdes	active_state->packlen = 0;
145392555Sdes	return type;
145457429Smarkm}
145557429Smarkm
145660573Skrisint
145792555Sdespacket_read_poll_seqnr(u_int32_t *seqnr_p)
145860573Skris{
145999060Sdes	u_int reason, seqnr;
146092555Sdes	u_char type;
146160573Skris	char *msg;
146292555Sdes
146360573Skris	for (;;) {
146492555Sdes		if (compat20) {
146592555Sdes			type = packet_read_poll2(seqnr_p);
1466181111Sdes			if (type) {
1467197679Sdes				active_state->keep_alive_timeouts = 0;
146860573Skris				DBG(debug("received packet type %d", type));
1469181111Sdes			}
147092555Sdes			switch (type) {
147160573Skris			case SSH2_MSG_IGNORE:
1472181111Sdes				debug3("Received SSH2_MSG_IGNORE");
147360573Skris				break;
147460573Skris			case SSH2_MSG_DEBUG:
147560573Skris				packet_get_char();
147660573Skris				msg = packet_get_string(NULL);
147760573Skris				debug("Remote: %.900s", msg);
1478263970Sdes				free(msg);
147960573Skris				msg = packet_get_string(NULL);
1480263970Sdes				free(msg);
148160573Skris				break;
148260573Skris			case SSH2_MSG_DISCONNECT:
148360573Skris				reason = packet_get_int();
148460573Skris				msg = packet_get_string(NULL);
1485251135Sdes				/* Ignore normal client exit notifications */
1486251135Sdes				do_log2(active_state->server_side &&
1487251135Sdes				    reason == SSH2_DISCONNECT_BY_APPLICATION ?
1488251135Sdes				    SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR,
1489251135Sdes				    "Received disconnect from %s: %u: %.400s",
149099060Sdes				    get_remote_ipaddr(), reason, msg);
1491263970Sdes				free(msg);
1492126274Sdes				cleanup_exit(255);
149360573Skris				break;
149492555Sdes			case SSH2_MSG_UNIMPLEMENTED:
149592555Sdes				seqnr = packet_get_int();
149699060Sdes				debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
149799060Sdes				    seqnr);
149892555Sdes				break;
149960573Skris			default:
150060573Skris				return type;
150176259Sgreen			}
150260573Skris		} else {
150392555Sdes			type = packet_read_poll1();
150492555Sdes			switch (type) {
1505263970Sdes			case SSH_MSG_NONE:
1506263970Sdes				return SSH_MSG_NONE;
150760573Skris			case SSH_MSG_IGNORE:
150860573Skris				break;
150960573Skris			case SSH_MSG_DEBUG:
151060573Skris				msg = packet_get_string(NULL);
151160573Skris				debug("Remote: %.900s", msg);
1512263970Sdes				free(msg);
151360573Skris				break;
151460573Skris			case SSH_MSG_DISCONNECT:
151560573Skris				msg = packet_get_string(NULL);
1516124208Sdes				logit("Received disconnect from %s: %.400s",
151799060Sdes				    get_remote_ipaddr(), msg);
1518126274Sdes				cleanup_exit(255);
151960573Skris				break;
152060573Skris			default:
1521263970Sdes				DBG(debug("received packet type %d", type));
152260573Skris				return type;
152376259Sgreen			}
152460573Skris		}
152560573Skris	}
152660573Skris}
152760573Skris
152857429Smarkm/*
152957429Smarkm * Buffers the given amount of input characters.  This is intended to be used
153057429Smarkm * together with packet_read_poll.
153157429Smarkm */
153257429Smarkm
153357429Smarkmvoid
153476259Sgreenpacket_process_incoming(const char *buf, u_int len)
153557429Smarkm{
1536197679Sdes	if (active_state->packet_discard) {
1537197679Sdes		active_state->keep_alive_timeouts = 0; /* ?? */
1538197679Sdes		if (len >= active_state->packet_discard)
1539192595Sdes			packet_stop_discard();
1540197679Sdes		active_state->packet_discard -= len;
1541192595Sdes		return;
1542192595Sdes	}
1543197679Sdes	buffer_append(&active_state->input, buf, len);
154457429Smarkm}
154557429Smarkm
154657429Smarkm/* Returns a character from the packet. */
154757429Smarkm
154876259Sgreenu_int
154992555Sdespacket_get_char(void)
155057429Smarkm{
155157429Smarkm	char ch;
1552106121Sdes
1553197679Sdes	buffer_get(&active_state->incoming_packet, &ch, 1);
155476259Sgreen	return (u_char) ch;
155557429Smarkm}
155657429Smarkm
155757429Smarkm/* Returns an integer from the packet data. */
155857429Smarkm
155976259Sgreenu_int
156092555Sdespacket_get_int(void)
156157429Smarkm{
1562197679Sdes	return buffer_get_int(&active_state->incoming_packet);
156357429Smarkm}
156457429Smarkm
1565197679Sdes/* Returns an 64 bit integer from the packet data. */
1566197679Sdes
1567197679Sdesu_int64_t
1568197679Sdespacket_get_int64(void)
1569197679Sdes{
1570197679Sdes	return buffer_get_int64(&active_state->incoming_packet);
1571197679Sdes}
1572197679Sdes
157357429Smarkm/*
157457429Smarkm * Returns an arbitrary precision integer from the packet data.  The integer
157557429Smarkm * must have been initialized before this call.
157657429Smarkm */
157757429Smarkm
157857429Smarkmvoid
157992555Sdespacket_get_bignum(BIGNUM * value)
158057429Smarkm{
1581197679Sdes	buffer_get_bignum(&active_state->incoming_packet, value);
158257429Smarkm}
158357429Smarkm
158460573Skrisvoid
158592555Sdespacket_get_bignum2(BIGNUM * value)
158660573Skris{
1587197679Sdes	buffer_get_bignum2(&active_state->incoming_packet, value);
158860573Skris}
158960573Skris
1590221420Sdes#ifdef OPENSSL_HAS_ECC
1591221420Sdesvoid
1592221420Sdespacket_get_ecpoint(const EC_GROUP *curve, EC_POINT *point)
1593221420Sdes{
1594221420Sdes	buffer_get_ecpoint(&active_state->incoming_packet, curve, point);
1595221420Sdes}
1596221420Sdes#endif
1597221420Sdes
159892555Sdesvoid *
1599149749Sdespacket_get_raw(u_int *length_ptr)
160060573Skris{
1601197679Sdes	u_int bytes = buffer_len(&active_state->incoming_packet);
1602106121Sdes
160360573Skris	if (length_ptr != NULL)
160460573Skris		*length_ptr = bytes;
1605197679Sdes	return buffer_ptr(&active_state->incoming_packet);
160660573Skris}
160760573Skris
160860573Skrisint
160960573Skrispacket_remaining(void)
161060573Skris{
1611197679Sdes	return buffer_len(&active_state->incoming_packet);
161260573Skris}
161360573Skris
161457429Smarkm/*
161557429Smarkm * Returns a string from the packet data.  The string is allocated using
161657429Smarkm * xmalloc; it is the responsibility of the calling program to free it when
161757429Smarkm * no longer needed.  The length_ptr argument may be NULL, or point to an
161857429Smarkm * integer into which the length of the string is stored.
161957429Smarkm */
162057429Smarkm
162192555Sdesvoid *
162276259Sgreenpacket_get_string(u_int *length_ptr)
162357429Smarkm{
1624197679Sdes	return buffer_get_string(&active_state->incoming_packet, length_ptr);
162557429Smarkm}
162657429Smarkm
1627181111Sdesvoid *
1628181111Sdespacket_get_string_ptr(u_int *length_ptr)
1629181111Sdes{
1630197679Sdes	return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
1631181111Sdes}
1632181111Sdes
1633221420Sdes/* Ensures the returned string has no embedded \0 characters in it. */
1634221420Sdeschar *
1635221420Sdespacket_get_cstring(u_int *length_ptr)
1636221420Sdes{
1637221420Sdes	return buffer_get_cstring(&active_state->incoming_packet, length_ptr);
1638221420Sdes}
1639221420Sdes
164057429Smarkm/*
164157429Smarkm * Sends a diagnostic message from the server to the client.  This message
164257429Smarkm * can be sent at any time (but not while constructing another message). The
164357429Smarkm * message is printed immediately, but only if the client is being executed
164457429Smarkm * in verbose mode.  These messages are primarily intended to ease debugging
164557429Smarkm * authentication problems.   The length of the formatted message must not
164657429Smarkm * exceed 1024 bytes.  This will automatically call packet_write_wait.
164757429Smarkm */
164857429Smarkm
164957429Smarkmvoid
165057429Smarkmpacket_send_debug(const char *fmt,...)
165157429Smarkm{
165257429Smarkm	char buf[1024];
165357429Smarkm	va_list args;
165457429Smarkm
165576259Sgreen	if (compat20 && (datafellows & SSH_BUG_DEBUG))
165676259Sgreen		return;
165776259Sgreen
165857429Smarkm	va_start(args, fmt);
165957429Smarkm	vsnprintf(buf, sizeof(buf), fmt, args);
166057429Smarkm	va_end(args);
166157429Smarkm
166260573Skris	if (compat20) {
166360573Skris		packet_start(SSH2_MSG_DEBUG);
166460573Skris		packet_put_char(0);	/* bool: always display */
166560573Skris		packet_put_cstring(buf);
166660573Skris		packet_put_cstring("");
166760573Skris	} else {
166860573Skris		packet_start(SSH_MSG_DEBUG);
166960573Skris		packet_put_cstring(buf);
167060573Skris	}
167157429Smarkm	packet_send();
167257429Smarkm	packet_write_wait();
167357429Smarkm}
167457429Smarkm
167557429Smarkm/*
167657429Smarkm * Logs the error plus constructs and sends a disconnect packet, closes the
167757429Smarkm * connection, and exits.  This function never returns. The error message
167857429Smarkm * should not contain a newline.  The length of the formatted message must
167957429Smarkm * not exceed 1024 bytes.
168057429Smarkm */
168157429Smarkm
168257429Smarkmvoid
168357429Smarkmpacket_disconnect(const char *fmt,...)
168457429Smarkm{
168557429Smarkm	char buf[1024];
168657429Smarkm	va_list args;
168757429Smarkm	static int disconnecting = 0;
1688106121Sdes
168957429Smarkm	if (disconnecting)	/* Guard against recursive invocations. */
169057429Smarkm		fatal("packet_disconnect called recursively.");
169157429Smarkm	disconnecting = 1;
169257429Smarkm
169357429Smarkm	/*
169457429Smarkm	 * Format the message.  Note that the caller must make sure the
169557429Smarkm	 * message is of limited size.
169657429Smarkm	 */
169757429Smarkm	va_start(args, fmt);
169857429Smarkm	vsnprintf(buf, sizeof(buf), fmt, args);
169957429Smarkm	va_end(args);
170057429Smarkm
1701113908Sdes	/* Display the error locally */
1702124208Sdes	logit("Disconnecting: %.100s", buf);
1703113908Sdes
170457429Smarkm	/* Send the disconnect message to the other side, and wait for it to get sent. */
170560573Skris	if (compat20) {
170660573Skris		packet_start(SSH2_MSG_DISCONNECT);
170760573Skris		packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR);
170860573Skris		packet_put_cstring(buf);
170960573Skris		packet_put_cstring("");
171060573Skris	} else {
171160573Skris		packet_start(SSH_MSG_DISCONNECT);
171292555Sdes		packet_put_cstring(buf);
171360573Skris	}
171457429Smarkm	packet_send();
171557429Smarkm	packet_write_wait();
171657429Smarkm
171757429Smarkm	/* Stop listening for connections. */
171892555Sdes	channel_close_all();
171957429Smarkm
172057429Smarkm	/* Close the connection. */
172157429Smarkm	packet_close();
1722126274Sdes	cleanup_exit(255);
172357429Smarkm}
172457429Smarkm
172557429Smarkm/* Checks if there is any buffered output, and tries to write some of the output. */
172657429Smarkm
172757429Smarkmvoid
172892555Sdespacket_write_poll(void)
172957429Smarkm{
1730197679Sdes	int len = buffer_len(&active_state->output);
1731197679Sdes	int cont;
1732106121Sdes
173357429Smarkm	if (len > 0) {
1734197679Sdes		cont = 0;
1735197679Sdes		len = roaming_write(active_state->connection_out,
1736197679Sdes		    buffer_ptr(&active_state->output), len, &cont);
1737181111Sdes		if (len == -1) {
1738181111Sdes			if (errno == EINTR || errno == EAGAIN ||
1739181111Sdes			    errno == EWOULDBLOCK)
174057429Smarkm				return;
1741181111Sdes			fatal("Write failed: %.100s", strerror(errno));
174257429Smarkm		}
1743197679Sdes		if (len == 0 && !cont)
1744181111Sdes			fatal("Write connection closed");
1745197679Sdes		buffer_consume(&active_state->output, len);
174657429Smarkm	}
174757429Smarkm}
174857429Smarkm
174957429Smarkm/*
175057429Smarkm * Calls packet_write_poll repeatedly until all pending output data has been
175157429Smarkm * written.
175257429Smarkm */
175357429Smarkm
175457429Smarkmvoid
175592555Sdespacket_write_wait(void)
175657429Smarkm{
175776259Sgreen	fd_set *setp;
1758263970Sdes	int ret, ms_remain = 0;
1759181111Sdes	struct timeval start, timeout, *timeoutp = NULL;
176076259Sgreen
1761197679Sdes	setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
1762197679Sdes	    NFDBITS), sizeof(fd_mask));
176357429Smarkm	packet_write_poll();
176457429Smarkm	while (packet_have_data_to_write()) {
1765197679Sdes		memset(setp, 0, howmany(active_state->connection_out + 1,
1766197679Sdes		    NFDBITS) * sizeof(fd_mask));
1767197679Sdes		FD_SET(active_state->connection_out, setp);
1768181111Sdes
1769197679Sdes		if (active_state->packet_timeout_ms > 0) {
1770197679Sdes			ms_remain = active_state->packet_timeout_ms;
1771181111Sdes			timeoutp = &timeout;
1772181111Sdes		}
1773181111Sdes		for (;;) {
1774197679Sdes			if (active_state->packet_timeout_ms != -1) {
1775181111Sdes				ms_to_timeval(&timeout, ms_remain);
1776181111Sdes				gettimeofday(&start, NULL);
1777181111Sdes			}
1778197679Sdes			if ((ret = select(active_state->connection_out + 1,
1779197679Sdes			    NULL, setp, NULL, timeoutp)) >= 0)
1780181111Sdes				break;
1781197679Sdes			if (errno != EAGAIN && errno != EINTR &&
1782181111Sdes			    errno != EWOULDBLOCK)
1783181111Sdes				break;
1784197679Sdes			if (active_state->packet_timeout_ms == -1)
1785181111Sdes				continue;
1786181111Sdes			ms_subtract_diff(&start, &ms_remain);
1787181111Sdes			if (ms_remain <= 0) {
1788181111Sdes				ret = 0;
1789181111Sdes				break;
1790181111Sdes			}
1791181111Sdes		}
1792181111Sdes		if (ret == 0) {
1793181111Sdes			logit("Connection to %.200s timed out while "
1794181111Sdes			    "waiting to write", get_remote_ipaddr());
1795181111Sdes			cleanup_exit(255);
1796181111Sdes		}
179757429Smarkm		packet_write_poll();
179857429Smarkm	}
1799263970Sdes	free(setp);
180057429Smarkm}
180157429Smarkm
180257429Smarkm/* Returns true if there is buffered data to write to the connection. */
180357429Smarkm
180457429Smarkmint
180592555Sdespacket_have_data_to_write(void)
180657429Smarkm{
1807197679Sdes	return buffer_len(&active_state->output) != 0;
180857429Smarkm}
180957429Smarkm
181057429Smarkm/* Returns true if there is not too much data to write to the connection. */
181157429Smarkm
181257429Smarkmint
181392555Sdespacket_not_very_much_data_to_write(void)
181457429Smarkm{
1815197679Sdes	if (active_state->interactive_mode)
1816197679Sdes		return buffer_len(&active_state->output) < 16384;
181757429Smarkm	else
1818197679Sdes		return buffer_len(&active_state->output) < 128 * 1024;
181957429Smarkm}
182057429Smarkm
1821113908Sdesstatic void
1822221420Sdespacket_set_tos(int tos)
1823113908Sdes{
1824247485Sdes#ifndef IP_TOS_IS_BROKEN
1825247485Sdes	if (!packet_connection_is_on_socket())
1826113908Sdes		return;
1827247485Sdes	switch (packet_connection_af()) {
1828247485Sdes# ifdef IP_TOS
1829247485Sdes	case AF_INET:
1830247485Sdes		debug3("%s: set IP_TOS 0x%02x", __func__, tos);
1831247485Sdes		if (setsockopt(active_state->connection_in,
1832247485Sdes		    IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
1833247485Sdes			error("setsockopt IP_TOS %d: %.100s:",
1834247485Sdes			    tos, strerror(errno));
1835247485Sdes		break;
1836247485Sdes# endif /* IP_TOS */
1837247485Sdes# ifdef IPV6_TCLASS
1838247485Sdes	case AF_INET6:
1839247485Sdes		debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos);
1840247485Sdes		if (setsockopt(active_state->connection_in,
1841247485Sdes		    IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0)
1842247485Sdes			error("setsockopt IPV6_TCLASS %d: %.100s:",
1843247485Sdes			    tos, strerror(errno));
1844247485Sdes		break;
1845247485Sdes# endif /* IPV6_TCLASS */
1846247485Sdes	}
1847247485Sdes#endif /* IP_TOS_IS_BROKEN */
1848113908Sdes}
1849113908Sdes
185057429Smarkm/* Informs that the current session is interactive.  Sets IP flags for that. */
185157429Smarkm
185257429Smarkmvoid
1853221420Sdespacket_set_interactive(int interactive, int qos_interactive, int qos_bulk)
185457429Smarkm{
1855197679Sdes	if (active_state->set_interactive_called)
185676259Sgreen		return;
1857197679Sdes	active_state->set_interactive_called = 1;
185876259Sgreen
185957429Smarkm	/* Record that we are in interactive mode. */
1860197679Sdes	active_state->interactive_mode = interactive;
186157429Smarkm
186257429Smarkm	/* Only set socket options if using a socket.  */
186357429Smarkm	if (!packet_connection_is_on_socket())
1864116791Sdes		return;
1865197679Sdes	set_nodelay(active_state->connection_in);
1866221420Sdes	packet_set_tos(interactive ? qos_interactive : qos_bulk);
186757429Smarkm}
186857429Smarkm
186957429Smarkm/* Returns true if the current connection is interactive. */
187057429Smarkm
187157429Smarkmint
187292555Sdespacket_is_interactive(void)
187357429Smarkm{
1874197679Sdes	return active_state->interactive_mode;
187557429Smarkm}
187657429Smarkm
1877137015Sdesint
1878124208Sdespacket_set_maxsize(u_int s)
187957429Smarkm{
1880197679Sdes	if (active_state->set_maxsize_called) {
1881124208Sdes		logit("packet_set_maxsize: called twice: old %d new %d",
1882197679Sdes		    active_state->max_packet_size, s);
188357429Smarkm		return -1;
188457429Smarkm	}
188557429Smarkm	if (s < 4 * 1024 || s > 1024 * 1024) {
1886124208Sdes		logit("packet_set_maxsize: bad size %d", s);
188757429Smarkm		return -1;
188857429Smarkm	}
1889197679Sdes	active_state->set_maxsize_called = 1;
189092555Sdes	debug("packet_set_maxsize: setting to %d", s);
1891197679Sdes	active_state->max_packet_size = s;
189257429Smarkm	return s;
189357429Smarkm}
189476259Sgreen
1895197679Sdesint
1896197679Sdespacket_inc_alive_timeouts(void)
1897197679Sdes{
1898197679Sdes	return ++active_state->keep_alive_timeouts;
1899197679Sdes}
1900197679Sdes
1901197679Sdesvoid
1902197679Sdespacket_set_alive_timeouts(int ka)
1903197679Sdes{
1904197679Sdes	active_state->keep_alive_timeouts = ka;
1905197679Sdes}
1906197679Sdes
1907197679Sdesu_int
1908197679Sdespacket_get_maxsize(void)
1909197679Sdes{
1910197679Sdes	return active_state->max_packet_size;
1911197679Sdes}
1912197679Sdes
191392555Sdes/* roundup current message to pad bytes */
191492555Sdesvoid
191592555Sdespacket_add_padding(u_char pad)
191692555Sdes{
1917197679Sdes	active_state->extra_pad = pad;
191892555Sdes}
191992555Sdes
192076259Sgreen/*
192176259Sgreen * 9.2.  Ignored Data Message
192276259Sgreen *
192376259Sgreen *   byte      SSH_MSG_IGNORE
192476259Sgreen *   string    data
192576259Sgreen *
192676259Sgreen * All implementations MUST understand (and ignore) this message at any
192776259Sgreen * time (after receiving the protocol version). No implementation is
192876259Sgreen * required to send them. This message can be used as an additional
192976259Sgreen * protection measure against advanced traffic analysis techniques.
193076259Sgreen */
193176259Sgreenvoid
193276259Sgreenpacket_send_ignore(int nbytes)
193376259Sgreen{
1934137015Sdes	u_int32_t rnd = 0;
193576259Sgreen	int i;
193676259Sgreen
193776259Sgreen	packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE);
193876259Sgreen	packet_put_int(nbytes);
193992555Sdes	for (i = 0; i < nbytes; i++) {
194076259Sgreen		if (i % 4 == 0)
1941137015Sdes			rnd = arc4random();
1942162852Sdes		packet_put_char((u_char)rnd & 0xff);
1943137015Sdes		rnd >>= 8;
194476259Sgreen	}
194576259Sgreen}
1946124208Sdes
1947224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
1948224638Sbrooksvoid
1949224638Sbrookspacket_request_rekeying(void)
1950224638Sbrooks{
1951224638Sbrooks	rekey_requested = 1;
1952224638Sbrooks}
1953224638Sbrooks#endif
1954224638Sbrooks
1955137015Sdes#define MAX_PACKETS	(1U<<31)
1956124208Sdesint
1957124208Sdespacket_need_rekeying(void)
1958124208Sdes{
1959124208Sdes	if (datafellows & SSH_BUG_NOREKEY)
1960124208Sdes		return 0;
1961224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
1962224638Sbrooks	if (rekey_requested == 1) {
1963224638Sbrooks		rekey_requested = 0;
1964224638Sbrooks		return 1;
1965224638Sbrooks	}
1966224638Sbrooks#endif
1967124208Sdes	return
1968197679Sdes	    (active_state->p_send.packets > MAX_PACKETS) ||
1969197679Sdes	    (active_state->p_read.packets > MAX_PACKETS) ||
1970197679Sdes	    (active_state->max_blocks_out &&
1971197679Sdes	        (active_state->p_send.blocks > active_state->max_blocks_out)) ||
1972197679Sdes	    (active_state->max_blocks_in &&
1973263970Sdes	        (active_state->p_read.blocks > active_state->max_blocks_in)) ||
1974263970Sdes	    (active_state->rekey_interval != 0 && active_state->rekey_time +
1975263970Sdes		 active_state->rekey_interval <= monotime());
1976124208Sdes}
1977124208Sdes
1978124208Sdesvoid
1979263970Sdespacket_set_rekey_limits(u_int32_t bytes, time_t seconds)
1980124208Sdes{
1981263970Sdes	debug3("rekey after %lld bytes, %d seconds", (long long)bytes,
1982263970Sdes	    (int)seconds);
1983197679Sdes	active_state->rekey_limit = bytes;
1984263970Sdes	active_state->rekey_interval = seconds;
1985263970Sdes	/*
1986263970Sdes	 * We set the time here so that in post-auth privsep slave we count
1987263970Sdes	 * from the completion of the authentication.
1988263970Sdes	 */
1989263970Sdes	active_state->rekey_time = monotime();
1990124208Sdes}
1991149749Sdes
1992263970Sdestime_t
1993263970Sdespacket_get_rekey_timeout(void)
1994263970Sdes{
1995263970Sdes	time_t seconds;
1996263970Sdes
1997263970Sdes	seconds = active_state->rekey_time + active_state->rekey_interval -
1998263970Sdes	    monotime();
1999263970Sdes	return (seconds <= 0 ? 1 : seconds);
2000263970Sdes}
2001263970Sdes
2002149749Sdesvoid
2003149749Sdespacket_set_server(void)
2004149749Sdes{
2005197679Sdes	active_state->server_side = 1;
2006149749Sdes}
2007149749Sdes
2008149749Sdesvoid
2009149749Sdespacket_set_authenticated(void)
2010149749Sdes{
2011197679Sdes	active_state->after_authentication = 1;
2012149749Sdes}
2013197679Sdes
2014197679Sdesvoid *
2015197679Sdespacket_get_input(void)
2016197679Sdes{
2017197679Sdes	return (void *)&active_state->input;
2018197679Sdes}
2019197679Sdes
2020197679Sdesvoid *
2021197679Sdespacket_get_output(void)
2022197679Sdes{
2023197679Sdes	return (void *)&active_state->output;
2024197679Sdes}
2025197679Sdes
2026197679Sdesvoid *
2027197679Sdespacket_get_newkeys(int mode)
2028197679Sdes{
2029197679Sdes	return (void *)active_state->newkeys[mode];
2030197679Sdes}
2031197679Sdes
2032197679Sdes/*
2033197679Sdes * Save the state for the real connection, and use a separate state when
2034197679Sdes * resuming a suspended connection.
2035197679Sdes */
2036197679Sdesvoid
2037197679Sdespacket_backup_state(void)
2038197679Sdes{
2039197679Sdes	struct session_state *tmp;
2040197679Sdes
2041197679Sdes	close(active_state->connection_in);
2042197679Sdes	active_state->connection_in = -1;
2043197679Sdes	close(active_state->connection_out);
2044197679Sdes	active_state->connection_out = -1;
2045197679Sdes	if (backup_state)
2046197679Sdes		tmp = backup_state;
2047197679Sdes	else
2048197679Sdes		tmp = alloc_session_state();
2049197679Sdes	backup_state = active_state;
2050197679Sdes	active_state = tmp;
2051197679Sdes}
2052197679Sdes
2053197679Sdes/*
2054197679Sdes * Swap in the old state when resuming a connecion.
2055197679Sdes */
2056197679Sdesvoid
2057197679Sdespacket_restore_state(void)
2058197679Sdes{
2059197679Sdes	struct session_state *tmp;
2060197679Sdes	void *buf;
2061197679Sdes	u_int len;
2062197679Sdes
2063197679Sdes	tmp = backup_state;
2064197679Sdes	backup_state = active_state;
2065197679Sdes	active_state = tmp;
2066197679Sdes	active_state->connection_in = backup_state->connection_in;
2067197679Sdes	backup_state->connection_in = -1;
2068197679Sdes	active_state->connection_out = backup_state->connection_out;
2069197679Sdes	backup_state->connection_out = -1;
2070197679Sdes	len = buffer_len(&backup_state->input);
2071197679Sdes	if (len > 0) {
2072197679Sdes		buf = buffer_ptr(&backup_state->input);
2073197679Sdes		buffer_append(&active_state->input, buf, len);
2074197679Sdes		buffer_clear(&backup_state->input);
2075197679Sdes		add_recv_bytes(len);
2076197679Sdes	}
2077197679Sdes}
2078224638Sbrooks
2079224638Sbrooks#ifdef	NONE_CIPHER_ENABLED
2080224638Sbrooksint
2081224638Sbrookspacket_get_authentication_state(void)
2082224638Sbrooks{
2083224638Sbrooks	return (active_state->after_authentication);
2084224638Sbrooks}
2085224638Sbrooks#endif
2086