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