1258343Sdes/* $OpenBSD: packet.c,v 1.189 2013/11/08 00:39:15 djm Exp $ */ 257429Smarkm/* 357429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 457429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 557429Smarkm * All rights reserved 657429Smarkm * This file contains code implementing the packet protocol and communication 757429Smarkm * with the other side. This same code is used both on client and server side. 860573Skris * 965668Skris * As far as I am concerned, the code I have written for this software 1065668Skris * can be used freely for any purpose. Any derived versions of this 1165668Skris * software must be clearly marked as such, and if the derived work is 1265668Skris * incompatible with the protocol description in the RFC file, it must be 1365668Skris * called by a name other than "ssh" or "Secure Shell". 1465668Skris * 1565668Skris * 1660573Skris * SSH2 packet format added by Markus Friedl. 1792555Sdes * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 1860573Skris * 1965668Skris * Redistribution and use in source and binary forms, with or without 2065668Skris * modification, are permitted provided that the following conditions 2165668Skris * are met: 2265668Skris * 1. Redistributions of source code must retain the above copyright 2365668Skris * notice, this list of conditions and the following disclaimer. 2465668Skris * 2. Redistributions in binary form must reproduce the above copyright 2565668Skris * notice, this list of conditions and the following disclaimer in the 2665668Skris * documentation and/or other materials provided with the distribution. 2765668Skris * 2865668Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2965668Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 3065668Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 3165668Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 3265668Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3365668Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3465668Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3565668Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3665668Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3765668Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3857429Smarkm */ 3957429Smarkm 4057429Smarkm#include "includes.h" 41162852Sdes 42162852Sdes#include <sys/types.h> 43124208Sdes#include "openbsd-compat/sys-queue.h" 44162852Sdes#include <sys/param.h> 45162852Sdes#include <sys/socket.h> 46162852Sdes#ifdef HAVE_SYS_TIME_H 47162852Sdes# include <sys/time.h> 48162852Sdes#endif 49124208Sdes 50162852Sdes#include <netinet/in.h> 51162852Sdes#include <netinet/ip.h> 52162852Sdes#include <arpa/inet.h> 53162852Sdes 54162852Sdes#include <errno.h> 55162852Sdes#include <stdarg.h> 56162852Sdes#include <stdio.h> 57162852Sdes#include <stdlib.h> 58162852Sdes#include <string.h> 59162852Sdes#include <unistd.h> 60162852Sdes#include <signal.h> 61255767Sdes#include <time.h> 62162852Sdes 6357429Smarkm#include "xmalloc.h" 6457429Smarkm#include "buffer.h" 6557429Smarkm#include "packet.h" 6657429Smarkm#include "crc32.h" 6757429Smarkm#include "compress.h" 6857429Smarkm#include "deattack.h" 6960573Skris#include "channels.h" 7060573Skris#include "compat.h" 7176259Sgreen#include "ssh1.h" 7260573Skris#include "ssh2.h" 7369587Sgreen#include "cipher.h" 74162852Sdes#include "key.h" 7560573Skris#include "kex.h" 7676259Sgreen#include "mac.h" 7776259Sgreen#include "log.h" 7876259Sgreen#include "canohost.h" 7992555Sdes#include "misc.h" 8098675Sdes#include "ssh.h" 81197679Sdes#include "roaming.h" 8260573Skris 8360573Skris#ifdef PACKET_DEBUG 8460573Skris#define DBG(x) x 8560573Skris#else 8660573Skris#define DBG(x) 8760573Skris#endif 8860573Skris 89192595Sdes#define PACKET_MAX_SIZE (256 * 1024) 90192595Sdes 91197679Sdesstruct packet_state { 92197679Sdes u_int32_t seqnr; 93197679Sdes u_int32_t packets; 94197679Sdes u_int64_t blocks; 95197679Sdes u_int64_t bytes; 96197679Sdes}; 9757429Smarkm 98197679Sdesstruct packet { 99197679Sdes TAILQ_ENTRY(packet) next; 100197679Sdes u_char type; 101197679Sdes Buffer payload; 102197679Sdes}; 10357429Smarkm 104197679Sdesstruct session_state { 105197679Sdes /* 106197679Sdes * This variable contains the file descriptors used for 107197679Sdes * communicating with the other side. connection_in is used for 108197679Sdes * reading; connection_out for writing. These can be the same 109197679Sdes * descriptor, in which case it is assumed to be a socket. 110197679Sdes */ 111197679Sdes int connection_in; 112197679Sdes int connection_out; 11357429Smarkm 114197679Sdes /* Protocol flags for the remote side. */ 115197679Sdes u_int remote_protocol_flags; 11657429Smarkm 117197679Sdes /* Encryption context for receiving data. Only used for decryption. */ 118197679Sdes CipherContext receive_context; 11957429Smarkm 120197679Sdes /* Encryption context for sending data. Only used for encryption. */ 121197679Sdes CipherContext send_context; 12257429Smarkm 123197679Sdes /* Buffer for raw input data from the socket. */ 124197679Sdes Buffer input; 12557429Smarkm 126197679Sdes /* Buffer for raw output data going to the socket. */ 127197679Sdes Buffer output; 12857429Smarkm 129197679Sdes /* Buffer for the partial outgoing packet being constructed. */ 130197679Sdes Buffer outgoing_packet; 13157429Smarkm 132197679Sdes /* Buffer for the incoming packet currently being processed. */ 133197679Sdes Buffer incoming_packet; 13457429Smarkm 135197679Sdes /* Scratch buffer for packet compression/decompression. */ 136197679Sdes Buffer compression_buffer; 137197679Sdes int compression_buffer_ready; 13857429Smarkm 139197679Sdes /* 140197679Sdes * Flag indicating whether packet compression/decompression is 141197679Sdes * enabled. 142197679Sdes */ 143197679Sdes int packet_compression; 14457429Smarkm 145197679Sdes /* default maximum packet size */ 146197679Sdes u_int max_packet_size; 14757429Smarkm 148197679Sdes /* Flag indicating whether this module has been initialized. */ 149197679Sdes int initialized; 150149749Sdes 151197679Sdes /* Set to true if the connection is interactive. */ 152197679Sdes int interactive_mode; 153149749Sdes 154197679Sdes /* Set to true if we are the server side. */ 155197679Sdes int server_side; 156181111Sdes 157197679Sdes /* Set to true if we are authenticated. */ 158197679Sdes int after_authentication; 159181111Sdes 160197679Sdes int keep_alive_timeouts; 16160573Skris 162197679Sdes /* The maximum time that we will wait to send or receive a packet */ 163197679Sdes int packet_timeout_ms; 164124208Sdes 165197679Sdes /* Session key information for Encryption and MAC */ 166197679Sdes Newkeys *newkeys[MODE_MAX]; 167197679Sdes struct packet_state p_read, p_send; 16898675Sdes 169255767Sdes /* Volume-based rekeying */ 170197679Sdes u_int64_t max_blocks_in, max_blocks_out; 171197679Sdes u_int32_t rekey_limit; 17260573Skris 173255767Sdes /* Time-based rekeying */ 174255767Sdes time_t rekey_interval; /* how often in seconds */ 175255767Sdes time_t rekey_time; /* time of last rekeying */ 176255767Sdes 177197679Sdes /* Session key for protocol v1 */ 178197679Sdes u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; 179197679Sdes u_int ssh1_keylen; 180192595Sdes 181197679Sdes /* roundup current message to extra_pad bytes */ 182197679Sdes u_char extra_pad; 183197679Sdes 184197679Sdes /* XXX discard incoming data after MAC error */ 185197679Sdes u_int packet_discard; 186197679Sdes Mac *packet_discard_mac; 187197679Sdes 188197679Sdes /* Used in packet_read_poll2() */ 189197679Sdes u_int packlen; 190197679Sdes 191197679Sdes /* Used in packet_send2 */ 192197679Sdes int rekeying; 193197679Sdes 194197679Sdes /* Used in packet_set_interactive */ 195197679Sdes int set_interactive_called; 196197679Sdes 197197679Sdes /* Used in packet_set_maxsize */ 198197679Sdes int set_maxsize_called; 199197679Sdes 200197679Sdes TAILQ_HEAD(, packet) outgoing; 201124208Sdes}; 202124208Sdes 203197679Sdesstatic struct session_state *active_state, *backup_state; 204224638Sbrooks#ifdef NONE_CIPHER_ENABLED 205224638Sbrooksstatic int rekey_requested = 0; 206224638Sbrooks#endif 207197679Sdes 208197679Sdesstatic struct session_state * 209197679Sdesalloc_session_state(void) 210197679Sdes{ 211221420Sdes struct session_state *s = xcalloc(1, sizeof(*s)); 212197679Sdes 213221420Sdes s->connection_in = -1; 214221420Sdes s->connection_out = -1; 215221420Sdes s->max_packet_size = 32768; 216221420Sdes s->packet_timeout_ms = -1; 217221420Sdes return s; 218197679Sdes} 219197679Sdes 22057429Smarkm/* 22157429Smarkm * Sets the descriptors used for communication. Disables encryption until 22257429Smarkm * packet_set_encryption_key is called. 22357429Smarkm */ 22457429Smarkmvoid 22557429Smarkmpacket_set_connection(int fd_in, int fd_out) 22657429Smarkm{ 227255767Sdes const Cipher *none = cipher_by_name("none"); 228106121Sdes 22969587Sgreen if (none == NULL) 23069587Sgreen fatal("packet_set_connection: cannot load cipher 'none'"); 231197679Sdes if (active_state == NULL) 232197679Sdes active_state = alloc_session_state(); 233197679Sdes active_state->connection_in = fd_in; 234197679Sdes active_state->connection_out = fd_out; 235197679Sdes cipher_init(&active_state->send_context, none, (const u_char *)"", 236137015Sdes 0, NULL, 0, CIPHER_ENCRYPT); 237197679Sdes cipher_init(&active_state->receive_context, none, (const u_char *)"", 238137015Sdes 0, NULL, 0, CIPHER_DECRYPT); 239197679Sdes active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL; 240197679Sdes if (!active_state->initialized) { 241197679Sdes active_state->initialized = 1; 242197679Sdes buffer_init(&active_state->input); 243197679Sdes buffer_init(&active_state->output); 244197679Sdes buffer_init(&active_state->outgoing_packet); 245197679Sdes buffer_init(&active_state->incoming_packet); 246197679Sdes TAILQ_INIT(&active_state->outgoing); 247197679Sdes active_state->p_send.packets = active_state->p_read.packets = 0; 24857429Smarkm } 24957429Smarkm} 25057429Smarkm 251181111Sdesvoid 252181111Sdespacket_set_timeout(int timeout, int count) 253181111Sdes{ 254240075Sdes if (timeout <= 0 || count <= 0) { 255197679Sdes active_state->packet_timeout_ms = -1; 256181111Sdes return; 257181111Sdes } 258181111Sdes if ((INT_MAX / 1000) / count < timeout) 259197679Sdes active_state->packet_timeout_ms = INT_MAX; 260181111Sdes else 261197679Sdes active_state->packet_timeout_ms = timeout * count * 1000; 262181111Sdes} 263181111Sdes 264192595Sdesstatic void 265192595Sdespacket_stop_discard(void) 266192595Sdes{ 267197679Sdes if (active_state->packet_discard_mac) { 268192595Sdes char buf[1024]; 269192595Sdes 270192595Sdes memset(buf, 'a', sizeof(buf)); 271197679Sdes while (buffer_len(&active_state->incoming_packet) < 272197679Sdes PACKET_MAX_SIZE) 273197679Sdes buffer_append(&active_state->incoming_packet, buf, 274197679Sdes sizeof(buf)); 275197679Sdes (void) mac_compute(active_state->packet_discard_mac, 276197679Sdes active_state->p_read.seqnr, 277197679Sdes buffer_ptr(&active_state->incoming_packet), 278192595Sdes PACKET_MAX_SIZE); 279192595Sdes } 280192595Sdes logit("Finished discarding for %.200s", get_remote_ipaddr()); 281192595Sdes cleanup_exit(255); 282192595Sdes} 283192595Sdes 284192595Sdesstatic void 285192595Sdespacket_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard) 286192595Sdes{ 287248619Sdes if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm)) 288192595Sdes packet_disconnect("Packet corrupt"); 289192595Sdes if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) 290197679Sdes active_state->packet_discard_mac = mac; 291197679Sdes if (buffer_len(&active_state->input) >= discard) 292192595Sdes packet_stop_discard(); 293197679Sdes active_state->packet_discard = discard - 294197679Sdes buffer_len(&active_state->input); 295192595Sdes} 296192595Sdes 29757429Smarkm/* Returns 1 if remote host is connected via socket, 0 if not. */ 29857429Smarkm 29957429Smarkmint 30092555Sdespacket_connection_is_on_socket(void) 30157429Smarkm{ 30257429Smarkm struct sockaddr_storage from, to; 30357429Smarkm socklen_t fromlen, tolen; 30457429Smarkm 30557429Smarkm /* filedescriptors in and out are the same, so it's a socket */ 306197679Sdes if (active_state->connection_in == active_state->connection_out) 30757429Smarkm return 1; 30857429Smarkm fromlen = sizeof(from); 30957429Smarkm memset(&from, 0, sizeof(from)); 310197679Sdes if (getpeername(active_state->connection_in, (struct sockaddr *)&from, 311197679Sdes &fromlen) < 0) 31257429Smarkm return 0; 31357429Smarkm tolen = sizeof(to); 31457429Smarkm memset(&to, 0, sizeof(to)); 315197679Sdes if (getpeername(active_state->connection_out, (struct sockaddr *)&to, 316197679Sdes &tolen) < 0) 31757429Smarkm return 0; 31857429Smarkm if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) 31957429Smarkm return 0; 32057429Smarkm if (from.ss_family != AF_INET && from.ss_family != AF_INET6) 32157429Smarkm return 0; 32257429Smarkm return 1; 32357429Smarkm} 32457429Smarkm 32598675Sdes/* 32698675Sdes * Exports an IV from the CipherContext required to export the key 32798675Sdes * state back from the unprivileged child to the privileged parent 32898675Sdes * process. 32998675Sdes */ 33098675Sdes 33198675Sdesvoid 33298675Sdespacket_get_keyiv(int mode, u_char *iv, u_int len) 33398675Sdes{ 33498675Sdes CipherContext *cc; 33598675Sdes 33698675Sdes if (mode == MODE_OUT) 337197679Sdes cc = &active_state->send_context; 33898675Sdes else 339197679Sdes cc = &active_state->receive_context; 34098675Sdes 34198675Sdes cipher_get_keyiv(cc, iv, len); 34298675Sdes} 34398675Sdes 34498675Sdesint 34598675Sdespacket_get_keycontext(int mode, u_char *dat) 34698675Sdes{ 34798675Sdes CipherContext *cc; 34898675Sdes 34998675Sdes if (mode == MODE_OUT) 350197679Sdes cc = &active_state->send_context; 35198675Sdes else 352197679Sdes cc = &active_state->receive_context; 35398675Sdes 35498675Sdes return (cipher_get_keycontext(cc, dat)); 35598675Sdes} 35698675Sdes 35798675Sdesvoid 35898675Sdespacket_set_keycontext(int mode, u_char *dat) 35998675Sdes{ 36098675Sdes CipherContext *cc; 36198675Sdes 36298675Sdes if (mode == MODE_OUT) 363197679Sdes cc = &active_state->send_context; 36498675Sdes else 365197679Sdes cc = &active_state->receive_context; 36698675Sdes 36798675Sdes cipher_set_keycontext(cc, dat); 36898675Sdes} 36998675Sdes 37098675Sdesint 37198675Sdespacket_get_keyiv_len(int mode) 37298675Sdes{ 37398675Sdes CipherContext *cc; 37498675Sdes 37598675Sdes if (mode == MODE_OUT) 376197679Sdes cc = &active_state->send_context; 37798675Sdes else 378197679Sdes cc = &active_state->receive_context; 37998675Sdes 38098675Sdes return (cipher_get_keyiv_len(cc)); 38198675Sdes} 382162852Sdes 38398675Sdesvoid 38498675Sdespacket_set_iv(int mode, u_char *dat) 38598675Sdes{ 38698675Sdes CipherContext *cc; 38798675Sdes 38898675Sdes if (mode == MODE_OUT) 389197679Sdes cc = &active_state->send_context; 39098675Sdes else 391197679Sdes cc = &active_state->receive_context; 39298675Sdes 39398675Sdes cipher_set_keyiv(cc, dat); 39498675Sdes} 395162852Sdes 39698675Sdesint 397124208Sdespacket_get_ssh1_cipher(void) 39898675Sdes{ 399197679Sdes return (cipher_get_number(active_state->receive_context.cipher)); 40098675Sdes} 40198675Sdes 402124208Sdesvoid 403221420Sdespacket_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, 404221420Sdes u_int32_t *packets, u_int64_t *bytes) 405124208Sdes{ 406124208Sdes struct packet_state *state; 40798675Sdes 408197679Sdes state = (mode == MODE_IN) ? 409197679Sdes &active_state->p_read : &active_state->p_send; 410181111Sdes if (seqnr) 411181111Sdes *seqnr = state->seqnr; 412181111Sdes if (blocks) 413181111Sdes *blocks = state->blocks; 414181111Sdes if (packets) 415181111Sdes *packets = state->packets; 416181111Sdes if (bytes) 417181111Sdes *bytes = state->bytes; 41898675Sdes} 41998675Sdes 42098675Sdesvoid 421181111Sdespacket_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets, 422181111Sdes u_int64_t bytes) 42398675Sdes{ 424124208Sdes struct packet_state *state; 425124208Sdes 426197679Sdes state = (mode == MODE_IN) ? 427197679Sdes &active_state->p_read : &active_state->p_send; 428124208Sdes state->seqnr = seqnr; 429124208Sdes state->blocks = blocks; 430124208Sdes state->packets = packets; 431181111Sdes state->bytes = bytes; 43298675Sdes} 43398675Sdes 434226046Sdesstatic int 435226046Sdespacket_connection_af(void) 43657429Smarkm{ 43757429Smarkm struct sockaddr_storage to; 43857429Smarkm socklen_t tolen = sizeof(to); 43957429Smarkm 44057429Smarkm memset(&to, 0, sizeof(to)); 441197679Sdes if (getsockname(active_state->connection_out, (struct sockaddr *)&to, 442197679Sdes &tolen) < 0) 44357429Smarkm return 0; 44498937Sdes#ifdef IPV4_IN_IPV6 445126274Sdes if (to.ss_family == AF_INET6 && 44698937Sdes IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) 447226046Sdes return AF_INET; 44898937Sdes#endif 449226046Sdes return to.ss_family; 45057429Smarkm} 45157429Smarkm 45257429Smarkm/* Sets the connection into non-blocking mode. */ 45357429Smarkm 45457429Smarkmvoid 45592555Sdespacket_set_nonblocking(void) 45657429Smarkm{ 45757429Smarkm /* Set the socket into non-blocking mode. */ 458197679Sdes set_nonblock(active_state->connection_in); 45957429Smarkm 460197679Sdes if (active_state->connection_out != active_state->connection_in) 461197679Sdes set_nonblock(active_state->connection_out); 46257429Smarkm} 46357429Smarkm 46457429Smarkm/* Returns the socket used for reading. */ 46557429Smarkm 46657429Smarkmint 46792555Sdespacket_get_connection_in(void) 46857429Smarkm{ 469197679Sdes return active_state->connection_in; 47057429Smarkm} 47157429Smarkm 47257429Smarkm/* Returns the descriptor used for writing. */ 47357429Smarkm 47457429Smarkmint 47592555Sdespacket_get_connection_out(void) 47657429Smarkm{ 477197679Sdes return active_state->connection_out; 47857429Smarkm} 47957429Smarkm 48057429Smarkm/* Closes the connection and clears and frees internal data structures. */ 48157429Smarkm 48257429Smarkmvoid 48392555Sdespacket_close(void) 48457429Smarkm{ 485197679Sdes if (!active_state->initialized) 48657429Smarkm return; 487197679Sdes active_state->initialized = 0; 488197679Sdes if (active_state->connection_in == active_state->connection_out) { 489197679Sdes shutdown(active_state->connection_out, SHUT_RDWR); 490197679Sdes close(active_state->connection_out); 49157429Smarkm } else { 492197679Sdes close(active_state->connection_in); 493197679Sdes close(active_state->connection_out); 49457429Smarkm } 495197679Sdes buffer_free(&active_state->input); 496197679Sdes buffer_free(&active_state->output); 497197679Sdes buffer_free(&active_state->outgoing_packet); 498197679Sdes buffer_free(&active_state->incoming_packet); 499197679Sdes if (active_state->compression_buffer_ready) { 500197679Sdes buffer_free(&active_state->compression_buffer); 50157429Smarkm buffer_compress_uninit(); 50257429Smarkm } 503197679Sdes cipher_cleanup(&active_state->send_context); 504197679Sdes cipher_cleanup(&active_state->receive_context); 50557429Smarkm} 50657429Smarkm 50757429Smarkm/* Sets remote side protocol flags. */ 50857429Smarkm 50957429Smarkmvoid 51076259Sgreenpacket_set_protocol_flags(u_int protocol_flags) 51157429Smarkm{ 512197679Sdes active_state->remote_protocol_flags = protocol_flags; 51357429Smarkm} 51457429Smarkm 51557429Smarkm/* Returns the remote protocol flags set earlier by the above function. */ 51657429Smarkm 51776259Sgreenu_int 51892555Sdespacket_get_protocol_flags(void) 51957429Smarkm{ 520197679Sdes return active_state->remote_protocol_flags; 52157429Smarkm} 52257429Smarkm 52357429Smarkm/* 52457429Smarkm * Starts packet compression from the next packet on in both directions. 52557429Smarkm * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. 52657429Smarkm */ 52757429Smarkm 52892555Sdesstatic void 52992555Sdespacket_init_compression(void) 53076259Sgreen{ 531197679Sdes if (active_state->compression_buffer_ready == 1) 53276259Sgreen return; 533197679Sdes active_state->compression_buffer_ready = 1; 534197679Sdes buffer_init(&active_state->compression_buffer); 53576259Sgreen} 53676259Sgreen 53776259Sgreenvoid 53857429Smarkmpacket_start_compression(int level) 53957429Smarkm{ 540197679Sdes if (active_state->packet_compression && !compat20) 54157429Smarkm fatal("Compression already enabled."); 542197679Sdes active_state->packet_compression = 1; 54376259Sgreen packet_init_compression(); 54476259Sgreen buffer_compress_init_send(level); 54576259Sgreen buffer_compress_init_recv(); 54657429Smarkm} 54757429Smarkm 54857429Smarkm/* 54957429Smarkm * Causes any further packets to be encrypted using the given key. The same 55057429Smarkm * key is used for both sending and reception. However, both directions are 55157429Smarkm * encrypted independently of each other. 55257429Smarkm */ 55398675Sdes 55457429Smarkmvoid 555221420Sdespacket_set_encryption_key(const u_char *key, u_int keylen, int number) 55657429Smarkm{ 557255767Sdes const Cipher *cipher = cipher_by_number(number); 558106121Sdes 55969587Sgreen if (cipher == NULL) 56069587Sgreen fatal("packet_set_encryption_key: unknown cipher number %d", number); 56160573Skris if (keylen < 20) 56269587Sgreen fatal("packet_set_encryption_key: keylen too small: %d", keylen); 56398675Sdes if (keylen > SSH_SESSION_KEY_LENGTH) 56498675Sdes fatal("packet_set_encryption_key: keylen too big: %d", keylen); 565197679Sdes memcpy(active_state->ssh1_key, key, keylen); 566197679Sdes active_state->ssh1_keylen = keylen; 567197679Sdes cipher_init(&active_state->send_context, cipher, key, keylen, NULL, 568197679Sdes 0, CIPHER_ENCRYPT); 569197679Sdes cipher_init(&active_state->receive_context, cipher, key, keylen, NULL, 570197679Sdes 0, CIPHER_DECRYPT); 57157429Smarkm} 57257429Smarkm 57398675Sdesu_int 57498675Sdespacket_get_encryption_key(u_char *key) 57598675Sdes{ 57698675Sdes if (key == NULL) 577197679Sdes return (active_state->ssh1_keylen); 578197679Sdes memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen); 579197679Sdes return (active_state->ssh1_keylen); 58098675Sdes} 58198675Sdes 58292555Sdes/* Start constructing a packet to send. */ 58357429Smarkmvoid 58492555Sdespacket_start(u_char type) 58557429Smarkm{ 58692555Sdes u_char buf[9]; 58792555Sdes int len; 58857429Smarkm 58992555Sdes DBG(debug("packet_start[%d]", type)); 59092555Sdes len = compat20 ? 6 : 9; 59192555Sdes memset(buf, 0, len - 1); 59292555Sdes buf[len - 1] = type; 593197679Sdes buffer_clear(&active_state->outgoing_packet); 594197679Sdes buffer_append(&active_state->outgoing_packet, buf, len); 59557429Smarkm} 59657429Smarkm 59792555Sdes/* Append payload. */ 59860573Skrisvoid 59957429Smarkmpacket_put_char(int value) 60057429Smarkm{ 60157429Smarkm char ch = value; 602106121Sdes 603197679Sdes buffer_append(&active_state->outgoing_packet, &ch, 1); 60457429Smarkm} 605162852Sdes 60657429Smarkmvoid 60776259Sgreenpacket_put_int(u_int value) 60857429Smarkm{ 609197679Sdes buffer_put_int(&active_state->outgoing_packet, value); 61057429Smarkm} 611162852Sdes 61257429Smarkmvoid 613197679Sdespacket_put_int64(u_int64_t value) 614197679Sdes{ 615197679Sdes buffer_put_int64(&active_state->outgoing_packet, value); 616197679Sdes} 617197679Sdes 618197679Sdesvoid 61992555Sdespacket_put_string(const void *buf, u_int len) 62057429Smarkm{ 621197679Sdes buffer_put_string(&active_state->outgoing_packet, buf, len); 62257429Smarkm} 623162852Sdes 62460573Skrisvoid 62560573Skrispacket_put_cstring(const char *str) 62660573Skris{ 627197679Sdes buffer_put_cstring(&active_state->outgoing_packet, str); 62860573Skris} 629162852Sdes 63060573Skrisvoid 63192555Sdespacket_put_raw(const void *buf, u_int len) 63260573Skris{ 633197679Sdes buffer_append(&active_state->outgoing_packet, buf, len); 63460573Skris} 635162852Sdes 63657429Smarkmvoid 63757429Smarkmpacket_put_bignum(BIGNUM * value) 63857429Smarkm{ 639197679Sdes buffer_put_bignum(&active_state->outgoing_packet, value); 64057429Smarkm} 641162852Sdes 64260573Skrisvoid 64360573Skrispacket_put_bignum2(BIGNUM * value) 64460573Skris{ 645197679Sdes buffer_put_bignum2(&active_state->outgoing_packet, value); 64660573Skris} 64757429Smarkm 648221420Sdes#ifdef OPENSSL_HAS_ECC 649221420Sdesvoid 650221420Sdespacket_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point) 651221420Sdes{ 652221420Sdes buffer_put_ecpoint(&active_state->outgoing_packet, curve, point); 653221420Sdes} 654221420Sdes#endif 655221420Sdes 65657429Smarkm/* 65757429Smarkm * Finalizes and sends the packet. If the encryption key has been set, 65857429Smarkm * encrypts the packet before sending. 65957429Smarkm */ 66057429Smarkm 66192555Sdesstatic void 66276259Sgreenpacket_send1(void) 66357429Smarkm{ 66492555Sdes u_char buf[8], *cp; 66557429Smarkm int i, padding, len; 66676259Sgreen u_int checksum; 667137015Sdes u_int32_t rnd = 0; 66857429Smarkm 66957429Smarkm /* 67057429Smarkm * If using packet compression, compress the payload of the outgoing 67157429Smarkm * packet. 67257429Smarkm */ 673197679Sdes if (active_state->packet_compression) { 674197679Sdes buffer_clear(&active_state->compression_buffer); 67557429Smarkm /* Skip padding. */ 676197679Sdes buffer_consume(&active_state->outgoing_packet, 8); 67757429Smarkm /* padding */ 678197679Sdes buffer_append(&active_state->compression_buffer, 679197679Sdes "\0\0\0\0\0\0\0\0", 8); 680197679Sdes buffer_compress(&active_state->outgoing_packet, 681197679Sdes &active_state->compression_buffer); 682197679Sdes buffer_clear(&active_state->outgoing_packet); 683197679Sdes buffer_append(&active_state->outgoing_packet, 684197679Sdes buffer_ptr(&active_state->compression_buffer), 685197679Sdes buffer_len(&active_state->compression_buffer)); 68657429Smarkm } 68757429Smarkm /* Compute packet length without padding (add checksum, remove padding). */ 688197679Sdes len = buffer_len(&active_state->outgoing_packet) + 4 - 8; 68957429Smarkm 69060573Skris /* Insert padding. Initialized to zero in packet_start1() */ 69157429Smarkm padding = 8 - len % 8; 692197679Sdes if (!active_state->send_context.plaintext) { 693197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 69457429Smarkm for (i = 0; i < padding; i++) { 69557429Smarkm if (i % 4 == 0) 696137015Sdes rnd = arc4random(); 697137015Sdes cp[7 - i] = rnd & 0xff; 698137015Sdes rnd >>= 8; 69957429Smarkm } 70057429Smarkm } 701197679Sdes buffer_consume(&active_state->outgoing_packet, 8 - padding); 70257429Smarkm 70357429Smarkm /* Add check bytes. */ 704197679Sdes checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet), 705197679Sdes buffer_len(&active_state->outgoing_packet)); 706162852Sdes put_u32(buf, checksum); 707197679Sdes buffer_append(&active_state->outgoing_packet, buf, 4); 70857429Smarkm 70957429Smarkm#ifdef PACKET_DEBUG 71057429Smarkm fprintf(stderr, "packet_send plain: "); 711197679Sdes buffer_dump(&active_state->outgoing_packet); 71257429Smarkm#endif 71357429Smarkm 71457429Smarkm /* Append to output. */ 715162852Sdes put_u32(buf, len); 716197679Sdes buffer_append(&active_state->output, buf, 4); 717197679Sdes cp = buffer_append_space(&active_state->output, 718197679Sdes buffer_len(&active_state->outgoing_packet)); 719197679Sdes cipher_crypt(&active_state->send_context, cp, 720197679Sdes buffer_ptr(&active_state->outgoing_packet), 721248619Sdes buffer_len(&active_state->outgoing_packet), 0, 0); 72257429Smarkm 72357429Smarkm#ifdef PACKET_DEBUG 72457429Smarkm fprintf(stderr, "encrypted: "); 725197679Sdes buffer_dump(&active_state->output); 72657429Smarkm#endif 727197679Sdes active_state->p_send.packets++; 728197679Sdes active_state->p_send.bytes += len + 729197679Sdes buffer_len(&active_state->outgoing_packet); 730197679Sdes buffer_clear(&active_state->outgoing_packet); 73157429Smarkm 73257429Smarkm /* 733157016Sdes * Note that the packet is now only buffered in output. It won't be 73457429Smarkm * actually sent until packet_write_wait or packet_write_poll is 73557429Smarkm * called. 73657429Smarkm */ 73757429Smarkm} 73857429Smarkm 73998675Sdesvoid 74076259Sgreenset_newkeys(int mode) 74176259Sgreen{ 74276259Sgreen Enc *enc; 74376259Sgreen Mac *mac; 74476259Sgreen Comp *comp; 74576259Sgreen CipherContext *cc; 746124208Sdes u_int64_t *max_blocks; 747137015Sdes int crypt_type; 74876259Sgreen 749113908Sdes debug2("set_newkeys: mode %d", mode); 75076259Sgreen 75192555Sdes if (mode == MODE_OUT) { 752197679Sdes cc = &active_state->send_context; 753137015Sdes crypt_type = CIPHER_ENCRYPT; 754197679Sdes active_state->p_send.packets = active_state->p_send.blocks = 0; 755197679Sdes max_blocks = &active_state->max_blocks_out; 75692555Sdes } else { 757197679Sdes cc = &active_state->receive_context; 758137015Sdes crypt_type = CIPHER_DECRYPT; 759197679Sdes active_state->p_read.packets = active_state->p_read.blocks = 0; 760197679Sdes max_blocks = &active_state->max_blocks_in; 76192555Sdes } 762197679Sdes if (active_state->newkeys[mode] != NULL) { 763113908Sdes debug("set_newkeys: rekeying"); 76492555Sdes cipher_cleanup(cc); 765197679Sdes enc = &active_state->newkeys[mode]->enc; 766197679Sdes mac = &active_state->newkeys[mode]->mac; 767197679Sdes comp = &active_state->newkeys[mode]->comp; 768181111Sdes mac_clear(mac); 769248619Sdes memset(enc->iv, 0, enc->iv_len); 770248619Sdes memset(enc->key, 0, enc->key_len); 771248619Sdes memset(mac->key, 0, mac->key_len); 772255767Sdes free(enc->name); 773255767Sdes free(enc->iv); 774255767Sdes free(enc->key); 775255767Sdes free(mac->name); 776255767Sdes free(mac->key); 777255767Sdes free(comp->name); 778255767Sdes free(active_state->newkeys[mode]); 77976259Sgreen } 780197679Sdes active_state->newkeys[mode] = kex_get_newkeys(mode); 781197679Sdes if (active_state->newkeys[mode] == NULL) 78276259Sgreen fatal("newkeys: no keys for mode %d", mode); 783197679Sdes enc = &active_state->newkeys[mode]->enc; 784197679Sdes mac = &active_state->newkeys[mode]->mac; 785197679Sdes comp = &active_state->newkeys[mode]->comp; 786248619Sdes if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0) 78776259Sgreen mac->enabled = 1; 78876259Sgreen DBG(debug("cipher_init_context: %d", mode)); 78992555Sdes cipher_init(cc, enc->cipher, enc->key, enc->key_len, 790248619Sdes enc->iv, enc->iv_len, crypt_type); 79198675Sdes /* Deleting the keys does not gain extra security */ 79298675Sdes /* memset(enc->iv, 0, enc->block_size); 793181111Sdes memset(enc->key, 0, enc->key_len); 794181111Sdes memset(mac->key, 0, mac->key_len); */ 795149749Sdes if ((comp->type == COMP_ZLIB || 796197679Sdes (comp->type == COMP_DELAYED && 797197679Sdes active_state->after_authentication)) && comp->enabled == 0) { 79876259Sgreen packet_init_compression(); 79976259Sgreen if (mode == MODE_OUT) 80076259Sgreen buffer_compress_init_send(6); 80176259Sgreen else 80276259Sgreen buffer_compress_init_recv(); 80376259Sgreen comp->enabled = 1; 80476259Sgreen } 805124208Sdes /* 806124208Sdes * The 2^(blocksize*2) limit is too expensive for 3DES, 807124208Sdes * blowfish, etc, so enforce a 1GB limit for small blocksizes. 808124208Sdes */ 809124208Sdes if (enc->block_size >= 16) 810124208Sdes *max_blocks = (u_int64_t)1 << (enc->block_size*2); 811124208Sdes else 812124208Sdes *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; 813197679Sdes if (active_state->rekey_limit) 814197679Sdes *max_blocks = MIN(*max_blocks, 815197679Sdes active_state->rekey_limit / enc->block_size); 81676259Sgreen} 81776259Sgreen 81857429Smarkm/* 819149749Sdes * Delayed compression for SSH2 is enabled after authentication: 820162852Sdes * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, 821149749Sdes * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. 822149749Sdes */ 823149749Sdesstatic void 824149749Sdespacket_enable_delayed_compress(void) 825149749Sdes{ 826149749Sdes Comp *comp = NULL; 827149749Sdes int mode; 828149749Sdes 829149749Sdes /* 830149749Sdes * Remember that we are past the authentication step, so rekeying 831149749Sdes * with COMP_DELAYED will turn on compression immediately. 832149749Sdes */ 833197679Sdes active_state->after_authentication = 1; 834149749Sdes for (mode = 0; mode < MODE_MAX; mode++) { 835162852Sdes /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ 836197679Sdes if (active_state->newkeys[mode] == NULL) 837162852Sdes continue; 838197679Sdes comp = &active_state->newkeys[mode]->comp; 839149749Sdes if (comp && !comp->enabled && comp->type == COMP_DELAYED) { 840149749Sdes packet_init_compression(); 841149749Sdes if (mode == MODE_OUT) 842149749Sdes buffer_compress_init_send(6); 843149749Sdes else 844149749Sdes buffer_compress_init_recv(); 845149749Sdes comp->enabled = 1; 846149749Sdes } 847149749Sdes } 848149749Sdes} 849149749Sdes 850149749Sdes/* 85160573Skris * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) 85260573Skris */ 85392555Sdesstatic void 854124208Sdespacket_send2_wrapped(void) 85560573Skris{ 85692555Sdes u_char type, *cp, *macbuf = NULL; 857248619Sdes u_char padlen, pad = 0; 858248619Sdes u_int i, len, authlen = 0, aadlen = 0; 859137015Sdes u_int32_t rnd = 0; 86060573Skris Enc *enc = NULL; 86160573Skris Mac *mac = NULL; 86260573Skris Comp *comp = NULL; 86360573Skris int block_size; 86460573Skris 865197679Sdes if (active_state->newkeys[MODE_OUT] != NULL) { 866197679Sdes enc = &active_state->newkeys[MODE_OUT]->enc; 867197679Sdes mac = &active_state->newkeys[MODE_OUT]->mac; 868197679Sdes comp = &active_state->newkeys[MODE_OUT]->comp; 869248619Sdes /* disable mac for authenticated encryption */ 870248619Sdes if ((authlen = cipher_authlen(enc->cipher)) != 0) 871248619Sdes mac = NULL; 87260573Skris } 87392555Sdes block_size = enc ? enc->block_size : 8; 874248619Sdes aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; 87560573Skris 876197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 87792555Sdes type = cp[5]; 87860573Skris 87960573Skris#ifdef PACKET_DEBUG 88060573Skris fprintf(stderr, "plain: "); 881197679Sdes buffer_dump(&active_state->outgoing_packet); 88260573Skris#endif 88360573Skris 88460573Skris if (comp && comp->enabled) { 885197679Sdes len = buffer_len(&active_state->outgoing_packet); 88660573Skris /* skip header, compress only payload */ 887197679Sdes buffer_consume(&active_state->outgoing_packet, 5); 888197679Sdes buffer_clear(&active_state->compression_buffer); 889197679Sdes buffer_compress(&active_state->outgoing_packet, 890197679Sdes &active_state->compression_buffer); 891197679Sdes buffer_clear(&active_state->outgoing_packet); 892197679Sdes buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5); 893197679Sdes buffer_append(&active_state->outgoing_packet, 894197679Sdes buffer_ptr(&active_state->compression_buffer), 895197679Sdes buffer_len(&active_state->compression_buffer)); 89660573Skris DBG(debug("compression: raw %d compressed %d", len, 897197679Sdes buffer_len(&active_state->outgoing_packet))); 89860573Skris } 89960573Skris 90060573Skris /* sizeof (packet_len + pad_len + payload) */ 901197679Sdes len = buffer_len(&active_state->outgoing_packet); 90260573Skris 90360573Skris /* 90460573Skris * calc size of padding, alloc space, get random data, 90560573Skris * minimum padding is 4 bytes 90660573Skris */ 907248619Sdes len -= aadlen; /* packet length is not encrypted for EtM modes */ 90860573Skris padlen = block_size - (len % block_size); 90960573Skris if (padlen < 4) 91060573Skris padlen += block_size; 911197679Sdes if (active_state->extra_pad) { 91292555Sdes /* will wrap if extra_pad+padlen > 255 */ 913197679Sdes active_state->extra_pad = 914197679Sdes roundup(active_state->extra_pad, block_size); 915197679Sdes pad = active_state->extra_pad - 916197679Sdes ((len + padlen) % active_state->extra_pad); 91798675Sdes debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)", 918197679Sdes pad, len, padlen, active_state->extra_pad); 91992555Sdes padlen += pad; 920197679Sdes active_state->extra_pad = 0; 92192555Sdes } 922197679Sdes cp = buffer_append_space(&active_state->outgoing_packet, padlen); 923197679Sdes if (enc && !active_state->send_context.plaintext) { 92460573Skris /* random padding */ 92560573Skris for (i = 0; i < padlen; i++) { 92660573Skris if (i % 4 == 0) 927137015Sdes rnd = arc4random(); 928137015Sdes cp[i] = rnd & 0xff; 929137015Sdes rnd >>= 8; 93060573Skris } 93160573Skris } else { 93260573Skris /* clear padding */ 93360573Skris memset(cp, 0, padlen); 93460573Skris } 935248619Sdes /* sizeof (packet_len + pad_len + payload + padding) */ 936248619Sdes len = buffer_len(&active_state->outgoing_packet); 937248619Sdes cp = buffer_ptr(&active_state->outgoing_packet); 93860573Skris /* packet_length includes payload, padding and padding length field */ 939248619Sdes put_u32(cp, len - 4); 94092555Sdes cp[4] = padlen; 941248619Sdes DBG(debug("send: len %d (includes padlen %d, aadlen %d)", 942248619Sdes len, padlen, aadlen)); 94360573Skris 94460573Skris /* compute MAC over seqnr and packet(length fields, payload, padding) */ 945248619Sdes if (mac && mac->enabled && !mac->etm) { 946197679Sdes macbuf = mac_compute(mac, active_state->p_send.seqnr, 947248619Sdes buffer_ptr(&active_state->outgoing_packet), len); 948197679Sdes DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr)); 94960573Skris } 95060573Skris /* encrypt packet and append to output buffer. */ 951248619Sdes cp = buffer_append_space(&active_state->output, len + authlen); 952197679Sdes cipher_crypt(&active_state->send_context, cp, 953197679Sdes buffer_ptr(&active_state->outgoing_packet), 954248619Sdes len - aadlen, aadlen, authlen); 95560573Skris /* append unencrypted MAC */ 956248619Sdes if (mac && mac->enabled) { 957248619Sdes if (mac->etm) { 958248619Sdes /* EtM: compute mac over aadlen + cipher text */ 959248619Sdes macbuf = mac_compute(mac, 960248619Sdes active_state->p_send.seqnr, cp, len); 961248619Sdes DBG(debug("done calc MAC(EtM) out #%d", 962248619Sdes active_state->p_send.seqnr)); 963248619Sdes } 964197679Sdes buffer_append(&active_state->output, macbuf, mac->mac_len); 965248619Sdes } 96660573Skris#ifdef PACKET_DEBUG 96760573Skris fprintf(stderr, "encrypted: "); 968197679Sdes buffer_dump(&active_state->output); 96960573Skris#endif 97060573Skris /* increment sequence number for outgoing packets */ 971197679Sdes if (++active_state->p_send.seqnr == 0) 972124208Sdes logit("outgoing seqnr wraps around"); 973197679Sdes if (++active_state->p_send.packets == 0) 974124208Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 975124208Sdes fatal("XXX too many packets with same key"); 976248619Sdes active_state->p_send.blocks += len / block_size; 977248619Sdes active_state->p_send.bytes += len; 978197679Sdes buffer_clear(&active_state->outgoing_packet); 97960573Skris 98076259Sgreen if (type == SSH2_MSG_NEWKEYS) 98176259Sgreen set_newkeys(MODE_OUT); 982197679Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side) 983149749Sdes packet_enable_delayed_compress(); 98460573Skris} 98560573Skris 986124208Sdesstatic void 987124208Sdespacket_send2(void) 988124208Sdes{ 989124208Sdes struct packet *p; 990124208Sdes u_char type, *cp; 991124208Sdes 992197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 993124208Sdes type = cp[5]; 994124208Sdes 995124208Sdes /* during rekeying we can only send key exchange messages */ 996197679Sdes if (active_state->rekeying) { 997240075Sdes if ((type < SSH2_MSG_TRANSPORT_MIN) || 998240075Sdes (type > SSH2_MSG_TRANSPORT_MAX) || 999240075Sdes (type == SSH2_MSG_SERVICE_REQUEST) || 1000240075Sdes (type == SSH2_MSG_SERVICE_ACCEPT)) { 1001124208Sdes debug("enqueue packet: %u", type); 1002258343Sdes p = xcalloc(1, sizeof(*p)); 1003124208Sdes p->type = type; 1004197679Sdes memcpy(&p->payload, &active_state->outgoing_packet, 1005197679Sdes sizeof(Buffer)); 1006197679Sdes buffer_init(&active_state->outgoing_packet); 1007197679Sdes TAILQ_INSERT_TAIL(&active_state->outgoing, p, next); 1008124208Sdes return; 1009124208Sdes } 1010124208Sdes } 1011124208Sdes 1012124208Sdes /* rekeying starts with sending KEXINIT */ 1013124208Sdes if (type == SSH2_MSG_KEXINIT) 1014197679Sdes active_state->rekeying = 1; 1015124208Sdes 1016124208Sdes packet_send2_wrapped(); 1017124208Sdes 1018124208Sdes /* after a NEWKEYS message we can send the complete queue */ 1019124208Sdes if (type == SSH2_MSG_NEWKEYS) { 1020197679Sdes active_state->rekeying = 0; 1021255767Sdes active_state->rekey_time = monotime(); 1022197679Sdes while ((p = TAILQ_FIRST(&active_state->outgoing))) { 1023124208Sdes type = p->type; 1024124208Sdes debug("dequeue packet: %u", type); 1025197679Sdes buffer_free(&active_state->outgoing_packet); 1026197679Sdes memcpy(&active_state->outgoing_packet, &p->payload, 1027124208Sdes sizeof(Buffer)); 1028197679Sdes TAILQ_REMOVE(&active_state->outgoing, p, next); 1029255767Sdes free(p); 1030124208Sdes packet_send2_wrapped(); 1031124208Sdes } 1032124208Sdes } 1033124208Sdes} 1034124208Sdes 103560573Skrisvoid 103692555Sdespacket_send(void) 103760573Skris{ 103892555Sdes if (compat20) 103960573Skris packet_send2(); 104060573Skris else 104160573Skris packet_send1(); 104260573Skris DBG(debug("packet_send done")); 104360573Skris} 104460573Skris 104560573Skris/* 104657429Smarkm * Waits until a packet has been received, and returns its type. Note that 104757429Smarkm * no other data is processed until this returns, so this function should not 104857429Smarkm * be used during the interactive session. 104957429Smarkm */ 105057429Smarkm 105157429Smarkmint 105292555Sdespacket_read_seqnr(u_int32_t *seqnr_p) 105357429Smarkm{ 1054255767Sdes int type, len, ret, cont, ms_remain = 0; 105576259Sgreen fd_set *setp; 105657429Smarkm char buf[8192]; 1057181111Sdes struct timeval timeout, start, *timeoutp = NULL; 1058181111Sdes 105960573Skris DBG(debug("packet_read()")); 106057429Smarkm 1061197679Sdes setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1, 1062197679Sdes NFDBITS), sizeof(fd_mask)); 106376259Sgreen 106457429Smarkm /* Since we are blocking, ensure that all written packets have been sent. */ 106557429Smarkm packet_write_wait(); 106657429Smarkm 106757429Smarkm /* Stay in the loop until we have received a complete packet. */ 106857429Smarkm for (;;) { 106957429Smarkm /* Try to read a packet from the buffer. */ 107092555Sdes type = packet_read_poll_seqnr(seqnr_p); 107192555Sdes if (!compat20 && ( 107260573Skris type == SSH_SMSG_SUCCESS 107357429Smarkm || type == SSH_SMSG_FAILURE 107457429Smarkm || type == SSH_CMSG_EOF 107560573Skris || type == SSH_CMSG_EXIT_CONFIRMATION)) 107692555Sdes packet_check_eom(); 107757429Smarkm /* If we got a packet, return it. */ 107876259Sgreen if (type != SSH_MSG_NONE) { 1079255767Sdes free(setp); 108057429Smarkm return type; 108176259Sgreen } 108257429Smarkm /* 108357429Smarkm * Otherwise, wait for some data to arrive, add it to the 108457429Smarkm * buffer, and try again. 108557429Smarkm */ 1086197679Sdes memset(setp, 0, howmany(active_state->connection_in + 1, 1087197679Sdes NFDBITS) * sizeof(fd_mask)); 1088197679Sdes FD_SET(active_state->connection_in, setp); 108957429Smarkm 1090197679Sdes if (active_state->packet_timeout_ms > 0) { 1091197679Sdes ms_remain = active_state->packet_timeout_ms; 1092181111Sdes timeoutp = &timeout; 1093181111Sdes } 109457429Smarkm /* Wait for some data to arrive. */ 1095181111Sdes for (;;) { 1096197679Sdes if (active_state->packet_timeout_ms != -1) { 1097181111Sdes ms_to_timeval(&timeout, ms_remain); 1098181111Sdes gettimeofday(&start, NULL); 1099181111Sdes } 1100197679Sdes if ((ret = select(active_state->connection_in + 1, setp, 1101197679Sdes NULL, NULL, timeoutp)) >= 0) 1102181111Sdes break; 1103197679Sdes if (errno != EAGAIN && errno != EINTR && 1104181111Sdes errno != EWOULDBLOCK) 1105181111Sdes break; 1106197679Sdes if (active_state->packet_timeout_ms == -1) 1107181111Sdes continue; 1108181111Sdes ms_subtract_diff(&start, &ms_remain); 1109181111Sdes if (ms_remain <= 0) { 1110181111Sdes ret = 0; 1111181111Sdes break; 1112181111Sdes } 1113181111Sdes } 1114181111Sdes if (ret == 0) { 1115181111Sdes logit("Connection to %.200s timed out while " 1116181111Sdes "waiting to read", get_remote_ipaddr()); 1117181111Sdes cleanup_exit(255); 1118181111Sdes } 111957429Smarkm /* Read data from the socket. */ 1120197679Sdes do { 1121197679Sdes cont = 0; 1122197679Sdes len = roaming_read(active_state->connection_in, buf, 1123197679Sdes sizeof(buf), &cont); 1124197679Sdes } while (len == 0 && cont); 112557429Smarkm if (len == 0) { 1126124208Sdes logit("Connection closed by %.200s", get_remote_ipaddr()); 1127126274Sdes cleanup_exit(255); 112857429Smarkm } 112957429Smarkm if (len < 0) 113057429Smarkm fatal("Read from socket failed: %.100s", strerror(errno)); 113157429Smarkm /* Append it to the buffer. */ 113257429Smarkm packet_process_incoming(buf, len); 113357429Smarkm } 113457429Smarkm /* NOTREACHED */ 113557429Smarkm} 113657429Smarkm 113792555Sdesint 113892555Sdespacket_read(void) 113992555Sdes{ 114092555Sdes return packet_read_seqnr(NULL); 114192555Sdes} 114292555Sdes 114357429Smarkm/* 114457429Smarkm * Waits until a packet has been received, verifies that its type matches 114557429Smarkm * that given, and gives a fatal error and exits if there is a mismatch. 114657429Smarkm */ 114757429Smarkm 114857429Smarkmvoid 114992555Sdespacket_read_expect(int expected_type) 115057429Smarkm{ 115157429Smarkm int type; 115257429Smarkm 115392555Sdes type = packet_read(); 115457429Smarkm if (type != expected_type) 115557429Smarkm packet_disconnect("Protocol error: expected packet type %d, got %d", 115660573Skris expected_type, type); 115757429Smarkm} 115857429Smarkm 115957429Smarkm/* Checks if a full packet is available in the data received so far via 116057429Smarkm * packet_process_incoming. If so, reads the packet; otherwise returns 116157429Smarkm * SSH_MSG_NONE. This does not wait for data from the connection. 116257429Smarkm * 116357429Smarkm * SSH_MSG_DISCONNECT is handled specially here. Also, 116457429Smarkm * SSH_MSG_IGNORE messages are skipped by this function and are never returned 116557429Smarkm * to higher levels. 116657429Smarkm */ 116757429Smarkm 116892555Sdesstatic int 116992555Sdespacket_read_poll1(void) 117057429Smarkm{ 117176259Sgreen u_int len, padded_len; 117292555Sdes u_char *cp, type; 117376259Sgreen u_int checksum, stored_checksum; 117457429Smarkm 117557429Smarkm /* Check if input size is less than minimum packet size. */ 1176197679Sdes if (buffer_len(&active_state->input) < 4 + 8) 117757429Smarkm return SSH_MSG_NONE; 117857429Smarkm /* Get length of incoming packet. */ 1179197679Sdes cp = buffer_ptr(&active_state->input); 1180162852Sdes len = get_u32(cp); 118157429Smarkm if (len < 1 + 2 + 2 || len > 256 * 1024) 1182113908Sdes packet_disconnect("Bad packet length %u.", len); 118357429Smarkm padded_len = (len + 8) & ~7; 118457429Smarkm 118557429Smarkm /* Check if the packet has been entirely received. */ 1186197679Sdes if (buffer_len(&active_state->input) < 4 + padded_len) 118757429Smarkm return SSH_MSG_NONE; 118857429Smarkm 118957429Smarkm /* The entire packet is in buffer. */ 119057429Smarkm 119157429Smarkm /* Consume packet length. */ 1192197679Sdes buffer_consume(&active_state->input, 4); 119357429Smarkm 119492555Sdes /* 119592555Sdes * Cryptographic attack detector for ssh 119692555Sdes * (C)1998 CORE-SDI, Buenos Aires Argentina 119792555Sdes * Ariel Futoransky(futo@core-sdi.com) 119892555Sdes */ 1199197679Sdes if (!active_state->receive_context.plaintext) { 1200197679Sdes switch (detect_attack(buffer_ptr(&active_state->input), 1201197679Sdes padded_len)) { 1202162852Sdes case DEATTACK_DETECTED: 1203162852Sdes packet_disconnect("crc32 compensation attack: " 1204162852Sdes "network attack detected"); 1205162852Sdes case DEATTACK_DOS_DETECTED: 1206162852Sdes packet_disconnect("deattack denial of " 1207162852Sdes "service detected"); 1208162852Sdes } 1209162852Sdes } 121092555Sdes 121192555Sdes /* Decrypt data to incoming_packet. */ 1212197679Sdes buffer_clear(&active_state->incoming_packet); 1213197679Sdes cp = buffer_append_space(&active_state->incoming_packet, padded_len); 1214197679Sdes cipher_crypt(&active_state->receive_context, cp, 1215248619Sdes buffer_ptr(&active_state->input), padded_len, 0, 0); 121692555Sdes 1217197679Sdes buffer_consume(&active_state->input, padded_len); 121857429Smarkm 121957429Smarkm#ifdef PACKET_DEBUG 122057429Smarkm fprintf(stderr, "read_poll plain: "); 1221197679Sdes buffer_dump(&active_state->incoming_packet); 122257429Smarkm#endif 122357429Smarkm 122457429Smarkm /* Compute packet checksum. */ 1225197679Sdes checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet), 1226197679Sdes buffer_len(&active_state->incoming_packet) - 4); 122757429Smarkm 122857429Smarkm /* Skip padding. */ 1229197679Sdes buffer_consume(&active_state->incoming_packet, 8 - len % 8); 123057429Smarkm 123157429Smarkm /* Test check bytes. */ 1232197679Sdes if (len != buffer_len(&active_state->incoming_packet)) 123392555Sdes packet_disconnect("packet_read_poll1: len %d != buffer_len %d.", 1234197679Sdes len, buffer_len(&active_state->incoming_packet)); 123557429Smarkm 1236197679Sdes cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4; 1237162852Sdes stored_checksum = get_u32(cp); 123857429Smarkm if (checksum != stored_checksum) 123957429Smarkm packet_disconnect("Corrupted check bytes on input."); 1240197679Sdes buffer_consume_end(&active_state->incoming_packet, 4); 124157429Smarkm 1242197679Sdes if (active_state->packet_compression) { 1243197679Sdes buffer_clear(&active_state->compression_buffer); 1244197679Sdes buffer_uncompress(&active_state->incoming_packet, 1245197679Sdes &active_state->compression_buffer); 1246197679Sdes buffer_clear(&active_state->incoming_packet); 1247197679Sdes buffer_append(&active_state->incoming_packet, 1248197679Sdes buffer_ptr(&active_state->compression_buffer), 1249197679Sdes buffer_len(&active_state->compression_buffer)); 125057429Smarkm } 1251197679Sdes active_state->p_read.packets++; 1252197679Sdes active_state->p_read.bytes += padded_len + 4; 1253197679Sdes type = buffer_get_char(&active_state->incoming_packet); 1254146998Sdes if (type < SSH_MSG_MIN || type > SSH_MSG_MAX) 1255146998Sdes packet_disconnect("Invalid ssh1 packet type: %d", type); 125692555Sdes return type; 125760573Skris} 125857429Smarkm 125992555Sdesstatic int 126092555Sdespacket_read_poll2(u_int32_t *seqnr_p) 126160573Skris{ 126276259Sgreen u_int padlen, need; 1263248619Sdes u_char *macbuf = NULL, *cp, type; 1264248619Sdes u_int maclen, authlen = 0, aadlen = 0, block_size; 126560573Skris Enc *enc = NULL; 126660573Skris Mac *mac = NULL; 126760573Skris Comp *comp = NULL; 126857429Smarkm 1269197679Sdes if (active_state->packet_discard) 1270192595Sdes return SSH_MSG_NONE; 1271192595Sdes 1272197679Sdes if (active_state->newkeys[MODE_IN] != NULL) { 1273197679Sdes enc = &active_state->newkeys[MODE_IN]->enc; 1274197679Sdes mac = &active_state->newkeys[MODE_IN]->mac; 1275197679Sdes comp = &active_state->newkeys[MODE_IN]->comp; 1276248619Sdes /* disable mac for authenticated encryption */ 1277248619Sdes if ((authlen = cipher_authlen(enc->cipher)) != 0) 1278248619Sdes mac = NULL; 127957429Smarkm } 128060573Skris maclen = mac && mac->enabled ? mac->mac_len : 0; 128192555Sdes block_size = enc ? enc->block_size : 8; 1282248619Sdes aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; 128360573Skris 1284248619Sdes if (aadlen && active_state->packlen == 0) { 1285248619Sdes if (buffer_len(&active_state->input) < 4) 1286248619Sdes return SSH_MSG_NONE; 1287248619Sdes cp = buffer_ptr(&active_state->input); 1288248619Sdes active_state->packlen = get_u32(cp); 1289248619Sdes if (active_state->packlen < 1 + 4 || 1290248619Sdes active_state->packlen > PACKET_MAX_SIZE) { 1291248619Sdes#ifdef PACKET_DEBUG 1292248619Sdes buffer_dump(&active_state->input); 1293248619Sdes#endif 1294248619Sdes logit("Bad packet length %u.", active_state->packlen); 1295248619Sdes packet_disconnect("Packet corrupt"); 1296248619Sdes } 1297248619Sdes buffer_clear(&active_state->incoming_packet); 1298248619Sdes } else if (active_state->packlen == 0) { 129960573Skris /* 130060573Skris * check if input size is less than the cipher block size, 130160573Skris * decrypt first block and extract length of incoming packet 130260573Skris */ 1303197679Sdes if (buffer_len(&active_state->input) < block_size) 130460573Skris return SSH_MSG_NONE; 1305197679Sdes buffer_clear(&active_state->incoming_packet); 1306197679Sdes cp = buffer_append_space(&active_state->incoming_packet, 130760573Skris block_size); 1308197679Sdes cipher_crypt(&active_state->receive_context, cp, 1309248619Sdes buffer_ptr(&active_state->input), block_size, 0, 0); 1310197679Sdes cp = buffer_ptr(&active_state->incoming_packet); 1311240075Sdes 1312197679Sdes active_state->packlen = get_u32(cp); 1313197679Sdes if (active_state->packlen < 1 + 4 || 1314197679Sdes active_state->packlen > PACKET_MAX_SIZE) { 1315124208Sdes#ifdef PACKET_DEBUG 1316197679Sdes buffer_dump(&active_state->incoming_packet); 1317124208Sdes#endif 1318197679Sdes logit("Bad packet length %u.", active_state->packlen); 1319197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1320192595Sdes PACKET_MAX_SIZE); 1321192595Sdes return SSH_MSG_NONE; 132260573Skris } 1323197679Sdes buffer_consume(&active_state->input, block_size); 132460573Skris } 1325248619Sdes DBG(debug("input: packet len %u", active_state->packlen+4)); 1326248619Sdes if (aadlen) { 1327248619Sdes /* only the payload is encrypted */ 1328248619Sdes need = active_state->packlen; 1329248619Sdes } else { 1330248619Sdes /* 1331248619Sdes * the payload size and the payload are encrypted, but we 1332248619Sdes * have a partial packet of block_size bytes 1333248619Sdes */ 1334248619Sdes need = 4 + active_state->packlen - block_size; 1335248619Sdes } 1336248619Sdes DBG(debug("partial packet: block %d, need %d, maclen %d, authlen %d," 1337248619Sdes " aadlen %d", block_size, need, maclen, authlen, aadlen)); 1338192595Sdes if (need % block_size != 0) { 1339192595Sdes logit("padding error: need %d block %d mod %d", 134060573Skris need, block_size, need % block_size); 1341197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1342192595Sdes PACKET_MAX_SIZE - block_size); 1343192595Sdes return SSH_MSG_NONE; 1344192595Sdes } 134560573Skris /* 134660573Skris * check if the entire packet has been received and 1347248619Sdes * decrypt into incoming_packet: 1348248619Sdes * 'aadlen' bytes are unencrypted, but authenticated. 1349248619Sdes * 'need' bytes are encrypted, followed by either 1350248619Sdes * 'authlen' bytes of authentication tag or 1351248619Sdes * 'maclen' bytes of message authentication code. 135260573Skris */ 1353248619Sdes if (buffer_len(&active_state->input) < aadlen + need + authlen + maclen) 135460573Skris return SSH_MSG_NONE; 135560573Skris#ifdef PACKET_DEBUG 135660573Skris fprintf(stderr, "read_poll enc/full: "); 1357197679Sdes buffer_dump(&active_state->input); 135860573Skris#endif 1359248619Sdes /* EtM: compute mac over encrypted input */ 1360248619Sdes if (mac && mac->enabled && mac->etm) 1361248619Sdes macbuf = mac_compute(mac, active_state->p_read.seqnr, 1362248619Sdes buffer_ptr(&active_state->input), aadlen + need); 1363248619Sdes cp = buffer_append_space(&active_state->incoming_packet, aadlen + need); 1364197679Sdes cipher_crypt(&active_state->receive_context, cp, 1365248619Sdes buffer_ptr(&active_state->input), need, aadlen, authlen); 1366248619Sdes buffer_consume(&active_state->input, aadlen + need + authlen); 136760573Skris /* 136860573Skris * compute MAC over seqnr and packet, 136960573Skris * increment sequence number for incoming packet 137060573Skris */ 137160573Skris if (mac && mac->enabled) { 1372248619Sdes if (!mac->etm) 1373248619Sdes macbuf = mac_compute(mac, active_state->p_read.seqnr, 1374248619Sdes buffer_ptr(&active_state->incoming_packet), 1375248619Sdes buffer_len(&active_state->incoming_packet)); 1376215116Sdes if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input), 1377197679Sdes mac->mac_len) != 0) { 1378192595Sdes logit("Corrupted MAC on input."); 1379192595Sdes if (need > PACKET_MAX_SIZE) 1380192595Sdes fatal("internal error need %d", need); 1381197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1382192595Sdes PACKET_MAX_SIZE - need); 1383192595Sdes return SSH_MSG_NONE; 1384192595Sdes } 1385192595Sdes 1386197679Sdes DBG(debug("MAC #%d ok", active_state->p_read.seqnr)); 1387197679Sdes buffer_consume(&active_state->input, mac->mac_len); 138860573Skris } 1389192595Sdes /* XXX now it's safe to use fatal/packet_disconnect */ 139092555Sdes if (seqnr_p != NULL) 1391197679Sdes *seqnr_p = active_state->p_read.seqnr; 1392197679Sdes if (++active_state->p_read.seqnr == 0) 1393124208Sdes logit("incoming seqnr wraps around"); 1394197679Sdes if (++active_state->p_read.packets == 0) 1395124208Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 1396124208Sdes fatal("XXX too many packets with same key"); 1397197679Sdes active_state->p_read.blocks += (active_state->packlen + 4) / block_size; 1398197679Sdes active_state->p_read.bytes += active_state->packlen + 4; 139960573Skris 140060573Skris /* get padlen */ 1401197679Sdes cp = buffer_ptr(&active_state->incoming_packet); 140292555Sdes padlen = cp[4]; 140360573Skris DBG(debug("input: padlen %d", padlen)); 140460573Skris if (padlen < 4) 140560573Skris packet_disconnect("Corrupted padlen %d on input.", padlen); 140660573Skris 140760573Skris /* skip packet size + padlen, discard padding */ 1408197679Sdes buffer_consume(&active_state->incoming_packet, 4 + 1); 1409197679Sdes buffer_consume_end(&active_state->incoming_packet, padlen); 141060573Skris 1411197679Sdes DBG(debug("input: len before de-compress %d", 1412197679Sdes buffer_len(&active_state->incoming_packet))); 141360573Skris if (comp && comp->enabled) { 1414197679Sdes buffer_clear(&active_state->compression_buffer); 1415197679Sdes buffer_uncompress(&active_state->incoming_packet, 1416197679Sdes &active_state->compression_buffer); 1417197679Sdes buffer_clear(&active_state->incoming_packet); 1418197679Sdes buffer_append(&active_state->incoming_packet, 1419197679Sdes buffer_ptr(&active_state->compression_buffer), 1420197679Sdes buffer_len(&active_state->compression_buffer)); 1421106121Sdes DBG(debug("input: len after de-compress %d", 1422197679Sdes buffer_len(&active_state->incoming_packet))); 142360573Skris } 142460573Skris /* 142560573Skris * get packet type, implies consume. 142660573Skris * return length of payload (without type field) 142760573Skris */ 1428197679Sdes type = buffer_get_char(&active_state->incoming_packet); 1429146998Sdes if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN) 1430146998Sdes packet_disconnect("Invalid ssh2 packet type: %d", type); 143176259Sgreen if (type == SSH2_MSG_NEWKEYS) 143276259Sgreen set_newkeys(MODE_IN); 1433197679Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && 1434197679Sdes !active_state->server_side) 1435149749Sdes packet_enable_delayed_compress(); 143660573Skris#ifdef PACKET_DEBUG 143776259Sgreen fprintf(stderr, "read/plain[%d]:\r\n", type); 1438197679Sdes buffer_dump(&active_state->incoming_packet); 143960573Skris#endif 144092555Sdes /* reset for next packet */ 1441197679Sdes active_state->packlen = 0; 144292555Sdes return type; 144357429Smarkm} 144457429Smarkm 144560573Skrisint 144692555Sdespacket_read_poll_seqnr(u_int32_t *seqnr_p) 144760573Skris{ 144899060Sdes u_int reason, seqnr; 144992555Sdes u_char type; 145060573Skris char *msg; 145192555Sdes 145260573Skris for (;;) { 145392555Sdes if (compat20) { 145492555Sdes type = packet_read_poll2(seqnr_p); 1455181111Sdes if (type) { 1456197679Sdes active_state->keep_alive_timeouts = 0; 145760573Skris DBG(debug("received packet type %d", type)); 1458181111Sdes } 145992555Sdes switch (type) { 146060573Skris case SSH2_MSG_IGNORE: 1461181111Sdes debug3("Received SSH2_MSG_IGNORE"); 146260573Skris break; 146360573Skris case SSH2_MSG_DEBUG: 146460573Skris packet_get_char(); 146560573Skris msg = packet_get_string(NULL); 146660573Skris debug("Remote: %.900s", msg); 1467255767Sdes free(msg); 146860573Skris msg = packet_get_string(NULL); 1469255767Sdes free(msg); 147060573Skris break; 147160573Skris case SSH2_MSG_DISCONNECT: 147260573Skris reason = packet_get_int(); 147360573Skris msg = packet_get_string(NULL); 1474249475Sdes /* Ignore normal client exit notifications */ 1475249475Sdes do_log2(active_state->server_side && 1476249475Sdes reason == SSH2_DISCONNECT_BY_APPLICATION ? 1477250739Sdes SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, 1478249475Sdes "Received disconnect from %s: %u: %.400s", 147999060Sdes get_remote_ipaddr(), reason, msg); 1480255767Sdes free(msg); 1481126274Sdes cleanup_exit(255); 148260573Skris break; 148392555Sdes case SSH2_MSG_UNIMPLEMENTED: 148492555Sdes seqnr = packet_get_int(); 148599060Sdes debug("Received SSH2_MSG_UNIMPLEMENTED for %u", 148699060Sdes seqnr); 148792555Sdes break; 148860573Skris default: 148960573Skris return type; 149076259Sgreen } 149160573Skris } else { 149292555Sdes type = packet_read_poll1(); 149392555Sdes switch (type) { 1494255767Sdes case SSH_MSG_NONE: 1495255767Sdes return SSH_MSG_NONE; 149660573Skris case SSH_MSG_IGNORE: 149760573Skris break; 149860573Skris case SSH_MSG_DEBUG: 149960573Skris msg = packet_get_string(NULL); 150060573Skris debug("Remote: %.900s", msg); 1501255767Sdes free(msg); 150260573Skris break; 150360573Skris case SSH_MSG_DISCONNECT: 150460573Skris msg = packet_get_string(NULL); 1505249475Sdes logit("Received disconnect from %s: %.400s", 150699060Sdes get_remote_ipaddr(), msg); 1507126274Sdes cleanup_exit(255); 150860573Skris break; 150960573Skris default: 1510255767Sdes DBG(debug("received packet type %d", type)); 151160573Skris return type; 151276259Sgreen } 151360573Skris } 151460573Skris } 151560573Skris} 151660573Skris 151757429Smarkm/* 151857429Smarkm * Buffers the given amount of input characters. This is intended to be used 151957429Smarkm * together with packet_read_poll. 152057429Smarkm */ 152157429Smarkm 152257429Smarkmvoid 152376259Sgreenpacket_process_incoming(const char *buf, u_int len) 152457429Smarkm{ 1525197679Sdes if (active_state->packet_discard) { 1526197679Sdes active_state->keep_alive_timeouts = 0; /* ?? */ 1527197679Sdes if (len >= active_state->packet_discard) 1528192595Sdes packet_stop_discard(); 1529197679Sdes active_state->packet_discard -= len; 1530192595Sdes return; 1531192595Sdes } 1532197679Sdes buffer_append(&active_state->input, buf, len); 153357429Smarkm} 153457429Smarkm 153557429Smarkm/* Returns a character from the packet. */ 153657429Smarkm 153776259Sgreenu_int 153892555Sdespacket_get_char(void) 153957429Smarkm{ 154057429Smarkm char ch; 1541106121Sdes 1542197679Sdes buffer_get(&active_state->incoming_packet, &ch, 1); 154376259Sgreen return (u_char) ch; 154457429Smarkm} 154557429Smarkm 154657429Smarkm/* Returns an integer from the packet data. */ 154757429Smarkm 154876259Sgreenu_int 154992555Sdespacket_get_int(void) 155057429Smarkm{ 1551197679Sdes return buffer_get_int(&active_state->incoming_packet); 155257429Smarkm} 155357429Smarkm 1554197679Sdes/* Returns an 64 bit integer from the packet data. */ 1555197679Sdes 1556197679Sdesu_int64_t 1557197679Sdespacket_get_int64(void) 1558197679Sdes{ 1559197679Sdes return buffer_get_int64(&active_state->incoming_packet); 1560197679Sdes} 1561197679Sdes 156257429Smarkm/* 156357429Smarkm * Returns an arbitrary precision integer from the packet data. The integer 156457429Smarkm * must have been initialized before this call. 156557429Smarkm */ 156657429Smarkm 156757429Smarkmvoid 156892555Sdespacket_get_bignum(BIGNUM * value) 156957429Smarkm{ 1570197679Sdes buffer_get_bignum(&active_state->incoming_packet, value); 157157429Smarkm} 157257429Smarkm 157360573Skrisvoid 157492555Sdespacket_get_bignum2(BIGNUM * value) 157560573Skris{ 1576197679Sdes buffer_get_bignum2(&active_state->incoming_packet, value); 157760573Skris} 157860573Skris 1579221420Sdes#ifdef OPENSSL_HAS_ECC 1580221420Sdesvoid 1581221420Sdespacket_get_ecpoint(const EC_GROUP *curve, EC_POINT *point) 1582221420Sdes{ 1583221420Sdes buffer_get_ecpoint(&active_state->incoming_packet, curve, point); 1584221420Sdes} 1585221420Sdes#endif 1586221420Sdes 158792555Sdesvoid * 1588149749Sdespacket_get_raw(u_int *length_ptr) 158960573Skris{ 1590197679Sdes u_int bytes = buffer_len(&active_state->incoming_packet); 1591106121Sdes 159260573Skris if (length_ptr != NULL) 159360573Skris *length_ptr = bytes; 1594197679Sdes return buffer_ptr(&active_state->incoming_packet); 159560573Skris} 159660573Skris 159760573Skrisint 159860573Skrispacket_remaining(void) 159960573Skris{ 1600197679Sdes return buffer_len(&active_state->incoming_packet); 160160573Skris} 160260573Skris 160357429Smarkm/* 160457429Smarkm * Returns a string from the packet data. The string is allocated using 160557429Smarkm * xmalloc; it is the responsibility of the calling program to free it when 160657429Smarkm * no longer needed. The length_ptr argument may be NULL, or point to an 160757429Smarkm * integer into which the length of the string is stored. 160857429Smarkm */ 160957429Smarkm 161092555Sdesvoid * 161176259Sgreenpacket_get_string(u_int *length_ptr) 161257429Smarkm{ 1613197679Sdes return buffer_get_string(&active_state->incoming_packet, length_ptr); 161457429Smarkm} 161557429Smarkm 1616181111Sdesvoid * 1617181111Sdespacket_get_string_ptr(u_int *length_ptr) 1618181111Sdes{ 1619197679Sdes return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr); 1620181111Sdes} 1621181111Sdes 1622221420Sdes/* Ensures the returned string has no embedded \0 characters in it. */ 1623221420Sdeschar * 1624221420Sdespacket_get_cstring(u_int *length_ptr) 1625221420Sdes{ 1626221420Sdes return buffer_get_cstring(&active_state->incoming_packet, length_ptr); 1627221420Sdes} 1628221420Sdes 162957429Smarkm/* 163057429Smarkm * Sends a diagnostic message from the server to the client. This message 163157429Smarkm * can be sent at any time (but not while constructing another message). The 163257429Smarkm * message is printed immediately, but only if the client is being executed 163357429Smarkm * in verbose mode. These messages are primarily intended to ease debugging 163457429Smarkm * authentication problems. The length of the formatted message must not 163557429Smarkm * exceed 1024 bytes. This will automatically call packet_write_wait. 163657429Smarkm */ 163757429Smarkm 163857429Smarkmvoid 163957429Smarkmpacket_send_debug(const char *fmt,...) 164057429Smarkm{ 164157429Smarkm char buf[1024]; 164257429Smarkm va_list args; 164357429Smarkm 164476259Sgreen if (compat20 && (datafellows & SSH_BUG_DEBUG)) 164576259Sgreen return; 164676259Sgreen 164757429Smarkm va_start(args, fmt); 164857429Smarkm vsnprintf(buf, sizeof(buf), fmt, args); 164957429Smarkm va_end(args); 165057429Smarkm 165160573Skris if (compat20) { 165260573Skris packet_start(SSH2_MSG_DEBUG); 165360573Skris packet_put_char(0); /* bool: always display */ 165460573Skris packet_put_cstring(buf); 165560573Skris packet_put_cstring(""); 165660573Skris } else { 165760573Skris packet_start(SSH_MSG_DEBUG); 165860573Skris packet_put_cstring(buf); 165960573Skris } 166057429Smarkm packet_send(); 166157429Smarkm packet_write_wait(); 166257429Smarkm} 166357429Smarkm 166457429Smarkm/* 166557429Smarkm * Logs the error plus constructs and sends a disconnect packet, closes the 166657429Smarkm * connection, and exits. This function never returns. The error message 166757429Smarkm * should not contain a newline. The length of the formatted message must 166857429Smarkm * not exceed 1024 bytes. 166957429Smarkm */ 167057429Smarkm 167157429Smarkmvoid 167257429Smarkmpacket_disconnect(const char *fmt,...) 167357429Smarkm{ 167457429Smarkm char buf[1024]; 167557429Smarkm va_list args; 167657429Smarkm static int disconnecting = 0; 1677106121Sdes 167857429Smarkm if (disconnecting) /* Guard against recursive invocations. */ 167957429Smarkm fatal("packet_disconnect called recursively."); 168057429Smarkm disconnecting = 1; 168157429Smarkm 168257429Smarkm /* 168357429Smarkm * Format the message. Note that the caller must make sure the 168457429Smarkm * message is of limited size. 168557429Smarkm */ 168657429Smarkm va_start(args, fmt); 168757429Smarkm vsnprintf(buf, sizeof(buf), fmt, args); 168857429Smarkm va_end(args); 168957429Smarkm 1690113908Sdes /* Display the error locally */ 1691124208Sdes logit("Disconnecting: %.100s", buf); 1692113908Sdes 169357429Smarkm /* Send the disconnect message to the other side, and wait for it to get sent. */ 169460573Skris if (compat20) { 169560573Skris packet_start(SSH2_MSG_DISCONNECT); 169660573Skris packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); 169760573Skris packet_put_cstring(buf); 169860573Skris packet_put_cstring(""); 169960573Skris } else { 170060573Skris packet_start(SSH_MSG_DISCONNECT); 170192555Sdes packet_put_cstring(buf); 170260573Skris } 170357429Smarkm packet_send(); 170457429Smarkm packet_write_wait(); 170557429Smarkm 170657429Smarkm /* Stop listening for connections. */ 170792555Sdes channel_close_all(); 170857429Smarkm 170957429Smarkm /* Close the connection. */ 171057429Smarkm packet_close(); 1711126274Sdes cleanup_exit(255); 171257429Smarkm} 171357429Smarkm 171457429Smarkm/* Checks if there is any buffered output, and tries to write some of the output. */ 171557429Smarkm 171657429Smarkmvoid 171792555Sdespacket_write_poll(void) 171857429Smarkm{ 1719197679Sdes int len = buffer_len(&active_state->output); 1720197679Sdes int cont; 1721106121Sdes 172257429Smarkm if (len > 0) { 1723197679Sdes cont = 0; 1724197679Sdes len = roaming_write(active_state->connection_out, 1725197679Sdes buffer_ptr(&active_state->output), len, &cont); 1726181111Sdes if (len == -1) { 1727181111Sdes if (errno == EINTR || errno == EAGAIN || 1728181111Sdes errno == EWOULDBLOCK) 172957429Smarkm return; 1730181111Sdes fatal("Write failed: %.100s", strerror(errno)); 173157429Smarkm } 1732197679Sdes if (len == 0 && !cont) 1733181111Sdes fatal("Write connection closed"); 1734197679Sdes buffer_consume(&active_state->output, len); 173557429Smarkm } 173657429Smarkm} 173757429Smarkm 173857429Smarkm/* 173957429Smarkm * Calls packet_write_poll repeatedly until all pending output data has been 174057429Smarkm * written. 174157429Smarkm */ 174257429Smarkm 174357429Smarkmvoid 174492555Sdespacket_write_wait(void) 174557429Smarkm{ 174676259Sgreen fd_set *setp; 1747255767Sdes int ret, ms_remain = 0; 1748181111Sdes struct timeval start, timeout, *timeoutp = NULL; 174976259Sgreen 1750197679Sdes setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, 1751197679Sdes NFDBITS), sizeof(fd_mask)); 175257429Smarkm packet_write_poll(); 175357429Smarkm while (packet_have_data_to_write()) { 1754197679Sdes memset(setp, 0, howmany(active_state->connection_out + 1, 1755197679Sdes NFDBITS) * sizeof(fd_mask)); 1756197679Sdes FD_SET(active_state->connection_out, setp); 1757181111Sdes 1758197679Sdes if (active_state->packet_timeout_ms > 0) { 1759197679Sdes ms_remain = active_state->packet_timeout_ms; 1760181111Sdes timeoutp = &timeout; 1761181111Sdes } 1762181111Sdes for (;;) { 1763197679Sdes if (active_state->packet_timeout_ms != -1) { 1764181111Sdes ms_to_timeval(&timeout, ms_remain); 1765181111Sdes gettimeofday(&start, NULL); 1766181111Sdes } 1767197679Sdes if ((ret = select(active_state->connection_out + 1, 1768197679Sdes NULL, setp, NULL, timeoutp)) >= 0) 1769181111Sdes break; 1770197679Sdes if (errno != EAGAIN && errno != EINTR && 1771181111Sdes errno != EWOULDBLOCK) 1772181111Sdes break; 1773197679Sdes if (active_state->packet_timeout_ms == -1) 1774181111Sdes continue; 1775181111Sdes ms_subtract_diff(&start, &ms_remain); 1776181111Sdes if (ms_remain <= 0) { 1777181111Sdes ret = 0; 1778181111Sdes break; 1779181111Sdes } 1780181111Sdes } 1781181111Sdes if (ret == 0) { 1782181111Sdes logit("Connection to %.200s timed out while " 1783181111Sdes "waiting to write", get_remote_ipaddr()); 1784181111Sdes cleanup_exit(255); 1785181111Sdes } 178657429Smarkm packet_write_poll(); 178757429Smarkm } 1788255767Sdes free(setp); 178957429Smarkm} 179057429Smarkm 179157429Smarkm/* Returns true if there is buffered data to write to the connection. */ 179257429Smarkm 179357429Smarkmint 179492555Sdespacket_have_data_to_write(void) 179557429Smarkm{ 1796197679Sdes return buffer_len(&active_state->output) != 0; 179757429Smarkm} 179857429Smarkm 179957429Smarkm/* Returns true if there is not too much data to write to the connection. */ 180057429Smarkm 180157429Smarkmint 180292555Sdespacket_not_very_much_data_to_write(void) 180357429Smarkm{ 1804197679Sdes if (active_state->interactive_mode) 1805197679Sdes return buffer_len(&active_state->output) < 16384; 180657429Smarkm else 1807197679Sdes return buffer_len(&active_state->output) < 128 * 1024; 180857429Smarkm} 180957429Smarkm 1810113908Sdesstatic void 1811221420Sdespacket_set_tos(int tos) 1812113908Sdes{ 1813226046Sdes#ifndef IP_TOS_IS_BROKEN 1814226046Sdes if (!packet_connection_is_on_socket()) 1815113908Sdes return; 1816226046Sdes switch (packet_connection_af()) { 1817226046Sdes# ifdef IP_TOS 1818226046Sdes case AF_INET: 1819226046Sdes debug3("%s: set IP_TOS 0x%02x", __func__, tos); 1820226046Sdes if (setsockopt(active_state->connection_in, 1821226046Sdes IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) 1822226046Sdes error("setsockopt IP_TOS %d: %.100s:", 1823226046Sdes tos, strerror(errno)); 1824226046Sdes break; 1825226046Sdes# endif /* IP_TOS */ 1826226046Sdes# ifdef IPV6_TCLASS 1827226046Sdes case AF_INET6: 1828226046Sdes debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos); 1829226046Sdes if (setsockopt(active_state->connection_in, 1830226046Sdes IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0) 1831226046Sdes error("setsockopt IPV6_TCLASS %d: %.100s:", 1832226046Sdes tos, strerror(errno)); 1833226046Sdes break; 1834226046Sdes# endif /* IPV6_TCLASS */ 1835226046Sdes } 1836226046Sdes#endif /* IP_TOS_IS_BROKEN */ 1837113908Sdes} 1838113908Sdes 183957429Smarkm/* Informs that the current session is interactive. Sets IP flags for that. */ 184057429Smarkm 184157429Smarkmvoid 1842221420Sdespacket_set_interactive(int interactive, int qos_interactive, int qos_bulk) 184357429Smarkm{ 1844197679Sdes if (active_state->set_interactive_called) 184576259Sgreen return; 1846197679Sdes active_state->set_interactive_called = 1; 184776259Sgreen 184857429Smarkm /* Record that we are in interactive mode. */ 1849197679Sdes active_state->interactive_mode = interactive; 185057429Smarkm 185157429Smarkm /* Only set socket options if using a socket. */ 185257429Smarkm if (!packet_connection_is_on_socket()) 1853116791Sdes return; 1854197679Sdes set_nodelay(active_state->connection_in); 1855221420Sdes packet_set_tos(interactive ? qos_interactive : qos_bulk); 185657429Smarkm} 185757429Smarkm 185857429Smarkm/* Returns true if the current connection is interactive. */ 185957429Smarkm 186057429Smarkmint 186192555Sdespacket_is_interactive(void) 186257429Smarkm{ 1863197679Sdes return active_state->interactive_mode; 186457429Smarkm} 186557429Smarkm 1866137015Sdesint 1867124208Sdespacket_set_maxsize(u_int s) 186857429Smarkm{ 1869197679Sdes if (active_state->set_maxsize_called) { 1870124208Sdes logit("packet_set_maxsize: called twice: old %d new %d", 1871197679Sdes active_state->max_packet_size, s); 187257429Smarkm return -1; 187357429Smarkm } 187457429Smarkm if (s < 4 * 1024 || s > 1024 * 1024) { 1875124208Sdes logit("packet_set_maxsize: bad size %d", s); 187657429Smarkm return -1; 187757429Smarkm } 1878197679Sdes active_state->set_maxsize_called = 1; 187992555Sdes debug("packet_set_maxsize: setting to %d", s); 1880197679Sdes active_state->max_packet_size = s; 188157429Smarkm return s; 188257429Smarkm} 188376259Sgreen 1884197679Sdesint 1885197679Sdespacket_inc_alive_timeouts(void) 1886197679Sdes{ 1887197679Sdes return ++active_state->keep_alive_timeouts; 1888197679Sdes} 1889197679Sdes 1890197679Sdesvoid 1891197679Sdespacket_set_alive_timeouts(int ka) 1892197679Sdes{ 1893197679Sdes active_state->keep_alive_timeouts = ka; 1894197679Sdes} 1895197679Sdes 1896197679Sdesu_int 1897197679Sdespacket_get_maxsize(void) 1898197679Sdes{ 1899197679Sdes return active_state->max_packet_size; 1900197679Sdes} 1901197679Sdes 190292555Sdes/* roundup current message to pad bytes */ 190392555Sdesvoid 190492555Sdespacket_add_padding(u_char pad) 190592555Sdes{ 1906197679Sdes active_state->extra_pad = pad; 190792555Sdes} 190892555Sdes 190976259Sgreen/* 191076259Sgreen * 9.2. Ignored Data Message 191176259Sgreen * 191276259Sgreen * byte SSH_MSG_IGNORE 191376259Sgreen * string data 191476259Sgreen * 191576259Sgreen * All implementations MUST understand (and ignore) this message at any 191676259Sgreen * time (after receiving the protocol version). No implementation is 191776259Sgreen * required to send them. This message can be used as an additional 191876259Sgreen * protection measure against advanced traffic analysis techniques. 191976259Sgreen */ 192076259Sgreenvoid 192176259Sgreenpacket_send_ignore(int nbytes) 192276259Sgreen{ 1923137015Sdes u_int32_t rnd = 0; 192476259Sgreen int i; 192576259Sgreen 192676259Sgreen packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); 192776259Sgreen packet_put_int(nbytes); 192892555Sdes for (i = 0; i < nbytes; i++) { 192976259Sgreen if (i % 4 == 0) 1930137015Sdes rnd = arc4random(); 1931162852Sdes packet_put_char((u_char)rnd & 0xff); 1932137015Sdes rnd >>= 8; 193376259Sgreen } 193476259Sgreen} 1935124208Sdes 1936224638Sbrooks#ifdef NONE_CIPHER_ENABLED 1937224638Sbrooksvoid 1938224638Sbrookspacket_request_rekeying(void) 1939224638Sbrooks{ 1940224638Sbrooks rekey_requested = 1; 1941224638Sbrooks} 1942224638Sbrooks#endif 1943224638Sbrooks 1944137015Sdes#define MAX_PACKETS (1U<<31) 1945124208Sdesint 1946124208Sdespacket_need_rekeying(void) 1947124208Sdes{ 1948124208Sdes if (datafellows & SSH_BUG_NOREKEY) 1949124208Sdes return 0; 1950224638Sbrooks#ifdef NONE_CIPHER_ENABLED 1951224638Sbrooks if (rekey_requested == 1) { 1952224638Sbrooks rekey_requested = 0; 1953224638Sbrooks return 1; 1954224638Sbrooks } 1955224638Sbrooks#endif 1956124208Sdes return 1957197679Sdes (active_state->p_send.packets > MAX_PACKETS) || 1958197679Sdes (active_state->p_read.packets > MAX_PACKETS) || 1959197679Sdes (active_state->max_blocks_out && 1960197679Sdes (active_state->p_send.blocks > active_state->max_blocks_out)) || 1961197679Sdes (active_state->max_blocks_in && 1962255767Sdes (active_state->p_read.blocks > active_state->max_blocks_in)) || 1963255767Sdes (active_state->rekey_interval != 0 && active_state->rekey_time + 1964255767Sdes active_state->rekey_interval <= monotime()); 1965124208Sdes} 1966124208Sdes 1967124208Sdesvoid 1968255767Sdespacket_set_rekey_limits(u_int32_t bytes, time_t seconds) 1969124208Sdes{ 1970255767Sdes debug3("rekey after %lld bytes, %d seconds", (long long)bytes, 1971255767Sdes (int)seconds); 1972197679Sdes active_state->rekey_limit = bytes; 1973255767Sdes active_state->rekey_interval = seconds; 1974255767Sdes /* 1975255767Sdes * We set the time here so that in post-auth privsep slave we count 1976255767Sdes * from the completion of the authentication. 1977255767Sdes */ 1978255767Sdes active_state->rekey_time = monotime(); 1979124208Sdes} 1980149749Sdes 1981255767Sdestime_t 1982255767Sdespacket_get_rekey_timeout(void) 1983255767Sdes{ 1984255767Sdes time_t seconds; 1985255767Sdes 1986255767Sdes seconds = active_state->rekey_time + active_state->rekey_interval - 1987255767Sdes monotime(); 1988255767Sdes return (seconds <= 0 ? 1 : seconds); 1989255767Sdes} 1990255767Sdes 1991149749Sdesvoid 1992149749Sdespacket_set_server(void) 1993149749Sdes{ 1994197679Sdes active_state->server_side = 1; 1995149749Sdes} 1996149749Sdes 1997149749Sdesvoid 1998149749Sdespacket_set_authenticated(void) 1999149749Sdes{ 2000197679Sdes active_state->after_authentication = 1; 2001149749Sdes} 2002197679Sdes 2003197679Sdesvoid * 2004197679Sdespacket_get_input(void) 2005197679Sdes{ 2006197679Sdes return (void *)&active_state->input; 2007197679Sdes} 2008197679Sdes 2009197679Sdesvoid * 2010197679Sdespacket_get_output(void) 2011197679Sdes{ 2012197679Sdes return (void *)&active_state->output; 2013197679Sdes} 2014197679Sdes 2015197679Sdesvoid * 2016197679Sdespacket_get_newkeys(int mode) 2017197679Sdes{ 2018197679Sdes return (void *)active_state->newkeys[mode]; 2019197679Sdes} 2020197679Sdes 2021197679Sdes/* 2022197679Sdes * Save the state for the real connection, and use a separate state when 2023197679Sdes * resuming a suspended connection. 2024197679Sdes */ 2025197679Sdesvoid 2026197679Sdespacket_backup_state(void) 2027197679Sdes{ 2028197679Sdes struct session_state *tmp; 2029197679Sdes 2030197679Sdes close(active_state->connection_in); 2031197679Sdes active_state->connection_in = -1; 2032197679Sdes close(active_state->connection_out); 2033197679Sdes active_state->connection_out = -1; 2034197679Sdes if (backup_state) 2035197679Sdes tmp = backup_state; 2036197679Sdes else 2037197679Sdes tmp = alloc_session_state(); 2038197679Sdes backup_state = active_state; 2039197679Sdes active_state = tmp; 2040197679Sdes} 2041197679Sdes 2042197679Sdes/* 2043197679Sdes * Swap in the old state when resuming a connecion. 2044197679Sdes */ 2045197679Sdesvoid 2046197679Sdespacket_restore_state(void) 2047197679Sdes{ 2048197679Sdes struct session_state *tmp; 2049197679Sdes void *buf; 2050197679Sdes u_int len; 2051197679Sdes 2052197679Sdes tmp = backup_state; 2053197679Sdes backup_state = active_state; 2054197679Sdes active_state = tmp; 2055197679Sdes active_state->connection_in = backup_state->connection_in; 2056197679Sdes backup_state->connection_in = -1; 2057197679Sdes active_state->connection_out = backup_state->connection_out; 2058197679Sdes backup_state->connection_out = -1; 2059197679Sdes len = buffer_len(&backup_state->input); 2060197679Sdes if (len > 0) { 2061197679Sdes buf = buffer_ptr(&backup_state->input); 2062197679Sdes buffer_append(&active_state->input, buf, len); 2063197679Sdes buffer_clear(&backup_state->input); 2064197679Sdes add_recv_bytes(len); 2065197679Sdes } 2066197679Sdes} 2067224638Sbrooks 2068224638Sbrooks#ifdef NONE_CIPHER_ENABLED 2069224638Sbrooksint 2070224638Sbrookspacket_get_authentication_state(void) 2071224638Sbrooks{ 2072224638Sbrooks return (active_state->after_authentication); 2073224638Sbrooks} 2074224638Sbrooks#endif 2075