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