packet.c revision 250739
1248619Sdes/* $OpenBSD: packet.c,v 1.181 2013/02/10 23:35:24 djm Exp $ */ 2250739Sdes/* $OpenBSD: packet.c,v 1.182 2013/04/11 02:27:50 djm Exp $ */ 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" 42162852Sdes 43162852Sdes#include <sys/types.h> 44124208Sdes#include "openbsd-compat/sys-queue.h" 45162852Sdes#include <sys/param.h> 46162852Sdes#include <sys/socket.h> 47162852Sdes#ifdef HAVE_SYS_TIME_H 48162852Sdes# include <sys/time.h> 49162852Sdes#endif 50124208Sdes 51162852Sdes#include <netinet/in.h> 52162852Sdes#include <netinet/ip.h> 53162852Sdes#include <arpa/inet.h> 54162852Sdes 55162852Sdes#include <errno.h> 56162852Sdes#include <stdarg.h> 57162852Sdes#include <stdio.h> 58162852Sdes#include <stdlib.h> 59162852Sdes#include <string.h> 60162852Sdes#include <unistd.h> 61162852Sdes#include <signal.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 169197679Sdes u_int64_t max_blocks_in, max_blocks_out; 170197679Sdes u_int32_t rekey_limit; 17160573Skris 172197679Sdes /* Session key for protocol v1 */ 173197679Sdes u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; 174197679Sdes u_int ssh1_keylen; 175192595Sdes 176197679Sdes /* roundup current message to extra_pad bytes */ 177197679Sdes u_char extra_pad; 178197679Sdes 179197679Sdes /* XXX discard incoming data after MAC error */ 180197679Sdes u_int packet_discard; 181197679Sdes Mac *packet_discard_mac; 182197679Sdes 183197679Sdes /* Used in packet_read_poll2() */ 184197679Sdes u_int packlen; 185197679Sdes 186197679Sdes /* Used in packet_send2 */ 187197679Sdes int rekeying; 188197679Sdes 189197679Sdes /* Used in packet_set_interactive */ 190197679Sdes int set_interactive_called; 191197679Sdes 192197679Sdes /* Used in packet_set_maxsize */ 193197679Sdes int set_maxsize_called; 194197679Sdes 195197679Sdes TAILQ_HEAD(, packet) outgoing; 196124208Sdes}; 197124208Sdes 198197679Sdesstatic struct session_state *active_state, *backup_state; 199224638Sbrooks#ifdef NONE_CIPHER_ENABLED 200224638Sbrooksstatic int rekey_requested = 0; 201224638Sbrooks#endif 202197679Sdes 203197679Sdesstatic struct session_state * 204197679Sdesalloc_session_state(void) 205197679Sdes{ 206221420Sdes struct session_state *s = xcalloc(1, sizeof(*s)); 207197679Sdes 208221420Sdes s->connection_in = -1; 209221420Sdes s->connection_out = -1; 210221420Sdes s->max_packet_size = 32768; 211221420Sdes s->packet_timeout_ms = -1; 212221420Sdes return s; 213197679Sdes} 214197679Sdes 21557429Smarkm/* 21657429Smarkm * Sets the descriptors used for communication. Disables encryption until 21757429Smarkm * packet_set_encryption_key is called. 21857429Smarkm */ 21957429Smarkmvoid 22057429Smarkmpacket_set_connection(int fd_in, int fd_out) 22157429Smarkm{ 22269587Sgreen Cipher *none = cipher_by_name("none"); 223106121Sdes 22469587Sgreen if (none == NULL) 22569587Sgreen fatal("packet_set_connection: cannot load cipher 'none'"); 226197679Sdes if (active_state == NULL) 227197679Sdes active_state = alloc_session_state(); 228197679Sdes active_state->connection_in = fd_in; 229197679Sdes active_state->connection_out = fd_out; 230197679Sdes cipher_init(&active_state->send_context, none, (const u_char *)"", 231137015Sdes 0, NULL, 0, CIPHER_ENCRYPT); 232197679Sdes cipher_init(&active_state->receive_context, none, (const u_char *)"", 233137015Sdes 0, NULL, 0, CIPHER_DECRYPT); 234197679Sdes active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL; 235197679Sdes if (!active_state->initialized) { 236197679Sdes active_state->initialized = 1; 237197679Sdes buffer_init(&active_state->input); 238197679Sdes buffer_init(&active_state->output); 239197679Sdes buffer_init(&active_state->outgoing_packet); 240197679Sdes buffer_init(&active_state->incoming_packet); 241197679Sdes TAILQ_INIT(&active_state->outgoing); 242197679Sdes active_state->p_send.packets = active_state->p_read.packets = 0; 24357429Smarkm } 24457429Smarkm} 24557429Smarkm 246181111Sdesvoid 247181111Sdespacket_set_timeout(int timeout, int count) 248181111Sdes{ 249240075Sdes if (timeout <= 0 || count <= 0) { 250197679Sdes active_state->packet_timeout_ms = -1; 251181111Sdes return; 252181111Sdes } 253181111Sdes if ((INT_MAX / 1000) / count < timeout) 254197679Sdes active_state->packet_timeout_ms = INT_MAX; 255181111Sdes else 256197679Sdes active_state->packet_timeout_ms = timeout * count * 1000; 257181111Sdes} 258181111Sdes 259192595Sdesstatic void 260192595Sdespacket_stop_discard(void) 261192595Sdes{ 262197679Sdes if (active_state->packet_discard_mac) { 263192595Sdes char buf[1024]; 264192595Sdes 265192595Sdes memset(buf, 'a', sizeof(buf)); 266197679Sdes while (buffer_len(&active_state->incoming_packet) < 267197679Sdes PACKET_MAX_SIZE) 268197679Sdes buffer_append(&active_state->incoming_packet, buf, 269197679Sdes sizeof(buf)); 270197679Sdes (void) mac_compute(active_state->packet_discard_mac, 271197679Sdes active_state->p_read.seqnr, 272197679Sdes buffer_ptr(&active_state->incoming_packet), 273192595Sdes PACKET_MAX_SIZE); 274192595Sdes } 275192595Sdes logit("Finished discarding for %.200s", get_remote_ipaddr()); 276192595Sdes cleanup_exit(255); 277192595Sdes} 278192595Sdes 279192595Sdesstatic void 280192595Sdespacket_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard) 281192595Sdes{ 282248619Sdes if (enc == NULL || !cipher_is_cbc(enc->cipher) || (mac && mac->etm)) 283192595Sdes packet_disconnect("Packet corrupt"); 284192595Sdes if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) 285197679Sdes active_state->packet_discard_mac = mac; 286197679Sdes if (buffer_len(&active_state->input) >= discard) 287192595Sdes packet_stop_discard(); 288197679Sdes active_state->packet_discard = discard - 289197679Sdes buffer_len(&active_state->input); 290192595Sdes} 291192595Sdes 29257429Smarkm/* Returns 1 if remote host is connected via socket, 0 if not. */ 29357429Smarkm 29457429Smarkmint 29592555Sdespacket_connection_is_on_socket(void) 29657429Smarkm{ 29757429Smarkm struct sockaddr_storage from, to; 29857429Smarkm socklen_t fromlen, tolen; 29957429Smarkm 30057429Smarkm /* filedescriptors in and out are the same, so it's a socket */ 301197679Sdes if (active_state->connection_in == active_state->connection_out) 30257429Smarkm return 1; 30357429Smarkm fromlen = sizeof(from); 30457429Smarkm memset(&from, 0, sizeof(from)); 305197679Sdes if (getpeername(active_state->connection_in, (struct sockaddr *)&from, 306197679Sdes &fromlen) < 0) 30757429Smarkm return 0; 30857429Smarkm tolen = sizeof(to); 30957429Smarkm memset(&to, 0, sizeof(to)); 310197679Sdes if (getpeername(active_state->connection_out, (struct sockaddr *)&to, 311197679Sdes &tolen) < 0) 31257429Smarkm return 0; 31357429Smarkm if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) 31457429Smarkm return 0; 31557429Smarkm if (from.ss_family != AF_INET && from.ss_family != AF_INET6) 31657429Smarkm return 0; 31757429Smarkm return 1; 31857429Smarkm} 31957429Smarkm 32098675Sdes/* 32198675Sdes * Exports an IV from the CipherContext required to export the key 32298675Sdes * state back from the unprivileged child to the privileged parent 32398675Sdes * process. 32498675Sdes */ 32598675Sdes 32698675Sdesvoid 32798675Sdespacket_get_keyiv(int mode, u_char *iv, u_int len) 32898675Sdes{ 32998675Sdes CipherContext *cc; 33098675Sdes 33198675Sdes if (mode == MODE_OUT) 332197679Sdes cc = &active_state->send_context; 33398675Sdes else 334197679Sdes cc = &active_state->receive_context; 33598675Sdes 33698675Sdes cipher_get_keyiv(cc, iv, len); 33798675Sdes} 33898675Sdes 33998675Sdesint 34098675Sdespacket_get_keycontext(int mode, u_char *dat) 34198675Sdes{ 34298675Sdes CipherContext *cc; 34398675Sdes 34498675Sdes if (mode == MODE_OUT) 345197679Sdes cc = &active_state->send_context; 34698675Sdes else 347197679Sdes cc = &active_state->receive_context; 34898675Sdes 34998675Sdes return (cipher_get_keycontext(cc, dat)); 35098675Sdes} 35198675Sdes 35298675Sdesvoid 35398675Sdespacket_set_keycontext(int mode, u_char *dat) 35498675Sdes{ 35598675Sdes CipherContext *cc; 35698675Sdes 35798675Sdes if (mode == MODE_OUT) 358197679Sdes cc = &active_state->send_context; 35998675Sdes else 360197679Sdes cc = &active_state->receive_context; 36198675Sdes 36298675Sdes cipher_set_keycontext(cc, dat); 36398675Sdes} 36498675Sdes 36598675Sdesint 36698675Sdespacket_get_keyiv_len(int mode) 36798675Sdes{ 36898675Sdes CipherContext *cc; 36998675Sdes 37098675Sdes if (mode == MODE_OUT) 371197679Sdes cc = &active_state->send_context; 37298675Sdes else 373197679Sdes cc = &active_state->receive_context; 37498675Sdes 37598675Sdes return (cipher_get_keyiv_len(cc)); 37698675Sdes} 377162852Sdes 37898675Sdesvoid 37998675Sdespacket_set_iv(int mode, u_char *dat) 38098675Sdes{ 38198675Sdes CipherContext *cc; 38298675Sdes 38398675Sdes if (mode == MODE_OUT) 384197679Sdes cc = &active_state->send_context; 38598675Sdes else 386197679Sdes cc = &active_state->receive_context; 38798675Sdes 38898675Sdes cipher_set_keyiv(cc, dat); 38998675Sdes} 390162852Sdes 39198675Sdesint 392124208Sdespacket_get_ssh1_cipher(void) 39398675Sdes{ 394197679Sdes return (cipher_get_number(active_state->receive_context.cipher)); 39598675Sdes} 39698675Sdes 397124208Sdesvoid 398221420Sdespacket_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, 399221420Sdes u_int32_t *packets, u_int64_t *bytes) 400124208Sdes{ 401124208Sdes struct packet_state *state; 40298675Sdes 403197679Sdes state = (mode == MODE_IN) ? 404197679Sdes &active_state->p_read : &active_state->p_send; 405181111Sdes if (seqnr) 406181111Sdes *seqnr = state->seqnr; 407181111Sdes if (blocks) 408181111Sdes *blocks = state->blocks; 409181111Sdes if (packets) 410181111Sdes *packets = state->packets; 411181111Sdes if (bytes) 412181111Sdes *bytes = state->bytes; 41398675Sdes} 41498675Sdes 41598675Sdesvoid 416181111Sdespacket_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets, 417181111Sdes u_int64_t bytes) 41898675Sdes{ 419124208Sdes struct packet_state *state; 420124208Sdes 421197679Sdes state = (mode == MODE_IN) ? 422197679Sdes &active_state->p_read : &active_state->p_send; 423124208Sdes state->seqnr = seqnr; 424124208Sdes state->blocks = blocks; 425124208Sdes state->packets = packets; 426181111Sdes state->bytes = bytes; 42798675Sdes} 42898675Sdes 429226046Sdesstatic int 430226046Sdespacket_connection_af(void) 43157429Smarkm{ 43257429Smarkm struct sockaddr_storage to; 43357429Smarkm socklen_t tolen = sizeof(to); 43457429Smarkm 43557429Smarkm memset(&to, 0, sizeof(to)); 436197679Sdes if (getsockname(active_state->connection_out, (struct sockaddr *)&to, 437197679Sdes &tolen) < 0) 43857429Smarkm return 0; 43998937Sdes#ifdef IPV4_IN_IPV6 440126274Sdes if (to.ss_family == AF_INET6 && 44198937Sdes IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) 442226046Sdes return AF_INET; 44398937Sdes#endif 444226046Sdes return to.ss_family; 44557429Smarkm} 44657429Smarkm 44757429Smarkm/* Sets the connection into non-blocking mode. */ 44857429Smarkm 44957429Smarkmvoid 45092555Sdespacket_set_nonblocking(void) 45157429Smarkm{ 45257429Smarkm /* Set the socket into non-blocking mode. */ 453197679Sdes set_nonblock(active_state->connection_in); 45457429Smarkm 455197679Sdes if (active_state->connection_out != active_state->connection_in) 456197679Sdes set_nonblock(active_state->connection_out); 45757429Smarkm} 45857429Smarkm 45957429Smarkm/* Returns the socket used for reading. */ 46057429Smarkm 46157429Smarkmint 46292555Sdespacket_get_connection_in(void) 46357429Smarkm{ 464197679Sdes return active_state->connection_in; 46557429Smarkm} 46657429Smarkm 46757429Smarkm/* Returns the descriptor used for writing. */ 46857429Smarkm 46957429Smarkmint 47092555Sdespacket_get_connection_out(void) 47157429Smarkm{ 472197679Sdes return active_state->connection_out; 47357429Smarkm} 47457429Smarkm 47557429Smarkm/* Closes the connection and clears and frees internal data structures. */ 47657429Smarkm 47757429Smarkmvoid 47892555Sdespacket_close(void) 47957429Smarkm{ 480197679Sdes if (!active_state->initialized) 48157429Smarkm return; 482197679Sdes active_state->initialized = 0; 483197679Sdes if (active_state->connection_in == active_state->connection_out) { 484197679Sdes shutdown(active_state->connection_out, SHUT_RDWR); 485197679Sdes close(active_state->connection_out); 48657429Smarkm } else { 487197679Sdes close(active_state->connection_in); 488197679Sdes close(active_state->connection_out); 48957429Smarkm } 490197679Sdes buffer_free(&active_state->input); 491197679Sdes buffer_free(&active_state->output); 492197679Sdes buffer_free(&active_state->outgoing_packet); 493197679Sdes buffer_free(&active_state->incoming_packet); 494197679Sdes if (active_state->compression_buffer_ready) { 495197679Sdes buffer_free(&active_state->compression_buffer); 49657429Smarkm buffer_compress_uninit(); 49757429Smarkm } 498197679Sdes cipher_cleanup(&active_state->send_context); 499197679Sdes cipher_cleanup(&active_state->receive_context); 50057429Smarkm} 50157429Smarkm 50257429Smarkm/* Sets remote side protocol flags. */ 50357429Smarkm 50457429Smarkmvoid 50576259Sgreenpacket_set_protocol_flags(u_int protocol_flags) 50657429Smarkm{ 507197679Sdes active_state->remote_protocol_flags = protocol_flags; 50857429Smarkm} 50957429Smarkm 51057429Smarkm/* Returns the remote protocol flags set earlier by the above function. */ 51157429Smarkm 51276259Sgreenu_int 51392555Sdespacket_get_protocol_flags(void) 51457429Smarkm{ 515197679Sdes return active_state->remote_protocol_flags; 51657429Smarkm} 51757429Smarkm 51857429Smarkm/* 51957429Smarkm * Starts packet compression from the next packet on in both directions. 52057429Smarkm * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. 52157429Smarkm */ 52257429Smarkm 52392555Sdesstatic void 52492555Sdespacket_init_compression(void) 52576259Sgreen{ 526197679Sdes if (active_state->compression_buffer_ready == 1) 52776259Sgreen return; 528197679Sdes active_state->compression_buffer_ready = 1; 529197679Sdes buffer_init(&active_state->compression_buffer); 53076259Sgreen} 53176259Sgreen 53276259Sgreenvoid 53357429Smarkmpacket_start_compression(int level) 53457429Smarkm{ 535197679Sdes if (active_state->packet_compression && !compat20) 53657429Smarkm fatal("Compression already enabled."); 537197679Sdes active_state->packet_compression = 1; 53876259Sgreen packet_init_compression(); 53976259Sgreen buffer_compress_init_send(level); 54076259Sgreen buffer_compress_init_recv(); 54157429Smarkm} 54257429Smarkm 54357429Smarkm/* 54457429Smarkm * Causes any further packets to be encrypted using the given key. The same 54557429Smarkm * key is used for both sending and reception. However, both directions are 54657429Smarkm * encrypted independently of each other. 54757429Smarkm */ 54898675Sdes 54957429Smarkmvoid 550221420Sdespacket_set_encryption_key(const u_char *key, u_int keylen, int number) 55157429Smarkm{ 55269587Sgreen Cipher *cipher = cipher_by_number(number); 553106121Sdes 55469587Sgreen if (cipher == NULL) 55569587Sgreen fatal("packet_set_encryption_key: unknown cipher number %d", number); 55660573Skris if (keylen < 20) 55769587Sgreen fatal("packet_set_encryption_key: keylen too small: %d", keylen); 55898675Sdes if (keylen > SSH_SESSION_KEY_LENGTH) 55998675Sdes fatal("packet_set_encryption_key: keylen too big: %d", keylen); 560197679Sdes memcpy(active_state->ssh1_key, key, keylen); 561197679Sdes active_state->ssh1_keylen = keylen; 562197679Sdes cipher_init(&active_state->send_context, cipher, key, keylen, NULL, 563197679Sdes 0, CIPHER_ENCRYPT); 564197679Sdes cipher_init(&active_state->receive_context, cipher, key, keylen, NULL, 565197679Sdes 0, CIPHER_DECRYPT); 56657429Smarkm} 56757429Smarkm 56898675Sdesu_int 56998675Sdespacket_get_encryption_key(u_char *key) 57098675Sdes{ 57198675Sdes if (key == NULL) 572197679Sdes return (active_state->ssh1_keylen); 573197679Sdes memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen); 574197679Sdes return (active_state->ssh1_keylen); 57598675Sdes} 57698675Sdes 57792555Sdes/* Start constructing a packet to send. */ 57857429Smarkmvoid 57992555Sdespacket_start(u_char type) 58057429Smarkm{ 58192555Sdes u_char buf[9]; 58292555Sdes int len; 58357429Smarkm 58492555Sdes DBG(debug("packet_start[%d]", type)); 58592555Sdes len = compat20 ? 6 : 9; 58692555Sdes memset(buf, 0, len - 1); 58792555Sdes buf[len - 1] = type; 588197679Sdes buffer_clear(&active_state->outgoing_packet); 589197679Sdes buffer_append(&active_state->outgoing_packet, buf, len); 59057429Smarkm} 59157429Smarkm 59292555Sdes/* Append payload. */ 59360573Skrisvoid 59457429Smarkmpacket_put_char(int value) 59557429Smarkm{ 59657429Smarkm char ch = value; 597106121Sdes 598197679Sdes buffer_append(&active_state->outgoing_packet, &ch, 1); 59957429Smarkm} 600162852Sdes 60157429Smarkmvoid 60276259Sgreenpacket_put_int(u_int value) 60357429Smarkm{ 604197679Sdes buffer_put_int(&active_state->outgoing_packet, value); 60557429Smarkm} 606162852Sdes 60757429Smarkmvoid 608197679Sdespacket_put_int64(u_int64_t value) 609197679Sdes{ 610197679Sdes buffer_put_int64(&active_state->outgoing_packet, value); 611197679Sdes} 612197679Sdes 613197679Sdesvoid 61492555Sdespacket_put_string(const void *buf, u_int len) 61557429Smarkm{ 616197679Sdes buffer_put_string(&active_state->outgoing_packet, buf, len); 61757429Smarkm} 618162852Sdes 61960573Skrisvoid 62060573Skrispacket_put_cstring(const char *str) 62160573Skris{ 622197679Sdes buffer_put_cstring(&active_state->outgoing_packet, str); 62360573Skris} 624162852Sdes 62560573Skrisvoid 62692555Sdespacket_put_raw(const void *buf, u_int len) 62760573Skris{ 628197679Sdes buffer_append(&active_state->outgoing_packet, buf, len); 62960573Skris} 630162852Sdes 63157429Smarkmvoid 63257429Smarkmpacket_put_bignum(BIGNUM * value) 63357429Smarkm{ 634197679Sdes buffer_put_bignum(&active_state->outgoing_packet, value); 63557429Smarkm} 636162852Sdes 63760573Skrisvoid 63860573Skrispacket_put_bignum2(BIGNUM * value) 63960573Skris{ 640197679Sdes buffer_put_bignum2(&active_state->outgoing_packet, value); 64160573Skris} 64257429Smarkm 643221420Sdes#ifdef OPENSSL_HAS_ECC 644221420Sdesvoid 645221420Sdespacket_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point) 646221420Sdes{ 647221420Sdes buffer_put_ecpoint(&active_state->outgoing_packet, curve, point); 648221420Sdes} 649221420Sdes#endif 650221420Sdes 65157429Smarkm/* 65257429Smarkm * Finalizes and sends the packet. If the encryption key has been set, 65357429Smarkm * encrypts the packet before sending. 65457429Smarkm */ 65557429Smarkm 65692555Sdesstatic void 65776259Sgreenpacket_send1(void) 65857429Smarkm{ 65992555Sdes u_char buf[8], *cp; 66057429Smarkm int i, padding, len; 66176259Sgreen u_int checksum; 662137015Sdes u_int32_t rnd = 0; 66357429Smarkm 66457429Smarkm /* 66557429Smarkm * If using packet compression, compress the payload of the outgoing 66657429Smarkm * packet. 66757429Smarkm */ 668197679Sdes if (active_state->packet_compression) { 669197679Sdes buffer_clear(&active_state->compression_buffer); 67057429Smarkm /* Skip padding. */ 671197679Sdes buffer_consume(&active_state->outgoing_packet, 8); 67257429Smarkm /* padding */ 673197679Sdes buffer_append(&active_state->compression_buffer, 674197679Sdes "\0\0\0\0\0\0\0\0", 8); 675197679Sdes buffer_compress(&active_state->outgoing_packet, 676197679Sdes &active_state->compression_buffer); 677197679Sdes buffer_clear(&active_state->outgoing_packet); 678197679Sdes buffer_append(&active_state->outgoing_packet, 679197679Sdes buffer_ptr(&active_state->compression_buffer), 680197679Sdes buffer_len(&active_state->compression_buffer)); 68157429Smarkm } 68257429Smarkm /* Compute packet length without padding (add checksum, remove padding). */ 683197679Sdes len = buffer_len(&active_state->outgoing_packet) + 4 - 8; 68457429Smarkm 68560573Skris /* Insert padding. Initialized to zero in packet_start1() */ 68657429Smarkm padding = 8 - len % 8; 687197679Sdes if (!active_state->send_context.plaintext) { 688197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 68957429Smarkm for (i = 0; i < padding; i++) { 69057429Smarkm if (i % 4 == 0) 691137015Sdes rnd = arc4random(); 692137015Sdes cp[7 - i] = rnd & 0xff; 693137015Sdes rnd >>= 8; 69457429Smarkm } 69557429Smarkm } 696197679Sdes buffer_consume(&active_state->outgoing_packet, 8 - padding); 69757429Smarkm 69857429Smarkm /* Add check bytes. */ 699197679Sdes checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet), 700197679Sdes buffer_len(&active_state->outgoing_packet)); 701162852Sdes put_u32(buf, checksum); 702197679Sdes buffer_append(&active_state->outgoing_packet, buf, 4); 70357429Smarkm 70457429Smarkm#ifdef PACKET_DEBUG 70557429Smarkm fprintf(stderr, "packet_send plain: "); 706197679Sdes buffer_dump(&active_state->outgoing_packet); 70757429Smarkm#endif 70857429Smarkm 70957429Smarkm /* Append to output. */ 710162852Sdes put_u32(buf, len); 711197679Sdes buffer_append(&active_state->output, buf, 4); 712197679Sdes cp = buffer_append_space(&active_state->output, 713197679Sdes buffer_len(&active_state->outgoing_packet)); 714197679Sdes cipher_crypt(&active_state->send_context, cp, 715197679Sdes buffer_ptr(&active_state->outgoing_packet), 716248619Sdes buffer_len(&active_state->outgoing_packet), 0, 0); 71757429Smarkm 71857429Smarkm#ifdef PACKET_DEBUG 71957429Smarkm fprintf(stderr, "encrypted: "); 720197679Sdes buffer_dump(&active_state->output); 72157429Smarkm#endif 722197679Sdes active_state->p_send.packets++; 723197679Sdes active_state->p_send.bytes += len + 724197679Sdes buffer_len(&active_state->outgoing_packet); 725197679Sdes buffer_clear(&active_state->outgoing_packet); 72657429Smarkm 72757429Smarkm /* 728157016Sdes * Note that the packet is now only buffered in output. It won't be 72957429Smarkm * actually sent until packet_write_wait or packet_write_poll is 73057429Smarkm * called. 73157429Smarkm */ 73257429Smarkm} 73357429Smarkm 73498675Sdesvoid 73576259Sgreenset_newkeys(int mode) 73676259Sgreen{ 73776259Sgreen Enc *enc; 73876259Sgreen Mac *mac; 73976259Sgreen Comp *comp; 74076259Sgreen CipherContext *cc; 741124208Sdes u_int64_t *max_blocks; 742137015Sdes int crypt_type; 74376259Sgreen 744113908Sdes debug2("set_newkeys: mode %d", mode); 74576259Sgreen 74692555Sdes if (mode == MODE_OUT) { 747197679Sdes cc = &active_state->send_context; 748137015Sdes crypt_type = CIPHER_ENCRYPT; 749197679Sdes active_state->p_send.packets = active_state->p_send.blocks = 0; 750197679Sdes max_blocks = &active_state->max_blocks_out; 75192555Sdes } else { 752197679Sdes cc = &active_state->receive_context; 753137015Sdes crypt_type = CIPHER_DECRYPT; 754197679Sdes active_state->p_read.packets = active_state->p_read.blocks = 0; 755197679Sdes max_blocks = &active_state->max_blocks_in; 75692555Sdes } 757197679Sdes if (active_state->newkeys[mode] != NULL) { 758113908Sdes debug("set_newkeys: rekeying"); 75992555Sdes cipher_cleanup(cc); 760197679Sdes enc = &active_state->newkeys[mode]->enc; 761197679Sdes mac = &active_state->newkeys[mode]->mac; 762197679Sdes comp = &active_state->newkeys[mode]->comp; 763181111Sdes mac_clear(mac); 764248619Sdes memset(enc->iv, 0, enc->iv_len); 765248619Sdes memset(enc->key, 0, enc->key_len); 766248619Sdes memset(mac->key, 0, mac->key_len); 76776259Sgreen xfree(enc->name); 76876259Sgreen xfree(enc->iv); 76976259Sgreen xfree(enc->key); 77076259Sgreen xfree(mac->name); 77176259Sgreen xfree(mac->key); 77276259Sgreen xfree(comp->name); 773197679Sdes xfree(active_state->newkeys[mode]); 77476259Sgreen } 775197679Sdes active_state->newkeys[mode] = kex_get_newkeys(mode); 776197679Sdes if (active_state->newkeys[mode] == NULL) 77776259Sgreen fatal("newkeys: no keys for mode %d", mode); 778197679Sdes enc = &active_state->newkeys[mode]->enc; 779197679Sdes mac = &active_state->newkeys[mode]->mac; 780197679Sdes comp = &active_state->newkeys[mode]->comp; 781248619Sdes if (cipher_authlen(enc->cipher) == 0 && mac_init(mac) == 0) 78276259Sgreen mac->enabled = 1; 78376259Sgreen DBG(debug("cipher_init_context: %d", mode)); 78492555Sdes cipher_init(cc, enc->cipher, enc->key, enc->key_len, 785248619Sdes enc->iv, enc->iv_len, crypt_type); 78698675Sdes /* Deleting the keys does not gain extra security */ 78798675Sdes /* memset(enc->iv, 0, enc->block_size); 788181111Sdes memset(enc->key, 0, enc->key_len); 789181111Sdes memset(mac->key, 0, mac->key_len); */ 790149749Sdes if ((comp->type == COMP_ZLIB || 791197679Sdes (comp->type == COMP_DELAYED && 792197679Sdes active_state->after_authentication)) && comp->enabled == 0) { 79376259Sgreen packet_init_compression(); 79476259Sgreen if (mode == MODE_OUT) 79576259Sgreen buffer_compress_init_send(6); 79676259Sgreen else 79776259Sgreen buffer_compress_init_recv(); 79876259Sgreen comp->enabled = 1; 79976259Sgreen } 800124208Sdes /* 801124208Sdes * The 2^(blocksize*2) limit is too expensive for 3DES, 802124208Sdes * blowfish, etc, so enforce a 1GB limit for small blocksizes. 803124208Sdes */ 804124208Sdes if (enc->block_size >= 16) 805124208Sdes *max_blocks = (u_int64_t)1 << (enc->block_size*2); 806124208Sdes else 807124208Sdes *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; 808197679Sdes if (active_state->rekey_limit) 809197679Sdes *max_blocks = MIN(*max_blocks, 810197679Sdes active_state->rekey_limit / enc->block_size); 81176259Sgreen} 81276259Sgreen 81357429Smarkm/* 814149749Sdes * Delayed compression for SSH2 is enabled after authentication: 815162852Sdes * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, 816149749Sdes * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. 817149749Sdes */ 818149749Sdesstatic void 819149749Sdespacket_enable_delayed_compress(void) 820149749Sdes{ 821149749Sdes Comp *comp = NULL; 822149749Sdes int mode; 823149749Sdes 824149749Sdes /* 825149749Sdes * Remember that we are past the authentication step, so rekeying 826149749Sdes * with COMP_DELAYED will turn on compression immediately. 827149749Sdes */ 828197679Sdes active_state->after_authentication = 1; 829149749Sdes for (mode = 0; mode < MODE_MAX; mode++) { 830162852Sdes /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ 831197679Sdes if (active_state->newkeys[mode] == NULL) 832162852Sdes continue; 833197679Sdes comp = &active_state->newkeys[mode]->comp; 834149749Sdes if (comp && !comp->enabled && comp->type == COMP_DELAYED) { 835149749Sdes packet_init_compression(); 836149749Sdes if (mode == MODE_OUT) 837149749Sdes buffer_compress_init_send(6); 838149749Sdes else 839149749Sdes buffer_compress_init_recv(); 840149749Sdes comp->enabled = 1; 841149749Sdes } 842149749Sdes } 843149749Sdes} 844149749Sdes 845149749Sdes/* 84660573Skris * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) 84760573Skris */ 84892555Sdesstatic void 849124208Sdespacket_send2_wrapped(void) 85060573Skris{ 85192555Sdes u_char type, *cp, *macbuf = NULL; 852248619Sdes u_char padlen, pad = 0; 853248619Sdes u_int i, len, authlen = 0, aadlen = 0; 854137015Sdes u_int32_t rnd = 0; 85560573Skris Enc *enc = NULL; 85660573Skris Mac *mac = NULL; 85760573Skris Comp *comp = NULL; 85860573Skris int block_size; 85960573Skris 860197679Sdes if (active_state->newkeys[MODE_OUT] != NULL) { 861197679Sdes enc = &active_state->newkeys[MODE_OUT]->enc; 862197679Sdes mac = &active_state->newkeys[MODE_OUT]->mac; 863197679Sdes comp = &active_state->newkeys[MODE_OUT]->comp; 864248619Sdes /* disable mac for authenticated encryption */ 865248619Sdes if ((authlen = cipher_authlen(enc->cipher)) != 0) 866248619Sdes mac = NULL; 86760573Skris } 86892555Sdes block_size = enc ? enc->block_size : 8; 869248619Sdes aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; 87060573Skris 871197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 87292555Sdes type = cp[5]; 87360573Skris 87460573Skris#ifdef PACKET_DEBUG 87560573Skris fprintf(stderr, "plain: "); 876197679Sdes buffer_dump(&active_state->outgoing_packet); 87760573Skris#endif 87860573Skris 87960573Skris if (comp && comp->enabled) { 880197679Sdes len = buffer_len(&active_state->outgoing_packet); 88160573Skris /* skip header, compress only payload */ 882197679Sdes buffer_consume(&active_state->outgoing_packet, 5); 883197679Sdes buffer_clear(&active_state->compression_buffer); 884197679Sdes buffer_compress(&active_state->outgoing_packet, 885197679Sdes &active_state->compression_buffer); 886197679Sdes buffer_clear(&active_state->outgoing_packet); 887197679Sdes buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5); 888197679Sdes buffer_append(&active_state->outgoing_packet, 889197679Sdes buffer_ptr(&active_state->compression_buffer), 890197679Sdes buffer_len(&active_state->compression_buffer)); 89160573Skris DBG(debug("compression: raw %d compressed %d", len, 892197679Sdes buffer_len(&active_state->outgoing_packet))); 89360573Skris } 89460573Skris 89560573Skris /* sizeof (packet_len + pad_len + payload) */ 896197679Sdes len = buffer_len(&active_state->outgoing_packet); 89760573Skris 89860573Skris /* 89960573Skris * calc size of padding, alloc space, get random data, 90060573Skris * minimum padding is 4 bytes 90160573Skris */ 902248619Sdes len -= aadlen; /* packet length is not encrypted for EtM modes */ 90360573Skris padlen = block_size - (len % block_size); 90460573Skris if (padlen < 4) 90560573Skris padlen += block_size; 906197679Sdes if (active_state->extra_pad) { 90792555Sdes /* will wrap if extra_pad+padlen > 255 */ 908197679Sdes active_state->extra_pad = 909197679Sdes roundup(active_state->extra_pad, block_size); 910197679Sdes pad = active_state->extra_pad - 911197679Sdes ((len + padlen) % active_state->extra_pad); 91298675Sdes debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)", 913197679Sdes pad, len, padlen, active_state->extra_pad); 91492555Sdes padlen += pad; 915197679Sdes active_state->extra_pad = 0; 91692555Sdes } 917197679Sdes cp = buffer_append_space(&active_state->outgoing_packet, padlen); 918197679Sdes if (enc && !active_state->send_context.plaintext) { 91960573Skris /* random padding */ 92060573Skris for (i = 0; i < padlen; i++) { 92160573Skris if (i % 4 == 0) 922137015Sdes rnd = arc4random(); 923137015Sdes cp[i] = rnd & 0xff; 924137015Sdes rnd >>= 8; 92560573Skris } 92660573Skris } else { 92760573Skris /* clear padding */ 92860573Skris memset(cp, 0, padlen); 92960573Skris } 930248619Sdes /* sizeof (packet_len + pad_len + payload + padding) */ 931248619Sdes len = buffer_len(&active_state->outgoing_packet); 932248619Sdes cp = buffer_ptr(&active_state->outgoing_packet); 93360573Skris /* packet_length includes payload, padding and padding length field */ 934248619Sdes put_u32(cp, len - 4); 93592555Sdes cp[4] = padlen; 936248619Sdes DBG(debug("send: len %d (includes padlen %d, aadlen %d)", 937248619Sdes len, padlen, aadlen)); 93860573Skris 93960573Skris /* compute MAC over seqnr and packet(length fields, payload, padding) */ 940248619Sdes if (mac && mac->enabled && !mac->etm) { 941197679Sdes macbuf = mac_compute(mac, active_state->p_send.seqnr, 942248619Sdes buffer_ptr(&active_state->outgoing_packet), len); 943197679Sdes DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr)); 94460573Skris } 94560573Skris /* encrypt packet and append to output buffer. */ 946248619Sdes cp = buffer_append_space(&active_state->output, len + authlen); 947197679Sdes cipher_crypt(&active_state->send_context, cp, 948197679Sdes buffer_ptr(&active_state->outgoing_packet), 949248619Sdes len - aadlen, aadlen, authlen); 95060573Skris /* append unencrypted MAC */ 951248619Sdes if (mac && mac->enabled) { 952248619Sdes if (mac->etm) { 953248619Sdes /* EtM: compute mac over aadlen + cipher text */ 954248619Sdes macbuf = mac_compute(mac, 955248619Sdes active_state->p_send.seqnr, cp, len); 956248619Sdes DBG(debug("done calc MAC(EtM) out #%d", 957248619Sdes active_state->p_send.seqnr)); 958248619Sdes } 959197679Sdes buffer_append(&active_state->output, macbuf, mac->mac_len); 960248619Sdes } 96160573Skris#ifdef PACKET_DEBUG 96260573Skris fprintf(stderr, "encrypted: "); 963197679Sdes buffer_dump(&active_state->output); 96460573Skris#endif 96560573Skris /* increment sequence number for outgoing packets */ 966197679Sdes if (++active_state->p_send.seqnr == 0) 967124208Sdes logit("outgoing seqnr wraps around"); 968197679Sdes if (++active_state->p_send.packets == 0) 969124208Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 970124208Sdes fatal("XXX too many packets with same key"); 971248619Sdes active_state->p_send.blocks += len / block_size; 972248619Sdes active_state->p_send.bytes += len; 973197679Sdes buffer_clear(&active_state->outgoing_packet); 97460573Skris 97576259Sgreen if (type == SSH2_MSG_NEWKEYS) 97676259Sgreen set_newkeys(MODE_OUT); 977197679Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side) 978149749Sdes packet_enable_delayed_compress(); 97960573Skris} 98060573Skris 981124208Sdesstatic void 982124208Sdespacket_send2(void) 983124208Sdes{ 984124208Sdes struct packet *p; 985124208Sdes u_char type, *cp; 986124208Sdes 987197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 988124208Sdes type = cp[5]; 989124208Sdes 990124208Sdes /* during rekeying we can only send key exchange messages */ 991197679Sdes if (active_state->rekeying) { 992240075Sdes if ((type < SSH2_MSG_TRANSPORT_MIN) || 993240075Sdes (type > SSH2_MSG_TRANSPORT_MAX) || 994240075Sdes (type == SSH2_MSG_SERVICE_REQUEST) || 995240075Sdes (type == SSH2_MSG_SERVICE_ACCEPT)) { 996124208Sdes debug("enqueue packet: %u", type); 997124208Sdes p = xmalloc(sizeof(*p)); 998124208Sdes p->type = type; 999197679Sdes memcpy(&p->payload, &active_state->outgoing_packet, 1000197679Sdes sizeof(Buffer)); 1001197679Sdes buffer_init(&active_state->outgoing_packet); 1002197679Sdes TAILQ_INSERT_TAIL(&active_state->outgoing, p, next); 1003124208Sdes return; 1004124208Sdes } 1005124208Sdes } 1006124208Sdes 1007124208Sdes /* rekeying starts with sending KEXINIT */ 1008124208Sdes if (type == SSH2_MSG_KEXINIT) 1009197679Sdes active_state->rekeying = 1; 1010124208Sdes 1011124208Sdes packet_send2_wrapped(); 1012124208Sdes 1013124208Sdes /* after a NEWKEYS message we can send the complete queue */ 1014124208Sdes if (type == SSH2_MSG_NEWKEYS) { 1015197679Sdes active_state->rekeying = 0; 1016197679Sdes while ((p = TAILQ_FIRST(&active_state->outgoing))) { 1017124208Sdes type = p->type; 1018124208Sdes debug("dequeue packet: %u", type); 1019197679Sdes buffer_free(&active_state->outgoing_packet); 1020197679Sdes memcpy(&active_state->outgoing_packet, &p->payload, 1021124208Sdes sizeof(Buffer)); 1022197679Sdes TAILQ_REMOVE(&active_state->outgoing, p, next); 1023124208Sdes xfree(p); 1024124208Sdes packet_send2_wrapped(); 1025124208Sdes } 1026124208Sdes } 1027124208Sdes} 1028124208Sdes 102960573Skrisvoid 103092555Sdespacket_send(void) 103160573Skris{ 103292555Sdes if (compat20) 103360573Skris packet_send2(); 103460573Skris else 103560573Skris packet_send1(); 103660573Skris DBG(debug("packet_send done")); 103760573Skris} 103860573Skris 103960573Skris/* 104057429Smarkm * Waits until a packet has been received, and returns its type. Note that 104157429Smarkm * no other data is processed until this returns, so this function should not 104257429Smarkm * be used during the interactive session. 104357429Smarkm */ 104457429Smarkm 104557429Smarkmint 104692555Sdespacket_read_seqnr(u_int32_t *seqnr_p) 104757429Smarkm{ 1048197679Sdes int type, len, ret, ms_remain, cont; 104976259Sgreen fd_set *setp; 105057429Smarkm char buf[8192]; 1051181111Sdes struct timeval timeout, start, *timeoutp = NULL; 1052181111Sdes 105360573Skris DBG(debug("packet_read()")); 105457429Smarkm 1055197679Sdes setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1, 1056197679Sdes NFDBITS), sizeof(fd_mask)); 105776259Sgreen 105857429Smarkm /* Since we are blocking, ensure that all written packets have been sent. */ 105957429Smarkm packet_write_wait(); 106057429Smarkm 106157429Smarkm /* Stay in the loop until we have received a complete packet. */ 106257429Smarkm for (;;) { 106357429Smarkm /* Try to read a packet from the buffer. */ 106492555Sdes type = packet_read_poll_seqnr(seqnr_p); 106592555Sdes if (!compat20 && ( 106660573Skris type == SSH_SMSG_SUCCESS 106757429Smarkm || type == SSH_SMSG_FAILURE 106857429Smarkm || type == SSH_CMSG_EOF 106960573Skris || type == SSH_CMSG_EXIT_CONFIRMATION)) 107092555Sdes packet_check_eom(); 107157429Smarkm /* If we got a packet, return it. */ 107276259Sgreen if (type != SSH_MSG_NONE) { 107376259Sgreen xfree(setp); 107457429Smarkm return type; 107576259Sgreen } 107657429Smarkm /* 107757429Smarkm * Otherwise, wait for some data to arrive, add it to the 107857429Smarkm * buffer, and try again. 107957429Smarkm */ 1080197679Sdes memset(setp, 0, howmany(active_state->connection_in + 1, 1081197679Sdes NFDBITS) * sizeof(fd_mask)); 1082197679Sdes FD_SET(active_state->connection_in, setp); 108357429Smarkm 1084197679Sdes if (active_state->packet_timeout_ms > 0) { 1085197679Sdes ms_remain = active_state->packet_timeout_ms; 1086181111Sdes timeoutp = &timeout; 1087181111Sdes } 108857429Smarkm /* Wait for some data to arrive. */ 1089181111Sdes for (;;) { 1090197679Sdes if (active_state->packet_timeout_ms != -1) { 1091181111Sdes ms_to_timeval(&timeout, ms_remain); 1092181111Sdes gettimeofday(&start, NULL); 1093181111Sdes } 1094197679Sdes if ((ret = select(active_state->connection_in + 1, setp, 1095197679Sdes NULL, NULL, timeoutp)) >= 0) 1096181111Sdes break; 1097197679Sdes if (errno != EAGAIN && errno != EINTR && 1098181111Sdes errno != EWOULDBLOCK) 1099181111Sdes break; 1100197679Sdes if (active_state->packet_timeout_ms == -1) 1101181111Sdes continue; 1102181111Sdes ms_subtract_diff(&start, &ms_remain); 1103181111Sdes if (ms_remain <= 0) { 1104181111Sdes ret = 0; 1105181111Sdes break; 1106181111Sdes } 1107181111Sdes } 1108181111Sdes if (ret == 0) { 1109181111Sdes logit("Connection to %.200s timed out while " 1110181111Sdes "waiting to read", get_remote_ipaddr()); 1111181111Sdes cleanup_exit(255); 1112181111Sdes } 111357429Smarkm /* Read data from the socket. */ 1114197679Sdes do { 1115197679Sdes cont = 0; 1116197679Sdes len = roaming_read(active_state->connection_in, buf, 1117197679Sdes sizeof(buf), &cont); 1118197679Sdes } while (len == 0 && cont); 111957429Smarkm if (len == 0) { 1120124208Sdes logit("Connection closed by %.200s", get_remote_ipaddr()); 1121126274Sdes cleanup_exit(255); 112257429Smarkm } 112357429Smarkm if (len < 0) 112457429Smarkm fatal("Read from socket failed: %.100s", strerror(errno)); 112557429Smarkm /* Append it to the buffer. */ 112657429Smarkm packet_process_incoming(buf, len); 112757429Smarkm } 112857429Smarkm /* NOTREACHED */ 112957429Smarkm} 113057429Smarkm 113192555Sdesint 113292555Sdespacket_read(void) 113392555Sdes{ 113492555Sdes return packet_read_seqnr(NULL); 113592555Sdes} 113692555Sdes 113757429Smarkm/* 113857429Smarkm * Waits until a packet has been received, verifies that its type matches 113957429Smarkm * that given, and gives a fatal error and exits if there is a mismatch. 114057429Smarkm */ 114157429Smarkm 114257429Smarkmvoid 114392555Sdespacket_read_expect(int expected_type) 114457429Smarkm{ 114557429Smarkm int type; 114657429Smarkm 114792555Sdes type = packet_read(); 114857429Smarkm if (type != expected_type) 114957429Smarkm packet_disconnect("Protocol error: expected packet type %d, got %d", 115060573Skris expected_type, type); 115157429Smarkm} 115257429Smarkm 115357429Smarkm/* Checks if a full packet is available in the data received so far via 115457429Smarkm * packet_process_incoming. If so, reads the packet; otherwise returns 115557429Smarkm * SSH_MSG_NONE. This does not wait for data from the connection. 115657429Smarkm * 115757429Smarkm * SSH_MSG_DISCONNECT is handled specially here. Also, 115857429Smarkm * SSH_MSG_IGNORE messages are skipped by this function and are never returned 115957429Smarkm * to higher levels. 116057429Smarkm */ 116157429Smarkm 116292555Sdesstatic int 116392555Sdespacket_read_poll1(void) 116457429Smarkm{ 116576259Sgreen u_int len, padded_len; 116692555Sdes u_char *cp, type; 116776259Sgreen u_int checksum, stored_checksum; 116857429Smarkm 116957429Smarkm /* Check if input size is less than minimum packet size. */ 1170197679Sdes if (buffer_len(&active_state->input) < 4 + 8) 117157429Smarkm return SSH_MSG_NONE; 117257429Smarkm /* Get length of incoming packet. */ 1173197679Sdes cp = buffer_ptr(&active_state->input); 1174162852Sdes len = get_u32(cp); 117557429Smarkm if (len < 1 + 2 + 2 || len > 256 * 1024) 1176113908Sdes packet_disconnect("Bad packet length %u.", len); 117757429Smarkm padded_len = (len + 8) & ~7; 117857429Smarkm 117957429Smarkm /* Check if the packet has been entirely received. */ 1180197679Sdes if (buffer_len(&active_state->input) < 4 + padded_len) 118157429Smarkm return SSH_MSG_NONE; 118257429Smarkm 118357429Smarkm /* The entire packet is in buffer. */ 118457429Smarkm 118557429Smarkm /* Consume packet length. */ 1186197679Sdes buffer_consume(&active_state->input, 4); 118757429Smarkm 118892555Sdes /* 118992555Sdes * Cryptographic attack detector for ssh 119092555Sdes * (C)1998 CORE-SDI, Buenos Aires Argentina 119192555Sdes * Ariel Futoransky(futo@core-sdi.com) 119292555Sdes */ 1193197679Sdes if (!active_state->receive_context.plaintext) { 1194197679Sdes switch (detect_attack(buffer_ptr(&active_state->input), 1195197679Sdes padded_len)) { 1196162852Sdes case DEATTACK_DETECTED: 1197162852Sdes packet_disconnect("crc32 compensation attack: " 1198162852Sdes "network attack detected"); 1199162852Sdes case DEATTACK_DOS_DETECTED: 1200162852Sdes packet_disconnect("deattack denial of " 1201162852Sdes "service detected"); 1202162852Sdes } 1203162852Sdes } 120492555Sdes 120592555Sdes /* Decrypt data to incoming_packet. */ 1206197679Sdes buffer_clear(&active_state->incoming_packet); 1207197679Sdes cp = buffer_append_space(&active_state->incoming_packet, padded_len); 1208197679Sdes cipher_crypt(&active_state->receive_context, cp, 1209248619Sdes buffer_ptr(&active_state->input), padded_len, 0, 0); 121092555Sdes 1211197679Sdes buffer_consume(&active_state->input, padded_len); 121257429Smarkm 121357429Smarkm#ifdef PACKET_DEBUG 121457429Smarkm fprintf(stderr, "read_poll plain: "); 1215197679Sdes buffer_dump(&active_state->incoming_packet); 121657429Smarkm#endif 121757429Smarkm 121857429Smarkm /* Compute packet checksum. */ 1219197679Sdes checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet), 1220197679Sdes buffer_len(&active_state->incoming_packet) - 4); 122157429Smarkm 122257429Smarkm /* Skip padding. */ 1223197679Sdes buffer_consume(&active_state->incoming_packet, 8 - len % 8); 122457429Smarkm 122557429Smarkm /* Test check bytes. */ 1226197679Sdes if (len != buffer_len(&active_state->incoming_packet)) 122792555Sdes packet_disconnect("packet_read_poll1: len %d != buffer_len %d.", 1228197679Sdes len, buffer_len(&active_state->incoming_packet)); 122957429Smarkm 1230197679Sdes cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4; 1231162852Sdes stored_checksum = get_u32(cp); 123257429Smarkm if (checksum != stored_checksum) 123357429Smarkm packet_disconnect("Corrupted check bytes on input."); 1234197679Sdes buffer_consume_end(&active_state->incoming_packet, 4); 123557429Smarkm 1236197679Sdes if (active_state->packet_compression) { 1237197679Sdes buffer_clear(&active_state->compression_buffer); 1238197679Sdes buffer_uncompress(&active_state->incoming_packet, 1239197679Sdes &active_state->compression_buffer); 1240197679Sdes buffer_clear(&active_state->incoming_packet); 1241197679Sdes buffer_append(&active_state->incoming_packet, 1242197679Sdes buffer_ptr(&active_state->compression_buffer), 1243197679Sdes buffer_len(&active_state->compression_buffer)); 124457429Smarkm } 1245197679Sdes active_state->p_read.packets++; 1246197679Sdes active_state->p_read.bytes += padded_len + 4; 1247197679Sdes type = buffer_get_char(&active_state->incoming_packet); 1248146998Sdes if (type < SSH_MSG_MIN || type > SSH_MSG_MAX) 1249146998Sdes packet_disconnect("Invalid ssh1 packet type: %d", type); 125092555Sdes return type; 125160573Skris} 125257429Smarkm 125392555Sdesstatic int 125492555Sdespacket_read_poll2(u_int32_t *seqnr_p) 125560573Skris{ 125676259Sgreen u_int padlen, need; 1257248619Sdes u_char *macbuf = NULL, *cp, type; 1258248619Sdes u_int maclen, authlen = 0, aadlen = 0, block_size; 125960573Skris Enc *enc = NULL; 126060573Skris Mac *mac = NULL; 126160573Skris Comp *comp = NULL; 126257429Smarkm 1263197679Sdes if (active_state->packet_discard) 1264192595Sdes return SSH_MSG_NONE; 1265192595Sdes 1266197679Sdes if (active_state->newkeys[MODE_IN] != NULL) { 1267197679Sdes enc = &active_state->newkeys[MODE_IN]->enc; 1268197679Sdes mac = &active_state->newkeys[MODE_IN]->mac; 1269197679Sdes comp = &active_state->newkeys[MODE_IN]->comp; 1270248619Sdes /* disable mac for authenticated encryption */ 1271248619Sdes if ((authlen = cipher_authlen(enc->cipher)) != 0) 1272248619Sdes mac = NULL; 127357429Smarkm } 127460573Skris maclen = mac && mac->enabled ? mac->mac_len : 0; 127592555Sdes block_size = enc ? enc->block_size : 8; 1276248619Sdes aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; 127760573Skris 1278248619Sdes if (aadlen && active_state->packlen == 0) { 1279248619Sdes if (buffer_len(&active_state->input) < 4) 1280248619Sdes return SSH_MSG_NONE; 1281248619Sdes cp = buffer_ptr(&active_state->input); 1282248619Sdes active_state->packlen = get_u32(cp); 1283248619Sdes if (active_state->packlen < 1 + 4 || 1284248619Sdes active_state->packlen > PACKET_MAX_SIZE) { 1285248619Sdes#ifdef PACKET_DEBUG 1286248619Sdes buffer_dump(&active_state->input); 1287248619Sdes#endif 1288248619Sdes logit("Bad packet length %u.", active_state->packlen); 1289248619Sdes packet_disconnect("Packet corrupt"); 1290248619Sdes } 1291248619Sdes buffer_clear(&active_state->incoming_packet); 1292248619Sdes } else if (active_state->packlen == 0) { 129360573Skris /* 129460573Skris * check if input size is less than the cipher block size, 129560573Skris * decrypt first block and extract length of incoming packet 129660573Skris */ 1297197679Sdes if (buffer_len(&active_state->input) < block_size) 129860573Skris return SSH_MSG_NONE; 1299197679Sdes buffer_clear(&active_state->incoming_packet); 1300197679Sdes cp = buffer_append_space(&active_state->incoming_packet, 130160573Skris block_size); 1302197679Sdes cipher_crypt(&active_state->receive_context, cp, 1303248619Sdes buffer_ptr(&active_state->input), block_size, 0, 0); 1304197679Sdes cp = buffer_ptr(&active_state->incoming_packet); 1305240075Sdes 1306197679Sdes active_state->packlen = get_u32(cp); 1307197679Sdes if (active_state->packlen < 1 + 4 || 1308197679Sdes active_state->packlen > PACKET_MAX_SIZE) { 1309124208Sdes#ifdef PACKET_DEBUG 1310197679Sdes buffer_dump(&active_state->incoming_packet); 1311124208Sdes#endif 1312197679Sdes logit("Bad packet length %u.", active_state->packlen); 1313197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1314192595Sdes PACKET_MAX_SIZE); 1315192595Sdes return SSH_MSG_NONE; 131660573Skris } 1317197679Sdes buffer_consume(&active_state->input, block_size); 131860573Skris } 1319248619Sdes DBG(debug("input: packet len %u", active_state->packlen+4)); 1320248619Sdes if (aadlen) { 1321248619Sdes /* only the payload is encrypted */ 1322248619Sdes need = active_state->packlen; 1323248619Sdes } else { 1324248619Sdes /* 1325248619Sdes * the payload size and the payload are encrypted, but we 1326248619Sdes * have a partial packet of block_size bytes 1327248619Sdes */ 1328248619Sdes need = 4 + active_state->packlen - block_size; 1329248619Sdes } 1330248619Sdes DBG(debug("partial packet: block %d, need %d, maclen %d, authlen %d," 1331248619Sdes " aadlen %d", block_size, need, maclen, authlen, aadlen)); 1332192595Sdes if (need % block_size != 0) { 1333192595Sdes logit("padding error: need %d block %d mod %d", 133460573Skris need, block_size, need % block_size); 1335197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1336192595Sdes PACKET_MAX_SIZE - block_size); 1337192595Sdes return SSH_MSG_NONE; 1338192595Sdes } 133960573Skris /* 134060573Skris * check if the entire packet has been received and 1341248619Sdes * decrypt into incoming_packet: 1342248619Sdes * 'aadlen' bytes are unencrypted, but authenticated. 1343248619Sdes * 'need' bytes are encrypted, followed by either 1344248619Sdes * 'authlen' bytes of authentication tag or 1345248619Sdes * 'maclen' bytes of message authentication code. 134660573Skris */ 1347248619Sdes if (buffer_len(&active_state->input) < aadlen + need + authlen + maclen) 134860573Skris return SSH_MSG_NONE; 134960573Skris#ifdef PACKET_DEBUG 135060573Skris fprintf(stderr, "read_poll enc/full: "); 1351197679Sdes buffer_dump(&active_state->input); 135260573Skris#endif 1353248619Sdes /* EtM: compute mac over encrypted input */ 1354248619Sdes if (mac && mac->enabled && mac->etm) 1355248619Sdes macbuf = mac_compute(mac, active_state->p_read.seqnr, 1356248619Sdes buffer_ptr(&active_state->input), aadlen + need); 1357248619Sdes cp = buffer_append_space(&active_state->incoming_packet, aadlen + need); 1358197679Sdes cipher_crypt(&active_state->receive_context, cp, 1359248619Sdes buffer_ptr(&active_state->input), need, aadlen, authlen); 1360248619Sdes buffer_consume(&active_state->input, aadlen + need + authlen); 136160573Skris /* 136260573Skris * compute MAC over seqnr and packet, 136360573Skris * increment sequence number for incoming packet 136460573Skris */ 136560573Skris if (mac && mac->enabled) { 1366248619Sdes if (!mac->etm) 1367248619Sdes macbuf = mac_compute(mac, active_state->p_read.seqnr, 1368248619Sdes buffer_ptr(&active_state->incoming_packet), 1369248619Sdes buffer_len(&active_state->incoming_packet)); 1370215116Sdes if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input), 1371197679Sdes mac->mac_len) != 0) { 1372192595Sdes logit("Corrupted MAC on input."); 1373192595Sdes if (need > PACKET_MAX_SIZE) 1374192595Sdes fatal("internal error need %d", need); 1375197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1376192595Sdes PACKET_MAX_SIZE - need); 1377192595Sdes return SSH_MSG_NONE; 1378192595Sdes } 1379192595Sdes 1380197679Sdes DBG(debug("MAC #%d ok", active_state->p_read.seqnr)); 1381197679Sdes buffer_consume(&active_state->input, mac->mac_len); 138260573Skris } 1383192595Sdes /* XXX now it's safe to use fatal/packet_disconnect */ 138492555Sdes if (seqnr_p != NULL) 1385197679Sdes *seqnr_p = active_state->p_read.seqnr; 1386197679Sdes if (++active_state->p_read.seqnr == 0) 1387124208Sdes logit("incoming seqnr wraps around"); 1388197679Sdes if (++active_state->p_read.packets == 0) 1389124208Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 1390124208Sdes fatal("XXX too many packets with same key"); 1391197679Sdes active_state->p_read.blocks += (active_state->packlen + 4) / block_size; 1392197679Sdes active_state->p_read.bytes += active_state->packlen + 4; 139360573Skris 139460573Skris /* get padlen */ 1395197679Sdes cp = buffer_ptr(&active_state->incoming_packet); 139692555Sdes padlen = cp[4]; 139760573Skris DBG(debug("input: padlen %d", padlen)); 139860573Skris if (padlen < 4) 139960573Skris packet_disconnect("Corrupted padlen %d on input.", padlen); 140060573Skris 140160573Skris /* skip packet size + padlen, discard padding */ 1402197679Sdes buffer_consume(&active_state->incoming_packet, 4 + 1); 1403197679Sdes buffer_consume_end(&active_state->incoming_packet, padlen); 140460573Skris 1405197679Sdes DBG(debug("input: len before de-compress %d", 1406197679Sdes buffer_len(&active_state->incoming_packet))); 140760573Skris if (comp && comp->enabled) { 1408197679Sdes buffer_clear(&active_state->compression_buffer); 1409197679Sdes buffer_uncompress(&active_state->incoming_packet, 1410197679Sdes &active_state->compression_buffer); 1411197679Sdes buffer_clear(&active_state->incoming_packet); 1412197679Sdes buffer_append(&active_state->incoming_packet, 1413197679Sdes buffer_ptr(&active_state->compression_buffer), 1414197679Sdes buffer_len(&active_state->compression_buffer)); 1415106121Sdes DBG(debug("input: len after de-compress %d", 1416197679Sdes buffer_len(&active_state->incoming_packet))); 141760573Skris } 141860573Skris /* 141960573Skris * get packet type, implies consume. 142060573Skris * return length of payload (without type field) 142160573Skris */ 1422197679Sdes type = buffer_get_char(&active_state->incoming_packet); 1423146998Sdes if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN) 1424146998Sdes packet_disconnect("Invalid ssh2 packet type: %d", type); 142576259Sgreen if (type == SSH2_MSG_NEWKEYS) 142676259Sgreen set_newkeys(MODE_IN); 1427197679Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && 1428197679Sdes !active_state->server_side) 1429149749Sdes packet_enable_delayed_compress(); 143060573Skris#ifdef PACKET_DEBUG 143176259Sgreen fprintf(stderr, "read/plain[%d]:\r\n", type); 1432197679Sdes buffer_dump(&active_state->incoming_packet); 143360573Skris#endif 143492555Sdes /* reset for next packet */ 1435197679Sdes active_state->packlen = 0; 143692555Sdes return type; 143757429Smarkm} 143857429Smarkm 143960573Skrisint 144092555Sdespacket_read_poll_seqnr(u_int32_t *seqnr_p) 144160573Skris{ 144299060Sdes u_int reason, seqnr; 144392555Sdes u_char type; 144460573Skris char *msg; 144592555Sdes 144660573Skris for (;;) { 144792555Sdes if (compat20) { 144892555Sdes type = packet_read_poll2(seqnr_p); 1449181111Sdes if (type) { 1450197679Sdes active_state->keep_alive_timeouts = 0; 145160573Skris DBG(debug("received packet type %d", type)); 1452181111Sdes } 145392555Sdes switch (type) { 145460573Skris case SSH2_MSG_IGNORE: 1455181111Sdes debug3("Received SSH2_MSG_IGNORE"); 145660573Skris break; 145760573Skris case SSH2_MSG_DEBUG: 145860573Skris packet_get_char(); 145960573Skris msg = packet_get_string(NULL); 146060573Skris debug("Remote: %.900s", msg); 146160573Skris xfree(msg); 146260573Skris msg = packet_get_string(NULL); 146360573Skris xfree(msg); 146460573Skris break; 146560573Skris case SSH2_MSG_DISCONNECT: 146660573Skris reason = packet_get_int(); 146760573Skris msg = packet_get_string(NULL); 1468249475Sdes /* Ignore normal client exit notifications */ 1469249475Sdes do_log2(active_state->server_side && 1470249475Sdes reason == SSH2_DISCONNECT_BY_APPLICATION ? 1471250739Sdes SYSLOG_LEVEL_INFO : SYSLOG_LEVEL_ERROR, 1472249475Sdes "Received disconnect from %s: %u: %.400s", 147399060Sdes get_remote_ipaddr(), reason, msg); 147460573Skris xfree(msg); 1475126274Sdes cleanup_exit(255); 147660573Skris break; 147792555Sdes case SSH2_MSG_UNIMPLEMENTED: 147892555Sdes seqnr = packet_get_int(); 147999060Sdes debug("Received SSH2_MSG_UNIMPLEMENTED for %u", 148099060Sdes seqnr); 148192555Sdes break; 148260573Skris default: 148360573Skris return type; 148476259Sgreen } 148560573Skris } else { 148692555Sdes type = packet_read_poll1(); 148792555Sdes switch (type) { 148860573Skris case SSH_MSG_IGNORE: 148960573Skris break; 149060573Skris case SSH_MSG_DEBUG: 149160573Skris msg = packet_get_string(NULL); 149260573Skris debug("Remote: %.900s", msg); 149360573Skris xfree(msg); 149460573Skris break; 149560573Skris case SSH_MSG_DISCONNECT: 149660573Skris msg = packet_get_string(NULL); 1497249475Sdes logit("Received disconnect from %s: %.400s", 149899060Sdes get_remote_ipaddr(), msg); 1499126274Sdes cleanup_exit(255); 150060573Skris break; 150160573Skris default: 150292555Sdes if (type) 150360573Skris DBG(debug("received packet type %d", type)); 150460573Skris return type; 150576259Sgreen } 150660573Skris } 150760573Skris } 150860573Skris} 150960573Skris 151057429Smarkm/* 151157429Smarkm * Buffers the given amount of input characters. This is intended to be used 151257429Smarkm * together with packet_read_poll. 151357429Smarkm */ 151457429Smarkm 151557429Smarkmvoid 151676259Sgreenpacket_process_incoming(const char *buf, u_int len) 151757429Smarkm{ 1518197679Sdes if (active_state->packet_discard) { 1519197679Sdes active_state->keep_alive_timeouts = 0; /* ?? */ 1520197679Sdes if (len >= active_state->packet_discard) 1521192595Sdes packet_stop_discard(); 1522197679Sdes active_state->packet_discard -= len; 1523192595Sdes return; 1524192595Sdes } 1525197679Sdes buffer_append(&active_state->input, buf, len); 152657429Smarkm} 152757429Smarkm 152857429Smarkm/* Returns a character from the packet. */ 152957429Smarkm 153076259Sgreenu_int 153192555Sdespacket_get_char(void) 153257429Smarkm{ 153357429Smarkm char ch; 1534106121Sdes 1535197679Sdes buffer_get(&active_state->incoming_packet, &ch, 1); 153676259Sgreen return (u_char) ch; 153757429Smarkm} 153857429Smarkm 153957429Smarkm/* Returns an integer from the packet data. */ 154057429Smarkm 154176259Sgreenu_int 154292555Sdespacket_get_int(void) 154357429Smarkm{ 1544197679Sdes return buffer_get_int(&active_state->incoming_packet); 154557429Smarkm} 154657429Smarkm 1547197679Sdes/* Returns an 64 bit integer from the packet data. */ 1548197679Sdes 1549197679Sdesu_int64_t 1550197679Sdespacket_get_int64(void) 1551197679Sdes{ 1552197679Sdes return buffer_get_int64(&active_state->incoming_packet); 1553197679Sdes} 1554197679Sdes 155557429Smarkm/* 155657429Smarkm * Returns an arbitrary precision integer from the packet data. The integer 155757429Smarkm * must have been initialized before this call. 155857429Smarkm */ 155957429Smarkm 156057429Smarkmvoid 156192555Sdespacket_get_bignum(BIGNUM * value) 156257429Smarkm{ 1563197679Sdes buffer_get_bignum(&active_state->incoming_packet, value); 156457429Smarkm} 156557429Smarkm 156660573Skrisvoid 156792555Sdespacket_get_bignum2(BIGNUM * value) 156860573Skris{ 1569197679Sdes buffer_get_bignum2(&active_state->incoming_packet, value); 157060573Skris} 157160573Skris 1572221420Sdes#ifdef OPENSSL_HAS_ECC 1573221420Sdesvoid 1574221420Sdespacket_get_ecpoint(const EC_GROUP *curve, EC_POINT *point) 1575221420Sdes{ 1576221420Sdes buffer_get_ecpoint(&active_state->incoming_packet, curve, point); 1577221420Sdes} 1578221420Sdes#endif 1579221420Sdes 158092555Sdesvoid * 1581149749Sdespacket_get_raw(u_int *length_ptr) 158260573Skris{ 1583197679Sdes u_int bytes = buffer_len(&active_state->incoming_packet); 1584106121Sdes 158560573Skris if (length_ptr != NULL) 158660573Skris *length_ptr = bytes; 1587197679Sdes return buffer_ptr(&active_state->incoming_packet); 158860573Skris} 158960573Skris 159060573Skrisint 159160573Skrispacket_remaining(void) 159260573Skris{ 1593197679Sdes return buffer_len(&active_state->incoming_packet); 159460573Skris} 159560573Skris 159657429Smarkm/* 159757429Smarkm * Returns a string from the packet data. The string is allocated using 159857429Smarkm * xmalloc; it is the responsibility of the calling program to free it when 159957429Smarkm * no longer needed. The length_ptr argument may be NULL, or point to an 160057429Smarkm * integer into which the length of the string is stored. 160157429Smarkm */ 160257429Smarkm 160392555Sdesvoid * 160476259Sgreenpacket_get_string(u_int *length_ptr) 160557429Smarkm{ 1606197679Sdes return buffer_get_string(&active_state->incoming_packet, length_ptr); 160757429Smarkm} 160857429Smarkm 1609181111Sdesvoid * 1610181111Sdespacket_get_string_ptr(u_int *length_ptr) 1611181111Sdes{ 1612197679Sdes return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr); 1613181111Sdes} 1614181111Sdes 1615221420Sdes/* Ensures the returned string has no embedded \0 characters in it. */ 1616221420Sdeschar * 1617221420Sdespacket_get_cstring(u_int *length_ptr) 1618221420Sdes{ 1619221420Sdes return buffer_get_cstring(&active_state->incoming_packet, length_ptr); 1620221420Sdes} 1621221420Sdes 162257429Smarkm/* 162357429Smarkm * Sends a diagnostic message from the server to the client. This message 162457429Smarkm * can be sent at any time (but not while constructing another message). The 162557429Smarkm * message is printed immediately, but only if the client is being executed 162657429Smarkm * in verbose mode. These messages are primarily intended to ease debugging 162757429Smarkm * authentication problems. The length of the formatted message must not 162857429Smarkm * exceed 1024 bytes. This will automatically call packet_write_wait. 162957429Smarkm */ 163057429Smarkm 163157429Smarkmvoid 163257429Smarkmpacket_send_debug(const char *fmt,...) 163357429Smarkm{ 163457429Smarkm char buf[1024]; 163557429Smarkm va_list args; 163657429Smarkm 163776259Sgreen if (compat20 && (datafellows & SSH_BUG_DEBUG)) 163876259Sgreen return; 163976259Sgreen 164057429Smarkm va_start(args, fmt); 164157429Smarkm vsnprintf(buf, sizeof(buf), fmt, args); 164257429Smarkm va_end(args); 164357429Smarkm 164460573Skris if (compat20) { 164560573Skris packet_start(SSH2_MSG_DEBUG); 164660573Skris packet_put_char(0); /* bool: always display */ 164760573Skris packet_put_cstring(buf); 164860573Skris packet_put_cstring(""); 164960573Skris } else { 165060573Skris packet_start(SSH_MSG_DEBUG); 165160573Skris packet_put_cstring(buf); 165260573Skris } 165357429Smarkm packet_send(); 165457429Smarkm packet_write_wait(); 165557429Smarkm} 165657429Smarkm 165757429Smarkm/* 165857429Smarkm * Logs the error plus constructs and sends a disconnect packet, closes the 165957429Smarkm * connection, and exits. This function never returns. The error message 166057429Smarkm * should not contain a newline. The length of the formatted message must 166157429Smarkm * not exceed 1024 bytes. 166257429Smarkm */ 166357429Smarkm 166457429Smarkmvoid 166557429Smarkmpacket_disconnect(const char *fmt,...) 166657429Smarkm{ 166757429Smarkm char buf[1024]; 166857429Smarkm va_list args; 166957429Smarkm static int disconnecting = 0; 1670106121Sdes 167157429Smarkm if (disconnecting) /* Guard against recursive invocations. */ 167257429Smarkm fatal("packet_disconnect called recursively."); 167357429Smarkm disconnecting = 1; 167457429Smarkm 167557429Smarkm /* 167657429Smarkm * Format the message. Note that the caller must make sure the 167757429Smarkm * message is of limited size. 167857429Smarkm */ 167957429Smarkm va_start(args, fmt); 168057429Smarkm vsnprintf(buf, sizeof(buf), fmt, args); 168157429Smarkm va_end(args); 168257429Smarkm 1683113908Sdes /* Display the error locally */ 1684124208Sdes logit("Disconnecting: %.100s", buf); 1685113908Sdes 168657429Smarkm /* Send the disconnect message to the other side, and wait for it to get sent. */ 168760573Skris if (compat20) { 168860573Skris packet_start(SSH2_MSG_DISCONNECT); 168960573Skris packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); 169060573Skris packet_put_cstring(buf); 169160573Skris packet_put_cstring(""); 169260573Skris } else { 169360573Skris packet_start(SSH_MSG_DISCONNECT); 169492555Sdes packet_put_cstring(buf); 169560573Skris } 169657429Smarkm packet_send(); 169757429Smarkm packet_write_wait(); 169857429Smarkm 169957429Smarkm /* Stop listening for connections. */ 170092555Sdes channel_close_all(); 170157429Smarkm 170257429Smarkm /* Close the connection. */ 170357429Smarkm packet_close(); 1704126274Sdes cleanup_exit(255); 170557429Smarkm} 170657429Smarkm 170757429Smarkm/* Checks if there is any buffered output, and tries to write some of the output. */ 170857429Smarkm 170957429Smarkmvoid 171092555Sdespacket_write_poll(void) 171157429Smarkm{ 1712197679Sdes int len = buffer_len(&active_state->output); 1713197679Sdes int cont; 1714106121Sdes 171557429Smarkm if (len > 0) { 1716197679Sdes cont = 0; 1717197679Sdes len = roaming_write(active_state->connection_out, 1718197679Sdes buffer_ptr(&active_state->output), len, &cont); 1719181111Sdes if (len == -1) { 1720181111Sdes if (errno == EINTR || errno == EAGAIN || 1721181111Sdes errno == EWOULDBLOCK) 172257429Smarkm return; 1723181111Sdes fatal("Write failed: %.100s", strerror(errno)); 172457429Smarkm } 1725197679Sdes if (len == 0 && !cont) 1726181111Sdes fatal("Write connection closed"); 1727197679Sdes buffer_consume(&active_state->output, len); 172857429Smarkm } 172957429Smarkm} 173057429Smarkm 173157429Smarkm/* 173257429Smarkm * Calls packet_write_poll repeatedly until all pending output data has been 173357429Smarkm * written. 173457429Smarkm */ 173557429Smarkm 173657429Smarkmvoid 173792555Sdespacket_write_wait(void) 173857429Smarkm{ 173976259Sgreen fd_set *setp; 1740181111Sdes int ret, ms_remain; 1741181111Sdes struct timeval start, timeout, *timeoutp = NULL; 174276259Sgreen 1743197679Sdes setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, 1744197679Sdes NFDBITS), sizeof(fd_mask)); 174557429Smarkm packet_write_poll(); 174657429Smarkm while (packet_have_data_to_write()) { 1747197679Sdes memset(setp, 0, howmany(active_state->connection_out + 1, 1748197679Sdes NFDBITS) * sizeof(fd_mask)); 1749197679Sdes FD_SET(active_state->connection_out, setp); 1750181111Sdes 1751197679Sdes if (active_state->packet_timeout_ms > 0) { 1752197679Sdes ms_remain = active_state->packet_timeout_ms; 1753181111Sdes timeoutp = &timeout; 1754181111Sdes } 1755181111Sdes for (;;) { 1756197679Sdes if (active_state->packet_timeout_ms != -1) { 1757181111Sdes ms_to_timeval(&timeout, ms_remain); 1758181111Sdes gettimeofday(&start, NULL); 1759181111Sdes } 1760197679Sdes if ((ret = select(active_state->connection_out + 1, 1761197679Sdes NULL, setp, NULL, timeoutp)) >= 0) 1762181111Sdes break; 1763197679Sdes if (errno != EAGAIN && errno != EINTR && 1764181111Sdes errno != EWOULDBLOCK) 1765181111Sdes break; 1766197679Sdes if (active_state->packet_timeout_ms == -1) 1767181111Sdes continue; 1768181111Sdes ms_subtract_diff(&start, &ms_remain); 1769181111Sdes if (ms_remain <= 0) { 1770181111Sdes ret = 0; 1771181111Sdes break; 1772181111Sdes } 1773181111Sdes } 1774181111Sdes if (ret == 0) { 1775181111Sdes logit("Connection to %.200s timed out while " 1776181111Sdes "waiting to write", get_remote_ipaddr()); 1777181111Sdes cleanup_exit(255); 1778181111Sdes } 177957429Smarkm packet_write_poll(); 178057429Smarkm } 178176259Sgreen xfree(setp); 178257429Smarkm} 178357429Smarkm 178457429Smarkm/* Returns true if there is buffered data to write to the connection. */ 178557429Smarkm 178657429Smarkmint 178792555Sdespacket_have_data_to_write(void) 178857429Smarkm{ 1789197679Sdes return buffer_len(&active_state->output) != 0; 179057429Smarkm} 179157429Smarkm 179257429Smarkm/* Returns true if there is not too much data to write to the connection. */ 179357429Smarkm 179457429Smarkmint 179592555Sdespacket_not_very_much_data_to_write(void) 179657429Smarkm{ 1797197679Sdes if (active_state->interactive_mode) 1798197679Sdes return buffer_len(&active_state->output) < 16384; 179957429Smarkm else 1800197679Sdes return buffer_len(&active_state->output) < 128 * 1024; 180157429Smarkm} 180257429Smarkm 1803113908Sdesstatic void 1804221420Sdespacket_set_tos(int tos) 1805113908Sdes{ 1806226046Sdes#ifndef IP_TOS_IS_BROKEN 1807226046Sdes if (!packet_connection_is_on_socket()) 1808113908Sdes return; 1809226046Sdes switch (packet_connection_af()) { 1810226046Sdes# ifdef IP_TOS 1811226046Sdes case AF_INET: 1812226046Sdes debug3("%s: set IP_TOS 0x%02x", __func__, tos); 1813226046Sdes if (setsockopt(active_state->connection_in, 1814226046Sdes IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) 1815226046Sdes error("setsockopt IP_TOS %d: %.100s:", 1816226046Sdes tos, strerror(errno)); 1817226046Sdes break; 1818226046Sdes# endif /* IP_TOS */ 1819226046Sdes# ifdef IPV6_TCLASS 1820226046Sdes case AF_INET6: 1821226046Sdes debug3("%s: set IPV6_TCLASS 0x%02x", __func__, tos); 1822226046Sdes if (setsockopt(active_state->connection_in, 1823226046Sdes IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0) 1824226046Sdes error("setsockopt IPV6_TCLASS %d: %.100s:", 1825226046Sdes tos, strerror(errno)); 1826226046Sdes break; 1827226046Sdes# endif /* IPV6_TCLASS */ 1828226046Sdes } 1829226046Sdes#endif /* IP_TOS_IS_BROKEN */ 1830113908Sdes} 1831113908Sdes 183257429Smarkm/* Informs that the current session is interactive. Sets IP flags for that. */ 183357429Smarkm 183457429Smarkmvoid 1835221420Sdespacket_set_interactive(int interactive, int qos_interactive, int qos_bulk) 183657429Smarkm{ 1837197679Sdes if (active_state->set_interactive_called) 183876259Sgreen return; 1839197679Sdes active_state->set_interactive_called = 1; 184076259Sgreen 184157429Smarkm /* Record that we are in interactive mode. */ 1842197679Sdes active_state->interactive_mode = interactive; 184357429Smarkm 184457429Smarkm /* Only set socket options if using a socket. */ 184557429Smarkm if (!packet_connection_is_on_socket()) 1846116791Sdes return; 1847197679Sdes set_nodelay(active_state->connection_in); 1848221420Sdes packet_set_tos(interactive ? qos_interactive : qos_bulk); 184957429Smarkm} 185057429Smarkm 185157429Smarkm/* Returns true if the current connection is interactive. */ 185257429Smarkm 185357429Smarkmint 185492555Sdespacket_is_interactive(void) 185557429Smarkm{ 1856197679Sdes return active_state->interactive_mode; 185757429Smarkm} 185857429Smarkm 1859137015Sdesint 1860124208Sdespacket_set_maxsize(u_int s) 186157429Smarkm{ 1862197679Sdes if (active_state->set_maxsize_called) { 1863124208Sdes logit("packet_set_maxsize: called twice: old %d new %d", 1864197679Sdes active_state->max_packet_size, s); 186557429Smarkm return -1; 186657429Smarkm } 186757429Smarkm if (s < 4 * 1024 || s > 1024 * 1024) { 1868124208Sdes logit("packet_set_maxsize: bad size %d", s); 186957429Smarkm return -1; 187057429Smarkm } 1871197679Sdes active_state->set_maxsize_called = 1; 187292555Sdes debug("packet_set_maxsize: setting to %d", s); 1873197679Sdes active_state->max_packet_size = s; 187457429Smarkm return s; 187557429Smarkm} 187676259Sgreen 1877197679Sdesint 1878197679Sdespacket_inc_alive_timeouts(void) 1879197679Sdes{ 1880197679Sdes return ++active_state->keep_alive_timeouts; 1881197679Sdes} 1882197679Sdes 1883197679Sdesvoid 1884197679Sdespacket_set_alive_timeouts(int ka) 1885197679Sdes{ 1886197679Sdes active_state->keep_alive_timeouts = ka; 1887197679Sdes} 1888197679Sdes 1889197679Sdesu_int 1890197679Sdespacket_get_maxsize(void) 1891197679Sdes{ 1892197679Sdes return active_state->max_packet_size; 1893197679Sdes} 1894197679Sdes 189592555Sdes/* roundup current message to pad bytes */ 189692555Sdesvoid 189792555Sdespacket_add_padding(u_char pad) 189892555Sdes{ 1899197679Sdes active_state->extra_pad = pad; 190092555Sdes} 190192555Sdes 190276259Sgreen/* 190376259Sgreen * 9.2. Ignored Data Message 190476259Sgreen * 190576259Sgreen * byte SSH_MSG_IGNORE 190676259Sgreen * string data 190776259Sgreen * 190876259Sgreen * All implementations MUST understand (and ignore) this message at any 190976259Sgreen * time (after receiving the protocol version). No implementation is 191076259Sgreen * required to send them. This message can be used as an additional 191176259Sgreen * protection measure against advanced traffic analysis techniques. 191276259Sgreen */ 191376259Sgreenvoid 191476259Sgreenpacket_send_ignore(int nbytes) 191576259Sgreen{ 1916137015Sdes u_int32_t rnd = 0; 191776259Sgreen int i; 191876259Sgreen 191976259Sgreen packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); 192076259Sgreen packet_put_int(nbytes); 192192555Sdes for (i = 0; i < nbytes; i++) { 192276259Sgreen if (i % 4 == 0) 1923137015Sdes rnd = arc4random(); 1924162852Sdes packet_put_char((u_char)rnd & 0xff); 1925137015Sdes rnd >>= 8; 192676259Sgreen } 192776259Sgreen} 1928124208Sdes 1929224638Sbrooks#ifdef NONE_CIPHER_ENABLED 1930224638Sbrooksvoid 1931224638Sbrookspacket_request_rekeying(void) 1932224638Sbrooks{ 1933224638Sbrooks rekey_requested = 1; 1934224638Sbrooks} 1935224638Sbrooks#endif 1936224638Sbrooks 1937137015Sdes#define MAX_PACKETS (1U<<31) 1938124208Sdesint 1939124208Sdespacket_need_rekeying(void) 1940124208Sdes{ 1941124208Sdes if (datafellows & SSH_BUG_NOREKEY) 1942124208Sdes return 0; 1943224638Sbrooks#ifdef NONE_CIPHER_ENABLED 1944224638Sbrooks if (rekey_requested == 1) { 1945224638Sbrooks rekey_requested = 0; 1946224638Sbrooks return 1; 1947224638Sbrooks } 1948224638Sbrooks#endif 1949124208Sdes return 1950197679Sdes (active_state->p_send.packets > MAX_PACKETS) || 1951197679Sdes (active_state->p_read.packets > MAX_PACKETS) || 1952197679Sdes (active_state->max_blocks_out && 1953197679Sdes (active_state->p_send.blocks > active_state->max_blocks_out)) || 1954197679Sdes (active_state->max_blocks_in && 1955197679Sdes (active_state->p_read.blocks > active_state->max_blocks_in)); 1956124208Sdes} 1957124208Sdes 1958124208Sdesvoid 1959124208Sdespacket_set_rekey_limit(u_int32_t bytes) 1960124208Sdes{ 1961197679Sdes active_state->rekey_limit = bytes; 1962124208Sdes} 1963149749Sdes 1964149749Sdesvoid 1965149749Sdespacket_set_server(void) 1966149749Sdes{ 1967197679Sdes active_state->server_side = 1; 1968149749Sdes} 1969149749Sdes 1970149749Sdesvoid 1971149749Sdespacket_set_authenticated(void) 1972149749Sdes{ 1973197679Sdes active_state->after_authentication = 1; 1974149749Sdes} 1975197679Sdes 1976197679Sdesvoid * 1977197679Sdespacket_get_input(void) 1978197679Sdes{ 1979197679Sdes return (void *)&active_state->input; 1980197679Sdes} 1981197679Sdes 1982197679Sdesvoid * 1983197679Sdespacket_get_output(void) 1984197679Sdes{ 1985197679Sdes return (void *)&active_state->output; 1986197679Sdes} 1987197679Sdes 1988197679Sdesvoid * 1989197679Sdespacket_get_newkeys(int mode) 1990197679Sdes{ 1991197679Sdes return (void *)active_state->newkeys[mode]; 1992197679Sdes} 1993197679Sdes 1994197679Sdes/* 1995197679Sdes * Save the state for the real connection, and use a separate state when 1996197679Sdes * resuming a suspended connection. 1997197679Sdes */ 1998197679Sdesvoid 1999197679Sdespacket_backup_state(void) 2000197679Sdes{ 2001197679Sdes struct session_state *tmp; 2002197679Sdes 2003197679Sdes close(active_state->connection_in); 2004197679Sdes active_state->connection_in = -1; 2005197679Sdes close(active_state->connection_out); 2006197679Sdes active_state->connection_out = -1; 2007197679Sdes if (backup_state) 2008197679Sdes tmp = backup_state; 2009197679Sdes else 2010197679Sdes tmp = alloc_session_state(); 2011197679Sdes backup_state = active_state; 2012197679Sdes active_state = tmp; 2013197679Sdes} 2014197679Sdes 2015197679Sdes/* 2016197679Sdes * Swap in the old state when resuming a connecion. 2017197679Sdes */ 2018197679Sdesvoid 2019197679Sdespacket_restore_state(void) 2020197679Sdes{ 2021197679Sdes struct session_state *tmp; 2022197679Sdes void *buf; 2023197679Sdes u_int len; 2024197679Sdes 2025197679Sdes tmp = backup_state; 2026197679Sdes backup_state = active_state; 2027197679Sdes active_state = tmp; 2028197679Sdes active_state->connection_in = backup_state->connection_in; 2029197679Sdes backup_state->connection_in = -1; 2030197679Sdes active_state->connection_out = backup_state->connection_out; 2031197679Sdes backup_state->connection_out = -1; 2032197679Sdes len = buffer_len(&backup_state->input); 2033197679Sdes if (len > 0) { 2034197679Sdes buf = buffer_ptr(&backup_state->input); 2035197679Sdes buffer_append(&active_state->input, buf, len); 2036197679Sdes buffer_clear(&backup_state->input); 2037197679Sdes add_recv_bytes(len); 2038197679Sdes } 2039197679Sdes} 2040224638Sbrooks 2041224638Sbrooks#ifdef NONE_CIPHER_ENABLED 2042224638Sbrooksint 2043224638Sbrookspacket_get_authentication_state(void) 2044224638Sbrooks{ 2045224638Sbrooks return (active_state->after_authentication); 2046224638Sbrooks} 2047224638Sbrooks#endif 2048