packet.c revision 215116
1215116Sdes/* $OpenBSD: packet.c,v 1.168 2010/07/13 23:13:16 djm Exp $ */ 257429Smarkm/* 357429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi> 457429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 557429Smarkm * All rights reserved 657429Smarkm * This file contains code implementing the packet protocol and communication 757429Smarkm * with the other side. This same code is used both on client and server side. 860573Skris * 965668Skris * As far as I am concerned, the code I have written for this software 1065668Skris * can be used freely for any purpose. Any derived versions of this 1165668Skris * software must be clearly marked as such, and if the derived work is 1265668Skris * incompatible with the protocol description in the RFC file, it must be 1365668Skris * called by a name other than "ssh" or "Secure Shell". 1465668Skris * 1565668Skris * 1660573Skris * SSH2 packet format added by Markus Friedl. 1792555Sdes * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 1860573Skris * 1965668Skris * Redistribution and use in source and binary forms, with or without 2065668Skris * modification, are permitted provided that the following conditions 2165668Skris * are met: 2265668Skris * 1. Redistributions of source code must retain the above copyright 2365668Skris * notice, this list of conditions and the following disclaimer. 2465668Skris * 2. Redistributions in binary form must reproduce the above copyright 2565668Skris * notice, this list of conditions and the following disclaimer in the 2665668Skris * documentation and/or other materials provided with the distribution. 2765668Skris * 2865668Skris * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2965668Skris * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 3065668Skris * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 3165668Skris * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 3265668Skris * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 3365668Skris * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3465668Skris * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3565668Skris * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3665668Skris * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3765668Skris * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3857429Smarkm */ 3957429Smarkm 4057429Smarkm#include "includes.h" 41162852Sdes 42162852Sdes#include <sys/types.h> 43124208Sdes#include "openbsd-compat/sys-queue.h" 44162852Sdes#include <sys/param.h> 45162852Sdes#include <sys/socket.h> 46162852Sdes#ifdef HAVE_SYS_TIME_H 47162852Sdes# include <sys/time.h> 48162852Sdes#endif 49124208Sdes 50162852Sdes#include <netinet/in.h> 51162852Sdes#include <netinet/ip.h> 52162852Sdes#include <arpa/inet.h> 53162852Sdes 54162852Sdes#include <errno.h> 55162852Sdes#include <stdarg.h> 56162852Sdes#include <stdio.h> 57162852Sdes#include <stdlib.h> 58162852Sdes#include <string.h> 59162852Sdes#include <unistd.h> 60162852Sdes#include <signal.h> 61162852Sdes 6257429Smarkm#include "xmalloc.h" 6357429Smarkm#include "buffer.h" 6457429Smarkm#include "packet.h" 6557429Smarkm#include "crc32.h" 6657429Smarkm#include "compress.h" 6757429Smarkm#include "deattack.h" 6860573Skris#include "channels.h" 6960573Skris#include "compat.h" 7076259Sgreen#include "ssh1.h" 7160573Skris#include "ssh2.h" 7269587Sgreen#include "cipher.h" 73162852Sdes#include "key.h" 7460573Skris#include "kex.h" 7576259Sgreen#include "mac.h" 7676259Sgreen#include "log.h" 7776259Sgreen#include "canohost.h" 7892555Sdes#include "misc.h" 7998675Sdes#include "ssh.h" 80197679Sdes#include "roaming.h" 8160573Skris 8260573Skris#ifdef PACKET_DEBUG 8360573Skris#define DBG(x) x 8460573Skris#else 8560573Skris#define DBG(x) 8660573Skris#endif 8760573Skris 88192595Sdes#define PACKET_MAX_SIZE (256 * 1024) 89192595Sdes 90197679Sdesstruct packet_state { 91197679Sdes u_int32_t seqnr; 92197679Sdes u_int32_t packets; 93197679Sdes u_int64_t blocks; 94197679Sdes u_int64_t bytes; 95197679Sdes}; 9657429Smarkm 97197679Sdesstruct packet { 98197679Sdes TAILQ_ENTRY(packet) next; 99197679Sdes u_char type; 100197679Sdes Buffer payload; 101197679Sdes}; 10257429Smarkm 103197679Sdesstruct session_state { 104197679Sdes /* 105197679Sdes * This variable contains the file descriptors used for 106197679Sdes * communicating with the other side. connection_in is used for 107197679Sdes * reading; connection_out for writing. These can be the same 108197679Sdes * descriptor, in which case it is assumed to be a socket. 109197679Sdes */ 110197679Sdes int connection_in; 111197679Sdes int connection_out; 11257429Smarkm 113197679Sdes /* Protocol flags for the remote side. */ 114197679Sdes u_int remote_protocol_flags; 11557429Smarkm 116197679Sdes /* Encryption context for receiving data. Only used for decryption. */ 117197679Sdes CipherContext receive_context; 11857429Smarkm 119197679Sdes /* Encryption context for sending data. Only used for encryption. */ 120197679Sdes CipherContext send_context; 12157429Smarkm 122197679Sdes /* Buffer for raw input data from the socket. */ 123197679Sdes Buffer input; 12457429Smarkm 125197679Sdes /* Buffer for raw output data going to the socket. */ 126197679Sdes Buffer output; 12757429Smarkm 128197679Sdes /* Buffer for the partial outgoing packet being constructed. */ 129197679Sdes Buffer outgoing_packet; 13057429Smarkm 131197679Sdes /* Buffer for the incoming packet currently being processed. */ 132197679Sdes Buffer incoming_packet; 13357429Smarkm 134197679Sdes /* Scratch buffer for packet compression/decompression. */ 135197679Sdes Buffer compression_buffer; 136197679Sdes int compression_buffer_ready; 13757429Smarkm 138197679Sdes /* 139197679Sdes * Flag indicating whether packet compression/decompression is 140197679Sdes * enabled. 141197679Sdes */ 142197679Sdes int packet_compression; 14357429Smarkm 144197679Sdes /* default maximum packet size */ 145197679Sdes u_int max_packet_size; 14657429Smarkm 147197679Sdes /* Flag indicating whether this module has been initialized. */ 148197679Sdes int initialized; 149149749Sdes 150197679Sdes /* Set to true if the connection is interactive. */ 151197679Sdes int interactive_mode; 152149749Sdes 153197679Sdes /* Set to true if we are the server side. */ 154197679Sdes int server_side; 155181111Sdes 156197679Sdes /* Set to true if we are authenticated. */ 157197679Sdes int after_authentication; 158181111Sdes 159197679Sdes int keep_alive_timeouts; 16060573Skris 161197679Sdes /* The maximum time that we will wait to send or receive a packet */ 162197679Sdes int packet_timeout_ms; 163124208Sdes 164197679Sdes /* Session key information for Encryption and MAC */ 165197679Sdes Newkeys *newkeys[MODE_MAX]; 166197679Sdes struct packet_state p_read, p_send; 16798675Sdes 168197679Sdes u_int64_t max_blocks_in, max_blocks_out; 169197679Sdes u_int32_t rekey_limit; 17060573Skris 171197679Sdes /* Session key for protocol v1 */ 172197679Sdes u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; 173197679Sdes u_int ssh1_keylen; 174192595Sdes 175197679Sdes /* roundup current message to extra_pad bytes */ 176197679Sdes u_char extra_pad; 177197679Sdes 178197679Sdes /* XXX discard incoming data after MAC error */ 179197679Sdes u_int packet_discard; 180197679Sdes Mac *packet_discard_mac; 181197679Sdes 182197679Sdes /* Used in packet_read_poll2() */ 183197679Sdes u_int packlen; 184197679Sdes 185197679Sdes /* Used in packet_send2 */ 186197679Sdes int rekeying; 187197679Sdes 188197679Sdes /* Used in packet_set_interactive */ 189197679Sdes int set_interactive_called; 190197679Sdes 191197679Sdes /* Used in packet_set_maxsize */ 192197679Sdes int set_maxsize_called; 193197679Sdes 194197679Sdes TAILQ_HEAD(, packet) outgoing; 195124208Sdes}; 196124208Sdes 197197679Sdesstatic struct session_state *active_state, *backup_state; 198197679Sdes 199197679Sdesstatic struct session_state * 200197679Sdesalloc_session_state(void) 201197679Sdes{ 202197679Sdes struct session_state *s = xcalloc(1, sizeof(*s)); 203197679Sdes 204197679Sdes s->connection_in = -1; 205197679Sdes s->connection_out = -1; 206197679Sdes s->max_packet_size = 32768; 207197679Sdes s->packet_timeout_ms = -1; 208197679Sdes return s; 209197679Sdes} 210197679Sdes 21157429Smarkm/* 21257429Smarkm * Sets the descriptors used for communication. Disables encryption until 21357429Smarkm * packet_set_encryption_key is called. 21457429Smarkm */ 21557429Smarkmvoid 21657429Smarkmpacket_set_connection(int fd_in, int fd_out) 21757429Smarkm{ 21869587Sgreen Cipher *none = cipher_by_name("none"); 219106121Sdes 22069587Sgreen if (none == NULL) 22169587Sgreen fatal("packet_set_connection: cannot load cipher 'none'"); 222197679Sdes if (active_state == NULL) 223197679Sdes active_state = alloc_session_state(); 224197679Sdes active_state->connection_in = fd_in; 225197679Sdes active_state->connection_out = fd_out; 226197679Sdes cipher_init(&active_state->send_context, none, (const u_char *)"", 227137015Sdes 0, NULL, 0, CIPHER_ENCRYPT); 228197679Sdes cipher_init(&active_state->receive_context, none, (const u_char *)"", 229137015Sdes 0, NULL, 0, CIPHER_DECRYPT); 230197679Sdes active_state->newkeys[MODE_IN] = active_state->newkeys[MODE_OUT] = NULL; 231197679Sdes if (!active_state->initialized) { 232197679Sdes active_state->initialized = 1; 233197679Sdes buffer_init(&active_state->input); 234197679Sdes buffer_init(&active_state->output); 235197679Sdes buffer_init(&active_state->outgoing_packet); 236197679Sdes buffer_init(&active_state->incoming_packet); 237197679Sdes TAILQ_INIT(&active_state->outgoing); 238197679Sdes active_state->p_send.packets = active_state->p_read.packets = 0; 23957429Smarkm } 24057429Smarkm} 24157429Smarkm 242181111Sdesvoid 243181111Sdespacket_set_timeout(int timeout, int count) 244181111Sdes{ 245181111Sdes if (timeout == 0 || count == 0) { 246197679Sdes active_state->packet_timeout_ms = -1; 247181111Sdes return; 248181111Sdes } 249181111Sdes if ((INT_MAX / 1000) / count < timeout) 250197679Sdes active_state->packet_timeout_ms = INT_MAX; 251181111Sdes else 252197679Sdes active_state->packet_timeout_ms = timeout * count * 1000; 253181111Sdes} 254181111Sdes 255192595Sdesstatic void 256192595Sdespacket_stop_discard(void) 257192595Sdes{ 258197679Sdes if (active_state->packet_discard_mac) { 259192595Sdes char buf[1024]; 260192595Sdes 261192595Sdes memset(buf, 'a', sizeof(buf)); 262197679Sdes while (buffer_len(&active_state->incoming_packet) < 263197679Sdes PACKET_MAX_SIZE) 264197679Sdes buffer_append(&active_state->incoming_packet, buf, 265197679Sdes sizeof(buf)); 266197679Sdes (void) mac_compute(active_state->packet_discard_mac, 267197679Sdes active_state->p_read.seqnr, 268197679Sdes buffer_ptr(&active_state->incoming_packet), 269192595Sdes PACKET_MAX_SIZE); 270192595Sdes } 271192595Sdes logit("Finished discarding for %.200s", get_remote_ipaddr()); 272192595Sdes cleanup_exit(255); 273192595Sdes} 274192595Sdes 275192595Sdesstatic void 276192595Sdespacket_start_discard(Enc *enc, Mac *mac, u_int packet_length, u_int discard) 277192595Sdes{ 278192595Sdes if (enc == NULL || !cipher_is_cbc(enc->cipher)) 279192595Sdes packet_disconnect("Packet corrupt"); 280192595Sdes if (packet_length != PACKET_MAX_SIZE && mac && mac->enabled) 281197679Sdes active_state->packet_discard_mac = mac; 282197679Sdes if (buffer_len(&active_state->input) >= discard) 283192595Sdes packet_stop_discard(); 284197679Sdes active_state->packet_discard = discard - 285197679Sdes buffer_len(&active_state->input); 286192595Sdes} 287192595Sdes 28857429Smarkm/* Returns 1 if remote host is connected via socket, 0 if not. */ 28957429Smarkm 29057429Smarkmint 29192555Sdespacket_connection_is_on_socket(void) 29257429Smarkm{ 29357429Smarkm struct sockaddr_storage from, to; 29457429Smarkm socklen_t fromlen, tolen; 29557429Smarkm 29657429Smarkm /* filedescriptors in and out are the same, so it's a socket */ 297197679Sdes if (active_state->connection_in == active_state->connection_out) 29857429Smarkm return 1; 29957429Smarkm fromlen = sizeof(from); 30057429Smarkm memset(&from, 0, sizeof(from)); 301197679Sdes if (getpeername(active_state->connection_in, (struct sockaddr *)&from, 302197679Sdes &fromlen) < 0) 30357429Smarkm return 0; 30457429Smarkm tolen = sizeof(to); 30557429Smarkm memset(&to, 0, sizeof(to)); 306197679Sdes if (getpeername(active_state->connection_out, (struct sockaddr *)&to, 307197679Sdes &tolen) < 0) 30857429Smarkm return 0; 30957429Smarkm if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) 31057429Smarkm return 0; 31157429Smarkm if (from.ss_family != AF_INET && from.ss_family != AF_INET6) 31257429Smarkm return 0; 31357429Smarkm return 1; 31457429Smarkm} 31557429Smarkm 31698675Sdes/* 31798675Sdes * Exports an IV from the CipherContext required to export the key 31898675Sdes * state back from the unprivileged child to the privileged parent 31998675Sdes * process. 32098675Sdes */ 32198675Sdes 32298675Sdesvoid 32398675Sdespacket_get_keyiv(int mode, u_char *iv, u_int len) 32498675Sdes{ 32598675Sdes CipherContext *cc; 32698675Sdes 32798675Sdes if (mode == MODE_OUT) 328197679Sdes cc = &active_state->send_context; 32998675Sdes else 330197679Sdes cc = &active_state->receive_context; 33198675Sdes 33298675Sdes cipher_get_keyiv(cc, iv, len); 33398675Sdes} 33498675Sdes 33598675Sdesint 33698675Sdespacket_get_keycontext(int mode, u_char *dat) 33798675Sdes{ 33898675Sdes CipherContext *cc; 33998675Sdes 34098675Sdes if (mode == MODE_OUT) 341197679Sdes cc = &active_state->send_context; 34298675Sdes else 343197679Sdes cc = &active_state->receive_context; 34498675Sdes 34598675Sdes return (cipher_get_keycontext(cc, dat)); 34698675Sdes} 34798675Sdes 34898675Sdesvoid 34998675Sdespacket_set_keycontext(int mode, u_char *dat) 35098675Sdes{ 35198675Sdes CipherContext *cc; 35298675Sdes 35398675Sdes if (mode == MODE_OUT) 354197679Sdes cc = &active_state->send_context; 35598675Sdes else 356197679Sdes cc = &active_state->receive_context; 35798675Sdes 35898675Sdes cipher_set_keycontext(cc, dat); 35998675Sdes} 36098675Sdes 36198675Sdesint 36298675Sdespacket_get_keyiv_len(int mode) 36398675Sdes{ 36498675Sdes CipherContext *cc; 36598675Sdes 36698675Sdes if (mode == MODE_OUT) 367197679Sdes cc = &active_state->send_context; 36898675Sdes else 369197679Sdes cc = &active_state->receive_context; 37098675Sdes 37198675Sdes return (cipher_get_keyiv_len(cc)); 37298675Sdes} 373162852Sdes 37498675Sdesvoid 37598675Sdespacket_set_iv(int mode, u_char *dat) 37698675Sdes{ 37798675Sdes CipherContext *cc; 37898675Sdes 37998675Sdes if (mode == MODE_OUT) 380197679Sdes cc = &active_state->send_context; 38198675Sdes else 382197679Sdes cc = &active_state->receive_context; 38398675Sdes 38498675Sdes cipher_set_keyiv(cc, dat); 38598675Sdes} 386162852Sdes 38798675Sdesint 388124208Sdespacket_get_ssh1_cipher(void) 38998675Sdes{ 390197679Sdes return (cipher_get_number(active_state->receive_context.cipher)); 39198675Sdes} 39298675Sdes 393124208Sdesvoid 394181111Sdespacket_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets, 395181111Sdes u_int64_t *bytes) 396124208Sdes{ 397124208Sdes struct packet_state *state; 39898675Sdes 399197679Sdes state = (mode == MODE_IN) ? 400197679Sdes &active_state->p_read : &active_state->p_send; 401181111Sdes if (seqnr) 402181111Sdes *seqnr = state->seqnr; 403181111Sdes if (blocks) 404181111Sdes *blocks = state->blocks; 405181111Sdes if (packets) 406181111Sdes *packets = state->packets; 407181111Sdes if (bytes) 408181111Sdes *bytes = state->bytes; 40998675Sdes} 41098675Sdes 41198675Sdesvoid 412181111Sdespacket_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets, 413181111Sdes u_int64_t bytes) 41498675Sdes{ 415124208Sdes struct packet_state *state; 416124208Sdes 417197679Sdes state = (mode == MODE_IN) ? 418197679Sdes &active_state->p_read : &active_state->p_send; 419124208Sdes state->seqnr = seqnr; 420124208Sdes state->blocks = blocks; 421124208Sdes state->packets = packets; 422181111Sdes state->bytes = bytes; 42398675Sdes} 42498675Sdes 42557429Smarkm/* returns 1 if connection is via ipv4 */ 42657429Smarkm 42757429Smarkmint 42892555Sdespacket_connection_is_ipv4(void) 42957429Smarkm{ 43057429Smarkm struct sockaddr_storage to; 43157429Smarkm socklen_t tolen = sizeof(to); 43257429Smarkm 43357429Smarkm memset(&to, 0, sizeof(to)); 434197679Sdes if (getsockname(active_state->connection_out, (struct sockaddr *)&to, 435197679Sdes &tolen) < 0) 43657429Smarkm return 0; 43798937Sdes if (to.ss_family == AF_INET) 43898937Sdes return 1; 43998937Sdes#ifdef IPV4_IN_IPV6 440126274Sdes if (to.ss_family == AF_INET6 && 44198937Sdes IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) 44298937Sdes return 1; 44398937Sdes#endif 44498937Sdes return 0; 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 55076259Sgreenpacket_set_encryption_key(const u_char *key, u_int keylen, 55169587Sgreen int number) 55257429Smarkm{ 55369587Sgreen Cipher *cipher = cipher_by_number(number); 554106121Sdes 55569587Sgreen if (cipher == NULL) 55669587Sgreen fatal("packet_set_encryption_key: unknown cipher number %d", number); 55760573Skris if (keylen < 20) 55869587Sgreen fatal("packet_set_encryption_key: keylen too small: %d", keylen); 55998675Sdes if (keylen > SSH_SESSION_KEY_LENGTH) 56098675Sdes fatal("packet_set_encryption_key: keylen too big: %d", keylen); 561197679Sdes memcpy(active_state->ssh1_key, key, keylen); 562197679Sdes active_state->ssh1_keylen = keylen; 563197679Sdes cipher_init(&active_state->send_context, cipher, key, keylen, NULL, 564197679Sdes 0, CIPHER_ENCRYPT); 565197679Sdes cipher_init(&active_state->receive_context, cipher, key, keylen, NULL, 566197679Sdes 0, CIPHER_DECRYPT); 56757429Smarkm} 56857429Smarkm 56998675Sdesu_int 57098675Sdespacket_get_encryption_key(u_char *key) 57198675Sdes{ 57298675Sdes if (key == NULL) 573197679Sdes return (active_state->ssh1_keylen); 574197679Sdes memcpy(key, active_state->ssh1_key, active_state->ssh1_keylen); 575197679Sdes return (active_state->ssh1_keylen); 57698675Sdes} 57798675Sdes 57892555Sdes/* Start constructing a packet to send. */ 57957429Smarkmvoid 58092555Sdespacket_start(u_char type) 58157429Smarkm{ 58292555Sdes u_char buf[9]; 58392555Sdes int len; 58457429Smarkm 58592555Sdes DBG(debug("packet_start[%d]", type)); 58692555Sdes len = compat20 ? 6 : 9; 58792555Sdes memset(buf, 0, len - 1); 58892555Sdes buf[len - 1] = type; 589197679Sdes buffer_clear(&active_state->outgoing_packet); 590197679Sdes buffer_append(&active_state->outgoing_packet, buf, len); 59157429Smarkm} 59257429Smarkm 59392555Sdes/* Append payload. */ 59460573Skrisvoid 59557429Smarkmpacket_put_char(int value) 59657429Smarkm{ 59757429Smarkm char ch = value; 598106121Sdes 599197679Sdes buffer_append(&active_state->outgoing_packet, &ch, 1); 60057429Smarkm} 601162852Sdes 60257429Smarkmvoid 60376259Sgreenpacket_put_int(u_int value) 60457429Smarkm{ 605197679Sdes buffer_put_int(&active_state->outgoing_packet, value); 60657429Smarkm} 607162852Sdes 60857429Smarkmvoid 609197679Sdespacket_put_int64(u_int64_t value) 610197679Sdes{ 611197679Sdes buffer_put_int64(&active_state->outgoing_packet, value); 612197679Sdes} 613197679Sdes 614197679Sdesvoid 61592555Sdespacket_put_string(const void *buf, u_int len) 61657429Smarkm{ 617197679Sdes buffer_put_string(&active_state->outgoing_packet, buf, len); 61857429Smarkm} 619162852Sdes 62060573Skrisvoid 62160573Skrispacket_put_cstring(const char *str) 62260573Skris{ 623197679Sdes buffer_put_cstring(&active_state->outgoing_packet, str); 62460573Skris} 625162852Sdes 62660573Skrisvoid 62792555Sdespacket_put_raw(const void *buf, u_int len) 62860573Skris{ 629197679Sdes buffer_append(&active_state->outgoing_packet, buf, len); 63060573Skris} 631162852Sdes 63257429Smarkmvoid 63357429Smarkmpacket_put_bignum(BIGNUM * value) 63457429Smarkm{ 635197679Sdes buffer_put_bignum(&active_state->outgoing_packet, value); 63657429Smarkm} 637162852Sdes 63860573Skrisvoid 63960573Skrispacket_put_bignum2(BIGNUM * value) 64060573Skris{ 641197679Sdes buffer_put_bignum2(&active_state->outgoing_packet, value); 64260573Skris} 64357429Smarkm 64457429Smarkm/* 64557429Smarkm * Finalizes and sends the packet. If the encryption key has been set, 64657429Smarkm * encrypts the packet before sending. 64757429Smarkm */ 64857429Smarkm 64992555Sdesstatic void 65076259Sgreenpacket_send1(void) 65157429Smarkm{ 65292555Sdes u_char buf[8], *cp; 65357429Smarkm int i, padding, len; 65476259Sgreen u_int checksum; 655137015Sdes u_int32_t rnd = 0; 65657429Smarkm 65757429Smarkm /* 65857429Smarkm * If using packet compression, compress the payload of the outgoing 65957429Smarkm * packet. 66057429Smarkm */ 661197679Sdes if (active_state->packet_compression) { 662197679Sdes buffer_clear(&active_state->compression_buffer); 66357429Smarkm /* Skip padding. */ 664197679Sdes buffer_consume(&active_state->outgoing_packet, 8); 66557429Smarkm /* padding */ 666197679Sdes buffer_append(&active_state->compression_buffer, 667197679Sdes "\0\0\0\0\0\0\0\0", 8); 668197679Sdes buffer_compress(&active_state->outgoing_packet, 669197679Sdes &active_state->compression_buffer); 670197679Sdes buffer_clear(&active_state->outgoing_packet); 671197679Sdes buffer_append(&active_state->outgoing_packet, 672197679Sdes buffer_ptr(&active_state->compression_buffer), 673197679Sdes buffer_len(&active_state->compression_buffer)); 67457429Smarkm } 67557429Smarkm /* Compute packet length without padding (add checksum, remove padding). */ 676197679Sdes len = buffer_len(&active_state->outgoing_packet) + 4 - 8; 67757429Smarkm 67860573Skris /* Insert padding. Initialized to zero in packet_start1() */ 67957429Smarkm padding = 8 - len % 8; 680197679Sdes if (!active_state->send_context.plaintext) { 681197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 68257429Smarkm for (i = 0; i < padding; i++) { 68357429Smarkm if (i % 4 == 0) 684137015Sdes rnd = arc4random(); 685137015Sdes cp[7 - i] = rnd & 0xff; 686137015Sdes rnd >>= 8; 68757429Smarkm } 68857429Smarkm } 689197679Sdes buffer_consume(&active_state->outgoing_packet, 8 - padding); 69057429Smarkm 69157429Smarkm /* Add check bytes. */ 692197679Sdes checksum = ssh_crc32(buffer_ptr(&active_state->outgoing_packet), 693197679Sdes buffer_len(&active_state->outgoing_packet)); 694162852Sdes put_u32(buf, checksum); 695197679Sdes buffer_append(&active_state->outgoing_packet, buf, 4); 69657429Smarkm 69757429Smarkm#ifdef PACKET_DEBUG 69857429Smarkm fprintf(stderr, "packet_send plain: "); 699197679Sdes buffer_dump(&active_state->outgoing_packet); 70057429Smarkm#endif 70157429Smarkm 70257429Smarkm /* Append to output. */ 703162852Sdes put_u32(buf, len); 704197679Sdes buffer_append(&active_state->output, buf, 4); 705197679Sdes cp = buffer_append_space(&active_state->output, 706197679Sdes buffer_len(&active_state->outgoing_packet)); 707197679Sdes cipher_crypt(&active_state->send_context, cp, 708197679Sdes buffer_ptr(&active_state->outgoing_packet), 709197679Sdes buffer_len(&active_state->outgoing_packet)); 71057429Smarkm 71157429Smarkm#ifdef PACKET_DEBUG 71257429Smarkm fprintf(stderr, "encrypted: "); 713197679Sdes buffer_dump(&active_state->output); 71457429Smarkm#endif 715197679Sdes active_state->p_send.packets++; 716197679Sdes active_state->p_send.bytes += len + 717197679Sdes buffer_len(&active_state->outgoing_packet); 718197679Sdes buffer_clear(&active_state->outgoing_packet); 71957429Smarkm 72057429Smarkm /* 721157016Sdes * Note that the packet is now only buffered in output. It won't be 72257429Smarkm * actually sent until packet_write_wait or packet_write_poll is 72357429Smarkm * called. 72457429Smarkm */ 72557429Smarkm} 72657429Smarkm 72798675Sdesvoid 72876259Sgreenset_newkeys(int mode) 72976259Sgreen{ 73076259Sgreen Enc *enc; 73176259Sgreen Mac *mac; 73276259Sgreen Comp *comp; 73376259Sgreen CipherContext *cc; 734124208Sdes u_int64_t *max_blocks; 735137015Sdes int crypt_type; 73676259Sgreen 737113908Sdes debug2("set_newkeys: mode %d", mode); 73876259Sgreen 73992555Sdes if (mode == MODE_OUT) { 740197679Sdes cc = &active_state->send_context; 741137015Sdes crypt_type = CIPHER_ENCRYPT; 742197679Sdes active_state->p_send.packets = active_state->p_send.blocks = 0; 743197679Sdes max_blocks = &active_state->max_blocks_out; 74492555Sdes } else { 745197679Sdes cc = &active_state->receive_context; 746137015Sdes crypt_type = CIPHER_DECRYPT; 747197679Sdes active_state->p_read.packets = active_state->p_read.blocks = 0; 748197679Sdes max_blocks = &active_state->max_blocks_in; 74992555Sdes } 750197679Sdes if (active_state->newkeys[mode] != NULL) { 751113908Sdes debug("set_newkeys: rekeying"); 75292555Sdes cipher_cleanup(cc); 753197679Sdes enc = &active_state->newkeys[mode]->enc; 754197679Sdes mac = &active_state->newkeys[mode]->mac; 755197679Sdes comp = &active_state->newkeys[mode]->comp; 756181111Sdes mac_clear(mac); 75776259Sgreen xfree(enc->name); 75876259Sgreen xfree(enc->iv); 75976259Sgreen xfree(enc->key); 76076259Sgreen xfree(mac->name); 76176259Sgreen xfree(mac->key); 76276259Sgreen xfree(comp->name); 763197679Sdes xfree(active_state->newkeys[mode]); 76476259Sgreen } 765197679Sdes active_state->newkeys[mode] = kex_get_newkeys(mode); 766197679Sdes if (active_state->newkeys[mode] == NULL) 76776259Sgreen fatal("newkeys: no keys for mode %d", mode); 768197679Sdes enc = &active_state->newkeys[mode]->enc; 769197679Sdes mac = &active_state->newkeys[mode]->mac; 770197679Sdes comp = &active_state->newkeys[mode]->comp; 771181111Sdes if (mac_init(mac) == 0) 77276259Sgreen mac->enabled = 1; 77376259Sgreen DBG(debug("cipher_init_context: %d", mode)); 77492555Sdes cipher_init(cc, enc->cipher, enc->key, enc->key_len, 775137015Sdes enc->iv, enc->block_size, crypt_type); 77698675Sdes /* Deleting the keys does not gain extra security */ 77798675Sdes /* memset(enc->iv, 0, enc->block_size); 778181111Sdes memset(enc->key, 0, enc->key_len); 779181111Sdes memset(mac->key, 0, mac->key_len); */ 780149749Sdes if ((comp->type == COMP_ZLIB || 781197679Sdes (comp->type == COMP_DELAYED && 782197679Sdes active_state->after_authentication)) && comp->enabled == 0) { 78376259Sgreen packet_init_compression(); 78476259Sgreen if (mode == MODE_OUT) 78576259Sgreen buffer_compress_init_send(6); 78676259Sgreen else 78776259Sgreen buffer_compress_init_recv(); 78876259Sgreen comp->enabled = 1; 78976259Sgreen } 790124208Sdes /* 791124208Sdes * The 2^(blocksize*2) limit is too expensive for 3DES, 792124208Sdes * blowfish, etc, so enforce a 1GB limit for small blocksizes. 793124208Sdes */ 794124208Sdes if (enc->block_size >= 16) 795124208Sdes *max_blocks = (u_int64_t)1 << (enc->block_size*2); 796124208Sdes else 797124208Sdes *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; 798197679Sdes if (active_state->rekey_limit) 799197679Sdes *max_blocks = MIN(*max_blocks, 800197679Sdes active_state->rekey_limit / enc->block_size); 80176259Sgreen} 80276259Sgreen 80357429Smarkm/* 804149749Sdes * Delayed compression for SSH2 is enabled after authentication: 805162852Sdes * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, 806149749Sdes * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. 807149749Sdes */ 808149749Sdesstatic void 809149749Sdespacket_enable_delayed_compress(void) 810149749Sdes{ 811149749Sdes Comp *comp = NULL; 812149749Sdes int mode; 813149749Sdes 814149749Sdes /* 815149749Sdes * Remember that we are past the authentication step, so rekeying 816149749Sdes * with COMP_DELAYED will turn on compression immediately. 817149749Sdes */ 818197679Sdes active_state->after_authentication = 1; 819149749Sdes for (mode = 0; mode < MODE_MAX; mode++) { 820162852Sdes /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ 821197679Sdes if (active_state->newkeys[mode] == NULL) 822162852Sdes continue; 823197679Sdes comp = &active_state->newkeys[mode]->comp; 824149749Sdes if (comp && !comp->enabled && comp->type == COMP_DELAYED) { 825149749Sdes packet_init_compression(); 826149749Sdes if (mode == MODE_OUT) 827149749Sdes buffer_compress_init_send(6); 828149749Sdes else 829149749Sdes buffer_compress_init_recv(); 830149749Sdes comp->enabled = 1; 831149749Sdes } 832149749Sdes } 833149749Sdes} 834149749Sdes 835149749Sdes/* 83660573Skris * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) 83760573Skris */ 83892555Sdesstatic void 839124208Sdespacket_send2_wrapped(void) 84060573Skris{ 84192555Sdes u_char type, *cp, *macbuf = NULL; 84292555Sdes u_char padlen, pad; 84376259Sgreen u_int packet_length = 0; 84492555Sdes u_int i, len; 845137015Sdes u_int32_t rnd = 0; 84660573Skris Enc *enc = NULL; 84760573Skris Mac *mac = NULL; 84860573Skris Comp *comp = NULL; 84960573Skris int block_size; 85060573Skris 851197679Sdes if (active_state->newkeys[MODE_OUT] != NULL) { 852197679Sdes enc = &active_state->newkeys[MODE_OUT]->enc; 853197679Sdes mac = &active_state->newkeys[MODE_OUT]->mac; 854197679Sdes comp = &active_state->newkeys[MODE_OUT]->comp; 85560573Skris } 85692555Sdes block_size = enc ? enc->block_size : 8; 85760573Skris 858197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 85992555Sdes type = cp[5]; 86060573Skris 86160573Skris#ifdef PACKET_DEBUG 86260573Skris fprintf(stderr, "plain: "); 863197679Sdes buffer_dump(&active_state->outgoing_packet); 86460573Skris#endif 86560573Skris 86660573Skris if (comp && comp->enabled) { 867197679Sdes len = buffer_len(&active_state->outgoing_packet); 86860573Skris /* skip header, compress only payload */ 869197679Sdes buffer_consume(&active_state->outgoing_packet, 5); 870197679Sdes buffer_clear(&active_state->compression_buffer); 871197679Sdes buffer_compress(&active_state->outgoing_packet, 872197679Sdes &active_state->compression_buffer); 873197679Sdes buffer_clear(&active_state->outgoing_packet); 874197679Sdes buffer_append(&active_state->outgoing_packet, "\0\0\0\0\0", 5); 875197679Sdes buffer_append(&active_state->outgoing_packet, 876197679Sdes buffer_ptr(&active_state->compression_buffer), 877197679Sdes buffer_len(&active_state->compression_buffer)); 87860573Skris DBG(debug("compression: raw %d compressed %d", len, 879197679Sdes buffer_len(&active_state->outgoing_packet))); 88060573Skris } 88160573Skris 88260573Skris /* sizeof (packet_len + pad_len + payload) */ 883197679Sdes len = buffer_len(&active_state->outgoing_packet); 88460573Skris 88560573Skris /* 88660573Skris * calc size of padding, alloc space, get random data, 88760573Skris * minimum padding is 4 bytes 88860573Skris */ 88960573Skris padlen = block_size - (len % block_size); 89060573Skris if (padlen < 4) 89160573Skris padlen += block_size; 892197679Sdes if (active_state->extra_pad) { 89392555Sdes /* will wrap if extra_pad+padlen > 255 */ 894197679Sdes active_state->extra_pad = 895197679Sdes roundup(active_state->extra_pad, block_size); 896197679Sdes pad = active_state->extra_pad - 897197679Sdes ((len + padlen) % active_state->extra_pad); 89898675Sdes debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)", 899197679Sdes pad, len, padlen, active_state->extra_pad); 90092555Sdes padlen += pad; 901197679Sdes active_state->extra_pad = 0; 90292555Sdes } 903197679Sdes cp = buffer_append_space(&active_state->outgoing_packet, padlen); 904197679Sdes if (enc && !active_state->send_context.plaintext) { 90560573Skris /* random padding */ 90660573Skris for (i = 0; i < padlen; i++) { 90760573Skris if (i % 4 == 0) 908137015Sdes rnd = arc4random(); 909137015Sdes cp[i] = rnd & 0xff; 910137015Sdes rnd >>= 8; 91160573Skris } 91260573Skris } else { 91360573Skris /* clear padding */ 91460573Skris memset(cp, 0, padlen); 91560573Skris } 91660573Skris /* packet_length includes payload, padding and padding length field */ 917197679Sdes packet_length = buffer_len(&active_state->outgoing_packet) - 4; 918197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 919162852Sdes put_u32(cp, packet_length); 92092555Sdes cp[4] = padlen; 92160573Skris DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); 92260573Skris 92360573Skris /* compute MAC over seqnr and packet(length fields, payload, padding) */ 92460573Skris if (mac && mac->enabled) { 925197679Sdes macbuf = mac_compute(mac, active_state->p_send.seqnr, 926197679Sdes buffer_ptr(&active_state->outgoing_packet), 927197679Sdes buffer_len(&active_state->outgoing_packet)); 928197679Sdes DBG(debug("done calc MAC out #%d", active_state->p_send.seqnr)); 92960573Skris } 93060573Skris /* encrypt packet and append to output buffer. */ 931197679Sdes cp = buffer_append_space(&active_state->output, 932197679Sdes buffer_len(&active_state->outgoing_packet)); 933197679Sdes cipher_crypt(&active_state->send_context, cp, 934197679Sdes buffer_ptr(&active_state->outgoing_packet), 935197679Sdes buffer_len(&active_state->outgoing_packet)); 93660573Skris /* append unencrypted MAC */ 93760573Skris if (mac && mac->enabled) 938197679Sdes buffer_append(&active_state->output, macbuf, mac->mac_len); 93960573Skris#ifdef PACKET_DEBUG 94060573Skris fprintf(stderr, "encrypted: "); 941197679Sdes buffer_dump(&active_state->output); 94260573Skris#endif 94360573Skris /* increment sequence number for outgoing packets */ 944197679Sdes if (++active_state->p_send.seqnr == 0) 945124208Sdes logit("outgoing seqnr wraps around"); 946197679Sdes if (++active_state->p_send.packets == 0) 947124208Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 948124208Sdes fatal("XXX too many packets with same key"); 949197679Sdes active_state->p_send.blocks += (packet_length + 4) / block_size; 950197679Sdes active_state->p_send.bytes += packet_length + 4; 951197679Sdes buffer_clear(&active_state->outgoing_packet); 95260573Skris 95376259Sgreen if (type == SSH2_MSG_NEWKEYS) 95476259Sgreen set_newkeys(MODE_OUT); 955197679Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && active_state->server_side) 956149749Sdes packet_enable_delayed_compress(); 95760573Skris} 95860573Skris 959124208Sdesstatic void 960124208Sdespacket_send2(void) 961124208Sdes{ 962124208Sdes struct packet *p; 963124208Sdes u_char type, *cp; 964124208Sdes 965197679Sdes cp = buffer_ptr(&active_state->outgoing_packet); 966124208Sdes type = cp[5]; 967124208Sdes 968124208Sdes /* during rekeying we can only send key exchange messages */ 969197679Sdes if (active_state->rekeying) { 970124208Sdes if (!((type >= SSH2_MSG_TRANSPORT_MIN) && 971124208Sdes (type <= SSH2_MSG_TRANSPORT_MAX))) { 972124208Sdes debug("enqueue packet: %u", type); 973124208Sdes p = xmalloc(sizeof(*p)); 974124208Sdes p->type = type; 975197679Sdes memcpy(&p->payload, &active_state->outgoing_packet, 976197679Sdes sizeof(Buffer)); 977197679Sdes buffer_init(&active_state->outgoing_packet); 978197679Sdes TAILQ_INSERT_TAIL(&active_state->outgoing, p, next); 979124208Sdes return; 980124208Sdes } 981124208Sdes } 982124208Sdes 983124208Sdes /* rekeying starts with sending KEXINIT */ 984124208Sdes if (type == SSH2_MSG_KEXINIT) 985197679Sdes active_state->rekeying = 1; 986124208Sdes 987124208Sdes packet_send2_wrapped(); 988124208Sdes 989124208Sdes /* after a NEWKEYS message we can send the complete queue */ 990124208Sdes if (type == SSH2_MSG_NEWKEYS) { 991197679Sdes active_state->rekeying = 0; 992197679Sdes while ((p = TAILQ_FIRST(&active_state->outgoing))) { 993124208Sdes type = p->type; 994124208Sdes debug("dequeue packet: %u", type); 995197679Sdes buffer_free(&active_state->outgoing_packet); 996197679Sdes memcpy(&active_state->outgoing_packet, &p->payload, 997124208Sdes sizeof(Buffer)); 998197679Sdes TAILQ_REMOVE(&active_state->outgoing, p, next); 999124208Sdes xfree(p); 1000124208Sdes packet_send2_wrapped(); 1001124208Sdes } 1002124208Sdes } 1003124208Sdes} 1004124208Sdes 100560573Skrisvoid 100692555Sdespacket_send(void) 100760573Skris{ 100892555Sdes if (compat20) 100960573Skris packet_send2(); 101060573Skris else 101160573Skris packet_send1(); 101260573Skris DBG(debug("packet_send done")); 101360573Skris} 101460573Skris 101560573Skris/* 101657429Smarkm * Waits until a packet has been received, and returns its type. Note that 101757429Smarkm * no other data is processed until this returns, so this function should not 101857429Smarkm * be used during the interactive session. 101957429Smarkm */ 102057429Smarkm 102157429Smarkmint 102292555Sdespacket_read_seqnr(u_int32_t *seqnr_p) 102357429Smarkm{ 1024197679Sdes int type, len, ret, ms_remain, cont; 102576259Sgreen fd_set *setp; 102657429Smarkm char buf[8192]; 1027181111Sdes struct timeval timeout, start, *timeoutp = NULL; 1028181111Sdes 102960573Skris DBG(debug("packet_read()")); 103057429Smarkm 1031197679Sdes setp = (fd_set *)xcalloc(howmany(active_state->connection_in + 1, 1032197679Sdes NFDBITS), sizeof(fd_mask)); 103376259Sgreen 103457429Smarkm /* Since we are blocking, ensure that all written packets have been sent. */ 103557429Smarkm packet_write_wait(); 103657429Smarkm 103757429Smarkm /* Stay in the loop until we have received a complete packet. */ 103857429Smarkm for (;;) { 103957429Smarkm /* Try to read a packet from the buffer. */ 104092555Sdes type = packet_read_poll_seqnr(seqnr_p); 104192555Sdes if (!compat20 && ( 104260573Skris type == SSH_SMSG_SUCCESS 104357429Smarkm || type == SSH_SMSG_FAILURE 104457429Smarkm || type == SSH_CMSG_EOF 104560573Skris || type == SSH_CMSG_EXIT_CONFIRMATION)) 104692555Sdes packet_check_eom(); 104757429Smarkm /* If we got a packet, return it. */ 104876259Sgreen if (type != SSH_MSG_NONE) { 104976259Sgreen xfree(setp); 105057429Smarkm return type; 105176259Sgreen } 105257429Smarkm /* 105357429Smarkm * Otherwise, wait for some data to arrive, add it to the 105457429Smarkm * buffer, and try again. 105557429Smarkm */ 1056197679Sdes memset(setp, 0, howmany(active_state->connection_in + 1, 1057197679Sdes NFDBITS) * sizeof(fd_mask)); 1058197679Sdes FD_SET(active_state->connection_in, setp); 105957429Smarkm 1060197679Sdes if (active_state->packet_timeout_ms > 0) { 1061197679Sdes ms_remain = active_state->packet_timeout_ms; 1062181111Sdes timeoutp = &timeout; 1063181111Sdes } 106457429Smarkm /* Wait for some data to arrive. */ 1065181111Sdes for (;;) { 1066197679Sdes if (active_state->packet_timeout_ms != -1) { 1067181111Sdes ms_to_timeval(&timeout, ms_remain); 1068181111Sdes gettimeofday(&start, NULL); 1069181111Sdes } 1070197679Sdes if ((ret = select(active_state->connection_in + 1, setp, 1071197679Sdes NULL, NULL, timeoutp)) >= 0) 1072181111Sdes break; 1073197679Sdes if (errno != EAGAIN && errno != EINTR && 1074181111Sdes errno != EWOULDBLOCK) 1075181111Sdes break; 1076197679Sdes if (active_state->packet_timeout_ms == -1) 1077181111Sdes continue; 1078181111Sdes ms_subtract_diff(&start, &ms_remain); 1079181111Sdes if (ms_remain <= 0) { 1080181111Sdes ret = 0; 1081181111Sdes break; 1082181111Sdes } 1083181111Sdes } 1084181111Sdes if (ret == 0) { 1085181111Sdes logit("Connection to %.200s timed out while " 1086181111Sdes "waiting to read", get_remote_ipaddr()); 1087181111Sdes cleanup_exit(255); 1088181111Sdes } 108957429Smarkm /* Read data from the socket. */ 1090197679Sdes do { 1091197679Sdes cont = 0; 1092197679Sdes len = roaming_read(active_state->connection_in, buf, 1093197679Sdes sizeof(buf), &cont); 1094197679Sdes } while (len == 0 && cont); 109557429Smarkm if (len == 0) { 1096124208Sdes logit("Connection closed by %.200s", get_remote_ipaddr()); 1097126274Sdes cleanup_exit(255); 109857429Smarkm } 109957429Smarkm if (len < 0) 110057429Smarkm fatal("Read from socket failed: %.100s", strerror(errno)); 110157429Smarkm /* Append it to the buffer. */ 110257429Smarkm packet_process_incoming(buf, len); 110357429Smarkm } 110457429Smarkm /* NOTREACHED */ 110557429Smarkm} 110657429Smarkm 110792555Sdesint 110892555Sdespacket_read(void) 110992555Sdes{ 111092555Sdes return packet_read_seqnr(NULL); 111192555Sdes} 111292555Sdes 111357429Smarkm/* 111457429Smarkm * Waits until a packet has been received, verifies that its type matches 111557429Smarkm * that given, and gives a fatal error and exits if there is a mismatch. 111657429Smarkm */ 111757429Smarkm 111857429Smarkmvoid 111992555Sdespacket_read_expect(int expected_type) 112057429Smarkm{ 112157429Smarkm int type; 112257429Smarkm 112392555Sdes type = packet_read(); 112457429Smarkm if (type != expected_type) 112557429Smarkm packet_disconnect("Protocol error: expected packet type %d, got %d", 112660573Skris expected_type, type); 112757429Smarkm} 112857429Smarkm 112957429Smarkm/* Checks if a full packet is available in the data received so far via 113057429Smarkm * packet_process_incoming. If so, reads the packet; otherwise returns 113157429Smarkm * SSH_MSG_NONE. This does not wait for data from the connection. 113257429Smarkm * 113357429Smarkm * SSH_MSG_DISCONNECT is handled specially here. Also, 113457429Smarkm * SSH_MSG_IGNORE messages are skipped by this function and are never returned 113557429Smarkm * to higher levels. 113657429Smarkm */ 113757429Smarkm 113892555Sdesstatic int 113992555Sdespacket_read_poll1(void) 114057429Smarkm{ 114176259Sgreen u_int len, padded_len; 114292555Sdes u_char *cp, type; 114376259Sgreen u_int checksum, stored_checksum; 114457429Smarkm 114557429Smarkm /* Check if input size is less than minimum packet size. */ 1146197679Sdes if (buffer_len(&active_state->input) < 4 + 8) 114757429Smarkm return SSH_MSG_NONE; 114857429Smarkm /* Get length of incoming packet. */ 1149197679Sdes cp = buffer_ptr(&active_state->input); 1150162852Sdes len = get_u32(cp); 115157429Smarkm if (len < 1 + 2 + 2 || len > 256 * 1024) 1152113908Sdes packet_disconnect("Bad packet length %u.", len); 115357429Smarkm padded_len = (len + 8) & ~7; 115457429Smarkm 115557429Smarkm /* Check if the packet has been entirely received. */ 1156197679Sdes if (buffer_len(&active_state->input) < 4 + padded_len) 115757429Smarkm return SSH_MSG_NONE; 115857429Smarkm 115957429Smarkm /* The entire packet is in buffer. */ 116057429Smarkm 116157429Smarkm /* Consume packet length. */ 1162197679Sdes buffer_consume(&active_state->input, 4); 116357429Smarkm 116492555Sdes /* 116592555Sdes * Cryptographic attack detector for ssh 116692555Sdes * (C)1998 CORE-SDI, Buenos Aires Argentina 116792555Sdes * Ariel Futoransky(futo@core-sdi.com) 116892555Sdes */ 1169197679Sdes if (!active_state->receive_context.plaintext) { 1170197679Sdes switch (detect_attack(buffer_ptr(&active_state->input), 1171197679Sdes padded_len)) { 1172162852Sdes case DEATTACK_DETECTED: 1173162852Sdes packet_disconnect("crc32 compensation attack: " 1174162852Sdes "network attack detected"); 1175162852Sdes case DEATTACK_DOS_DETECTED: 1176162852Sdes packet_disconnect("deattack denial of " 1177162852Sdes "service detected"); 1178162852Sdes } 1179162852Sdes } 118092555Sdes 118192555Sdes /* Decrypt data to incoming_packet. */ 1182197679Sdes buffer_clear(&active_state->incoming_packet); 1183197679Sdes cp = buffer_append_space(&active_state->incoming_packet, padded_len); 1184197679Sdes cipher_crypt(&active_state->receive_context, cp, 1185197679Sdes buffer_ptr(&active_state->input), padded_len); 118692555Sdes 1187197679Sdes buffer_consume(&active_state->input, padded_len); 118857429Smarkm 118957429Smarkm#ifdef PACKET_DEBUG 119057429Smarkm fprintf(stderr, "read_poll plain: "); 1191197679Sdes buffer_dump(&active_state->incoming_packet); 119257429Smarkm#endif 119357429Smarkm 119457429Smarkm /* Compute packet checksum. */ 1195197679Sdes checksum = ssh_crc32(buffer_ptr(&active_state->incoming_packet), 1196197679Sdes buffer_len(&active_state->incoming_packet) - 4); 119757429Smarkm 119857429Smarkm /* Skip padding. */ 1199197679Sdes buffer_consume(&active_state->incoming_packet, 8 - len % 8); 120057429Smarkm 120157429Smarkm /* Test check bytes. */ 1202197679Sdes if (len != buffer_len(&active_state->incoming_packet)) 120392555Sdes packet_disconnect("packet_read_poll1: len %d != buffer_len %d.", 1204197679Sdes len, buffer_len(&active_state->incoming_packet)); 120557429Smarkm 1206197679Sdes cp = (u_char *)buffer_ptr(&active_state->incoming_packet) + len - 4; 1207162852Sdes stored_checksum = get_u32(cp); 120857429Smarkm if (checksum != stored_checksum) 120957429Smarkm packet_disconnect("Corrupted check bytes on input."); 1210197679Sdes buffer_consume_end(&active_state->incoming_packet, 4); 121157429Smarkm 1212197679Sdes if (active_state->packet_compression) { 1213197679Sdes buffer_clear(&active_state->compression_buffer); 1214197679Sdes buffer_uncompress(&active_state->incoming_packet, 1215197679Sdes &active_state->compression_buffer); 1216197679Sdes buffer_clear(&active_state->incoming_packet); 1217197679Sdes buffer_append(&active_state->incoming_packet, 1218197679Sdes buffer_ptr(&active_state->compression_buffer), 1219197679Sdes buffer_len(&active_state->compression_buffer)); 122057429Smarkm } 1221197679Sdes active_state->p_read.packets++; 1222197679Sdes active_state->p_read.bytes += padded_len + 4; 1223197679Sdes type = buffer_get_char(&active_state->incoming_packet); 1224146998Sdes if (type < SSH_MSG_MIN || type > SSH_MSG_MAX) 1225146998Sdes packet_disconnect("Invalid ssh1 packet type: %d", type); 122692555Sdes return type; 122760573Skris} 122857429Smarkm 122992555Sdesstatic int 123092555Sdespacket_read_poll2(u_int32_t *seqnr_p) 123160573Skris{ 123276259Sgreen u_int padlen, need; 123392555Sdes u_char *macbuf, *cp, type; 1234149749Sdes u_int maclen, block_size; 123560573Skris Enc *enc = NULL; 123660573Skris Mac *mac = NULL; 123760573Skris Comp *comp = NULL; 123857429Smarkm 1239197679Sdes if (active_state->packet_discard) 1240192595Sdes return SSH_MSG_NONE; 1241192595Sdes 1242197679Sdes if (active_state->newkeys[MODE_IN] != NULL) { 1243197679Sdes enc = &active_state->newkeys[MODE_IN]->enc; 1244197679Sdes mac = &active_state->newkeys[MODE_IN]->mac; 1245197679Sdes comp = &active_state->newkeys[MODE_IN]->comp; 124657429Smarkm } 124760573Skris maclen = mac && mac->enabled ? mac->mac_len : 0; 124892555Sdes block_size = enc ? enc->block_size : 8; 124960573Skris 1250197679Sdes if (active_state->packlen == 0) { 125160573Skris /* 125260573Skris * check if input size is less than the cipher block size, 125360573Skris * decrypt first block and extract length of incoming packet 125460573Skris */ 1255197679Sdes if (buffer_len(&active_state->input) < block_size) 125660573Skris return SSH_MSG_NONE; 1257197679Sdes buffer_clear(&active_state->incoming_packet); 1258197679Sdes cp = buffer_append_space(&active_state->incoming_packet, 125960573Skris block_size); 1260197679Sdes cipher_crypt(&active_state->receive_context, cp, 1261197679Sdes buffer_ptr(&active_state->input), block_size); 1262197679Sdes cp = buffer_ptr(&active_state->incoming_packet); 1263197679Sdes active_state->packlen = get_u32(cp); 1264197679Sdes if (active_state->packlen < 1 + 4 || 1265197679Sdes active_state->packlen > PACKET_MAX_SIZE) { 1266124208Sdes#ifdef PACKET_DEBUG 1267197679Sdes buffer_dump(&active_state->incoming_packet); 1268124208Sdes#endif 1269197679Sdes logit("Bad packet length %u.", active_state->packlen); 1270197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1271192595Sdes PACKET_MAX_SIZE); 1272192595Sdes return SSH_MSG_NONE; 127360573Skris } 1274197679Sdes DBG(debug("input: packet len %u", active_state->packlen+4)); 1275197679Sdes buffer_consume(&active_state->input, block_size); 127660573Skris } 127760573Skris /* we have a partial packet of block_size bytes */ 1278197679Sdes need = 4 + active_state->packlen - block_size; 127960573Skris DBG(debug("partial packet %d, need %d, maclen %d", block_size, 128060573Skris need, maclen)); 1281192595Sdes if (need % block_size != 0) { 1282192595Sdes logit("padding error: need %d block %d mod %d", 128360573Skris need, block_size, need % block_size); 1284197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1285192595Sdes PACKET_MAX_SIZE - block_size); 1286192595Sdes return SSH_MSG_NONE; 1287192595Sdes } 128860573Skris /* 128960573Skris * check if the entire packet has been received and 129060573Skris * decrypt into incoming_packet 129160573Skris */ 1292197679Sdes if (buffer_len(&active_state->input) < need + maclen) 129360573Skris return SSH_MSG_NONE; 129460573Skris#ifdef PACKET_DEBUG 129560573Skris fprintf(stderr, "read_poll enc/full: "); 1296197679Sdes buffer_dump(&active_state->input); 129760573Skris#endif 1298197679Sdes cp = buffer_append_space(&active_state->incoming_packet, need); 1299197679Sdes cipher_crypt(&active_state->receive_context, cp, 1300197679Sdes buffer_ptr(&active_state->input), need); 1301197679Sdes buffer_consume(&active_state->input, need); 130260573Skris /* 130360573Skris * compute MAC over seqnr and packet, 130460573Skris * increment sequence number for incoming packet 130560573Skris */ 130660573Skris if (mac && mac->enabled) { 1307197679Sdes macbuf = mac_compute(mac, active_state->p_read.seqnr, 1308197679Sdes buffer_ptr(&active_state->incoming_packet), 1309197679Sdes buffer_len(&active_state->incoming_packet)); 1310215116Sdes if (timingsafe_bcmp(macbuf, buffer_ptr(&active_state->input), 1311197679Sdes mac->mac_len) != 0) { 1312192595Sdes logit("Corrupted MAC on input."); 1313192595Sdes if (need > PACKET_MAX_SIZE) 1314192595Sdes fatal("internal error need %d", need); 1315197679Sdes packet_start_discard(enc, mac, active_state->packlen, 1316192595Sdes PACKET_MAX_SIZE - need); 1317192595Sdes return SSH_MSG_NONE; 1318192595Sdes } 1319192595Sdes 1320197679Sdes DBG(debug("MAC #%d ok", active_state->p_read.seqnr)); 1321197679Sdes buffer_consume(&active_state->input, mac->mac_len); 132260573Skris } 1323192595Sdes /* XXX now it's safe to use fatal/packet_disconnect */ 132492555Sdes if (seqnr_p != NULL) 1325197679Sdes *seqnr_p = active_state->p_read.seqnr; 1326197679Sdes if (++active_state->p_read.seqnr == 0) 1327124208Sdes logit("incoming seqnr wraps around"); 1328197679Sdes if (++active_state->p_read.packets == 0) 1329124208Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 1330124208Sdes fatal("XXX too many packets with same key"); 1331197679Sdes active_state->p_read.blocks += (active_state->packlen + 4) / block_size; 1332197679Sdes active_state->p_read.bytes += active_state->packlen + 4; 133360573Skris 133460573Skris /* get padlen */ 1335197679Sdes cp = buffer_ptr(&active_state->incoming_packet); 133692555Sdes padlen = cp[4]; 133760573Skris DBG(debug("input: padlen %d", padlen)); 133860573Skris if (padlen < 4) 133960573Skris packet_disconnect("Corrupted padlen %d on input.", padlen); 134060573Skris 134160573Skris /* skip packet size + padlen, discard padding */ 1342197679Sdes buffer_consume(&active_state->incoming_packet, 4 + 1); 1343197679Sdes buffer_consume_end(&active_state->incoming_packet, padlen); 134460573Skris 1345197679Sdes DBG(debug("input: len before de-compress %d", 1346197679Sdes buffer_len(&active_state->incoming_packet))); 134760573Skris if (comp && comp->enabled) { 1348197679Sdes buffer_clear(&active_state->compression_buffer); 1349197679Sdes buffer_uncompress(&active_state->incoming_packet, 1350197679Sdes &active_state->compression_buffer); 1351197679Sdes buffer_clear(&active_state->incoming_packet); 1352197679Sdes buffer_append(&active_state->incoming_packet, 1353197679Sdes buffer_ptr(&active_state->compression_buffer), 1354197679Sdes buffer_len(&active_state->compression_buffer)); 1355106121Sdes DBG(debug("input: len after de-compress %d", 1356197679Sdes buffer_len(&active_state->incoming_packet))); 135760573Skris } 135860573Skris /* 135960573Skris * get packet type, implies consume. 136060573Skris * return length of payload (without type field) 136160573Skris */ 1362197679Sdes type = buffer_get_char(&active_state->incoming_packet); 1363146998Sdes if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN) 1364146998Sdes packet_disconnect("Invalid ssh2 packet type: %d", type); 136576259Sgreen if (type == SSH2_MSG_NEWKEYS) 136676259Sgreen set_newkeys(MODE_IN); 1367197679Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && 1368197679Sdes !active_state->server_side) 1369149749Sdes packet_enable_delayed_compress(); 137060573Skris#ifdef PACKET_DEBUG 137176259Sgreen fprintf(stderr, "read/plain[%d]:\r\n", type); 1372197679Sdes buffer_dump(&active_state->incoming_packet); 137360573Skris#endif 137492555Sdes /* reset for next packet */ 1375197679Sdes active_state->packlen = 0; 137692555Sdes return type; 137757429Smarkm} 137857429Smarkm 137960573Skrisint 138092555Sdespacket_read_poll_seqnr(u_int32_t *seqnr_p) 138160573Skris{ 138299060Sdes u_int reason, seqnr; 138392555Sdes u_char type; 138460573Skris char *msg; 138592555Sdes 138660573Skris for (;;) { 138792555Sdes if (compat20) { 138892555Sdes type = packet_read_poll2(seqnr_p); 1389181111Sdes if (type) { 1390197679Sdes active_state->keep_alive_timeouts = 0; 139160573Skris DBG(debug("received packet type %d", type)); 1392181111Sdes } 139392555Sdes switch (type) { 139460573Skris case SSH2_MSG_IGNORE: 1395181111Sdes debug3("Received SSH2_MSG_IGNORE"); 139660573Skris break; 139760573Skris case SSH2_MSG_DEBUG: 139860573Skris packet_get_char(); 139960573Skris msg = packet_get_string(NULL); 140060573Skris debug("Remote: %.900s", msg); 140160573Skris xfree(msg); 140260573Skris msg = packet_get_string(NULL); 140360573Skris xfree(msg); 140460573Skris break; 140560573Skris case SSH2_MSG_DISCONNECT: 140660573Skris reason = packet_get_int(); 140760573Skris msg = packet_get_string(NULL); 1408124208Sdes logit("Received disconnect from %s: %u: %.400s", 140999060Sdes get_remote_ipaddr(), reason, msg); 141060573Skris xfree(msg); 1411126274Sdes cleanup_exit(255); 141260573Skris break; 141392555Sdes case SSH2_MSG_UNIMPLEMENTED: 141492555Sdes seqnr = packet_get_int(); 141599060Sdes debug("Received SSH2_MSG_UNIMPLEMENTED for %u", 141699060Sdes seqnr); 141792555Sdes break; 141860573Skris default: 141960573Skris return type; 142076259Sgreen } 142160573Skris } else { 142292555Sdes type = packet_read_poll1(); 142392555Sdes switch (type) { 142460573Skris case SSH_MSG_IGNORE: 142560573Skris break; 142660573Skris case SSH_MSG_DEBUG: 142760573Skris msg = packet_get_string(NULL); 142860573Skris debug("Remote: %.900s", msg); 142960573Skris xfree(msg); 143060573Skris break; 143160573Skris case SSH_MSG_DISCONNECT: 143260573Skris msg = packet_get_string(NULL); 1433124208Sdes logit("Received disconnect from %s: %.400s", 143499060Sdes get_remote_ipaddr(), msg); 1435126274Sdes cleanup_exit(255); 143660573Skris break; 143760573Skris default: 143892555Sdes if (type) 143960573Skris DBG(debug("received packet type %d", type)); 144060573Skris return type; 144176259Sgreen } 144260573Skris } 144360573Skris } 144460573Skris} 144560573Skris 144692555Sdesint 144792555Sdespacket_read_poll(void) 144892555Sdes{ 144992555Sdes return packet_read_poll_seqnr(NULL); 145092555Sdes} 145192555Sdes 145257429Smarkm/* 145357429Smarkm * Buffers the given amount of input characters. This is intended to be used 145457429Smarkm * together with packet_read_poll. 145557429Smarkm */ 145657429Smarkm 145757429Smarkmvoid 145876259Sgreenpacket_process_incoming(const char *buf, u_int len) 145957429Smarkm{ 1460197679Sdes if (active_state->packet_discard) { 1461197679Sdes active_state->keep_alive_timeouts = 0; /* ?? */ 1462197679Sdes if (len >= active_state->packet_discard) 1463192595Sdes packet_stop_discard(); 1464197679Sdes active_state->packet_discard -= len; 1465192595Sdes return; 1466192595Sdes } 1467197679Sdes buffer_append(&active_state->input, buf, len); 146857429Smarkm} 146957429Smarkm 147057429Smarkm/* Returns a character from the packet. */ 147157429Smarkm 147276259Sgreenu_int 147392555Sdespacket_get_char(void) 147457429Smarkm{ 147557429Smarkm char ch; 1476106121Sdes 1477197679Sdes buffer_get(&active_state->incoming_packet, &ch, 1); 147876259Sgreen return (u_char) ch; 147957429Smarkm} 148057429Smarkm 148157429Smarkm/* Returns an integer from the packet data. */ 148257429Smarkm 148376259Sgreenu_int 148492555Sdespacket_get_int(void) 148557429Smarkm{ 1486197679Sdes return buffer_get_int(&active_state->incoming_packet); 148757429Smarkm} 148857429Smarkm 1489197679Sdes/* Returns an 64 bit integer from the packet data. */ 1490197679Sdes 1491197679Sdesu_int64_t 1492197679Sdespacket_get_int64(void) 1493197679Sdes{ 1494197679Sdes return buffer_get_int64(&active_state->incoming_packet); 1495197679Sdes} 1496197679Sdes 149757429Smarkm/* 149857429Smarkm * Returns an arbitrary precision integer from the packet data. The integer 149957429Smarkm * must have been initialized before this call. 150057429Smarkm */ 150157429Smarkm 150257429Smarkmvoid 150392555Sdespacket_get_bignum(BIGNUM * value) 150457429Smarkm{ 1505197679Sdes buffer_get_bignum(&active_state->incoming_packet, value); 150657429Smarkm} 150757429Smarkm 150860573Skrisvoid 150992555Sdespacket_get_bignum2(BIGNUM * value) 151060573Skris{ 1511197679Sdes buffer_get_bignum2(&active_state->incoming_packet, value); 151260573Skris} 151360573Skris 151492555Sdesvoid * 1515149749Sdespacket_get_raw(u_int *length_ptr) 151660573Skris{ 1517197679Sdes u_int bytes = buffer_len(&active_state->incoming_packet); 1518106121Sdes 151960573Skris if (length_ptr != NULL) 152060573Skris *length_ptr = bytes; 1521197679Sdes return buffer_ptr(&active_state->incoming_packet); 152260573Skris} 152360573Skris 152460573Skrisint 152560573Skrispacket_remaining(void) 152660573Skris{ 1527197679Sdes return buffer_len(&active_state->incoming_packet); 152860573Skris} 152960573Skris 153057429Smarkm/* 153157429Smarkm * Returns a string from the packet data. The string is allocated using 153257429Smarkm * xmalloc; it is the responsibility of the calling program to free it when 153357429Smarkm * no longer needed. The length_ptr argument may be NULL, or point to an 153457429Smarkm * integer into which the length of the string is stored. 153557429Smarkm */ 153657429Smarkm 153792555Sdesvoid * 153876259Sgreenpacket_get_string(u_int *length_ptr) 153957429Smarkm{ 1540197679Sdes return buffer_get_string(&active_state->incoming_packet, length_ptr); 154157429Smarkm} 154257429Smarkm 1543181111Sdesvoid * 1544181111Sdespacket_get_string_ptr(u_int *length_ptr) 1545181111Sdes{ 1546197679Sdes return buffer_get_string_ptr(&active_state->incoming_packet, length_ptr); 1547181111Sdes} 1548181111Sdes 154957429Smarkm/* 155057429Smarkm * Sends a diagnostic message from the server to the client. This message 155157429Smarkm * can be sent at any time (but not while constructing another message). The 155257429Smarkm * message is printed immediately, but only if the client is being executed 155357429Smarkm * in verbose mode. These messages are primarily intended to ease debugging 155457429Smarkm * authentication problems. The length of the formatted message must not 155557429Smarkm * exceed 1024 bytes. This will automatically call packet_write_wait. 155657429Smarkm */ 155757429Smarkm 155857429Smarkmvoid 155957429Smarkmpacket_send_debug(const char *fmt,...) 156057429Smarkm{ 156157429Smarkm char buf[1024]; 156257429Smarkm va_list args; 156357429Smarkm 156476259Sgreen if (compat20 && (datafellows & SSH_BUG_DEBUG)) 156576259Sgreen return; 156676259Sgreen 156757429Smarkm va_start(args, fmt); 156857429Smarkm vsnprintf(buf, sizeof(buf), fmt, args); 156957429Smarkm va_end(args); 157057429Smarkm 157160573Skris if (compat20) { 157260573Skris packet_start(SSH2_MSG_DEBUG); 157360573Skris packet_put_char(0); /* bool: always display */ 157460573Skris packet_put_cstring(buf); 157560573Skris packet_put_cstring(""); 157660573Skris } else { 157760573Skris packet_start(SSH_MSG_DEBUG); 157860573Skris packet_put_cstring(buf); 157960573Skris } 158057429Smarkm packet_send(); 158157429Smarkm packet_write_wait(); 158257429Smarkm} 158357429Smarkm 158457429Smarkm/* 158557429Smarkm * Logs the error plus constructs and sends a disconnect packet, closes the 158657429Smarkm * connection, and exits. This function never returns. The error message 158757429Smarkm * should not contain a newline. The length of the formatted message must 158857429Smarkm * not exceed 1024 bytes. 158957429Smarkm */ 159057429Smarkm 159157429Smarkmvoid 159257429Smarkmpacket_disconnect(const char *fmt,...) 159357429Smarkm{ 159457429Smarkm char buf[1024]; 159557429Smarkm va_list args; 159657429Smarkm static int disconnecting = 0; 1597106121Sdes 159857429Smarkm if (disconnecting) /* Guard against recursive invocations. */ 159957429Smarkm fatal("packet_disconnect called recursively."); 160057429Smarkm disconnecting = 1; 160157429Smarkm 160257429Smarkm /* 160357429Smarkm * Format the message. Note that the caller must make sure the 160457429Smarkm * message is of limited size. 160557429Smarkm */ 160657429Smarkm va_start(args, fmt); 160757429Smarkm vsnprintf(buf, sizeof(buf), fmt, args); 160857429Smarkm va_end(args); 160957429Smarkm 1610113908Sdes /* Display the error locally */ 1611124208Sdes logit("Disconnecting: %.100s", buf); 1612113908Sdes 161357429Smarkm /* Send the disconnect message to the other side, and wait for it to get sent. */ 161460573Skris if (compat20) { 161560573Skris packet_start(SSH2_MSG_DISCONNECT); 161660573Skris packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); 161760573Skris packet_put_cstring(buf); 161860573Skris packet_put_cstring(""); 161960573Skris } else { 162060573Skris packet_start(SSH_MSG_DISCONNECT); 162192555Sdes packet_put_cstring(buf); 162260573Skris } 162357429Smarkm packet_send(); 162457429Smarkm packet_write_wait(); 162557429Smarkm 162657429Smarkm /* Stop listening for connections. */ 162792555Sdes channel_close_all(); 162857429Smarkm 162957429Smarkm /* Close the connection. */ 163057429Smarkm packet_close(); 1631126274Sdes cleanup_exit(255); 163257429Smarkm} 163357429Smarkm 163457429Smarkm/* Checks if there is any buffered output, and tries to write some of the output. */ 163557429Smarkm 163657429Smarkmvoid 163792555Sdespacket_write_poll(void) 163857429Smarkm{ 1639197679Sdes int len = buffer_len(&active_state->output); 1640197679Sdes int cont; 1641106121Sdes 164257429Smarkm if (len > 0) { 1643197679Sdes cont = 0; 1644197679Sdes len = roaming_write(active_state->connection_out, 1645197679Sdes buffer_ptr(&active_state->output), len, &cont); 1646181111Sdes if (len == -1) { 1647181111Sdes if (errno == EINTR || errno == EAGAIN || 1648181111Sdes errno == EWOULDBLOCK) 164957429Smarkm return; 1650181111Sdes fatal("Write failed: %.100s", strerror(errno)); 165157429Smarkm } 1652197679Sdes if (len == 0 && !cont) 1653181111Sdes fatal("Write connection closed"); 1654197679Sdes buffer_consume(&active_state->output, len); 165557429Smarkm } 165657429Smarkm} 165757429Smarkm 165857429Smarkm/* 165957429Smarkm * Calls packet_write_poll repeatedly until all pending output data has been 166057429Smarkm * written. 166157429Smarkm */ 166257429Smarkm 166357429Smarkmvoid 166492555Sdespacket_write_wait(void) 166557429Smarkm{ 166676259Sgreen fd_set *setp; 1667181111Sdes int ret, ms_remain; 1668181111Sdes struct timeval start, timeout, *timeoutp = NULL; 166976259Sgreen 1670197679Sdes setp = (fd_set *)xcalloc(howmany(active_state->connection_out + 1, 1671197679Sdes NFDBITS), sizeof(fd_mask)); 167257429Smarkm packet_write_poll(); 167357429Smarkm while (packet_have_data_to_write()) { 1674197679Sdes memset(setp, 0, howmany(active_state->connection_out + 1, 1675197679Sdes NFDBITS) * sizeof(fd_mask)); 1676197679Sdes FD_SET(active_state->connection_out, setp); 1677181111Sdes 1678197679Sdes if (active_state->packet_timeout_ms > 0) { 1679197679Sdes ms_remain = active_state->packet_timeout_ms; 1680181111Sdes timeoutp = &timeout; 1681181111Sdes } 1682181111Sdes for (;;) { 1683197679Sdes if (active_state->packet_timeout_ms != -1) { 1684181111Sdes ms_to_timeval(&timeout, ms_remain); 1685181111Sdes gettimeofday(&start, NULL); 1686181111Sdes } 1687197679Sdes if ((ret = select(active_state->connection_out + 1, 1688197679Sdes NULL, setp, NULL, timeoutp)) >= 0) 1689181111Sdes break; 1690197679Sdes if (errno != EAGAIN && errno != EINTR && 1691181111Sdes errno != EWOULDBLOCK) 1692181111Sdes break; 1693197679Sdes if (active_state->packet_timeout_ms == -1) 1694181111Sdes continue; 1695181111Sdes ms_subtract_diff(&start, &ms_remain); 1696181111Sdes if (ms_remain <= 0) { 1697181111Sdes ret = 0; 1698181111Sdes break; 1699181111Sdes } 1700181111Sdes } 1701181111Sdes if (ret == 0) { 1702181111Sdes logit("Connection to %.200s timed out while " 1703181111Sdes "waiting to write", get_remote_ipaddr()); 1704181111Sdes cleanup_exit(255); 1705181111Sdes } 170657429Smarkm packet_write_poll(); 170757429Smarkm } 170876259Sgreen xfree(setp); 170957429Smarkm} 171057429Smarkm 171157429Smarkm/* Returns true if there is buffered data to write to the connection. */ 171257429Smarkm 171357429Smarkmint 171492555Sdespacket_have_data_to_write(void) 171557429Smarkm{ 1716197679Sdes return buffer_len(&active_state->output) != 0; 171757429Smarkm} 171857429Smarkm 171957429Smarkm/* Returns true if there is not too much data to write to the connection. */ 172057429Smarkm 172157429Smarkmint 172292555Sdespacket_not_very_much_data_to_write(void) 172357429Smarkm{ 1724197679Sdes if (active_state->interactive_mode) 1725197679Sdes return buffer_len(&active_state->output) < 16384; 172657429Smarkm else 1727197679Sdes return buffer_len(&active_state->output) < 128 * 1024; 172857429Smarkm} 172957429Smarkm 1730113908Sdesstatic void 1731113908Sdespacket_set_tos(int interactive) 1732113908Sdes{ 1733126274Sdes#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) 1734113908Sdes int tos = interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT; 1735113908Sdes 1736113908Sdes if (!packet_connection_is_on_socket() || 1737113908Sdes !packet_connection_is_ipv4()) 1738113908Sdes return; 1739197679Sdes if (setsockopt(active_state->connection_in, IPPROTO_IP, IP_TOS, &tos, 1740113908Sdes sizeof(tos)) < 0) 1741113908Sdes error("setsockopt IP_TOS %d: %.100s:", 1742113908Sdes tos, strerror(errno)); 1743126274Sdes#endif 1744113908Sdes} 1745113908Sdes 174657429Smarkm/* Informs that the current session is interactive. Sets IP flags for that. */ 174757429Smarkm 174857429Smarkmvoid 174976259Sgreenpacket_set_interactive(int interactive) 175057429Smarkm{ 1751197679Sdes if (active_state->set_interactive_called) 175276259Sgreen return; 1753197679Sdes active_state->set_interactive_called = 1; 175476259Sgreen 175557429Smarkm /* Record that we are in interactive mode. */ 1756197679Sdes active_state->interactive_mode = interactive; 175757429Smarkm 175857429Smarkm /* Only set socket options if using a socket. */ 175957429Smarkm if (!packet_connection_is_on_socket()) 1760116791Sdes return; 1761197679Sdes set_nodelay(active_state->connection_in); 1762113908Sdes packet_set_tos(interactive); 176357429Smarkm} 176457429Smarkm 176557429Smarkm/* Returns true if the current connection is interactive. */ 176657429Smarkm 176757429Smarkmint 176892555Sdespacket_is_interactive(void) 176957429Smarkm{ 1770197679Sdes return active_state->interactive_mode; 177157429Smarkm} 177257429Smarkm 1773137015Sdesint 1774124208Sdespacket_set_maxsize(u_int s) 177557429Smarkm{ 1776197679Sdes if (active_state->set_maxsize_called) { 1777124208Sdes logit("packet_set_maxsize: called twice: old %d new %d", 1778197679Sdes active_state->max_packet_size, s); 177957429Smarkm return -1; 178057429Smarkm } 178157429Smarkm if (s < 4 * 1024 || s > 1024 * 1024) { 1782124208Sdes logit("packet_set_maxsize: bad size %d", s); 178357429Smarkm return -1; 178457429Smarkm } 1785197679Sdes active_state->set_maxsize_called = 1; 178692555Sdes debug("packet_set_maxsize: setting to %d", s); 1787197679Sdes active_state->max_packet_size = s; 178857429Smarkm return s; 178957429Smarkm} 179076259Sgreen 1791197679Sdesint 1792197679Sdespacket_inc_alive_timeouts(void) 1793197679Sdes{ 1794197679Sdes return ++active_state->keep_alive_timeouts; 1795197679Sdes} 1796197679Sdes 1797197679Sdesvoid 1798197679Sdespacket_set_alive_timeouts(int ka) 1799197679Sdes{ 1800197679Sdes active_state->keep_alive_timeouts = ka; 1801197679Sdes} 1802197679Sdes 1803197679Sdesu_int 1804197679Sdespacket_get_maxsize(void) 1805197679Sdes{ 1806197679Sdes return active_state->max_packet_size; 1807197679Sdes} 1808197679Sdes 180992555Sdes/* roundup current message to pad bytes */ 181092555Sdesvoid 181192555Sdespacket_add_padding(u_char pad) 181292555Sdes{ 1813197679Sdes active_state->extra_pad = pad; 181492555Sdes} 181592555Sdes 181676259Sgreen/* 181776259Sgreen * 9.2. Ignored Data Message 181876259Sgreen * 181976259Sgreen * byte SSH_MSG_IGNORE 182076259Sgreen * string data 182176259Sgreen * 182276259Sgreen * All implementations MUST understand (and ignore) this message at any 182376259Sgreen * time (after receiving the protocol version). No implementation is 182476259Sgreen * required to send them. This message can be used as an additional 182576259Sgreen * protection measure against advanced traffic analysis techniques. 182676259Sgreen */ 182776259Sgreenvoid 182876259Sgreenpacket_send_ignore(int nbytes) 182976259Sgreen{ 1830137015Sdes u_int32_t rnd = 0; 183176259Sgreen int i; 183276259Sgreen 183376259Sgreen packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); 183476259Sgreen packet_put_int(nbytes); 183592555Sdes for (i = 0; i < nbytes; i++) { 183676259Sgreen if (i % 4 == 0) 1837137015Sdes rnd = arc4random(); 1838162852Sdes packet_put_char((u_char)rnd & 0xff); 1839137015Sdes rnd >>= 8; 184076259Sgreen } 184176259Sgreen} 1842124208Sdes 1843137015Sdes#define MAX_PACKETS (1U<<31) 1844124208Sdesint 1845124208Sdespacket_need_rekeying(void) 1846124208Sdes{ 1847124208Sdes if (datafellows & SSH_BUG_NOREKEY) 1848124208Sdes return 0; 1849124208Sdes return 1850197679Sdes (active_state->p_send.packets > MAX_PACKETS) || 1851197679Sdes (active_state->p_read.packets > MAX_PACKETS) || 1852197679Sdes (active_state->max_blocks_out && 1853197679Sdes (active_state->p_send.blocks > active_state->max_blocks_out)) || 1854197679Sdes (active_state->max_blocks_in && 1855197679Sdes (active_state->p_read.blocks > active_state->max_blocks_in)); 1856124208Sdes} 1857124208Sdes 1858124208Sdesvoid 1859124208Sdespacket_set_rekey_limit(u_int32_t bytes) 1860124208Sdes{ 1861197679Sdes active_state->rekey_limit = bytes; 1862124208Sdes} 1863149749Sdes 1864149749Sdesvoid 1865149749Sdespacket_set_server(void) 1866149749Sdes{ 1867197679Sdes active_state->server_side = 1; 1868149749Sdes} 1869149749Sdes 1870149749Sdesvoid 1871149749Sdespacket_set_authenticated(void) 1872149749Sdes{ 1873197679Sdes active_state->after_authentication = 1; 1874149749Sdes} 1875197679Sdes 1876197679Sdesvoid * 1877197679Sdespacket_get_input(void) 1878197679Sdes{ 1879197679Sdes return (void *)&active_state->input; 1880197679Sdes} 1881197679Sdes 1882197679Sdesvoid * 1883197679Sdespacket_get_output(void) 1884197679Sdes{ 1885197679Sdes return (void *)&active_state->output; 1886197679Sdes} 1887197679Sdes 1888197679Sdesvoid * 1889197679Sdespacket_get_newkeys(int mode) 1890197679Sdes{ 1891197679Sdes return (void *)active_state->newkeys[mode]; 1892197679Sdes} 1893197679Sdes 1894197679Sdes/* 1895197679Sdes * Save the state for the real connection, and use a separate state when 1896197679Sdes * resuming a suspended connection. 1897197679Sdes */ 1898197679Sdesvoid 1899197679Sdespacket_backup_state(void) 1900197679Sdes{ 1901197679Sdes struct session_state *tmp; 1902197679Sdes 1903197679Sdes close(active_state->connection_in); 1904197679Sdes active_state->connection_in = -1; 1905197679Sdes close(active_state->connection_out); 1906197679Sdes active_state->connection_out = -1; 1907197679Sdes if (backup_state) 1908197679Sdes tmp = backup_state; 1909197679Sdes else 1910197679Sdes tmp = alloc_session_state(); 1911197679Sdes backup_state = active_state; 1912197679Sdes active_state = tmp; 1913197679Sdes} 1914197679Sdes 1915197679Sdes/* 1916197679Sdes * Swap in the old state when resuming a connecion. 1917197679Sdes */ 1918197679Sdesvoid 1919197679Sdespacket_restore_state(void) 1920197679Sdes{ 1921197679Sdes struct session_state *tmp; 1922197679Sdes void *buf; 1923197679Sdes u_int len; 1924197679Sdes 1925197679Sdes tmp = backup_state; 1926197679Sdes backup_state = active_state; 1927197679Sdes active_state = tmp; 1928197679Sdes active_state->connection_in = backup_state->connection_in; 1929197679Sdes backup_state->connection_in = -1; 1930197679Sdes active_state->connection_out = backup_state->connection_out; 1931197679Sdes backup_state->connection_out = -1; 1932197679Sdes len = buffer_len(&backup_state->input); 1933197679Sdes if (len > 0) { 1934197679Sdes buf = buffer_ptr(&backup_state->input); 1935197679Sdes buffer_append(&active_state->input, buf, len); 1936197679Sdes buffer_clear(&backup_state->input); 1937197679Sdes add_recv_bytes(len); 1938197679Sdes } 1939197679Sdes} 1940