11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: packet.c,v 1.173 2011/05/06 21:14:05 djm Exp $ */
21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Author: Tatu Ylonen <ylo@cs.hut.fi>
41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *                    All rights reserved
61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This file contains code implementing the packet protocol and communication
71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * with the other side.  This same code is used both on client and server side.
81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * As far as I am concerned, the code I have written for this software
101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be used freely for any purpose.  Any derived versions of this
111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * software must be clearly marked as such, and if the derived work is
121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * incompatible with the protocol description in the RFC file, it must be
131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * called by a name other than "ssh" or "Secure Shell".
141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH2 packet format added by Markus Friedl.
171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without
201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions
211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met:
221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright
231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer.
241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright
251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    notice, this list of conditions and the following disclaimer in the
261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *    documentation and/or other materials provided with the distribution.
271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h"
411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h>
431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "openbsd-compat/sys-queue.h"
441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h>
451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h>
461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_SYS_TIME_H
471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <sys/time.h>
481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/in.h>
511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/ip.h>
521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <arpa/inet.h>
531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h>
551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h>
561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h>
571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h>
581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h>
591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h>
601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h>
611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h"
631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h"
641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h"
651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "crc32.h"
661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "compress.h"
671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "deattack.h"
681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "channels.h"
691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "compat.h"
701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh1.h"
711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h"
721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h"
731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h"
741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h"
751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "mac.h"
761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h"
771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "canohost.h"
781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h"
791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh.h"
801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "roaming.h"
811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DBG(x) x
841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else
851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DBG(x)
861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define PACKET_MAX_SIZE (256 * 1024)
891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct packet_state {
911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int32_t seqnr;
921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int32_t packets;
931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int64_t blocks;
941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int64_t bytes;
951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood};
961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct packet {
981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	TAILQ_ENTRY(packet) next;
991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char type;
1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Buffer payload;
1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood};
1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct session_state {
1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * This variable contains the file descriptors used for
1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * communicating with the other side.  connection_in is used for
1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * reading; connection_out for writing.  These can be the same
1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * descriptor, in which case it is assumed to be a socket.
1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int connection_in;
1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int connection_out;
1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Protocol flags for the remote side. */
1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int remote_protocol_flags;
1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Encryption context for receiving data.  Only used for decryption. */
1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	CipherContext receive_context;
1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Encryption context for sending data.  Only used for encryption. */
1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	CipherContext send_context;
1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Buffer for raw input data from the socket. */
1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Buffer input;
1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Buffer for raw output data going to the socket. */
1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Buffer output;
1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Buffer for the partial outgoing packet being constructed. */
1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Buffer outgoing_packet;
1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Buffer for the incoming packet currently being processed. */
1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Buffer incoming_packet;
1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Scratch buffer for packet compression/decompression. */
1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Buffer compression_buffer;
1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int compression_buffer_ready;
1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Flag indicating whether packet compression/decompression is
1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * enabled.
1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int packet_compression;
1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* default maximum packet size */
1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int max_packet_size;
1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Flag indicating whether this module has been initialized. */
1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int initialized;
1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Set to true if the connection is interactive. */
1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int interactive_mode;
1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Set to true if we are the server side. */
1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int server_side;
1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Set to true if we are authenticated. */
1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int after_authentication;
1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int keep_alive_timeouts;
1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* The maximum time that we will wait to send or receive a packet */
1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int packet_timeout_ms;
1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Session key information for Encryption and MAC */
1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Newkeys *newkeys[MODE_MAX];
1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct packet_state p_read, p_send;
1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int64_t max_blocks_in, max_blocks_out;
1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int32_t rekey_limit;
1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Session key for protocol v1 */
1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int ssh1_keylen;
1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* roundup current message to extra_pad bytes */
1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char extra_pad;
1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* XXX discard incoming data after MAC error */
1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int packet_discard;
1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Mac *packet_discard_mac;
1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Used in packet_read_poll2() */
1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int packlen;
1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Used in packet_send2 */
1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int rekeying;
1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Used in packet_set_interactive */
1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int set_interactive_called;
1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Used in packet_set_maxsize */
1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int set_maxsize_called;
1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	TAILQ_HEAD(, packet) outgoing;
1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood};
1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic struct session_state *active_state, *backup_state;
1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic struct session_state *
2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodalloc_session_state(void)
2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct session_state *s = xcalloc(1, sizeof(*s));
2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	s->connection_in = -1;
2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	s->connection_out = -1;
2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	s->max_packet_size = 32768;
2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	s->packet_timeout_ms = -1;
2081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return s;
2091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Sets the descriptors used for communication.  Disables encryption until
2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * packet_set_encryption_key is called.
2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_connection(int fd_in, int fd_out)
2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Cipher *none = cipher_by_name("none");
2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (none == NULL)
2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("packet_set_connection: cannot load cipher 'none'");
2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state == NULL)
2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state = alloc_session_state();
2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->connection_in = fd_in;
2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->connection_out = fd_out;
2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_init(&active_state->send_context, none, (const u_char *)"",
2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    0, NULL, 0, CIPHER_ENCRYPT);
2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_init(&active_state->receive_context, none, (const u_char *)"",
2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    0, NULL, 0, CIPHER_DECRYPT);
2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL;
2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!active_state->initialized) {
2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->initialized = 1;
2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_init(&active_state->input);
2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_init(&active_state->output);
2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_init(&active_state->outgoing_packet);
2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_init(&active_state->incoming_packet);
2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		TAILQ_INIT(&active_state->outgoing);
2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->p_send.packets = active_state->p_read.packets = 0;
2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_timeout(int timeout, int count)
2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (timeout == 0 || count == 0) {
2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->packet_timeout_ms = -1;
2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((INT_MAX / 1000) / count < timeout)
2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->packet_timeout_ms = INT_MAX;
2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->packet_timeout_ms = timeout * count * 1000;
2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_stop_discard(void)
2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->packet_discard_mac) {
2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		char buf[1024];
2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memset(buf, 'a', sizeof(buf));
2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		while (buffer_len(&active_state->incoming_packet) <
2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    PACKET_MAX_SIZE)
2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			buffer_append(&active_state->incoming_packet, buf,
2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    sizeof(buf));
2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		(void) mac_compute(active_state->packet_discard_mac,
2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    active_state->p_read.seqnr,
2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->incoming_packet),
2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    PACKET_MAX_SIZE);
2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	logit("Finished discarding for %.200s", get_remote_ipaddr());
2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cleanup_exit(255);
2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard)
2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (enc == NULL || !cipher_is_cbc(enc->cipher))
2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Packet corrupt");
2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled)
2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->packet_discard_mac = mac;
2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (buffer_len(&active_state->input) >= discard)
2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_stop_discard();
2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->packet_discard = discard -
2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->input);
2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns 1 if remote host is connected via socket, 0 if not. */
2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_connection_is_on_socket(void)
2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct sockaddr_storage from, to;
2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	socklen_t fromlen, tolen;
2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* filedescriptors in and out are the same, so it's a socket */
2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->connection_in == active_state->connection_out)
2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 1;
2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fromlen = sizeof(from);
3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(&from, 0, sizeof(from));
3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getpeername(active_state->connection_in, (struct sockaddr *)&from,
3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    &fromlen) < 0)
3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	tolen = sizeof(to);
3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(&to, 0, sizeof(to));
3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getpeername(active_state->connection_out, (struct sockaddr *)&to,
3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    &tolen) < 0)
3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return 1;
3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Exports an IV from the CipherContext required to export the key
3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * state back from the unprivileged child to the privileged parent
3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * process.
3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_keyiv(int mode, u_char *iv, u_int len)
3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	CipherContext *cc;
3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mode == MODE_OUT)
3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->send_context;
3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->receive_context;
3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_get_keyiv(cc, iv, len);
3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_keycontext(int mode, u_char *dat)
3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	CipherContext *cc;
3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mode == MODE_OUT)
3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->send_context;
3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->receive_context;
3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (cipher_get_keycontext(cc, dat));
3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_keycontext(int mode, u_char *dat)
3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	CipherContext *cc;
3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mode == MODE_OUT)
3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->send_context;
3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->receive_context;
3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_set_keycontext(cc, dat);
3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_keyiv_len(int mode)
3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	CipherContext *cc;
3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mode == MODE_OUT)
3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->send_context;
3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->receive_context;
3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (cipher_get_keyiv_len(cc));
3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_iv(int mode, u_char *dat)
3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	CipherContext *cc;
3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mode == MODE_OUT)
3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->send_context;
3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->receive_context;
3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_set_keyiv(cc, dat);
3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_ssh1_cipher(void)
3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (cipher_get_number(active_state->receive_context.cipher));
3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks,
3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    u_int32_t *packets, u_int64_t *bytes)
3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct packet_state *state;
3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	state = (mode == MODE_IN) ?
4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    &active_state->p_read : &active_state->p_send;
4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (seqnr)
4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*seqnr = state->seqnr;
4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (blocks)
4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*blocks = state->blocks;
4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (packets)
4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*packets = state->packets;
4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (bytes)
4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*bytes = state->bytes;
4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets,
4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood    u_int64_t bytes)
4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct packet_state *state;
4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	state = (mode == MODE_IN) ?
4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    &active_state->p_read : &active_state->p_send;
4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	state->seqnr = seqnr;
4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	state->blocks = blocks;
4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	state->packets = packets;
4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	state->bytes = bytes;
4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_connection_af(void)
4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct sockaddr_storage to;
4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	socklen_t tolen = sizeof(to);
4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(&to, 0, sizeof(to));
4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (getsockname(active_state->connection_out, (struct sockaddr *)&to,
4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    &tolen) < 0)
4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (to.ss_family == AF_INET)
4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 1;
4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef IPV4_IN_IPV6
4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (to.ss_family == AF_INET6 &&
4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))
4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return AF_INET;
4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return to.ss_family;
4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Sets the connection into non-blocking mode. */
4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_nonblocking(void)
4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Set the socket into non-blocking mode. */
4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	set_nonblock(active_state->connection_in);
4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->connection_out != active_state->connection_in)
4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		set_nonblock(active_state->connection_out);
4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns the socket used for reading. */
4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_connection_in(void)
4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return active_state->connection_in;
4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns the descriptor used for writing. */
4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_connection_out(void)
4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return active_state->connection_out;
4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Closes the connection and clears and frees internal data structures. */
4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_close(void)
4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!active_state->initialized)
4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->initialized = 0;
4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->connection_in == active_state->connection_out) {
4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		shutdown(active_state->connection_out, SHUT_RDWR);
4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		close(active_state->connection_out);
4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		close(active_state->connection_in);
4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		close(active_state->connection_out);
4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_free(&active_state->input);
4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_free(&active_state->output);
4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_free(&active_state->outgoing_packet);
4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_free(&active_state->incoming_packet);
4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->compression_buffer_ready) {
4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_free(&active_state->compression_buffer);
4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_compress_uninit();
4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_cleanup(&active_state->send_context);
4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_cleanup(&active_state->receive_context);
4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Sets remote side protocol flags. */
5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_protocol_flags(u_int protocol_flags)
5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->remote_protocol_flags = protocol_flags;
5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns the remote protocol flags set earlier by the above function. */
5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int
5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_protocol_flags(void)
5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return active_state->remote_protocol_flags;
5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Starts packet compression from the next packet on in both directions.
5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip.
5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_init_compression(void)
5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->compression_buffer_ready == 1)
5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->compression_buffer_ready = 1;
5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_init(&active_state->compression_buffer);
5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_start_compression(int level)
5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->packet_compression && !compat20)
5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("Compression already enabled.");
5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->packet_compression = 1;
5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_init_compression();
5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_compress_init_send(level);
5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_compress_init_recv();
5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Causes any further packets to be encrypted using the given key.  The same
5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * key is used for both sending and reception.  However, both directions are
5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * encrypted independently of each other.
5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_encryption_key(const u_char *key, u_int keylen, int number)
5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Cipher *cipher = cipher_by_number(number);
5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (cipher == NULL)
5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("packet_set_encryption_key: unknown cipher number %d", number);
5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (keylen < 20)
5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("packet_set_encryption_key: keylen too small: %d", keylen);
5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (keylen > SSH_SESSION_KEY_LENGTH)
5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("packet_set_encryption_key: keylen too big: %d", keylen);
5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memcpy(active_state->ssh1_key, key, keylen);
5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->ssh1_keylen = keylen;
5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_init(&active_state->send_context, cipher, key, keylen, NULL,
5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    0, CIPHER_ENCRYPT);
5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_init(&active_state->receive_context, cipher, key, keylen, NULL,
5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    0, CIPHER_DECRYPT);
5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int
5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_encryption_key(u_char *key)
5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (key == NULL)
5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return (active_state->ssh1_keylen);
5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen);
5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (active_state->ssh1_keylen);
5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Start constructing a packet to send. */
5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_start(u_char type)
5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char buf[9];
5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int len;
5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DBG(debug("packet_start[%d]", type));
5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	len = compat20 ? 6 : 9;
5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	memset(buf, 0, len - 1);
5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buf[len - 1] = type;
5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_clear(&active_state->outgoing_packet);
5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_append(&active_state->outgoing_packet, buf, len);
5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Append payload. */
5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_char(int value)
5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char ch = value;
5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_append(&active_state->outgoing_packet, &ch, 1);
5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_int(u_int value)
6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_int(&active_state->outgoing_packet, value);
6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_int64(u_int64_t value)
6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_int64(&active_state->outgoing_packet, value);
6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_string(const void *buf, u_int len)
6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_string(&active_state->outgoing_packet, buf, len);
6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_cstring(const char *str)
6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_cstring(&active_state->outgoing_packet, str);
6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_raw(const void *buf, u_int len)
6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_append(&active_state->outgoing_packet, buf, len);
6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_bignum(BIGNUM * value)
6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_bignum(&active_state->outgoing_packet, value);
6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_bignum2(BIGNUM * value)
6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_bignum2(&active_state->outgoing_packet, value);
6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC
6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point)
6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_put_ecpoint(&active_state->outgoing_packet, curve, point);
6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Finalizes and sends the packet.  If the encryption key has been set,
6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * encrypts the packet before sending.
6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_send1(void)
6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char buf[8], *cp;
6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i, padding, len;
6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int checksum;
6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int32_t rnd = 0;
6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * If using packet compression, compress the payload of the outgoing
6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * packet.
6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->packet_compression) {
6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->compression_buffer);
6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Skip padding. */
6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_consume(&active_state->outgoing_packet, 8);
6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* padding */
6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&active_state->compression_buffer,
6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    "\0\0\0\0\0\0\0\0", 8);
6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_compress(&active_state->outgoing_packet,
6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    &active_state->compression_buffer);
6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->outgoing_packet);
6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&active_state->outgoing_packet,
6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->compression_buffer),
6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_len(&active_state->compression_buffer));
6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Compute packet length without padding (add checksum, remove padding). */
6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	len = buffer_len(&active_state->outgoing_packet) + 4 - 8;
6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Insert padding. Initialized to zero in packet_start1() */
6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	padding = 8 - len % 8;
6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!active_state->send_context.plaintext) {
6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cp = buffer_ptr(&active_state->outgoing_packet);
6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < padding; i++) {
6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (i % 4 == 0)
6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				rnd = arc4random();
6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			cp[7 - i] = rnd & 0xff;
6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			rnd >>= 8;
6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_consume(&active_state->outgoing_packet, 8 - padding);
6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Add check bytes. */
6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet),
6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->outgoing_packet));
6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	put_u32(buf, checksum);
7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_append(&active_state->outgoing_packet, buf, 4);
7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fprintf(stderr, "packet_send plain: ");
7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_dump(&active_state->outgoing_packet);
7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Append to output. */
7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	put_u32(buf, len);
7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_append(&active_state->output, buf, 4);
7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_append_space(&active_state->output,
7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->outgoing_packet));
7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_crypt(&active_state->send_context, cp,
7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_ptr(&active_state->outgoing_packet),
7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->outgoing_packet));
7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fprintf(stderr, "encrypted: ");
7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_dump(&active_state->output);
7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->p_send.packets++;
7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->p_send.bytes += len +
7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->outgoing_packet);
7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_clear(&active_state->outgoing_packet);
7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Note that the packet is now only buffered in output.  It won't be
7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * actually sent until packet_write_wait or packet_write_poll is
7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * called.
7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodset_newkeys(int mode)
7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Enc *enc;
7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Mac *mac;
7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Comp *comp;
7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	CipherContext *cc;
7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int64_t *max_blocks;
7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int crypt_type;
7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug2("set_newkeys: mode %d", mode);
7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mode == MODE_OUT) {
7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->send_context;
7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		crypt_type = CIPHER_ENCRYPT;
7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->p_send.packets = active_state->p_send.blocks = 0;
7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		max_blocks = &active_state->max_blocks_out;
7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cc = &active_state->receive_context;
7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		crypt_type = CIPHER_DECRYPT;
7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->p_read.packets = active_state->p_read.blocks = 0;
7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		max_blocks = &active_state->max_blocks_in;
7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->newkeys[mode] != NULL) {
7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug("set_newkeys: rekeying");
7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cipher_cleanup(cc);
7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		enc  = &active_state->newkeys[mode]->enc;
7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		mac  = &active_state->newkeys[mode]->mac;
7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		comp = &active_state->newkeys[mode]->comp;
7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		mac_clear(mac);
7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(enc->name);
7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(enc->iv);
7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(enc->key);
7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(mac->name);
7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(mac->key);
7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(comp->name);
7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		xfree(active_state->newkeys[mode]);
7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->newkeys[mode] = kex_get_newkeys(mode);
7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->newkeys[mode] == NULL)
7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("newkeys: no keys for mode %d", mode);
7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	enc  = &active_state->newkeys[mode]->enc;
7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	mac  = &active_state->newkeys[mode]->mac;
7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	comp = &active_state->newkeys[mode]->comp;
7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mac_init(mac) == 0)
7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		mac->enabled = 1;
7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DBG(debug("cipher_init_context: %d", mode));
7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_init(cc, enc->cipher, enc->key, enc->key_len,
7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    enc->iv, enc->block_size, crypt_type);
7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Deleting the keys does not gain extra security */
7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* memset(enc->iv,  0, enc->block_size);
7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	   memset(enc->key, 0, enc->key_len);
7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	   memset(mac->key, 0, mac->key_len); */
7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if ((comp->type == COMP_ZLIB ||
7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (comp->type == COMP_DELAYED &&
7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	     active_state->after_authentication)) && comp->enabled == 0) {
7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_init_compression();
7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (mode == MODE_OUT)
7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			buffer_compress_init_send(6);
7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		else
7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			buffer_compress_init_recv();
7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		comp->enabled = 1;
7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * The 2^(blocksize*2) limit is too expensive for 3DES,
7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * blowfish, etc, so enforce a 1GB limit for small blocksizes.
7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (enc->block_size >= 16)
8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*max_blocks = (u_int64_t)1 << (enc->block_size*2);
8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*max_blocks = ((u_int64_t)1 << 30) / enc->block_size;
8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->rekey_limit)
8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*max_blocks = MIN(*max_blocks,
8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    active_state->rekey_limit / enc->block_size);
8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Delayed compression for SSH2 is enabled after authentication:
8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent,
8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received.
8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_enable_delayed_compress(void)
8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Comp *comp = NULL;
8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int mode;
8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Remember that we are past the authentication step, so rekeying
8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * with COMP_DELAYED will turn on compression immediately.
8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->after_authentication = 1;
8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (mode = 0; mode < MODE_MAX; mode++) {
8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* protocol error: USERAUTH_SUCCESS received before NEWKEYS */
8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (active_state->newkeys[mode] == NULL)
8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			continue;
8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		comp = &active_state->newkeys[mode]->comp;
8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (comp && !comp->enabled && comp->type == COMP_DELAYED) {
8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_init_compression();
8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (mode == MODE_OUT)
8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				buffer_compress_init_send(6);
8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			else
8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				buffer_compress_init_recv();
8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			comp->enabled = 1;
8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_send2_wrapped(void)
8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char type, *cp, *macbuf = NULL;
8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char padlen, pad;
8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int packet_length = 0;
8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int i, len;
8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int32_t rnd = 0;
8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Enc *enc   = NULL;
8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Mac *mac   = NULL;
8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Comp *comp = NULL;
8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int block_size;
8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->newkeys[MODE_OUT] != NULL) {
8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		enc  = &active_state->newkeys[MODE_OUT]->enc;
8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		mac  = &active_state->newkeys[MODE_OUT]->mac;
8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		comp = &active_state->newkeys[MODE_OUT]->comp;
8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	block_size = enc ? enc->block_size : 8;
8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_ptr(&active_state->outgoing_packet);
8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = cp[5];
8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fprintf(stderr, "plain:     ");
8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_dump(&active_state->outgoing_packet);
8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (comp && comp->enabled) {
8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		len = buffer_len(&active_state->outgoing_packet);
8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* skip header, compress only payload */
8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_consume(&active_state->outgoing_packet, 5);
8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->compression_buffer);
8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_compress(&active_state->outgoing_packet,
8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    &active_state->compression_buffer);
8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->outgoing_packet);
8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5);
8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&active_state->outgoing_packet,
8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->compression_buffer),
8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_len(&active_state->compression_buffer));
8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		DBG(debug("compression: raw %d compressed %d", len,
8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_len(&active_state->outgoing_packet)));
8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* sizeof (packet_len + pad_len + payload) */
8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	len = buffer_len(&active_state->outgoing_packet);
8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * calc size of padding, alloc space, get random data,
8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * minimum padding is 4 bytes
8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	padlen = block_size - (len % block_size);
8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (padlen < 4)
8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		padlen += block_size;
8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->extra_pad) {
8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* will wrap if extra_pad+padlen > 255 */
8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->extra_pad =
9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    roundup(active_state->extra_pad, block_size);
9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		pad = active_state->extra_pad -
9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    ((len + padlen) % active_state->extra_pad);
9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    pad, len, padlen, active_state->extra_pad);
9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		padlen += pad;
9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->extra_pad = 0;
9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_append_space(&active_state->outgoing_packet, padlen);
9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (enc && !active_state->send_context.plaintext) {
9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* random padding */
9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (i = 0; i < padlen; i++) {
9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (i % 4 == 0)
9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				rnd = arc4random();
9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			cp[i] = rnd & 0xff;
9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			rnd >>= 8;
9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* clear padding */
9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memset(cp, 0, padlen);
9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* packet_length includes payload, padding and padding length field */
9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_length = buffer_len(&active_state->outgoing_packet) - 4;
9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_ptr(&active_state->outgoing_packet);
9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	put_u32(cp, packet_length);
9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp[4] = padlen;
9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* compute MAC over seqnr and packet(length fields, payload, padding) */
9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mac && mac->enabled) {
9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		macbuf = mac_compute(mac, active_state->p_send.seqnr,
9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->outgoing_packet),
9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_len(&active_state->outgoing_packet));
9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr));
9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* encrypt packet and append to output buffer. */
9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_append_space(&active_state->output,
9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->outgoing_packet));
9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_crypt(&active_state->send_context, cp,
9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_ptr(&active_state->outgoing_packet),
9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->outgoing_packet));
9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* append unencrypted MAC */
9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mac && mac->enabled)
9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&active_state->output, macbuf, mac->mac_len);
9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fprintf(stderr, "encrypted: ");
9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_dump(&active_state->output);
9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* increment sequence number for outgoing packets */
9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (++active_state->p_send.seqnr == 0)
9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("outgoing seqnr wraps around");
9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (++active_state->p_send.packets == 0)
9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!(datafellows & SSH_BUG_NOREKEY))
9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("XXX too many packets with same key");
9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->p_send.blocks += (packet_length + 4) / block_size;
9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->p_send.bytes += packet_length + 4;
9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_clear(&active_state->outgoing_packet);
9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH2_MSG_NEWKEYS)
9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		set_newkeys(MODE_OUT);
9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side)
9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_enable_delayed_compress();
9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_send2(void)
9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct packet *p;
9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char type, *cp;
9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_ptr(&active_state->outgoing_packet);
9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = cp[5];
9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* during rekeying we can only send key exchange messages */
9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->rekeying) {
9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!((type >= SSH2_MSG_TRANSPORT_MIN) &&
9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    (type <= SSH2_MSG_TRANSPORT_MAX))) {
9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug("enqueue packet: %u", type);
9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			p = xmalloc(sizeof(*p));
9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			p->type = type;
9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			memcpy(&p->payload, &active_state->outgoing_packet,
9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    sizeof(Buffer));
9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			buffer_init(&active_state->outgoing_packet);
9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			TAILQ_INSERT_TAIL(&active_state->outgoing, p, next);
9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return;
9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* rekeying starts with sending KEXINIT */
9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH2_MSG_KEXINIT)
9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->rekeying = 1;
9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_send2_wrapped();
9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* after a NEWKEYS message we can send the complete queue */
9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH2_MSG_NEWKEYS) {
9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->rekeying = 0;
9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		while ((p = TAILQ_FIRST(&active_state->outgoing))) {
9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			type = p->type;
9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			debug("dequeue packet: %u", type);
10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			buffer_free(&active_state->outgoing_packet);
10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			memcpy(&active_state->outgoing_packet, &p->payload,
10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    sizeof(Buffer));
10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			TAILQ_REMOVE(&active_state->outgoing, p, next);
10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(p);
10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_send2_wrapped();
10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_send(void)
10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (compat20)
10141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send2();
10151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
10161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_send1();
10171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DBG(debug("packet_send done"));
10181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
10191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
10211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Waits until a packet has been received, and returns its type.  Note that
10221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * no other data is processed until this returns, so this function should not
10231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * be used during the interactive session.
10241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
10251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
10271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_read_seqnr(u_int32_t *seqnr_p)
10281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
10291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int type, len, ret, ms_remain, cont;
10301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fd_set *setp;
10311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char buf[8192];
10321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct timeval timeout, start, *timeoutp = NULL;
10331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DBG(debug("packet_read()"));
10351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1,
10371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    NFDBITS), sizeof(fd_mask));
10381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Since we are blocking, ensure that all written packets have been sent. */
10401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_wait();
10411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Stay in the loop until we have received a complete packet. */
10431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (;;) {
10441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Try to read a packet from the buffer. */
10451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		type = packet_read_poll_seqnr(seqnr_p);
10461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!compat20 && (
10471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    type == SSH_SMSG_SUCCESS
10481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    || type == SSH_SMSG_FAILURE
10491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    || type == SSH_CMSG_EOF
10501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    || type == SSH_CMSG_EXIT_CONFIRMATION))
10511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_check_eom();
10521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* If we got a packet, return it. */
10531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (type != SSH_MSG_NONE) {
10541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			xfree(setp);
10551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return type;
10561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
10571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/*
10581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * Otherwise, wait for some data to arrive, add it to the
10591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * buffer, and try again.
10601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 */
10611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memset(setp, 0, howmany(active_state->connection_in + 1,
10621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    NFDBITS) * sizeof(fd_mask));
10631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		FD_SET(active_state->connection_in, setp);
10641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
10651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (active_state->packet_timeout_ms > 0) {
10661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			ms_remain = active_state->packet_timeout_ms;
10671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			timeoutp = &timeout;
10681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
10691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Wait for some data to arrive. */
10701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (;;) {
10711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (active_state->packet_timeout_ms != -1) {
10721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				ms_to_timeval(&timeout, ms_remain);
10731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				gettimeofday(&start, NULL);
10741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
10751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((ret = select(active_state->connection_in + 1, setp,
10761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    NULL, NULL, timeoutp)) >= 0)
10771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
10781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (errno != EAGAIN && errno != EINTR &&
10791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    errno != EWOULDBLOCK)
10801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
10811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (active_state->packet_timeout_ms == -1)
10821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				continue;
10831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			ms_subtract_diff(&start, &ms_remain);
10841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (ms_remain <= 0) {
10851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				ret = 0;
10861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
10871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
10881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
10891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (ret == 0) {
10901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Connection to %.200s timed out while "
10911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "waiting to read", get_remote_ipaddr());
10921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			cleanup_exit(255);
10931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
10941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Read data from the socket. */
10951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		do {
10961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			cont = 0;
10971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			len = roaming_read(active_state->connection_in, buf,
10981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    sizeof(buf), &cont);
10991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} while (len == 0 && cont);
11001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (len == 0) {
11011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Connection closed by %.200s", get_remote_ipaddr());
11021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			cleanup_exit(255);
11031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
11041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (len < 0)
11051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("Read from socket failed: %.100s", strerror(errno));
11061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/* Append it to the buffer. */
11071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_process_incoming(buf, len);
11081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
11091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* NOTREACHED */
11101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
11111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
11131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_read(void)
11141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
11151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return packet_read_seqnr(NULL);
11161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
11171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
11191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Waits until a packet has been received, verifies that its type matches
11201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * that given, and gives a fatal error and exits if there is a mismatch.
11211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
11221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
11241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_read_expect(int expected_type)
11251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
11261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int type;
11271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = packet_read();
11291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type != expected_type)
11301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Protocol error: expected packet type %d, got %d",
11311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    expected_type, type);
11321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
11331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Checks if a full packet is available in the data received so far via
11351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * packet_process_incoming.  If so, reads the packet; otherwise returns
11361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH_MSG_NONE.  This does not wait for data from the connection.
11371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
11381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH_MSG_DISCONNECT is handled specially here.  Also,
11391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * SSH_MSG_IGNORE messages are skipped by this function and are never returned
11401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * to higher levels.
11411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
11421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
11441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_read_poll1(void)
11451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
11461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int len, padded_len;
11471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char *cp, type;
11481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int checksum, stored_checksum;
11491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Check if input size is less than minimum packet size. */
11511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (buffer_len(&active_state->input) < 4 + 8)
11521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return SSH_MSG_NONE;
11531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Get length of incoming packet. */
11541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_ptr(&active_state->input);
11551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	len = get_u32(cp);
11561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (len < 1 + 2 + 2 || len > 256 * 1024)
11571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Bad packet length %u.", len);
11581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	padded_len = (len + 8) & ~7;
11591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Check if the packet has been entirely received. */
11611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (buffer_len(&active_state->input) < 4 + padded_len)
11621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return SSH_MSG_NONE;
11631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* The entire packet is in buffer. */
11651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Consume packet length. */
11671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_consume(&active_state->input, 4);
11681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
11701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Cryptographic attack detector for ssh
11711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * (C)1998 CORE-SDI, Buenos Aires Argentina
11721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Ariel Futoransky(futo@core-sdi.com)
11731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
11741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!active_state->receive_context.plaintext) {
11751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		switch (detect_attack(buffer_ptr(&active_state->input),
11761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    padded_len)) {
11771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case DEATTACK_DETECTED:
11781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("crc32 compensation attack: "
11791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "network attack detected");
11801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		case DEATTACK_DOS_DETECTED:
11811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_disconnect("deattack denial of "
11821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "service detected");
11831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
11841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
11851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Decrypt data to incoming_packet. */
11871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_clear(&active_state->incoming_packet);
11881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_append_space(&active_state->incoming_packet, padded_len);
11891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_crypt(&active_state->receive_context, cp,
11901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_ptr(&active_state->input), padded_len);
11911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_consume(&active_state->input, padded_len);
11931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
11951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fprintf(stderr, "read_poll plain: ");
11961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_dump(&active_state->incoming_packet);
11971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
11981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
11991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Compute packet checksum. */
12001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet),
12011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->incoming_packet) - 4);
12021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Skip padding. */
12041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_consume(&active_state->incoming_packet, 8 - len % 8);
12051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Test check bytes. */
12071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (len != buffer_len(&active_state->incoming_packet))
12081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
12091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    len, buffer_len(&active_state->incoming_packet));
12101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4;
12121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	stored_checksum = get_u32(cp);
12131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (checksum != stored_checksum)
12141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Corrupted check bytes on input.");
12151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_consume_end(&active_state->incoming_packet, 4);
12161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->packet_compression) {
12181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->compression_buffer);
12191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_uncompress(&active_state->incoming_packet,
12201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    &active_state->compression_buffer);
12211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->incoming_packet);
12221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&active_state->incoming_packet,
12231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->compression_buffer),
12241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_len(&active_state->compression_buffer));
12251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
12261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->p_read.packets++;
12271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->p_read.bytes += padded_len + 4;
12281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = buffer_get_char(&active_state->incoming_packet);
12291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type < SSH_MSG_MIN || type > SSH_MSG_MAX)
12301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Invalid ssh1 packet type: %d", type);
12311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return type;
12321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
12331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic int
12351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_read_poll2(u_int32_t *seqnr_p)
12361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
12371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int padlen, need;
12381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char *macbuf, *cp, type;
12391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int maclen, block_size;
12401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Enc *enc   = NULL;
12411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Mac *mac   = NULL;
12421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	Comp *comp = NULL;
12431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->packet_discard)
12451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return SSH_MSG_NONE;
12461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->newkeys[MODE_IN] != NULL) {
12481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		enc  = &active_state->newkeys[MODE_IN]->enc;
12491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		mac  = &active_state->newkeys[MODE_IN]->mac;
12501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		comp = &active_state->newkeys[MODE_IN]->comp;
12511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
12521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	maclen = mac && mac->enabled ? mac->mac_len : 0;
12531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	block_size = enc ? enc->block_size : 8;
12541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
12551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->packlen == 0) {
12561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		/*
12571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * check if input size is less than the cipher block size,
12581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 * decrypt first block and extract length of incoming packet
12591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		 */
12601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (buffer_len(&active_state->input) < block_size)
12611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return SSH_MSG_NONE;
12621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->incoming_packet);
12631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cp = buffer_append_space(&active_state->incoming_packet,
12641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    block_size);
12651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cipher_crypt(&active_state->receive_context, cp,
12661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->input), block_size);
12671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cp = buffer_ptr(&active_state->incoming_packet);
12681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->packlen = get_u32(cp);
12691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (active_state->packlen < 1 + 4 ||
12701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    active_state->packlen > PACKET_MAX_SIZE) {
12711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
12721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			buffer_dump(&active_state->incoming_packet);
12731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
12741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Bad packet length %u.", active_state->packlen);
12751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_start_discard(enc, mac, active_state->packlen,
12761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    PACKET_MAX_SIZE);
12771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return SSH_MSG_NONE;
12781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
12791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		DBG(debug("input: packet len %u", active_state->packlen+4));
12801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_consume(&active_state->input, block_size);
12811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
12821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* we have a partial packet of block_size bytes */
12831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	need = 4 + active_state->packlen - block_size;
12841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DBG(debug("partial packet %d, need %d, maclen %d", block_size,
12851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    need, maclen));
12861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (need % block_size != 0) {
12871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("padding error: need %d block %d mod %d",
12881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    need, block_size, need % block_size);
12891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start_discard(enc, mac, active_state->packlen,
12901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    PACKET_MAX_SIZE - block_size);
12911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return SSH_MSG_NONE;
12921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
12931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
12941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * check if the entire packet has been received and
12951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * decrypt into incoming_packet
12961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
12971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (buffer_len(&active_state->input) < need + maclen)
12981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return SSH_MSG_NONE;
12991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
13001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fprintf(stderr, "read_poll enc/full: ");
13011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_dump(&active_state->input);
13021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
13031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_append_space(&active_state->incoming_packet, need);
13041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cipher_crypt(&active_state->receive_context, cp,
13051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_ptr(&active_state->input), need);
13061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_consume(&active_state->input, need);
13071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
13081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * compute MAC over seqnr and packet,
13091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * increment sequence number for incoming packet
13101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
13111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (mac && mac->enabled) {
13121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		macbuf = mac_compute(mac, active_state->p_read.seqnr,
13131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->incoming_packet),
13141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_len(&active_state->incoming_packet));
13151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input),
13161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    mac->mac_len) != 0) {
13171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Corrupted MAC on input.");
13181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (need > PACKET_MAX_SIZE)
13191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				fatal("internal error need %d", need);
13201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_start_discard(enc, mac, active_state->packlen,
13211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    PACKET_MAX_SIZE - need);
13221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			return SSH_MSG_NONE;
13231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
13241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		DBG(debug("MAC #%d ok", active_state->p_read.seqnr));
13261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_consume(&active_state->input, mac->mac_len);
13271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
13281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* XXX now it's safe to use fatal/packet_disconnect */
13291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (seqnr_p != NULL)
13301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*seqnr_p = active_state->p_read.seqnr;
13311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (++active_state->p_read.seqnr == 0)
13321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("incoming seqnr wraps around");
13331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (++active_state->p_read.packets == 0)
13341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (!(datafellows & SSH_BUG_NOREKEY))
13351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("XXX too many packets with same key");
13361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->p_read.blocks += (active_state->packlen + 4) / block_size;
13371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->p_read.bytes += active_state->packlen + 4;
13381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* get padlen */
13401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cp = buffer_ptr(&active_state->incoming_packet);
13411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	padlen = cp[4];
13421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DBG(debug("input: padlen %d", padlen));
13431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (padlen < 4)
13441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Corrupted padlen %d on input.", padlen);
13451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* skip packet size + padlen, discard padding */
13471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_consume(&active_state->incoming_packet, 4 + 1);
13481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_consume_end(&active_state->incoming_packet, padlen);
13491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	DBG(debug("input: len before de-compress %d",
13511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    buffer_len(&active_state->incoming_packet)));
13521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (comp && comp->enabled) {
13531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->compression_buffer);
13541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_uncompress(&active_state->incoming_packet,
13551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    &active_state->compression_buffer);
13561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&active_state->incoming_packet);
13571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&active_state->incoming_packet,
13581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->compression_buffer),
13591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_len(&active_state->compression_buffer));
13601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		DBG(debug("input: len after de-compress %d",
13611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_len(&active_state->incoming_packet)));
13621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
13631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
13641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * get packet type, implies consume.
13651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * return length of payload (without type field)
13661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
13671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	type = buffer_get_char(&active_state->incoming_packet);
13681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN)
13691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_disconnect("Invalid ssh2 packet type: %d", type);
13701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (type == SSH2_MSG_NEWKEYS)
13711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		set_newkeys(MODE_IN);
13721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else if (type == SSH2_MSG_USERAUTH_SUCCESS &&
13731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    !active_state->server_side)
13741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_enable_delayed_compress();
13751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef PACKET_DEBUG
13761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fprintf(stderr, "read/plain[%d]:\r\n", type);
13771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_dump(&active_state->incoming_packet);
13781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
13791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* reset for next packet */
13801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->packlen = 0;
13811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return type;
13821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
13831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
13851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_read_poll_seqnr(u_int32_t *seqnr_p)
13861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
13871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int reason, seqnr;
13881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_char type;
13891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char *msg;
13901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
13911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (;;) {
13921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (compat20) {
13931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			type = packet_read_poll2(seqnr_p);
13941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (type) {
13951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				active_state->keep_alive_timeouts = 0;
13961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				DBG(debug("received packet type %d", type));
13971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
13981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			switch (type) {
13991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			case SSH2_MSG_IGNORE:
14001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				debug3("Received SSH2_MSG_IGNORE");
14011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
14021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			case SSH2_MSG_DEBUG:
14031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				packet_get_char();
14041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				msg = packet_get_string(NULL);
14051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				debug("Remote: %.900s", msg);
14061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				xfree(msg);
14071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				msg = packet_get_string(NULL);
14081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				xfree(msg);
14091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
14101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			case SSH2_MSG_DISCONNECT:
14111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				reason = packet_get_int();
14121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				msg = packet_get_string(NULL);
14131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				logit("Received disconnect from %s: %u: %.400s",
14141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    get_remote_ipaddr(), reason, msg);
14151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				xfree(msg);
14161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				cleanup_exit(255);
14171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
14181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			case SSH2_MSG_UNIMPLEMENTED:
14191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				seqnr = packet_get_int();
14201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
14211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    seqnr);
14221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
14231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			default:
14241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return type;
14251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
14261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		} else {
14271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			type = packet_read_poll1();
14281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			switch (type) {
14291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			case SSH_MSG_IGNORE:
14301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
14311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			case SSH_MSG_DEBUG:
14321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				msg = packet_get_string(NULL);
14331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				debug("Remote: %.900s", msg);
14341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				xfree(msg);
14351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
14361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			case SSH_MSG_DISCONNECT:
14371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				msg = packet_get_string(NULL);
14381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				logit("Received disconnect from %s: %.400s",
14391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				    get_remote_ipaddr(), msg);
14401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				cleanup_exit(255);
14411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
14421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			default:
14431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				if (type)
14441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood					DBG(debug("received packet type %d", type));
14451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return type;
14461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
14471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
14481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
14491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
14501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
14521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_read_poll(void)
14531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
14541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return packet_read_poll_seqnr(NULL);
14551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
14561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
14581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Buffers the given amount of input characters.  This is intended to be used
14591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * together with packet_read_poll.
14601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
14611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
14631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_process_incoming(const char *buf, u_int len)
14641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
14651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->packet_discard) {
14661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->keep_alive_timeouts = 0; /* ?? */
14671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (len >= active_state->packet_discard)
14681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			packet_stop_discard();
14691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		active_state->packet_discard -= len;
14701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
14711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
14721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_append(&active_state->input, buf, len);
14731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
14741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns a character from the packet. */
14761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int
14781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_char(void)
14791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
14801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char ch;
14811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_get(&active_state->incoming_packet, &ch, 1);
14831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (u_char) ch;
14841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
14851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns an integer from the packet data. */
14871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int
14891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_int(void)
14901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
14911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return buffer_get_int(&active_state->incoming_packet);
14921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
14931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns an 64 bit integer from the packet data. */
14951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
14961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int64_t
14971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_int64(void)
14981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
14991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return buffer_get_int64(&active_state->incoming_packet);
15001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
15031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Returns an arbitrary precision integer from the packet data.  The integer
15041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * must have been initialized before this call.
15051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
15061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
15081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_bignum(BIGNUM * value)
15091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_get_bignum(&active_state->incoming_packet, value);
15111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
15141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_bignum2(BIGNUM * value)
15151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_get_bignum2(&active_state->incoming_packet, value);
15171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC
15201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
15211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_ecpoint(const EC_GROUP *curve, EC_POINT *point)
15221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	buffer_get_ecpoint(&active_state->incoming_packet, curve, point);
15241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif
15261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid *
15281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_raw(u_int *length_ptr)
15291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int bytes = buffer_len(&active_state->incoming_packet);
15311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (length_ptr != NULL)
15331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		*length_ptr = bytes;
15341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return buffer_ptr(&active_state->incoming_packet);
15351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
15381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_remaining(void)
15391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return buffer_len(&active_state->incoming_packet);
15411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
15441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Returns a string from the packet data.  The string is allocated using
15451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * xmalloc; it is the responsibility of the calling program to free it when
15461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * no longer needed.  The length_ptr argument may be NULL, or point to an
15471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * integer into which the length of the string is stored.
15481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
15491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid *
15511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_string(u_int *length_ptr)
15521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return buffer_get_string(&active_state->incoming_packet, length_ptr);
15541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid *
15571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_string_ptr(u_int *length_ptr)
15581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr);
15601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Ensures the returned string has no embedded \0 characters in it. */
15631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar *
15641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_cstring(u_int *length_ptr)
15651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return buffer_get_cstring(&active_state->incoming_packet, length_ptr);
15671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
15681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
15701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Sends a diagnostic message from the server to the client.  This message
15711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * can be sent at any time (but not while constructing another message). The
15721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * message is printed immediately, but only if the client is being executed
15731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * in verbose mode.  These messages are primarily intended to ease debugging
15741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * authentication problems.   The length of the formatted message must not
15751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * exceed 1024 bytes.  This will automatically call packet_write_wait.
15761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
15771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
15791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_send_debug(const char *fmt,...)
15801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
15811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char buf[1024];
15821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	va_list args;
15831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (compat20 && (datafellows & SSH_BUG_DEBUG))
15851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
15861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	va_start(args, fmt);
15881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	vsnprintf(buf, sizeof(buf), fmt, args);
15891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	va_end(args);
15901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
15911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (compat20) {
15921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH2_MSG_DEBUG);
15931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_char(0);	/* bool: always display */
15941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_cstring(buf);
15951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_cstring("");
15961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
15971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_MSG_DEBUG);
15981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_cstring(buf);
15991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
16001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_send();
16011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_wait();
16021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
16031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
16051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Logs the error plus constructs and sends a disconnect packet, closes the
16061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * connection, and exits.  This function never returns. The error message
16071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * should not contain a newline.  The length of the formatted message must
16081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * not exceed 1024 bytes.
16091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
16101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
16121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_disconnect(const char *fmt,...)
16131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
16141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	char buf[1024];
16151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	va_list args;
16161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	static int disconnecting = 0;
16171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (disconnecting)	/* Guard against recursive invocations. */
16191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		fatal("packet_disconnect called recursively.");
16201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	disconnecting = 1;
16211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/*
16231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * Format the message.  Note that the caller must make sure the
16241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 * message is of limited size.
16251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	 */
16261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	va_start(args, fmt);
16271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	vsnprintf(buf, sizeof(buf), fmt, args);
16281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	va_end(args);
16291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Display the error locally */
16311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	logit("Disconnecting: %.100s", buf);
16321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Send the disconnect message to the other side, and wait for it to get sent. */
16341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (compat20) {
16351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH2_MSG_DISCONNECT);
16361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR);
16371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_cstring(buf);
16381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_cstring("");
16391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	} else {
16401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_start(SSH_MSG_DISCONNECT);
16411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_cstring(buf);
16421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
16431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_send();
16441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_wait();
16451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Stop listening for connections. */
16471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	channel_close_all();
16481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Close the connection. */
16501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_close();
16511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	cleanup_exit(255);
16521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
16531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Checks if there is any buffered output, and tries to write some of the output. */
16551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
16571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_write_poll(void)
16581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
16591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int len = buffer_len(&active_state->output);
16601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int cont;
16611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (len > 0) {
16631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		cont = 0;
16641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		len = roaming_write(active_state->connection_out,
16651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    buffer_ptr(&active_state->output), len, &cont);
16661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (len == -1) {
16671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (errno == EINTR || errno == EAGAIN ||
16681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    errno == EWOULDBLOCK)
16691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				return;
16701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("Write failed: %.100s", strerror(errno));
16711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
16721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (len == 0 && !cont)
16731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			fatal("Write connection closed");
16741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_consume(&active_state->output, len);
16751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
16761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
16771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
16791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Calls packet_write_poll repeatedly until all pending output data has been
16801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * written.
16811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
16821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
16841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_write_wait(void)
16851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
16861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	fd_set *setp;
16871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int ret, ms_remain;
16881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct timeval start, timeout, *timeoutp = NULL;
16891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1,
16911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    NFDBITS), sizeof(fd_mask));
16921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_write_poll();
16931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	while (packet_have_data_to_write()) {
16941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		memset(setp, 0, howmany(active_state->connection_out + 1,
16951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    NFDBITS) * sizeof(fd_mask));
16961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		FD_SET(active_state->connection_out, setp);
16971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
16981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (active_state->packet_timeout_ms > 0) {
16991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			ms_remain = active_state->packet_timeout_ms;
17001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			timeoutp = &timeout;
17011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
17021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		for (;;) {
17031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (active_state->packet_timeout_ms != -1) {
17041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				ms_to_timeval(&timeout, ms_remain);
17051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				gettimeofday(&start, NULL);
17061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
17071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if ((ret = select(active_state->connection_out + 1,
17081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    NULL, setp, NULL, timeoutp)) >= 0)
17091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
17101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (errno != EAGAIN && errno != EINTR &&
17111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    errno != EWOULDBLOCK)
17121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
17131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (active_state->packet_timeout_ms == -1)
17141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				continue;
17151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			ms_subtract_diff(&start, &ms_remain);
17161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			if (ms_remain <= 0) {
17171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				ret = 0;
17181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood				break;
17191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			}
17201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
17211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (ret == 0) {
17221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			logit("Connection to %.200s timed out while "
17231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    "waiting to write", get_remote_ipaddr());
17241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			cleanup_exit(255);
17251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		}
17261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_write_poll();
17271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
17281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	xfree(setp);
17291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
17301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns true if there is buffered data to write to the connection. */
17321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
17341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_have_data_to_write(void)
17351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
17361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return buffer_len(&active_state->output) != 0;
17371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
17381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns true if there is not too much data to write to the connection. */
17401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
17421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_not_very_much_data_to_write(void)
17431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
17441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->interactive_mode)
17451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return buffer_len(&active_state->output) < 16384;
17461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
17471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return buffer_len(&active_state->output) < 128 * 1024;
17481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
17491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic void
17511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_tos(int tos)
17521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
17531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifndef IP_TOS_IS_BROKEN
17541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!packet_connection_is_on_socket())
17551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
17561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	switch (packet_connection_af()) {
17571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# ifdef IP_TOS
17581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	case AF_INET:
17591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug3("%s: set IP_TOS 0x%02x", __func__, tos);
17601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (setsockopt(active_state->connection_in,
17611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0)
17621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			error("setsockopt IP_TOS %d: %.100s:",
17631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    tos, strerror(errno));
17641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		break;
17651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif /* IP_TOS */
17661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# ifdef IPV6_TCLASS
17671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	case AF_INET6:
17681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos);
17691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (setsockopt(active_state->connection_in,
17701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0)
17711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			error("setsockopt IPV6_TCLASS %d: %.100s:",
17721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			    tos, strerror(errno));
17731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		break;
17741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# endif /* IPV6_TCLASS */
17751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
17761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* IP_TOS_IS_BROKEN */
17771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
17781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Informs that the current session is interactive.  Sets IP flags for that. */
17801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
17821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_interactive(int interactive, int qos_interactive, int qos_bulk)
17831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
17841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->set_interactive_called)
17851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
17861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->set_interactive_called = 1;
17871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Record that we are in interactive mode. */
17891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->interactive_mode = interactive;
17901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	/* Only set socket options if using a socket.  */
17921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (!packet_connection_is_on_socket())
17931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return;
17941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	set_nodelay(active_state->connection_in);
17951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_set_tos(interactive ? qos_interactive : qos_bulk);
17961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
17971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
17981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Returns true if the current connection is interactive. */
17991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
18011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_is_interactive(void)
18021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return active_state->interactive_mode;
18041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
18071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_maxsize(u_int s)
18081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (active_state->set_maxsize_called) {
18101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("packet_set_maxsize: called twice: old %d new %d",
18111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		    active_state->max_packet_size, s);
18121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return -1;
18131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
18141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (s < 4 * 1024 || s > 1024 * 1024) {
18151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		logit("packet_set_maxsize: bad size %d", s);
18161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return -1;
18171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
18181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->set_maxsize_called = 1;
18191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	debug("packet_set_maxsize: setting to %d", s);
18201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->max_packet_size = s;
18211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return s;
18221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
18251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_inc_alive_timeouts(void)
18261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return ++active_state->keep_alive_timeouts;
18281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
18311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_alive_timeouts(int ka)
18321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->keep_alive_timeouts = ka;
18341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int
18371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_maxsize(void)
18381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return active_state->max_packet_size;
18401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* roundup current message to pad bytes */
18431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
18441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_add_padding(u_char pad)
18451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->extra_pad = pad;
18471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
18501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 9.2.  Ignored Data Message
18511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
18521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *   byte      SSH_MSG_IGNORE
18531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *   string    data
18541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *
18551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * All implementations MUST understand (and ignore) this message at any
18561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * time (after receiving the protocol version). No implementation is
18571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * required to send them. This message can be used as an additional
18581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * protection measure against advanced traffic analysis techniques.
18591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
18601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
18611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_send_ignore(int nbytes)
18621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int32_t rnd = 0;
18641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	int i;
18651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE);
18671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	packet_put_int(nbytes);
18681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	for (i = 0; i < nbytes; i++) {
18691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		if (i % 4 == 0)
18701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood			rnd = arc4random();
18711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		packet_put_char((u_char)rnd & 0xff);
18721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		rnd >>= 8;
18731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
18741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define MAX_PACKETS	(1U<<31)
18771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint
18781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_need_rekeying(void)
18791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (datafellows & SSH_BUG_NOREKEY)
18811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		return 0;
18821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return
18831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (active_state->p_send.packets > MAX_PACKETS) ||
18841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (active_state->p_read.packets > MAX_PACKETS) ||
18851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (active_state->max_blocks_out &&
18861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	        (active_state->p_send.blocks > active_state->max_blocks_out)) ||
18871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	    (active_state->max_blocks_in &&
18881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	        (active_state->p_read.blocks > active_state->max_blocks_in));
18891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
18921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_rekey_limit(u_int32_t bytes)
18931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
18941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->rekey_limit = bytes;
18951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
18961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
18971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
18981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_server(void)
18991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
19001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->server_side = 1;
19011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
19021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
19031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
19041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_set_authenticated(void)
19051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
19061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->after_authentication = 1;
19071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
19081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
19091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid *
19101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_input(void)
19111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
19121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (void *)&active_state->input;
19131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
19141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
19151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid *
19161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_output(void)
19171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
19181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (void *)&active_state->output;
19191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
19201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
19211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid *
19221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_get_newkeys(int mode)
19231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
19241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	return (void *)active_state->newkeys[mode];
19251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
19261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
19271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
19281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Save the state for the real connection, and use a separate state when
19291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * resuming a suspended connection.
19301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
19311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
19321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_backup_state(void)
19331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
19341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct session_state *tmp;
19351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
19361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	close(active_state->connection_in);
19371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->connection_in = -1;
19381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	close(active_state->connection_out);
19391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->connection_out = -1;
19401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (backup_state)
19411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tmp = backup_state;
19421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	else
19431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		tmp = alloc_session_state();
19441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	backup_state = active_state;
19451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state = tmp;
19461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
19471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
19481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/*
19491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Swap in the old state when resuming a connecion.
19501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */
19511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid
19521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpacket_restore_state(void)
19531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{
19541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	struct session_state *tmp;
19551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	void *buf;
19561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	u_int len;
19571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood
19581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	tmp = backup_state;
19591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	backup_state = active_state;
19601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state = tmp;
19611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->connection_in = backup_state->connection_in;
19621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	backup_state->connection_in = -1;
19631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	active_state->connection_out = backup_state->connection_out;
19641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	backup_state->connection_out = -1;
19651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	len = buffer_len(&backup_state->input);
19661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	if (len > 0) {
19671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buf = buffer_ptr(&backup_state->input);
19681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_append(&active_state->input, buf, len);
19691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		buffer_clear(&backup_state->input);
19701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood		add_recv_bytes(len);
19711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood	}
19721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}
1973