packet.c revision 224638
1221420Sdes/* $OpenBSD: packet.c,v 1.172 2010/11/13 23:27:50 djm Exp $ */ 2224638Sbrooks/* $FreeBSD$ */ 357429Smarkm/* 457429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 557429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 657429Smarkm * All rights reserved 757429Smarkm * This file contains code implementing the packet protocol and communication 857429Smarkm * with the other side. This same code is used both on client and server side. 960573Skris * 1065668Skris * As far as I am concerned, the code I have written for this software 1165668Skris * can be used freely for any purpose. Any derived versions of this 1265668Skris * software must be clearly marked as such, and if the derived work is 1365668Skris * incompatible with the protocol description in the RFC file, it must be 1465668Skris * called by a name other than "ssh" or "Secure Shell". 1565668Skris * 1665668Skris * 1760573Skris * SSH2 packet format added by Markus Friedl. 1892555Sdes * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 1960573Skris * 2065668Skris * Redistribution and use in source and binary forms, with or without 2165668Skris * modification, are permitted provided that the following conditions 2265668Skris * are met: 2365668Skris * 1. Redistributions of source code must retain the above copyright 2465668Skris * notice, this list of conditions and the following disclaimer. 2565668Skris * 2. Redistributions in binary form must reproduce the above copyright 2665668Skris * notice, this list of conditions and the following disclaimer in the 2765668Skris * documentation and/or other materials provided with the distribution. 2865668Skris * 2965668Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 3065668Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 3165668Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 3265668Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 3365668Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3465668Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3565668Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3665668Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3765668Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3865668Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3957429Smarkm */ 4057429Smarkm 4157429Smarkm#include "includes.h" 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{ 249181111Sdes 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{ 282192595Sdes if (enc == NULL || !cipher_is_cbc(enc->cipher)) 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 42957429Smarkm/* returns 1 if connection is via ipv4 */ 43057429Smarkm 43157429Smarkmint 43292555Sdespacket_connection_is_ipv4(void) 43357429Smarkm{ 43457429Smarkm struct sockaddr_storage to; 43557429Smarkm socklen_t tolen = sizeof(to); 43657429Smarkm 43757429Smarkm memset(&to, 0, sizeof(to)); 438197679Sdes if (getsockname(active_state->connection_out, (struct sockaddr *)&to, 439197679Sdes &tolen) < 0) 44057429Smarkm return 0; 44198937Sdes if (to.ss_family == AF_INET) 44298937Sdes return 1; 44398937Sdes#ifdef IPV4_IN_IPV6 444126274Sdes if (to.ss_family == AF_INET6 && 44598937Sdes IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) 44698937Sdes return 1; 44798937Sdes#endif 44898937Sdes return 0; 44957429Smarkm} 45057429Smarkm 45157429Smarkm/* Sets the connection into non-blocking mode. */ 45257429Smarkm 45357429Smarkmvoid 45492555Sdespacket_set_nonblocking(void) 45557429Smarkm{ 45657429Smarkm /* Set the socket into non-blocking mode. */ 457197679Sdes set_nonblock(active_state->connection_in); 45857429Smarkm 459197679Sdes if (active_state->connection_out != active_state->connection_in) 460197679Sdes set_nonblock(active_state->connection_out); 46157429Smarkm} 46257429Smarkm 46357429Smarkm/* Returns the socket used for reading. */ 46457429Smarkm 46557429Smarkmint 46692555Sdespacket_get_connection_in(void) 46757429Smarkm{ 468197679Sdes return active_state->connection_in; 46957429Smarkm} 47057429Smarkm 47157429Smarkm/* Returns the descriptor used for writing. */ 47257429Smarkm 47357429Smarkmint 47492555Sdespacket_get_connection_out(void) 47557429Smarkm{ 476197679Sdes return active_state->connection_out; 47757429Smarkm} 47857429Smarkm 47957429Smarkm/* Closes the connection and clears and frees internal data structures. */ 48057429Smarkm 48157429Smarkmvoid 48292555Sdespacket_close(void) 48357429Smarkm{ 484197679Sdes if (!active_state->initialized) 48557429Smarkm return; 486197679Sdes active_state->initialized = 0; 487197679Sdes if (active_state->connection_in == active_state->connection_out) { 488197679Sdes shutdown(active_state->connection_out, SHUT_RDWR); 489197679Sdes close(active_state->connection_out); 49057429Smarkm } else { 491197679Sdes close(active_state->connection_in); 492197679Sdes close(active_state->connection_out); 49357429Smarkm } 494197679Sdes buffer_free(&active_state->input); 495197679Sdes buffer_free(&active_state->output); 496197679Sdes buffer_free(&active_state->outgoing_packet); 497197679Sdes buffer_free(&active_state->incoming_packet); 498197679Sdes if (active_state->compression_buffer_ready) { 499197679Sdes buffer_free(&active_state->compression_buffer); 50057429Smarkm buffer_compress_uninit(); 50157429Smarkm } 502197679Sdes cipher_cleanup(&active_state->send_context); 503197679Sdes cipher_cleanup(&active_state->receive_context); 50457429Smarkm} 50557429Smarkm 50657429Smarkm/* Sets remote side protocol flags. */ 50757429Smarkm 50857429Smarkmvoid 50976259Sgreenpacket_set_protocol_flags(u_int protocol_flags) 51057429Smarkm{ 511197679Sdes active_state->remote_protocol_flags = protocol_flags; 51257429Smarkm} 51357429Smarkm 51457429Smarkm/* Returns the remote protocol flags set earlier by the above function. */ 51557429Smarkm 51676259Sgreenu_int 51792555Sdespacket_get_protocol_flags(void) 51857429Smarkm{ 519197679Sdes return active_state->remote_protocol_flags; 52057429Smarkm} 52157429Smarkm 52257429Smarkm/* 52357429Smarkm * Starts packet compression from the next packet on in both directions. 52457429Smarkm * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. 52557429Smarkm */ 52657429Smarkm 52792555Sdesstatic void 52892555Sdespacket_init_compression(void) 52976259Sgreen{ 530197679Sdes if (active_state->compression_buffer_ready == 1) 53176259Sgreen return; 532197679Sdes active_state->compression_buffer_ready = 1; 533197679Sdes buffer_init(&active_state->compression_buffer); 53476259Sgreen} 53576259Sgreen 53676259Sgreenvoid 53757429Smarkmpacket_start_compression(int level) 53857429Smarkm{ 539197679Sdes if (active_state->packet_compression && !compat20) 54057429Smarkm fatal("Compression already enabled."); 541197679Sdes active_state->packet_compression = 1; 54276259Sgreen packet_init_compression(); 54376259Sgreen buffer_compress_init_send(level); 54476259Sgreen buffer_compress_init_recv(); 54557429Smarkm} 54657429Smarkm 54757429Smarkm/* 54857429Smarkm * Causes any further packets to be encrypted using the given key. The same 54957429Smarkm * key is used for both sending and reception. However, both directions are 55057429Smarkm * encrypted independently of each other. 55157429Smarkm */ 55298675Sdes 55357429Smarkmvoid 554221420Sdespacket_set_encryption_key(const u_char *key, u_int keylen, int number) 55557429Smarkm{ 55669587Sgreen Cipher *cipher = cipher_by_number(number); 557106121Sdes 55869587Sgreen if (cipher == NULL) 55969587Sgreen fatal("packet_set_encryption_key: unknown cipher number %d", number); 56060573Skris if (keylen < 20) 56169587Sgreen fatal("packet_set_encryption_key: keylen too small: %d", keylen); 56298675Sdes if (keylen > SSH_SESSION_KEY_LENGTH) 56398675Sdes fatal("packet_set_encryption_key: keylen too big: %d", keylen); 564197679Sdes memcpy(active_state->ssh1_key, key, keylen); 565197679Sdes active_state->ssh1_keylen = keylen; 566197679Sdes cipher_init(&active_state->send_context, cipher, key, keylen, NULL, 567197679Sdes 0, CIPHER_ENCRYPT); 568197679Sdes cipher_init(&active_state->receive_context, cipher, key, keylen, NULL, 569197679Sdes 0, CIPHER_DECRYPT); 57057429Smarkm} 57157429Smarkm 57298675Sdesu_int 57398675Sdespacket_get_encryption_key(u_char *key) 57498675Sdes{ 57598675Sdes if (key == NULL) 576197679Sdes return (active_state->ssh1_keylen); 577197679Sdes memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen); 578197679Sdes return (active_state->ssh1_keylen); 57998675Sdes} 58098675Sdes 58192555Sdes/* Start constructing a packet to send. */ 58257429Smarkmvoid 58392555Sdespacket_start(u_char type) 58457429Smarkm{ 58592555Sdes u_char buf[9]; 58692555Sdes int len; 58757429Smarkm 58892555Sdes DBG(debug("packet_start[%d]", type)); 58992555Sdes len = compat20 ? 6 : 9; 59092555Sdes memset(buf, 0, len - 1); 59192555Sdes buf[len - 1] = type; 592197679Sdes buffer_clear(&active_state->outgoing_packet); 593197679Sdes buffer_append(&active_state->outgoing_packet, buf, len); 59457429Smarkm} 59557429Smarkm 59692555Sdes/* Append payload. */ 59760573Skrisvoid 59857429Smarkmpacket_put_char(int value) 59957429Smarkm{ 60057429Smarkm char ch = value; 601106121Sdes 602197679Sdes buffer_append(&active_state->outgoing_packet, &ch, 1); 60357429Smarkm} 604162852Sdes 60557429Smarkmvoid 60676259Sgreenpacket_put_int(u_int value) 60757429Smarkm{ 608197679Sdes buffer_put_int(&active_state->outgoing_packet, value); 60957429Smarkm} 610162852Sdes 61157429Smarkmvoid 612197679Sdespacket_put_int64(u_int64_t value) 613197679Sdes{ 614197679Sdes buffer_put_int64(&active_state->outgoing_packet, value); 615197679Sdes} 616197679Sdes 617197679Sdesvoid 61892555Sdespacket_put_string(const void *buf, u_int len) 61957429Smarkm{ 620197679Sdes buffer_put_string(&active_state->outgoing_packet, buf, len); 62157429Smarkm} 622162852Sdes 62360573Skrisvoid 62460573Skrispacket_put_cstring(const char *str) 62560573Skris{ 626197679Sdes buffer_put_cstring(&active_state->outgoing_packet, str); 62760573Skris} 628162852Sdes 62960573Skrisvoid 63092555Sdespacket_put_raw(const void *buf, u_int len) 63160573Skris{ 632197679Sdes buffer_append(&active_state->outgoing_packet, buf, len); 63360573Skris} 634162852Sdes 63557429Smarkmvoid 63657429Smarkmpacket_put_bignum(BIGNUM * value) 63757429Smarkm{ 638197679Sdes buffer_put_bignum(&active_state->outgoing_packet, value); 63957429Smarkm} 640162852Sdes 64160573Skrisvoid 64260573Skrispacket_put_bignum2(BIGNUM * value) 64360573Skris{ 644197679Sdes buffer_put_bignum2(&active_state->outgoing_packet, value); 64560573Skris} 64657429Smarkm 647221420Sdes#ifdef OPENSSL_HAS_ECC 648221420Sdesvoid 649221420Sdespacket_put_ecpoint(const EC_GROUP *curve, const EC_POINT *point) 650221420Sdes{ 651221420Sdes buffer_put_ecpoint(&active_state->outgoing_packet, curve, point); 652221420Sdes} 653221420Sdes#endif 654221420Sdes 65557429Smarkm/* 65657429Smarkm * Finalizes and sends the packet. If the encryption key has been set, 65757429Smarkm * encrypts the packet before sending. 65857429Smarkm */ 65957429Smarkm 66092555Sdesstatic void 66176259Sgreenpacket_send1(void) 66257429Smarkm{ 66392555Sdes u_char buf[8], *cp; 66457429Smarkm int i, padding, len; 66576259Sgreen u_int checksum; 666137015Sdes u_int32_t rnd = 0; 66757429Smarkm 66857429Smarkm /* 66957429Smarkm * If using packet compression, compress the payload of the outgoing 67057429Smarkm * packet. 67157429Smarkm */ 672197679Sdes if (active_state->packet_compression) { 673197679Sdes buffer_clear(&active_state->compression_buffer); 67457429Smarkm /* Skip padding. */ 675197679Sdes buffer_consume(&active_state->outgoing_packet, 8); 67657429Smarkm /* padding */ 677197679Sdes buffer_append(&active_state->compression_buffer, 678197679Sdes "\0\0\0\0\0\0\0\0", 8); 679197679Sdes buffer_compress(&active_state->outgoing_packet, 680197679Sdes &active_state->compression_buffer); 681197679Sdes buffer_clear(&active_state->outgoing_packet); 682197679Sdes buffer_append(&active_state->outgoing_packet, 683197679Sdes buffer_ptr(&active_state->compression_buffer), 684197679Sdes buffer_len(&active_state->compression_buffer)); 68557429Smarkm } 68657429Smarkm /* Compute packet length without padding (add checksum, remove padding). */ 687197679Sdes len = buffer_len(&active_state->outgoing_packet) + 4 - 8; 68857429Smarkm 68960573Skris /* Insert padding. Initialized to zero in packet_start1() */ 69057429Smarkm padding = 8 - len % 8; 691197679Sdes if (!active_state->send_context.plaintext) { 692197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 69357429Smarkm for (i = 0; i < padding; i++) { 69457429Smarkm if (i % 4 == 0) 695137015Sdes rnd = arc4random(); 696137015Sdes cp[7 - i] = rnd & 0xff; 697137015Sdes rnd >>= 8; 69857429Smarkm } 69957429Smarkm } 700197679Sdes buffer_consume(&active_state->outgoing_packet, 8 - padding); 70157429Smarkm 70257429Smarkm /* Add check bytes. */ 703197679Sdes checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet), 704197679Sdes buffer_len(&active_state->outgoing_packet)); 705162852Sdes put_u32(buf, checksum); 706197679Sdes buffer_append(&active_state->outgoing_packet, buf, 4); 70757429Smarkm 70857429Smarkm#ifdef PACKET_DEBUG 70957429Smarkm fprintf(stderr, "packet_send plain: "); 710197679Sdes buffer_dump(&active_state->outgoing_packet); 71157429Smarkm#endif 71257429Smarkm 71357429Smarkm /* Append to output. */ 714162852Sdes put_u32(buf, len); 715197679Sdes buffer_append(&active_state->output, buf, 4); 716197679Sdes cp = buffer_append_space(&active_state->output, 717197679Sdes buffer_len(&active_state->outgoing_packet)); 718197679Sdes cipher_crypt(&active_state->send_context, cp, 719197679Sdes buffer_ptr(&active_state->outgoing_packet), 720197679Sdes buffer_len(&active_state->outgoing_packet)); 72157429Smarkm 72257429Smarkm#ifdef PACKET_DEBUG 72357429Smarkm fprintf(stderr, "encrypted: "); 724197679Sdes buffer_dump(&active_state->output); 72557429Smarkm#endif 726197679Sdes active_state->p_send.packets++; 727197679Sdes active_state->p_send.bytes += len + 728197679Sdes buffer_len(&active_state->outgoing_packet); 729197679Sdes buffer_clear(&active_state->outgoing_packet); 73057429Smarkm 73157429Smarkm /* 732157016Sdes * Note that the packet is now only buffered in output. It won't be 73357429Smarkm * actually sent until packet_write_wait or packet_write_poll is 73457429Smarkm * called. 73557429Smarkm */ 73657429Smarkm} 73757429Smarkm 73898675Sdesvoid 73976259Sgreenset_newkeys(int mode) 74076259Sgreen{ 74176259Sgreen Enc *enc; 74276259Sgreen Mac *mac; 74376259Sgreen Comp *comp; 74476259Sgreen CipherContext *cc; 745124208Sdes u_int64_t *max_blocks; 746137015Sdes int crypt_type; 74776259Sgreen 748113908Sdes debug2("set_newkeys: mode %d", mode); 74976259Sgreen 75092555Sdes if (mode == MODE_OUT) { 751197679Sdes cc = &active_state->send_context; 752137015Sdes crypt_type = CIPHER_ENCRYPT; 753197679Sdes active_state->p_send.packets = active_state->p_send.blocks = 0; 754197679Sdes max_blocks = &active_state->max_blocks_out; 75592555Sdes } else { 756197679Sdes cc = &active_state->receive_context; 757137015Sdes crypt_type = CIPHER_DECRYPT; 758197679Sdes active_state->p_read.packets = active_state->p_read.blocks = 0; 759197679Sdes max_blocks = &active_state->max_blocks_in; 76092555Sdes } 761197679Sdes if (active_state->newkeys[mode] != NULL) { 762113908Sdes debug("set_newkeys: rekeying"); 76392555Sdes cipher_cleanup(cc); 764197679Sdes enc = &active_state->newkeys[mode]->enc; 765197679Sdes mac = &active_state->newkeys[mode]->mac; 766197679Sdes comp = &active_state->newkeys[mode]->comp; 767181111Sdes mac_clear(mac); 76876259Sgreen xfree(enc->name); 76976259Sgreen xfree(enc->iv); 77076259Sgreen xfree(enc->key); 77176259Sgreen xfree(mac->name); 77276259Sgreen xfree(mac->key); 77376259Sgreen xfree(comp->name); 774197679Sdes xfree(active_state->newkeys[mode]); 77576259Sgreen } 776197679Sdes active_state->newkeys[mode] = kex_get_newkeys(mode); 777197679Sdes if (active_state->newkeys[mode] == NULL) 77876259Sgreen fatal("newkeys: no keys for mode %d", mode); 779197679Sdes enc = &active_state->newkeys[mode]->enc; 780197679Sdes mac = &active_state->newkeys[mode]->mac; 781197679Sdes comp = &active_state->newkeys[mode]->comp; 782181111Sdes if (mac_init(mac) == 0) 78376259Sgreen mac->enabled = 1; 78476259Sgreen DBG(debug("cipher_init_context: %d", mode)); 78592555Sdes cipher_init(cc, enc->cipher, enc->key, enc->key_len, 786137015Sdes enc->iv, enc->block_size, crypt_type); 78798675Sdes /* Deleting the keys does not gain extra security */ 78898675Sdes /* memset(enc->iv, 0, enc->block_size); 789181111Sdes memset(enc->key, 0, enc->key_len); 790181111Sdes memset(mac->key, 0, mac->key_len); */ 791149749Sdes if ((comp->type == COMP_ZLIB || 792197679Sdes (comp->type == COMP_DELAYED && 793197679Sdes active_state->after_authentication)) && comp->enabled == 0) { 79476259Sgreen packet_init_compression(); 79576259Sgreen if (mode == MODE_OUT) 79676259Sgreen buffer_compress_init_send(6); 79776259Sgreen else 79876259Sgreen buffer_compress_init_recv(); 79976259Sgreen comp->enabled = 1; 80076259Sgreen } 801124208Sdes /* 802124208Sdes * The 2^(blocksize*2) limit is too expensive for 3DES, 803124208Sdes * blowfish, etc, so enforce a 1GB limit for small blocksizes. 804124208Sdes */ 805124208Sdes if (enc->block_size >= 16) 806124208Sdes *max_blocks = (u_int64_t)1 << (enc->block_size*2); 807124208Sdes else 808124208Sdes *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; 809197679Sdes if (active_state->rekey_limit) 810197679Sdes *max_blocks = MIN(*max_blocks, 811197679Sdes active_state->rekey_limit / enc->block_size); 81276259Sgreen} 81376259Sgreen 81457429Smarkm/* 815149749Sdes * Delayed compression for SSH2 is enabled after authentication: 816162852Sdes * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, 817149749Sdes * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. 818149749Sdes */ 819149749Sdesstatic void 820149749Sdespacket_enable_delayed_compress(void) 821149749Sdes{ 822149749Sdes Comp *comp = NULL; 823149749Sdes int mode; 824149749Sdes 825149749Sdes /* 826149749Sdes * Remember that we are past the authentication step, so rekeying 827149749Sdes * with COMP_DELAYED will turn on compression immediately. 828149749Sdes */ 829197679Sdes active_state->after_authentication = 1; 830149749Sdes for (mode = 0; mode < MODE_MAX; mode++) { 831162852Sdes /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ 832197679Sdes if (active_state->newkeys[mode] == NULL) 833162852Sdes continue; 834197679Sdes comp = &active_state->newkeys[mode]->comp; 835149749Sdes if (comp && !comp->enabled && comp->type == COMP_DELAYED) { 836149749Sdes packet_init_compression(); 837149749Sdes if (mode == MODE_OUT) 838149749Sdes buffer_compress_init_send(6); 839149749Sdes else 840149749Sdes buffer_compress_init_recv(); 841149749Sdes comp->enabled = 1; 842149749Sdes } 843149749Sdes } 844149749Sdes} 845149749Sdes 846149749Sdes/* 84760573Skris * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) 84860573Skris */ 84992555Sdesstatic void 850124208Sdespacket_send2_wrapped(void) 85160573Skris{ 85292555Sdes u_char type, *cp, *macbuf = NULL; 85392555Sdes u_char padlen, pad; 85476259Sgreen u_int packet_length = 0; 85592555Sdes u_int i, len; 856137015Sdes u_int32_t rnd = 0; 85760573Skris Enc *enc = NULL; 85860573Skris Mac *mac = NULL; 85960573Skris Comp *comp = NULL; 86060573Skris int block_size; 86160573Skris 862197679Sdes if (active_state->newkeys[MODE_OUT] != NULL) { 863197679Sdes enc = &active_state->newkeys[MODE_OUT]->enc; 864197679Sdes mac = &active_state->newkeys[MODE_OUT]->mac; 865197679Sdes comp = &active_state->newkeys[MODE_OUT]->comp; 86660573Skris } 86792555Sdes block_size = enc ? enc->block_size : 8; 86860573Skris 869197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 87092555Sdes type = cp[5]; 87160573Skris 87260573Skris#ifdef PACKET_DEBUG 87360573Skris fprintf(stderr, "plain: "); 874197679Sdes buffer_dump(&active_state->outgoing_packet); 87560573Skris#endif 87660573Skris 87760573Skris if (comp && comp->enabled) { 878197679Sdes len = buffer_len(&active_state->outgoing_packet); 87960573Skris /* skip header, compress only payload */ 880197679Sdes buffer_consume(&active_state->outgoing_packet, 5); 881197679Sdes buffer_clear(&active_state->compression_buffer); 882197679Sdes buffer_compress(&active_state->outgoing_packet, 883197679Sdes &active_state->compression_buffer); 884197679Sdes buffer_clear(&active_state->outgoing_packet); 885197679Sdes buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5); 886197679Sdes buffer_append(&active_state->outgoing_packet, 887197679Sdes buffer_ptr(&active_state->compression_buffer), 888197679Sdes buffer_len(&active_state->compression_buffer)); 88960573Skris DBG(debug("compression: raw %d compressed %d", len, 890197679Sdes buffer_len(&active_state->outgoing_packet))); 89160573Skris } 89260573Skris 89360573Skris /* sizeof (packet_len + pad_len + payload) */ 894197679Sdes len = buffer_len(&active_state->outgoing_packet); 89560573Skris 89660573Skris /* 89760573Skris * calc size of padding, alloc space, get random data, 89860573Skris * minimum padding is 4 bytes 89960573Skris */ 90060573Skris padlen = block_size - (len % block_size); 90160573Skris if (padlen < 4) 90260573Skris padlen += block_size; 903197679Sdes if (active_state->extra_pad) { 90492555Sdes /* will wrap if extra_pad+padlen > 255 */ 905197679Sdes active_state->extra_pad = 906197679Sdes roundup(active_state->extra_pad, block_size); 907197679Sdes pad = active_state->extra_pad - 908197679Sdes ((len + padlen) % active_state->extra_pad); 90998675Sdes debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)", 910197679Sdes pad, len, padlen, active_state->extra_pad); 91192555Sdes padlen += pad; 912197679Sdes active_state->extra_pad = 0; 91392555Sdes } 914197679Sdes cp = buffer_append_space(&active_state->outgoing_packet, padlen); 915197679Sdes if (enc && !active_state->send_context.plaintext) { 91660573Skris /* random padding */ 91760573Skris for (i = 0; i < padlen; i++) { 91860573Skris if (i % 4 == 0) 919137015Sdes rnd = arc4random(); 920137015Sdes cp[i] = rnd & 0xff; 921137015Sdes rnd >>= 8; 92260573Skris } 92360573Skris } else { 92460573Skris /* clear padding */ 92560573Skris memset(cp, 0, padlen); 92660573Skris } 92760573Skris /* packet_length includes payload, padding and padding length field */ 928197679Sdes packet_length = buffer_len(&active_state->outgoing_packet) - 4; 929197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 930162852Sdes put_u32(cp, packet_length); 93192555Sdes cp[4] = padlen; 93260573Skris DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); 93360573Skris 93460573Skris /* compute MAC over seqnr and packet(length fields, payload, padding) */ 93560573Skris if (mac && mac->enabled) { 936197679Sdes macbuf = mac_compute(mac, active_state->p_send.seqnr, 937197679Sdes buffer_ptr(&active_state->outgoing_packet), 938197679Sdes buffer_len(&active_state->outgoing_packet)); 939197679Sdes DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr)); 94060573Skris } 94160573Skris /* encrypt packet and append to output buffer. */ 942197679Sdes cp = buffer_append_space(&active_state->output, 943197679Sdes buffer_len(&active_state->outgoing_packet)); 944197679Sdes cipher_crypt(&active_state->send_context, cp, 945197679Sdes buffer_ptr(&active_state->outgoing_packet), 946197679Sdes buffer_len(&active_state->outgoing_packet)); 94760573Skris /* append unencrypted MAC */ 94860573Skris if (mac && mac->enabled) 949197679Sdes buffer_append(&active_state->output, macbuf, mac->mac_len); 95060573Skris#ifdef PACKET_DEBUG 95160573Skris fprintf(stderr, "encrypted: "); 952197679Sdes buffer_dump(&active_state->output); 95360573Skris#endif 95460573Skris /* increment sequence number for outgoing packets */ 955197679Sdes if (++active_state->p_send.seqnr == 0) 956124208Sdes logit("outgoing seqnr wraps around"); 957197679Sdes if (++active_state->p_send.packets == 0) 958124208Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 959124208Sdes fatal("XXX too many packets with same key"); 960197679Sdes active_state->p_send.blocks += (packet_length + 4) / block_size; 961197679Sdes active_state->p_send.bytes += packet_length + 4; 962197679Sdes buffer_clear(&active_state->outgoing_packet); 96360573Skris 96476259Sgreen if (type == SSH2_MSG_NEWKEYS) 96576259Sgreen set_newkeys(MODE_OUT); 966197679Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side) 967149749Sdes packet_enable_delayed_compress(); 96860573Skris} 96960573Skris 970124208Sdesstatic void 971124208Sdespacket_send2(void) 972124208Sdes{ 973124208Sdes struct packet *p; 974124208Sdes u_char type, *cp; 975124208Sdes 976197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 977124208Sdes type = cp[5]; 978124208Sdes 979124208Sdes /* during rekeying we can only send key exchange messages */ 980197679Sdes if (active_state->rekeying) { 981124208Sdes if (!((type >= SSH2_MSG_TRANSPORT_MIN) && 982124208Sdes (type <= SSH2_MSG_TRANSPORT_MAX))) { 983124208Sdes debug("enqueue packet: %u", type); 984124208Sdes p = xmalloc(sizeof(*p)); 985124208Sdes p->type = type; 986197679Sdes memcpy(&p->payload, &active_state->outgoing_packet, 987197679Sdes sizeof(Buffer)); 988197679Sdes buffer_init(&active_state->outgoing_packet); 989197679Sdes TAILQ_INSERT_TAIL(&active_state->outgoing, p, next); 990124208Sdes return; 991124208Sdes } 992124208Sdes } 993124208Sdes 994124208Sdes /* rekeying starts with sending KEXINIT */ 995124208Sdes if (type == SSH2_MSG_KEXINIT) 996197679Sdes active_state->rekeying = 1; 997124208Sdes 998124208Sdes packet_send2_wrapped(); 999124208Sdes 1000124208Sdes /* after a NEWKEYS message we can send the complete queue */ 1001124208Sdes if (type == SSH2_MSG_NEWKEYS) { 1002197679Sdes active_state->rekeying = 0; 1003197679Sdes while ((p = TAILQ_FIRST(&active_state->outgoing))) { 1004124208Sdes type = p->type; 1005124208Sdes debug("dequeue packet: %u", type); 1006197679Sdes buffer_free(&active_state->outgoing_packet); 1007197679Sdes memcpy(&active_state->outgoing_packet, &p->payload, 1008124208Sdes sizeof(Buffer)); 1009197679Sdes TAILQ_REMOVE(&active_state->outgoing, p, next); 1010124208Sdes xfree(p); 1011124208Sdes packet_send2_wrapped(); 1012124208Sdes } 1013124208Sdes } 1014124208Sdes} 1015124208Sdes 101660573Skrisvoid 101792555Sdespacket_send(void) 101860573Skris{ 101992555Sdes if (compat20) 102060573Skris packet_send2(); 102160573Skris else 102260573Skris packet_send1(); 102360573Skris DBG(debug("packet_send done")); 102460573Skris} 102560573Skris 102660573Skris/* 102757429Smarkm * Waits until a packet has been received, and returns its type. Note that 102857429Smarkm * no other data is processed until this returns, so this function should not 102957429Smarkm * be used during the interactive session. 103057429Smarkm */ 103157429Smarkm 103257429Smarkmint 103392555Sdespacket_read_seqnr(u_int32_t *seqnr_p) 103457429Smarkm{ 1035197679Sdes int type, len, ret, ms_remain, cont; 103676259Sgreen fd_set *setp; 103757429Smarkm char buf[8192]; 1038181111Sdes struct timeval timeout, start, *timeoutp = NULL; 1039181111Sdes 104060573Skris DBG(debug("packet_read()")); 104157429Smarkm 1042197679Sdes setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1, 1043197679Sdes NFDBITS), sizeof(fd_mask)); 104476259Sgreen 104557429Smarkm /* Since we are blocking, ensure that all written packets have been sent. */ 104657429Smarkm packet_write_wait(); 104757429Smarkm 104857429Smarkm /* Stay in the loop until we have received a complete packet. */ 104957429Smarkm for (;;) { 105057429Smarkm /* Try to read a packet from the buffer. */ 105192555Sdes type = packet_read_poll_seqnr(seqnr_p); 105292555Sdes if (!compat20 && ( 105360573Skris type == SSH_SMSG_SUCCESS 105457429Smarkm || type == SSH_SMSG_FAILURE 105557429Smarkm || type == SSH_CMSG_EOF 105660573Skris || type == SSH_CMSG_EXIT_CONFIRMATION)) 105792555Sdes packet_check_eom(); 105857429Smarkm /* If we got a packet, return it. */ 105976259Sgreen if (type != SSH_MSG_NONE) { 106076259Sgreen xfree(setp); 106157429Smarkm return type; 106276259Sgreen } 106357429Smarkm /* 106457429Smarkm * Otherwise, wait for some data to arrive, add it to the 106557429Smarkm * buffer, and try again. 106657429Smarkm */ 1067197679Sdes memset(setp, 0, howmany(active_state->connection_in + 1, 1068197679Sdes NFDBITS) * sizeof(fd_mask)); 1069197679Sdes FD_SET(active_state->connection_in, setp); 107057429Smarkm 1071197679Sdes if (active_state->packet_timeout_ms > 0) { 1072197679Sdes ms_remain = active_state->packet_timeout_ms; 1073181111Sdes timeoutp = &timeout; 1074181111Sdes } 107557429Smarkm /* Wait for some data to arrive. */ 1076181111Sdes for (;;) { 1077197679Sdes if (active_state->packet_timeout_ms != -1) { 1078181111Sdes ms_to_timeval(&timeout, ms_remain); 1079181111Sdes gettimeofday(&start, NULL); 1080181111Sdes } 1081197679Sdes if ((ret = select(active_state->connection_in + 1, setp, 1082197679Sdes NULL, NULL, timeoutp)) >= 0) 1083181111Sdes break; 1084197679Sdes if (errno != EAGAIN && errno != EINTR && 1085181111Sdes errno != EWOULDBLOCK) 1086181111Sdes break; 1087197679Sdes if (active_state->packet_timeout_ms == -1) 1088181111Sdes continue; 1089181111Sdes ms_subtract_diff(&start, &ms_remain); 1090181111Sdes if (ms_remain <= 0) { 1091181111Sdes ret = 0; 1092181111Sdes break; 1093181111Sdes } 1094181111Sdes } 1095181111Sdes if (ret == 0) { 1096181111Sdes logit("Connection to %.200s timed out while " 1097181111Sdes "waiting to read", get_remote_ipaddr()); 1098181111Sdes cleanup_exit(255); 1099181111Sdes } 110057429Smarkm /* Read data from the socket. */ 1101197679Sdes do { 1102197679Sdes cont = 0; 1103197679Sdes len = roaming_read(active_state->connection_in, buf, 1104197679Sdes sizeof(buf), &cont); 1105197679Sdes } while (len == 0 && cont); 110657429Smarkm if (len == 0) { 1107124208Sdes logit("Connection closed by %.200s", get_remote_ipaddr()); 1108126274Sdes cleanup_exit(255); 110957429Smarkm } 111057429Smarkm if (len < 0) 111157429Smarkm fatal("Read from socket failed: %.100s", strerror(errno)); 111257429Smarkm /* Append it to the buffer. */ 111357429Smarkm packet_process_incoming(buf, len); 111457429Smarkm } 111557429Smarkm /* NOTREACHED */ 111657429Smarkm} 111757429Smarkm 111892555Sdesint 111992555Sdespacket_read(void) 112092555Sdes{ 112192555Sdes return packet_read_seqnr(NULL); 112292555Sdes} 112392555Sdes 112457429Smarkm/* 112557429Smarkm * Waits until a packet has been received, verifies that its type matches 112657429Smarkm * that given, and gives a fatal error and exits if there is a mismatch. 112757429Smarkm */ 112857429Smarkm 112957429Smarkmvoid 113092555Sdespacket_read_expect(int expected_type) 113157429Smarkm{ 113257429Smarkm int type; 113357429Smarkm 113492555Sdes type = packet_read(); 113557429Smarkm if (type != expected_type) 113657429Smarkm packet_disconnect("Protocol error: expected packet type %d, got %d", 113760573Skris expected_type, type); 113857429Smarkm} 113957429Smarkm 114057429Smarkm/* Checks if a full packet is available in the data received so far via 114157429Smarkm * packet_process_incoming. If so, reads the packet; otherwise returns 114257429Smarkm * SSH_MSG_NONE. This does not wait for data from the connection. 114357429Smarkm * 114457429Smarkm * SSH_MSG_DISCONNECT is handled specially here. Also, 114557429Smarkm * SSH_MSG_IGNORE messages are skipped by this function and are never returned 114657429Smarkm * to higher levels. 114757429Smarkm */ 114857429Smarkm 114992555Sdesstatic int 115092555Sdespacket_read_poll1(void) 115157429Smarkm{ 115276259Sgreen u_int len, padded_len; 115392555Sdes u_char *cp, type; 115476259Sgreen u_int checksum, stored_checksum; 115557429Smarkm 115657429Smarkm /* Check if input size is less than minimum packet size. */ 1157197679Sdes if (buffer_len(&active_state->input) < 4 + 8) 115857429Smarkm return SSH_MSG_NONE; 115957429Smarkm /* Get length of incoming packet. */ 1160197679Sdes cp = buffer_ptr(&active_state->input); 1161162852Sdes len = get_u32(cp); 116257429Smarkm if (len < 1 + 2 + 2 || len > 256 * 1024) 1163113908Sdes packet_disconnect("Bad packet length %u.", len); 116457429Smarkm padded_len = (len + 8) & ~7; 116557429Smarkm 116657429Smarkm /* Check if the packet has been entirely received. */ 1167197679Sdes if (buffer_len(&active_state->input) < 4 + padded_len) 116857429Smarkm return SSH_MSG_NONE; 116957429Smarkm 117057429Smarkm /* The entire packet is in buffer. */ 117157429Smarkm 117257429Smarkm /* Consume packet length. */ 1173197679Sdes buffer_consume(&active_state->input, 4); 117457429Smarkm 117592555Sdes /* 117692555Sdes * Cryptographic attack detector for ssh 117792555Sdes * (C)1998 CORE-SDI, Buenos Aires Argentina 117892555Sdes * Ariel Futoransky(futo@core-sdi.com) 117992555Sdes */ 1180197679Sdes if (!active_state->receive_context.plaintext) { 1181197679Sdes switch (detect_attack(buffer_ptr(&active_state->input), 1182197679Sdes padded_len)) { 1183162852Sdes case DEATTACK_DETECTED: 1184162852Sdes packet_disconnect("crc32 compensation attack: " 1185162852Sdes "network attack detected"); 1186162852Sdes case DEATTACK_DOS_DETECTED: 1187162852Sdes packet_disconnect("deattack denial of " 1188162852Sdes "service detected"); 1189162852Sdes } 1190162852Sdes } 119192555Sdes 119292555Sdes /* Decrypt data to incoming_packet. */ 1193197679Sdes buffer_clear(&active_state->incoming_packet); 1194197679Sdes cp = buffer_append_space(&active_state->incoming_packet, padded_len); 1195197679Sdes cipher_crypt(&active_state->receive_context, cp, 1196197679Sdes buffer_ptr(&active_state->input), padded_len); 119792555Sdes 1198197679Sdes buffer_consume(&active_state->input, padded_len); 119957429Smarkm 120057429Smarkm#ifdef PACKET_DEBUG 120157429Smarkm fprintf(stderr, "read_poll plain: "); 1202197679Sdes buffer_dump(&active_state->incoming_packet); 120357429Smarkm#endif 120457429Smarkm 120557429Smarkm /* Compute packet checksum. */ 1206197679Sdes checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet), 1207197679Sdes buffer_len(&active_state->incoming_packet) - 4); 120857429Smarkm 120957429Smarkm /* Skip padding. */ 1210197679Sdes buffer_consume(&active_state->incoming_packet, 8 - len % 8); 121157429Smarkm 121257429Smarkm /* Test check bytes. */ 1213197679Sdes if (len != buffer_len(&active_state->incoming_packet)) 121492555Sdes packet_disconnect("packet_read_poll1: len %d != buffer_len %d.", 1215197679Sdes len, buffer_len(&active_state->incoming_packet)); 121657429Smarkm 1217197679Sdes cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4; 1218162852Sdes stored_checksum = get_u32(cp); 121957429Smarkm if (checksum != stored_checksum) 122057429Smarkm packet_disconnect("Corrupted check bytes on input."); 1221197679Sdes buffer_consume_end(&active_state->incoming_packet, 4); 122257429Smarkm 1223197679Sdes if (active_state->packet_compression) { 1224197679Sdes buffer_clear(&active_state->compression_buffer); 1225197679Sdes buffer_uncompress(&active_state->incoming_packet, 1226197679Sdes &active_state->compression_buffer); 1227197679Sdes buffer_clear(&active_state->incoming_packet); 1228197679Sdes buffer_append(&active_state->incoming_packet, 1229197679Sdes buffer_ptr(&active_state->compression_buffer), 1230197679Sdes buffer_len(&active_state->compression_buffer)); 123157429Smarkm } 1232197679Sdes active_state->p_read.packets++; 1233197679Sdes active_state->p_read.bytes += padded_len + 4; 1234197679Sdes type = buffer_get_char(&active_state->incoming_packet); 1235146998Sdes if (type < SSH_MSG_MIN || type > SSH_MSG_MAX) 1236146998Sdes packet_disconnect("Invalid ssh1 packet type: %d", type); 123792555Sdes return type; 123860573Skris} 123957429Smarkm 124092555Sdesstatic int 124192555Sdespacket_read_poll2(u_int32_t *seqnr_p) 124260573Skris{ 124376259Sgreen u_int padlen, need; 124492555Sdes u_char *macbuf, *cp, type; 1245149749Sdes u_int maclen, block_size; 124660573Skris Enc *enc = NULL; 124760573Skris Mac *mac = NULL; 124860573Skris Comp *comp = NULL; 124957429Smarkm 1250197679Sdes if (active_state->packet_discard) 1251192595Sdes return SSH_MSG_NONE; 1252192595Sdes 1253197679Sdes if (active_state->newkeys[MODE_IN] != NULL) { 1254197679Sdes enc = &active_state->newkeys[MODE_IN]->enc; 1255197679Sdes mac = &active_state->newkeys[MODE_IN]->mac; 1256197679Sdes comp = &active_state->newkeys[MODE_IN]->comp; 125757429Smarkm } 125860573Skris maclen = mac && mac->enabled ? mac->mac_len : 0; 125992555Sdes block_size = enc ? enc->block_size : 8; 126060573Skris 1261197679Sdes if (active_state->packlen == 0) { 126260573Skris /* 126360573Skris * check if input size is less than the cipher block size, 126460573Skris * decrypt first block and extract length of incoming packet 126560573Skris */ 1266197679Sdes if (buffer_len(&active_state->input) < block_size) 126760573Skris return SSH_MSG_NONE; 1268197679Sdes buffer_clear(&active_state->incoming_packet); 1269197679Sdes cp = buffer_append_space(&active_state->incoming_packet, 127060573Skris block_size); 1271197679Sdes cipher_crypt(&active_state->receive_context, cp, 1272197679Sdes buffer_ptr(&active_state->input), block_size); 1273197679Sdes cp = buffer_ptr(&active_state->incoming_packet); 1274197679Sdes active_state->packlen = get_u32(cp); 1275197679Sdes if (active_state->packlen < 1 + 4 || 1276197679Sdes active_state->packlen > PACKET_MAX_SIZE) { 1277124208Sdes#ifdef PACKET_DEBUG 1278197679Sdes buffer_dump(&active_state->incoming_packet); 1279124208Sdes#endif 1280197679Sdes logit("Bad packet length %u.", active_state->packlen); 1281197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1282192595Sdes PACKET_MAX_SIZE); 1283192595Sdes return SSH_MSG_NONE; 128460573Skris } 1285197679Sdes DBG(debug("input: packet len %u", active_state->packlen+4)); 1286197679Sdes buffer_consume(&active_state->input, block_size); 128760573Skris } 128860573Skris /* we have a partial packet of block_size bytes */ 1289197679Sdes need = 4 + active_state->packlen - block_size; 129060573Skris DBG(debug("partial packet %d, need %d, maclen %d", block_size, 129160573Skris need, maclen)); 1292192595Sdes if (need % block_size != 0) { 1293192595Sdes logit("padding error: need %d block %d mod %d", 129460573Skris need, block_size, need % block_size); 1295197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1296192595Sdes PACKET_MAX_SIZE - block_size); 1297192595Sdes return SSH_MSG_NONE; 1298192595Sdes } 129960573Skris /* 130060573Skris * check if the entire packet has been received and 130160573Skris * decrypt into incoming_packet 130260573Skris */ 1303197679Sdes if (buffer_len(&active_state->input) < need + maclen) 130460573Skris return SSH_MSG_NONE; 130560573Skris#ifdef PACKET_DEBUG 130660573Skris fprintf(stderr, "read_poll enc/full: "); 1307197679Sdes buffer_dump(&active_state->input); 130860573Skris#endif 1309197679Sdes cp = buffer_append_space(&active_state->incoming_packet, need); 1310197679Sdes cipher_crypt(&active_state->receive_context, cp, 1311197679Sdes buffer_ptr(&active_state->input), need); 1312197679Sdes buffer_consume(&active_state->input, need); 131360573Skris /* 131460573Skris * compute MAC over seqnr and packet, 131560573Skris * increment sequence number for incoming packet 131660573Skris */ 131760573Skris if (mac && mac->enabled) { 1318197679Sdes macbuf = mac_compute(mac, active_state->p_read.seqnr, 1319197679Sdes buffer_ptr(&active_state->incoming_packet), 1320197679Sdes buffer_len(&active_state->incoming_packet)); 1321215116Sdes if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input), 1322197679Sdes mac->mac_len) != 0) { 1323192595Sdes logit("Corrupted MAC on input."); 1324192595Sdes if (need > PACKET_MAX_SIZE) 1325192595Sdes fatal("internal error need %d", need); 1326197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1327192595Sdes PACKET_MAX_SIZE - need); 1328192595Sdes return SSH_MSG_NONE; 1329192595Sdes } 1330192595Sdes 1331197679Sdes DBG(debug("MAC #%d ok", active_state->p_read.seqnr)); 1332197679Sdes buffer_consume(&active_state->input, mac->mac_len); 133360573Skris } 1334192595Sdes /* XXX now it's safe to use fatal/packet_disconnect */ 133592555Sdes if (seqnr_p != NULL) 1336197679Sdes *seqnr_p = active_state->p_read.seqnr; 1337197679Sdes if (++active_state->p_read.seqnr == 0) 1338124208Sdes logit("incoming seqnr wraps around"); 1339197679Sdes if (++active_state->p_read.packets == 0) 1340124208Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 1341124208Sdes fatal("XXX too many packets with same key"); 1342197679Sdes active_state->p_read.blocks += (active_state->packlen + 4) / block_size; 1343197679Sdes active_state->p_read.bytes += active_state->packlen + 4; 134460573Skris 134560573Skris /* get padlen */ 1346197679Sdes cp = buffer_ptr(&active_state->incoming_packet); 134792555Sdes padlen = cp[4]; 134860573Skris DBG(debug("input: padlen %d", padlen)); 134960573Skris if (padlen < 4) 135060573Skris packet_disconnect("Corrupted padlen %d on input.", padlen); 135160573Skris 135260573Skris /* skip packet size + padlen, discard padding */ 1353197679Sdes buffer_consume(&active_state->incoming_packet, 4 + 1); 1354197679Sdes buffer_consume_end(&active_state->incoming_packet, padlen); 135560573Skris 1356197679Sdes DBG(debug("input: len before de-compress %d", 1357197679Sdes buffer_len(&active_state->incoming_packet))); 135860573Skris if (comp && comp->enabled) { 1359197679Sdes buffer_clear(&active_state->compression_buffer); 1360197679Sdes buffer_uncompress(&active_state->incoming_packet, 1361197679Sdes &active_state->compression_buffer); 1362197679Sdes buffer_clear(&active_state->incoming_packet); 1363197679Sdes buffer_append(&active_state->incoming_packet, 1364197679Sdes buffer_ptr(&active_state->compression_buffer), 1365197679Sdes buffer_len(&active_state->compression_buffer)); 1366106121Sdes DBG(debug("input: len after de-compress %d", 1367197679Sdes buffer_len(&active_state->incoming_packet))); 136860573Skris } 136960573Skris /* 137060573Skris * get packet type, implies consume. 137160573Skris * return length of payload (without type field) 137260573Skris */ 1373197679Sdes type = buffer_get_char(&active_state->incoming_packet); 1374146998Sdes if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN) 1375146998Sdes packet_disconnect("Invalid ssh2 packet type: %d", type); 137676259Sgreen if (type == SSH2_MSG_NEWKEYS) 137776259Sgreen set_newkeys(MODE_IN); 1378197679Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && 1379197679Sdes !active_state->server_side) 1380149749Sdes packet_enable_delayed_compress(); 138160573Skris#ifdef PACKET_DEBUG 138276259Sgreen fprintf(stderr, "read/plain[%d]:\r\n", type); 1383197679Sdes buffer_dump(&active_state->incoming_packet); 138460573Skris#endif 138592555Sdes /* reset for next packet */ 1386197679Sdes active_state->packlen = 0; 138792555Sdes return type; 138857429Smarkm} 138957429Smarkm 139060573Skrisint 139192555Sdespacket_read_poll_seqnr(u_int32_t *seqnr_p) 139260573Skris{ 139399060Sdes u_int reason, seqnr; 139492555Sdes u_char type; 139560573Skris char *msg; 139692555Sdes 139760573Skris for (;;) { 139892555Sdes if (compat20) { 139992555Sdes type = packet_read_poll2(seqnr_p); 1400181111Sdes if (type) { 1401197679Sdes active_state->keep_alive_timeouts = 0; 140260573Skris DBG(debug("received packet type %d", type)); 1403181111Sdes } 140492555Sdes switch (type) { 140560573Skris case SSH2_MSG_IGNORE: 1406181111Sdes debug3("Received SSH2_MSG_IGNORE"); 140760573Skris break; 140860573Skris case SSH2_MSG_DEBUG: 140960573Skris packet_get_char(); 141060573Skris msg = packet_get_string(NULL); 141160573Skris debug("Remote: %.900s", msg); 141260573Skris xfree(msg); 141360573Skris msg = packet_get_string(NULL); 141460573Skris xfree(msg); 141560573Skris break; 141660573Skris case SSH2_MSG_DISCONNECT: 141760573Skris reason = packet_get_int(); 141860573Skris msg = packet_get_string(NULL); 1419124208Sdes logit("Received disconnect from %s: %u: %.400s", 142099060Sdes get_remote_ipaddr(), reason, msg); 142160573Skris xfree(msg); 1422126274Sdes cleanup_exit(255); 142360573Skris break; 142492555Sdes case SSH2_MSG_UNIMPLEMENTED: 142592555Sdes seqnr = packet_get_int(); 142699060Sdes debug("Received SSH2_MSG_UNIMPLEMENTED for %u", 142799060Sdes seqnr); 142892555Sdes break; 142960573Skris default: 143060573Skris return type; 143176259Sgreen } 143260573Skris } else { 143392555Sdes type = packet_read_poll1(); 143492555Sdes switch (type) { 143560573Skris case SSH_MSG_IGNORE: 143660573Skris break; 143760573Skris case SSH_MSG_DEBUG: 143860573Skris msg = packet_get_string(NULL); 143960573Skris debug("Remote: %.900s", msg); 144060573Skris xfree(msg); 144160573Skris break; 144260573Skris case SSH_MSG_DISCONNECT: 144360573Skris msg = packet_get_string(NULL); 1444124208Sdes logit("Received disconnect from %s: %.400s", 144599060Sdes get_remote_ipaddr(), msg); 1446126274Sdes cleanup_exit(255); 144760573Skris break; 144860573Skris default: 144992555Sdes if (type) 145060573Skris DBG(debug("received packet type %d", type)); 145160573Skris return type; 145276259Sgreen } 145360573Skris } 145460573Skris } 145560573Skris} 145660573Skris 145792555Sdesint 145892555Sdespacket_read_poll(void) 145992555Sdes{ 146092555Sdes return packet_read_poll_seqnr(NULL); 146192555Sdes} 146292555Sdes 146357429Smarkm/* 146457429Smarkm * Buffers the given amount of input characters. This is intended to be used 146557429Smarkm * together with packet_read_poll. 146657429Smarkm */ 146757429Smarkm 146857429Smarkmvoid 146976259Sgreenpacket_process_incoming(const char *buf, u_int len) 147057429Smarkm{ 1471197679Sdes if (active_state->packet_discard) { 1472197679Sdes active_state->keep_alive_timeouts = 0; /* ?? */ 1473197679Sdes if (len >= active_state->packet_discard) 1474192595Sdes packet_stop_discard(); 1475197679Sdes active_state->packet_discard -= len; 1476192595Sdes return; 1477192595Sdes } 1478197679Sdes buffer_append(&active_state->input, buf, len); 147957429Smarkm} 148057429Smarkm 148157429Smarkm/* Returns a character from the packet. */ 148257429Smarkm 148376259Sgreenu_int 148492555Sdespacket_get_char(void) 148557429Smarkm{ 148657429Smarkm char ch; 1487106121Sdes 1488197679Sdes buffer_get(&active_state->incoming_packet, &ch, 1); 148976259Sgreen return (u_char) ch; 149057429Smarkm} 149157429Smarkm 149257429Smarkm/* Returns an integer from the packet data. */ 149357429Smarkm 149476259Sgreenu_int 149592555Sdespacket_get_int(void) 149657429Smarkm{ 1497197679Sdes return buffer_get_int(&active_state->incoming_packet); 149857429Smarkm} 149957429Smarkm 1500197679Sdes/* Returns an 64 bit integer from the packet data. */ 1501197679Sdes 1502197679Sdesu_int64_t 1503197679Sdespacket_get_int64(void) 1504197679Sdes{ 1505197679Sdes return buffer_get_int64(&active_state->incoming_packet); 1506197679Sdes} 1507197679Sdes 150857429Smarkm/* 150957429Smarkm * Returns an arbitrary precision integer from the packet data. The integer 151057429Smarkm * must have been initialized before this call. 151157429Smarkm */ 151257429Smarkm 151357429Smarkmvoid 151492555Sdespacket_get_bignum(BIGNUM * value) 151557429Smarkm{ 1516197679Sdes buffer_get_bignum(&active_state->incoming_packet, value); 151757429Smarkm} 151857429Smarkm 151960573Skrisvoid 152092555Sdespacket_get_bignum2(BIGNUM * value) 152160573Skris{ 1522197679Sdes buffer_get_bignum2(&active_state->incoming_packet, value); 152360573Skris} 152460573Skris 1525221420Sdes#ifdef OPENSSL_HAS_ECC 1526221420Sdesvoid 1527221420Sdespacket_get_ecpoint(const EC_GROUP *curve, EC_POINT *point) 1528221420Sdes{ 1529221420Sdes buffer_get_ecpoint(&active_state->incoming_packet, curve, point); 1530221420Sdes} 1531221420Sdes#endif 1532221420Sdes 153392555Sdesvoid * 1534149749Sdespacket_get_raw(u_int *length_ptr) 153560573Skris{ 1536197679Sdes u_int bytes = buffer_len(&active_state->incoming_packet); 1537106121Sdes 153860573Skris if (length_ptr != NULL) 153960573Skris *length_ptr = bytes; 1540197679Sdes return buffer_ptr(&active_state->incoming_packet); 154160573Skris} 154260573Skris 154360573Skrisint 154460573Skrispacket_remaining(void) 154560573Skris{ 1546197679Sdes return buffer_len(&active_state->incoming_packet); 154760573Skris} 154860573Skris 154957429Smarkm/* 155057429Smarkm * Returns a string from the packet data. The string is allocated using 155157429Smarkm * xmalloc; it is the responsibility of the calling program to free it when 155257429Smarkm * no longer needed. The length_ptr argument may be NULL, or point to an 155357429Smarkm * integer into which the length of the string is stored. 155457429Smarkm */ 155557429Smarkm 155692555Sdesvoid * 155776259Sgreenpacket_get_string(u_int *length_ptr) 155857429Smarkm{ 1559197679Sdes return buffer_get_string(&active_state->incoming_packet, length_ptr); 156057429Smarkm} 156157429Smarkm 1562181111Sdesvoid * 1563181111Sdespacket_get_string_ptr(u_int *length_ptr) 1564181111Sdes{ 1565197679Sdes return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr); 1566181111Sdes} 1567181111Sdes 1568221420Sdes/* Ensures the returned string has no embedded \0 characters in it. */ 1569221420Sdeschar * 1570221420Sdespacket_get_cstring(u_int *length_ptr) 1571221420Sdes{ 1572221420Sdes return buffer_get_cstring(&active_state->incoming_packet, length_ptr); 1573221420Sdes} 1574221420Sdes 157557429Smarkm/* 157657429Smarkm * Sends a diagnostic message from the server to the client. This message 157757429Smarkm * can be sent at any time (but not while constructing another message). The 157857429Smarkm * message is printed immediately, but only if the client is being executed 157957429Smarkm * in verbose mode. These messages are primarily intended to ease debugging 158057429Smarkm * authentication problems. The length of the formatted message must not 158157429Smarkm * exceed 1024 bytes. This will automatically call packet_write_wait. 158257429Smarkm */ 158357429Smarkm 158457429Smarkmvoid 158557429Smarkmpacket_send_debug(const char *fmt,...) 158657429Smarkm{ 158757429Smarkm char buf[1024]; 158857429Smarkm va_list args; 158957429Smarkm 159076259Sgreen if (compat20 && (datafellows & SSH_BUG_DEBUG)) 159176259Sgreen return; 159276259Sgreen 159357429Smarkm va_start(args, fmt); 159457429Smarkm vsnprintf(buf, sizeof(buf), fmt, args); 159557429Smarkm va_end(args); 159657429Smarkm 159760573Skris if (compat20) { 159860573Skris packet_start(SSH2_MSG_DEBUG); 159960573Skris packet_put_char(0); /* bool: always display */ 160060573Skris packet_put_cstring(buf); 160160573Skris packet_put_cstring(""); 160260573Skris } else { 160360573Skris packet_start(SSH_MSG_DEBUG); 160460573Skris packet_put_cstring(buf); 160560573Skris } 160657429Smarkm packet_send(); 160757429Smarkm packet_write_wait(); 160857429Smarkm} 160957429Smarkm 161057429Smarkm/* 161157429Smarkm * Logs the error plus constructs and sends a disconnect packet, closes the 161257429Smarkm * connection, and exits. This function never returns. The error message 161357429Smarkm * should not contain a newline. The length of the formatted message must 161457429Smarkm * not exceed 1024 bytes. 161557429Smarkm */ 161657429Smarkm 161757429Smarkmvoid 161857429Smarkmpacket_disconnect(const char *fmt,...) 161957429Smarkm{ 162057429Smarkm char buf[1024]; 162157429Smarkm va_list args; 162257429Smarkm static int disconnecting = 0; 1623106121Sdes 162457429Smarkm if (disconnecting) /* Guard against recursive invocations. */ 162557429Smarkm fatal("packet_disconnect called recursively."); 162657429Smarkm disconnecting = 1; 162757429Smarkm 162857429Smarkm /* 162957429Smarkm * Format the message. Note that the caller must make sure the 163057429Smarkm * message is of limited size. 163157429Smarkm */ 163257429Smarkm va_start(args, fmt); 163357429Smarkm vsnprintf(buf, sizeof(buf), fmt, args); 163457429Smarkm va_end(args); 163557429Smarkm 1636113908Sdes /* Display the error locally */ 1637124208Sdes logit("Disconnecting: %.100s", buf); 1638113908Sdes 163957429Smarkm /* Send the disconnect message to the other side, and wait for it to get sent. */ 164060573Skris if (compat20) { 164160573Skris packet_start(SSH2_MSG_DISCONNECT); 164260573Skris packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); 164360573Skris packet_put_cstring(buf); 164460573Skris packet_put_cstring(""); 164560573Skris } else { 164660573Skris packet_start(SSH_MSG_DISCONNECT); 164792555Sdes packet_put_cstring(buf); 164860573Skris } 164957429Smarkm packet_send(); 165057429Smarkm packet_write_wait(); 165157429Smarkm 165257429Smarkm /* Stop listening for connections. */ 165392555Sdes channel_close_all(); 165457429Smarkm 165557429Smarkm /* Close the connection. */ 165657429Smarkm packet_close(); 1657126274Sdes cleanup_exit(255); 165857429Smarkm} 165957429Smarkm 166057429Smarkm/* Checks if there is any buffered output, and tries to write some of the output. */ 166157429Smarkm 166257429Smarkmvoid 166392555Sdespacket_write_poll(void) 166457429Smarkm{ 1665197679Sdes int len = buffer_len(&active_state->output); 1666197679Sdes int cont; 1667106121Sdes 166857429Smarkm if (len > 0) { 1669197679Sdes cont = 0; 1670197679Sdes len = roaming_write(active_state->connection_out, 1671197679Sdes buffer_ptr(&active_state->output), len, &cont); 1672181111Sdes if (len == -1) { 1673181111Sdes if (errno == EINTR || errno == EAGAIN || 1674181111Sdes errno == EWOULDBLOCK) 167557429Smarkm return; 1676181111Sdes fatal("Write failed: %.100s", strerror(errno)); 167757429Smarkm } 1678197679Sdes if (len == 0 && !cont) 1679181111Sdes fatal("Write connection closed"); 1680197679Sdes buffer_consume(&active_state->output, len); 168157429Smarkm } 168257429Smarkm} 168357429Smarkm 168457429Smarkm/* 168557429Smarkm * Calls packet_write_poll repeatedly until all pending output data has been 168657429Smarkm * written. 168757429Smarkm */ 168857429Smarkm 168957429Smarkmvoid 169092555Sdespacket_write_wait(void) 169157429Smarkm{ 169276259Sgreen fd_set *setp; 1693181111Sdes int ret, ms_remain; 1694181111Sdes struct timeval start, timeout, *timeoutp = NULL; 169576259Sgreen 1696197679Sdes setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, 1697197679Sdes NFDBITS), sizeof(fd_mask)); 169857429Smarkm packet_write_poll(); 169957429Smarkm while (packet_have_data_to_write()) { 1700197679Sdes memset(setp, 0, howmany(active_state->connection_out + 1, 1701197679Sdes NFDBITS) * sizeof(fd_mask)); 1702197679Sdes FD_SET(active_state->connection_out, setp); 1703181111Sdes 1704197679Sdes if (active_state->packet_timeout_ms > 0) { 1705197679Sdes ms_remain = active_state->packet_timeout_ms; 1706181111Sdes timeoutp = &timeout; 1707181111Sdes } 1708181111Sdes for (;;) { 1709197679Sdes if (active_state->packet_timeout_ms != -1) { 1710181111Sdes ms_to_timeval(&timeout, ms_remain); 1711181111Sdes gettimeofday(&start, NULL); 1712181111Sdes } 1713197679Sdes if ((ret = select(active_state->connection_out + 1, 1714197679Sdes NULL, setp, NULL, timeoutp)) >= 0) 1715181111Sdes break; 1716197679Sdes if (errno != EAGAIN && errno != EINTR && 1717181111Sdes errno != EWOULDBLOCK) 1718181111Sdes break; 1719197679Sdes if (active_state->packet_timeout_ms == -1) 1720181111Sdes continue; 1721181111Sdes ms_subtract_diff(&start, &ms_remain); 1722181111Sdes if (ms_remain <= 0) { 1723181111Sdes ret = 0; 1724181111Sdes break; 1725181111Sdes } 1726181111Sdes } 1727181111Sdes if (ret == 0) { 1728181111Sdes logit("Connection to %.200s timed out while " 1729181111Sdes "waiting to write", get_remote_ipaddr()); 1730181111Sdes cleanup_exit(255); 1731181111Sdes } 173257429Smarkm packet_write_poll(); 173357429Smarkm } 173476259Sgreen xfree(setp); 173557429Smarkm} 173657429Smarkm 173757429Smarkm/* Returns true if there is buffered data to write to the connection. */ 173857429Smarkm 173957429Smarkmint 174092555Sdespacket_have_data_to_write(void) 174157429Smarkm{ 1742197679Sdes return buffer_len(&active_state->output) != 0; 174357429Smarkm} 174457429Smarkm 174557429Smarkm/* Returns true if there is not too much data to write to the connection. */ 174657429Smarkm 174757429Smarkmint 174892555Sdespacket_not_very_much_data_to_write(void) 174957429Smarkm{ 1750197679Sdes if (active_state->interactive_mode) 1751197679Sdes return buffer_len(&active_state->output) < 16384; 175257429Smarkm else 1753197679Sdes return buffer_len(&active_state->output) < 128 * 1024; 175457429Smarkm} 175557429Smarkm 1756113908Sdesstatic void 1757221420Sdespacket_set_tos(int tos) 1758113908Sdes{ 1759126274Sdes#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) 1760113908Sdes if (!packet_connection_is_on_socket() || 1761113908Sdes !packet_connection_is_ipv4()) 1762113908Sdes return; 1763221420Sdes debug3("%s: set IP_TOS 0x%02x", __func__, tos); 1764197679Sdes if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos, 1765113908Sdes sizeof(tos)) < 0) 1766113908Sdes error("setsockopt IP_TOS %d: %.100s:", 1767113908Sdes tos, strerror(errno)); 1768126274Sdes#endif 1769113908Sdes} 1770113908Sdes 177157429Smarkm/* Informs that the current session is interactive. Sets IP flags for that. */ 177257429Smarkm 177357429Smarkmvoid 1774221420Sdespacket_set_interactive(int interactive, int qos_interactive, int qos_bulk) 177557429Smarkm{ 1776197679Sdes if (active_state->set_interactive_called) 177776259Sgreen return; 1778197679Sdes active_state->set_interactive_called = 1; 177976259Sgreen 178057429Smarkm /* Record that we are in interactive mode. */ 1781197679Sdes active_state->interactive_mode = interactive; 178257429Smarkm 178357429Smarkm /* Only set socket options if using a socket. */ 178457429Smarkm if (!packet_connection_is_on_socket()) 1785116791Sdes return; 1786197679Sdes set_nodelay(active_state->connection_in); 1787221420Sdes packet_set_tos(interactive ? qos_interactive : qos_bulk); 178857429Smarkm} 178957429Smarkm 179057429Smarkm/* Returns true if the current connection is interactive. */ 179157429Smarkm 179257429Smarkmint 179392555Sdespacket_is_interactive(void) 179457429Smarkm{ 1795197679Sdes return active_state->interactive_mode; 179657429Smarkm} 179757429Smarkm 1798137015Sdesint 1799124208Sdespacket_set_maxsize(u_int s) 180057429Smarkm{ 1801197679Sdes if (active_state->set_maxsize_called) { 1802124208Sdes logit("packet_set_maxsize: called twice: old %d new %d", 1803197679Sdes active_state->max_packet_size, s); 180457429Smarkm return -1; 180557429Smarkm } 180657429Smarkm if (s < 4 * 1024 || s > 1024 * 1024) { 1807124208Sdes logit("packet_set_maxsize: bad size %d", s); 180857429Smarkm return -1; 180957429Smarkm } 1810197679Sdes active_state->set_maxsize_called = 1; 181192555Sdes debug("packet_set_maxsize: setting to %d", s); 1812197679Sdes active_state->max_packet_size = s; 181357429Smarkm return s; 181457429Smarkm} 181576259Sgreen 1816197679Sdesint 1817197679Sdespacket_inc_alive_timeouts(void) 1818197679Sdes{ 1819197679Sdes return ++active_state->keep_alive_timeouts; 1820197679Sdes} 1821197679Sdes 1822197679Sdesvoid 1823197679Sdespacket_set_alive_timeouts(int ka) 1824197679Sdes{ 1825197679Sdes active_state->keep_alive_timeouts = ka; 1826197679Sdes} 1827197679Sdes 1828197679Sdesu_int 1829197679Sdespacket_get_maxsize(void) 1830197679Sdes{ 1831197679Sdes return active_state->max_packet_size; 1832197679Sdes} 1833197679Sdes 183492555Sdes/* roundup current message to pad bytes */ 183592555Sdesvoid 183692555Sdespacket_add_padding(u_char pad) 183792555Sdes{ 1838197679Sdes active_state->extra_pad = pad; 183992555Sdes} 184092555Sdes 184176259Sgreen/* 184276259Sgreen * 9.2. Ignored Data Message 184376259Sgreen * 184476259Sgreen * byte SSH_MSG_IGNORE 184576259Sgreen * string data 184676259Sgreen * 184776259Sgreen * All implementations MUST understand (and ignore) this message at any 184876259Sgreen * time (after receiving the protocol version). No implementation is 184976259Sgreen * required to send them. This message can be used as an additional 185076259Sgreen * protection measure against advanced traffic analysis techniques. 185176259Sgreen */ 185276259Sgreenvoid 185376259Sgreenpacket_send_ignore(int nbytes) 185476259Sgreen{ 1855137015Sdes u_int32_t rnd = 0; 185676259Sgreen int i; 185776259Sgreen 185876259Sgreen packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); 185976259Sgreen packet_put_int(nbytes); 186092555Sdes for (i = 0; i < nbytes; i++) { 186176259Sgreen if (i % 4 == 0) 1862137015Sdes rnd = arc4random(); 1863162852Sdes packet_put_char((u_char)rnd & 0xff); 1864137015Sdes rnd >>= 8; 186576259Sgreen } 186676259Sgreen} 1867124208Sdes 1868224638Sbrooks#ifdef NONE_CIPHER_ENABLED 1869224638Sbrooksvoid 1870224638Sbrookspacket_request_rekeying(void) 1871224638Sbrooks{ 1872224638Sbrooks rekey_requested = 1; 1873224638Sbrooks} 1874224638Sbrooks#endif 1875224638Sbrooks 1876137015Sdes#define MAX_PACKETS (1U<<31) 1877124208Sdesint 1878124208Sdespacket_need_rekeying(void) 1879124208Sdes{ 1880124208Sdes if (datafellows & SSH_BUG_NOREKEY) 1881124208Sdes return 0; 1882224638Sbrooks#ifdef NONE_CIPHER_ENABLED 1883224638Sbrooks if (rekey_requested == 1) { 1884224638Sbrooks rekey_requested = 0; 1885224638Sbrooks return 1; 1886224638Sbrooks } 1887224638Sbrooks#endif 1888124208Sdes return 1889197679Sdes (active_state->p_send.packets > MAX_PACKETS) || 1890197679Sdes (active_state->p_read.packets > MAX_PACKETS) || 1891197679Sdes (active_state->max_blocks_out && 1892197679Sdes (active_state->p_send.blocks > active_state->max_blocks_out)) || 1893197679Sdes (active_state->max_blocks_in && 1894197679Sdes (active_state->p_read.blocks > active_state->max_blocks_in)); 1895124208Sdes} 1896124208Sdes 1897124208Sdesvoid 1898124208Sdespacket_set_rekey_limit(u_int32_t bytes) 1899124208Sdes{ 1900197679Sdes active_state->rekey_limit = bytes; 1901124208Sdes} 1902149749Sdes 1903149749Sdesvoid 1904149749Sdespacket_set_server(void) 1905149749Sdes{ 1906197679Sdes active_state->server_side = 1; 1907149749Sdes} 1908149749Sdes 1909149749Sdesvoid 1910149749Sdespacket_set_authenticated(void) 1911149749Sdes{ 1912197679Sdes active_state->after_authentication = 1; 1913149749Sdes} 1914197679Sdes 1915197679Sdesvoid * 1916197679Sdespacket_get_input(void) 1917197679Sdes{ 1918197679Sdes return (void *)&active_state->input; 1919197679Sdes} 1920197679Sdes 1921197679Sdesvoid * 1922197679Sdespacket_get_output(void) 1923197679Sdes{ 1924197679Sdes return (void *)&active_state->output; 1925197679Sdes} 1926197679Sdes 1927197679Sdesvoid * 1928197679Sdespacket_get_newkeys(int mode) 1929197679Sdes{ 1930197679Sdes return (void *)active_state->newkeys[mode]; 1931197679Sdes} 1932197679Sdes 1933197679Sdes/* 1934197679Sdes * Save the state for the real connection, and use a separate state when 1935197679Sdes * resuming a suspended connection. 1936197679Sdes */ 1937197679Sdesvoid 1938197679Sdespacket_backup_state(void) 1939197679Sdes{ 1940197679Sdes struct session_state *tmp; 1941197679Sdes 1942197679Sdes close(active_state->connection_in); 1943197679Sdes active_state->connection_in = -1; 1944197679Sdes close(active_state->connection_out); 1945197679Sdes active_state->connection_out = -1; 1946197679Sdes if (backup_state) 1947197679Sdes tmp = backup_state; 1948197679Sdes else 1949197679Sdes tmp = alloc_session_state(); 1950197679Sdes backup_state = active_state; 1951197679Sdes active_state = tmp; 1952197679Sdes} 1953197679Sdes 1954197679Sdes/* 1955197679Sdes * Swap in the old state when resuming a connecion. 1956197679Sdes */ 1957197679Sdesvoid 1958197679Sdespacket_restore_state(void) 1959197679Sdes{ 1960197679Sdes struct session_state *tmp; 1961197679Sdes void *buf; 1962197679Sdes u_int len; 1963197679Sdes 1964197679Sdes tmp = backup_state; 1965197679Sdes backup_state = active_state; 1966197679Sdes active_state = tmp; 1967197679Sdes active_state->connection_in = backup_state->connection_in; 1968197679Sdes backup_state->connection_in = -1; 1969197679Sdes active_state->connection_out = backup_state->connection_out; 1970197679Sdes backup_state->connection_out = -1; 1971197679Sdes len = buffer_len(&backup_state->input); 1972197679Sdes if (len > 0) { 1973197679Sdes buf = buffer_ptr(&backup_state->input); 1974197679Sdes buffer_append(&active_state->input, buf, len); 1975197679Sdes buffer_clear(&backup_state->input); 1976197679Sdes add_recv_bytes(len); 1977197679Sdes } 1978197679Sdes} 1979224638Sbrooks 1980224638Sbrooks#ifdef NONE_CIPHER_ENABLED 1981224638Sbrooksint 1982224638Sbrookspacket_get_authentication_state(void) 1983224638Sbrooks{ 1984224638Sbrooks return (active_state->after_authentication); 1985224638Sbrooks} 1986224638Sbrooks#endif 1987