packet.c revision 181111
198937Sdes/* $OpenBSD: packet.c,v 1.157 2008/07/10 18:08:11 markus Exp $ */ 298937Sdes/* 398937Sdes * Author: Tatu Ylonen <ylo@cs.hut.fi> 498937Sdes * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 598937Sdes * All rights reserved 698937Sdes * This file contains code implementing the packet protocol and communication 798937Sdes * with the other side. This same code is used both on client and server side. 898937Sdes * 998937Sdes * As far as I am concerned, the code I have written for this software 1098937Sdes * can be used freely for any purpose. Any derived versions of this 1198937Sdes * software must be clearly marked as such, and if the derived work is 1298937Sdes * incompatible with the protocol description in the RFC file, it must be 1398937Sdes * called by a name other than "ssh" or "Secure Shell". 1498937Sdes * 1598937Sdes * 1698937Sdes * SSH2 packet format added by Markus Friedl. 1798937Sdes * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 1898937Sdes * 1998937Sdes * Redistribution and use in source and binary forms, with or without 2098937Sdes * modification, are permitted provided that the following conditions 2198937Sdes * are met: 2298937Sdes * 1. Redistributions of source code must retain the above copyright 2398937Sdes * notice, this list of conditions and the following disclaimer. 2498937Sdes * 2. Redistributions in binary form must reproduce the above copyright 2598937Sdes * notice, this list of conditions and the following disclaimer in the 2698937Sdes * documentation and/or other materials provided with the distribution. 2798937Sdes * 28147005Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 29147005Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 30147005Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 31147005Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 32147005Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 33147005Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 34147005Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 35147005Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 36147005Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 37147005Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38147005Sdes */ 39147005Sdes 40147005Sdes#include "includes.h" 41147005Sdes 42147005Sdes#include <sys/types.h> 43147005Sdes#include "openbsd-compat/sys-queue.h" 44147005Sdes#include <sys/param.h> 45147005Sdes#include <sys/socket.h> 46147005Sdes#ifdef HAVE_SYS_TIME_H 47147005Sdes# include <sys/time.h> 48147005Sdes#endif 4998937Sdes 5098937Sdes#include <netinet/in.h> 5198937Sdes#include <netinet/ip.h> 5298937Sdes#include <arpa/inet.h> 5398937Sdes 54147005Sdes#include <errno.h> 55147005Sdes#include <stdarg.h> 56147005Sdes#include <stdio.h> 57147005Sdes#include <stdlib.h> 58147005Sdes#include <string.h> 59147005Sdes#include <unistd.h> 60147005Sdes#include <signal.h> 61147005Sdes 62147005Sdes#include "xmalloc.h" 63147005Sdes#include "buffer.h" 64147005Sdes#include "packet.h" 65147005Sdes#include "crc32.h" 66147005Sdes#include "compress.h" 67147005Sdes#include "deattack.h" 68147005Sdes#include "channels.h" 69147005Sdes#include "compat.h" 70147005Sdes#include "ssh1.h" 71147005Sdes#include "ssh2.h" 72147005Sdes#include "cipher.h" 73147005Sdes#include "key.h" 74147005Sdes#include "kex.h" 75147005Sdes#include "mac.h" 76147005Sdes#include "log.h" 77147005Sdes#include "canohost.h" 78147005Sdes#include "misc.h" 79147005Sdes#include "ssh.h" 80147005Sdes 81147005Sdes#ifdef PACKET_DEBUG 82147005Sdes#define DBG(x) x 83147005Sdes#else 84147005Sdes#define DBG(x) 85147005Sdes#endif 86147005Sdes 87147005Sdes/* 88147005Sdes * This variable contains the file descriptors used for communicating with 89147005Sdes * the other side. connection_in is used for reading; connection_out for 90147005Sdes * writing. These can be the same descriptor, in which case it is assumed to 91147005Sdes * be a socket. 92147005Sdes */ 93147005Sdesstatic int connection_in = -1; 94147005Sdesstatic int connection_out = -1; 95147005Sdes 96147005Sdes/* Protocol flags for the remote side. */ 97147005Sdesstatic u_int remote_protocol_flags = 0; 98147005Sdes 99147005Sdes/* Encryption context for receiving data. This is only used for decryption. */ 100147005Sdesstatic CipherContext receive_context; 101147005Sdes 102147005Sdes/* Encryption context for sending data. This is only used for encryption. */ 103147005Sdesstatic CipherContext send_context; 104147005Sdes 105147005Sdes/* Buffer for raw input data from the socket. */ 106147005SdesBuffer input; 107147005Sdes 108147005Sdes/* Buffer for raw output data going to the socket. */ 109147005SdesBuffer output; 110147005Sdes 111147005Sdes/* Buffer for the partial outgoing packet being constructed. */ 112147005Sdesstatic Buffer outgoing_packet; 113147005Sdes 114147005Sdes/* Buffer for the incoming packet currently being processed. */ 115147005Sdesstatic Buffer incoming_packet; 116147005Sdes 117147005Sdes/* Scratch buffer for packet compression/decompression. */ 118147005Sdesstatic Buffer compression_buffer; 119147005Sdesstatic int compression_buffer_ready = 0; 120147005Sdes 121147005Sdes/* Flag indicating whether packet compression/decompression is enabled. */ 122147005Sdesstatic int packet_compression = 0; 123147005Sdes 124147005Sdes/* default maximum packet size */ 125147005Sdesu_int max_packet_size = 32768; 126147005Sdes 127147005Sdes/* Flag indicating whether this module has been initialized. */ 128147005Sdesstatic int initialized = 0; 129147005Sdes 130147005Sdes/* Set to true if the connection is interactive. */ 131147005Sdesstatic int interactive_mode = 0; 132147005Sdes 133147005Sdes/* Set to true if we are the server side. */ 134147005Sdesstatic int server_side = 0; 135147005Sdes 136147005Sdes/* Set to true if we are authenticated. */ 137147005Sdesstatic int after_authentication = 0; 138147005Sdes 139147005Sdesint keep_alive_timeouts = 0; 140147005Sdes 141147005Sdes/* Set to the maximum time that we will wait to send or receive a packet */ 142147005Sdesstatic int packet_timeout_ms = -1; 143147005Sdes 144147005Sdes/* Session key information for Encryption and MAC */ 145147005SdesNewkeys *newkeys[MODE_MAX]; 146147005Sdesstatic struct packet_state { 14798937Sdes u_int32_t seqnr; 14898937Sdes u_int32_t packets; 14998937Sdes u_int64_t blocks; 150162856Sdes u_int64_t bytes; 151162856Sdes} p_read, p_send; 152162856Sdes 153162856Sdesstatic u_int64_t max_blocks_in, max_blocks_out; 154162856Sdesstatic u_int32_t rekey_limit; 155162856Sdes 156162856Sdes/* Session key for protocol v1 */ 157162856Sdesstatic u_char ssh1_key[SSH_SESSION_KEY_LENGTH]; 158162856Sdesstatic u_int ssh1_keylen; 159162856Sdes 160162856Sdes/* roundup current message to extra_pad bytes */ 161162856Sdesstatic u_char extra_pad = 0; 162162856Sdes 163162856Sdesstruct packet { 164181111Sdes TAILQ_ENTRY(packet) next; 165162856Sdes u_char type; 166162856Sdes Buffer payload; 167162856Sdes}; 168162856SdesTAILQ_HEAD(, packet) outgoing; 169162856Sdes 17098937Sdes/* 17198937Sdes * Sets the descriptors used for communication. Disables encryption until 17298937Sdes * packet_set_encryption_key is called. 17398937Sdes */ 174147005Sdesvoid 175147005Sdespacket_set_connection(int fd_in, int fd_out) 176147005Sdes{ 177147005Sdes Cipher *none = cipher_by_name("none"); 17898937Sdes 17998937Sdes if (none == NULL) 180147005Sdes fatal("packet_set_connection: cannot load cipher 'none'"); 18198937Sdes connection_in = fd_in; 18298937Sdes connection_out = fd_out; 18398937Sdes cipher_init(&send_context, none, (const u_char *)"", 18498937Sdes 0, NULL, 0, CIPHER_ENCRYPT); 18598937Sdes cipher_init(&receive_context, none, (const u_char *)"", 18698937Sdes 0, NULL, 0, CIPHER_DECRYPT); 18798937Sdes newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; 18898937Sdes if (!initialized) { 18998937Sdes initialized = 1; 19098937Sdes buffer_init(&input); 19198937Sdes buffer_init(&output); 19298937Sdes buffer_init(&outgoing_packet); 19398937Sdes buffer_init(&incoming_packet); 19498937Sdes TAILQ_INIT(&outgoing); 19598937Sdes p_send.packets = p_read.packets = 0; 19698937Sdes } 19798937Sdes} 19898937Sdes 19998937Sdesvoid 20098937Sdespacket_set_timeout(int timeout, int count) 20198937Sdes{ 20298937Sdes if (timeout == 0 || count == 0) { 20398937Sdes packet_timeout_ms = -1; 20498937Sdes return; 20598937Sdes } 206202213Sed if ((INT_MAX / 1000) / count < timeout) 20798937Sdes packet_timeout_ms = INT_MAX; 20898937Sdes else 20998937Sdes packet_timeout_ms = timeout * count * 1000; 210147005Sdes} 211147005Sdes 21298937Sdes/* Returns 1 if remote host is connected via socket, 0 if not. */ 213147005Sdes 21498937Sdesint 21598937Sdespacket_connection_is_on_socket(void) 21698937Sdes{ 21798937Sdes struct sockaddr_storage from, to; 21898937Sdes socklen_t fromlen, tolen; 219147005Sdes 220147005Sdes /* filedescriptors in and out are the same, so it's a socket */ 22198937Sdes if (connection_in == connection_out) 22298937Sdes return 1; 22398937Sdes fromlen = sizeof(from); 22498937Sdes memset(&from, 0, sizeof(from)); 22598937Sdes if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0) 22698937Sdes return 0; 22798937Sdes tolen = sizeof(to); 22898937Sdes memset(&to, 0, sizeof(to)); 22998937Sdes if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0) 230147005Sdes return 0; 23198937Sdes if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0) 23298937Sdes return 0; 233147005Sdes if (from.ss_family != AF_INET && from.ss_family != AF_INET6) 23498937Sdes return 0; 23598937Sdes return 1; 23698937Sdes} 237147005Sdes 238147005Sdes/* 23998937Sdes * Exports an IV from the CipherContext required to export the key 24098937Sdes * state back from the unprivileged child to the privileged parent 24198937Sdes * process. 24298937Sdes */ 24398937Sdes 24498937Sdesvoid 24598937Sdespacket_get_keyiv(int mode, u_char *iv, u_int len) 24698937Sdes{ 24798937Sdes CipherContext *cc; 24898937Sdes 24998937Sdes if (mode == MODE_OUT) 250147005Sdes cc = &send_context; 25198937Sdes else 25298937Sdes cc = &receive_context; 253147005Sdes 254147005Sdes cipher_get_keyiv(cc, iv, len); 25598937Sdes} 25698937Sdes 25798937Sdesint 25898937Sdespacket_get_keycontext(int mode, u_char *dat) 25998937Sdes{ 26098937Sdes CipherContext *cc; 26198937Sdes 26298937Sdes if (mode == MODE_OUT) 26398937Sdes cc = &send_context; 26498937Sdes else 26598937Sdes cc = &receive_context; 26698937Sdes 26798937Sdes return (cipher_get_keycontext(cc, dat)); 26898937Sdes} 26998937Sdes 27098937Sdesvoid 27198937Sdespacket_set_keycontext(int mode, u_char *dat) 272221420Sdes{ 27398937Sdes CipherContext *cc; 27498937Sdes 27598937Sdes if (mode == MODE_OUT) 27698937Sdes cc = &send_context; 277147005Sdes else 27898937Sdes cc = &receive_context; 279147005Sdes 28098937Sdes cipher_set_keycontext(cc, dat); 28198937Sdes} 282147005Sdes 283147005Sdesint 28498937Sdespacket_get_keyiv_len(int mode) 28598937Sdes{ 28698937Sdes CipherContext *cc; 28798937Sdes 28898937Sdes if (mode == MODE_OUT) 28998937Sdes cc = &send_context; 29098937Sdes else 29198937Sdes cc = &receive_context; 29298937Sdes 29398937Sdes return (cipher_get_keyiv_len(cc)); 29498937Sdes} 29598937Sdes 296221420Sdesvoid 29798937Sdespacket_set_iv(int mode, u_char *dat) 29898937Sdes{ 29998937Sdes CipherContext *cc; 30098937Sdes 30198937Sdes if (mode == MODE_OUT) 30298937Sdes cc = &send_context; 30398937Sdes else 30498937Sdes cc = &receive_context; 30598937Sdes 30698937Sdes cipher_set_keyiv(cc, dat); 30798937Sdes} 30898937Sdes 30998937Sdesint 310221420Sdespacket_get_ssh1_cipher(void) 311221420Sdes{ 31298937Sdes return (cipher_get_number(receive_context.cipher)); 31398937Sdes} 314147005Sdes 31598937Sdesvoid 31698937Sdespacket_get_state(int mode, u_int32_t *seqnr, u_int64_t *blocks, u_int32_t *packets, 31798937Sdes u_int64_t *bytes) 318147005Sdes{ 31998937Sdes struct packet_state *state; 320147005Sdes 32198937Sdes state = (mode == MODE_IN) ? &p_read : &p_send; 32298937Sdes if (seqnr) 32398937Sdes *seqnr = state->seqnr; 324147005Sdes if (blocks) 325147005Sdes *blocks = state->blocks; 32698937Sdes if (packets) 32798937Sdes *packets = state->packets; 32898937Sdes if (bytes) 32998937Sdes *bytes = state->bytes; 33098937Sdes} 33198937Sdes 33298937Sdesvoid 33398937Sdespacket_set_state(int mode, u_int32_t seqnr, u_int64_t blocks, u_int32_t packets, 33498937Sdes u_int64_t bytes) 335221420Sdes{ 336147005Sdes struct packet_state *state; 33798937Sdes 33898937Sdes state = (mode == MODE_IN) ? &p_read : &p_send; 33998937Sdes state->seqnr = seqnr; 340147005Sdes state->blocks = blocks; 341147005Sdes state->packets = packets; 342147005Sdes state->bytes = bytes; 34398937Sdes} 34498937Sdes 34598937Sdes/* returns 1 if connection is via ipv4 */ 34698937Sdes 34798937Sdesint 34898937Sdespacket_connection_is_ipv4(void) 34998937Sdes{ 350255767Sdes struct sockaddr_storage to; 35198937Sdes socklen_t tolen = sizeof(to); 35298937Sdes 35398937Sdes memset(&to, 0, sizeof(to)); 35498937Sdes if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0) 35598937Sdes return 0; 35698937Sdes if (to.ss_family == AF_INET) 35798937Sdes return 1; 35898937Sdes#ifdef IPV4_IN_IPV6 35998937Sdes if (to.ss_family == AF_INET6 && 36098937Sdes IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr)) 36198937Sdes return 1; 36298937Sdes#endif 363221420Sdes return 0; 364147005Sdes} 36598937Sdes 36698937Sdes/* Sets the connection into non-blocking mode. */ 36798937Sdes 36898937Sdesvoid 36998937Sdespacket_set_nonblocking(void) 37098937Sdes{ 37198937Sdes /* Set the socket into non-blocking mode. */ 37298937Sdes set_nonblock(connection_in); 37398937Sdes 37498937Sdes if (connection_out != connection_in) 37598937Sdes set_nonblock(connection_out); 37698937Sdes} 37798937Sdes 37898937Sdes/* Returns the socket used for reading. */ 379147005Sdes 380149753Sdesint 381147005Sdespacket_get_connection_in(void) 382147005Sdes{ 38398937Sdes return connection_in; 38498937Sdes} 38598937Sdes 38698937Sdes/* Returns the descriptor used for writing. */ 38798937Sdes 38898937Sdesint 389147005Sdespacket_get_connection_out(void) 39098937Sdes{ 39198937Sdes return connection_out; 392149753Sdes} 393147005Sdes 39498937Sdes/* Closes the connection and clears and frees internal data structures. */ 39598937Sdes 39698937Sdesvoid 39798937Sdespacket_close(void) 39898937Sdes{ 39998937Sdes if (!initialized) 40098937Sdes return; 40198937Sdes initialized = 0; 40298937Sdes if (connection_in == connection_out) { 40398937Sdes shutdown(connection_out, SHUT_RDWR); 40498937Sdes close(connection_out); 40598937Sdes } else { 40698937Sdes close(connection_in); 40798937Sdes close(connection_out); 40898937Sdes } 40998937Sdes buffer_free(&input); 41098937Sdes buffer_free(&output); 41198937Sdes buffer_free(&outgoing_packet); 41298937Sdes buffer_free(&incoming_packet); 413147005Sdes if (compression_buffer_ready) { 41498937Sdes buffer_free(&compression_buffer); 41598937Sdes buffer_compress_uninit(); 41698937Sdes } 41798937Sdes cipher_cleanup(&send_context); 41898937Sdes cipher_cleanup(&receive_context); 41998937Sdes} 42098937Sdes 421147005Sdes/* Sets remote side protocol flags. */ 42298937Sdes 42398937Sdesvoid 42498937Sdespacket_set_protocol_flags(u_int protocol_flags) 42598937Sdes{ 42698937Sdes remote_protocol_flags = protocol_flags; 42798937Sdes} 42898937Sdes 42998937Sdes/* Returns the remote protocol flags set earlier by the above function. */ 430147005Sdes 43198937Sdesu_int 43298937Sdespacket_get_protocol_flags(void) 433147005Sdes{ 434147005Sdes return remote_protocol_flags; 435147005Sdes} 43698937Sdes 43798937Sdes/* 43898937Sdes * Starts packet compression from the next packet on in both directions. 43998937Sdes * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. 44098937Sdes */ 44198937Sdes 44298937Sdesstatic void 44398937Sdespacket_init_compression(void) 44498937Sdes{ 445147005Sdes if (compression_buffer_ready == 1) 44698937Sdes return; 44798937Sdes compression_buffer_ready = 1; 44898937Sdes buffer_init(&compression_buffer); 44998937Sdes} 45098937Sdes 45198937Sdesvoid 45298937Sdespacket_start_compression(int level) 45398937Sdes{ 45498937Sdes if (packet_compression && !compat20) 45598937Sdes fatal("Compression already enabled."); 45698937Sdes packet_compression = 1; 45798937Sdes packet_init_compression(); 45898937Sdes buffer_compress_init_send(level); 45998937Sdes buffer_compress_init_recv(); 460137019Sdes} 461149753Sdes 462149753Sdes/* 463149753Sdes * Causes any further packets to be encrypted using the given key. The same 464137019Sdes * key is used for both sending and reception. However, both directions are 465137019Sdes * encrypted independently of each other. 466147005Sdes */ 467147005Sdes 468221420Sdesvoid 469147005Sdespacket_set_encryption_key(const u_char *key, u_int keylen, 470221420Sdes int number) 471147005Sdes{ 472147005Sdes Cipher *cipher = cipher_by_number(number); 47398937Sdes 47498937Sdes if (cipher == NULL) 47598937Sdes fatal("packet_set_encryption_key: unknown cipher number %d", number); 47698937Sdes if (keylen < 20) 47798937Sdes fatal("packet_set_encryption_key: keylen too small: %d", keylen); 47898937Sdes if (keylen > SSH_SESSION_KEY_LENGTH) 479126277Sdes fatal("packet_set_encryption_key: keylen too big: %d", keylen); 48098937Sdes memcpy(ssh1_key, key, keylen); 48198937Sdes ssh1_keylen = keylen; 48298937Sdes cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT); 48398937Sdes cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT); 48498937Sdes} 48598937Sdes 48698937Sdesu_int 48798937Sdespacket_get_encryption_key(u_char *key) 48898937Sdes{ 48998937Sdes if (key == NULL) 49098937Sdes return (ssh1_keylen); 49198937Sdes memcpy(key, ssh1_key, ssh1_keylen); 49298937Sdes return (ssh1_keylen); 493147005Sdes} 49498937Sdes 49598937Sdes/* Start constructing a packet to send. */ 49698937Sdesvoid 49798937Sdespacket_start(u_char type) 49898937Sdes{ 49998937Sdes u_char buf[9]; 50098937Sdes int len; 50198937Sdes 50298937Sdes DBG(debug("packet_start[%d]", type)); 50398937Sdes len = compat20 ? 6 : 9; 50498937Sdes memset(buf, 0, len - 1); 50598937Sdes buf[len - 1] = type; 50698937Sdes buffer_clear(&outgoing_packet); 50798937Sdes buffer_append(&outgoing_packet, buf, len); 50898937Sdes} 509207319Sdes 510207319Sdes/* Append payload. */ 511207319Sdesvoid 512207319Sdespacket_put_char(int value) 51398937Sdes{ 514147005Sdes char ch = value; 51598937Sdes 51698937Sdes buffer_append(&outgoing_packet, &ch, 1); 517147005Sdes} 518147005Sdes 519147005Sdesvoid 52098937Sdespacket_put_int(u_int value) 52198937Sdes{ 522147005Sdes buffer_put_int(&outgoing_packet, value); 523147005Sdes} 52498937Sdes 52598937Sdesvoid 526147005Sdespacket_put_string(const void *buf, u_int len) 52798937Sdes{ 528147005Sdes buffer_put_string(&outgoing_packet, buf, len); 52998937Sdes} 53098937Sdes 53198937Sdesvoid 53298937Sdespacket_put_cstring(const char *str) 53398937Sdes{ 53498937Sdes buffer_put_cstring(&outgoing_packet, str); 53598937Sdes} 53698937Sdes 53798937Sdesvoid 53898937Sdespacket_put_raw(const void *buf, u_int len) 53998937Sdes{ 54098937Sdes buffer_append(&outgoing_packet, buf, len); 54198937Sdes} 54298937Sdes 54398937Sdesvoid 54498937Sdespacket_put_bignum(BIGNUM * value) 54598937Sdes{ 54698937Sdes buffer_put_bignum(&outgoing_packet, value); 54798937Sdes} 54898937Sdes 54998937Sdesvoid 55098937Sdespacket_put_bignum2(BIGNUM * value) 55198937Sdes{ 552147005Sdes buffer_put_bignum2(&outgoing_packet, value); 553147005Sdes} 554147005Sdes 555147005Sdes/* 55698937Sdes * Finalizes and sends the packet. If the encryption key has been set, 557149753Sdes * encrypts the packet before sending. 55898937Sdes */ 55998937Sdes 560147005Sdesstatic void 56198937Sdespacket_send1(void) 562147005Sdes{ 56398937Sdes u_char buf[8], *cp; 56498937Sdes int i, padding, len; 56598937Sdes u_int checksum; 566147005Sdes u_int32_t rnd = 0; 56798937Sdes 56898937Sdes /* 56998937Sdes * If using packet compression, compress the payload of the outgoing 57098937Sdes * packet. 57198937Sdes */ 57298937Sdes if (packet_compression) { 57398937Sdes buffer_clear(&compression_buffer); 57498937Sdes /* Skip padding. */ 57598937Sdes buffer_consume(&outgoing_packet, 8); 57698937Sdes /* padding */ 57798937Sdes buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8); 578147005Sdes buffer_compress(&outgoing_packet, &compression_buffer); 57998937Sdes buffer_clear(&outgoing_packet); 58098937Sdes buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), 581149753Sdes buffer_len(&compression_buffer)); 582147005Sdes } 58398937Sdes /* Compute packet length without padding (add checksum, remove padding). */ 58498937Sdes len = buffer_len(&outgoing_packet) + 4 - 8; 58598937Sdes 58698937Sdes /* Insert padding. Initialized to zero in packet_start1() */ 587147005Sdes padding = 8 - len % 8; 588147005Sdes if (!send_context.plaintext) { 58998937Sdes cp = buffer_ptr(&outgoing_packet); 59098937Sdes for (i = 0; i < padding; i++) { 59198937Sdes if (i % 4 == 0) 59298937Sdes rnd = arc4random(); 59398937Sdes cp[7 - i] = rnd & 0xff; 59498937Sdes rnd >>= 8; 59598937Sdes } 59698937Sdes } 59798937Sdes buffer_consume(&outgoing_packet, 8 - padding); 59898937Sdes 59998937Sdes /* Add check bytes. */ 60098937Sdes checksum = ssh_crc32(buffer_ptr(&outgoing_packet), 60198937Sdes buffer_len(&outgoing_packet)); 60298937Sdes put_u32(buf, checksum); 60398937Sdes buffer_append(&outgoing_packet, buf, 4); 60498937Sdes 60598937Sdes#ifdef PACKET_DEBUG 60698937Sdes fprintf(stderr, "packet_send plain: "); 60798937Sdes buffer_dump(&outgoing_packet); 60898937Sdes#endif 60998937Sdes 61098937Sdes /* Append to output. */ 61198937Sdes put_u32(buf, len); 61298937Sdes buffer_append(&output, buf, 4); 61398937Sdes cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); 61498937Sdes cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), 615147005Sdes buffer_len(&outgoing_packet)); 61698937Sdes 61798937Sdes#ifdef PACKET_DEBUG 61898937Sdes fprintf(stderr, "encrypted: "); 61998937Sdes buffer_dump(&output); 62098937Sdes#endif 62198937Sdes p_send.packets++; 62298937Sdes p_send.bytes += len + buffer_len(&outgoing_packet); 62398937Sdes buffer_clear(&outgoing_packet); 62498937Sdes 62598937Sdes /* 62698937Sdes * Note that the packet is now only buffered in output. It won't be 62798937Sdes * actually sent until packet_write_wait or packet_write_poll is 62898937Sdes * called. 62998937Sdes */ 63098937Sdes} 631147005Sdes 63298937Sdesvoid 63398937Sdesset_newkeys(int mode) 634147005Sdes{ 63598937Sdes Enc *enc; 63698937Sdes Mac *mac; 63798937Sdes Comp *comp; 63898937Sdes CipherContext *cc; 63998937Sdes u_int64_t *max_blocks; 64098937Sdes int crypt_type; 64198937Sdes 64298937Sdes debug2("set_newkeys: mode %d", mode); 643113911Sdes 644113911Sdes if (mode == MODE_OUT) { 645147005Sdes cc = &send_context; 646147005Sdes crypt_type = CIPHER_ENCRYPT; 64798937Sdes p_send.packets = p_send.blocks = 0; 64898937Sdes max_blocks = &max_blocks_out; 64998937Sdes } else { 65098937Sdes cc = &receive_context; 65198937Sdes crypt_type = CIPHER_DECRYPT; 65298937Sdes p_read.packets = p_read.blocks = 0; 65398937Sdes max_blocks = &max_blocks_in; 65498937Sdes } 65598937Sdes if (newkeys[mode] != NULL) { 65698937Sdes debug("set_newkeys: rekeying"); 65798937Sdes cipher_cleanup(cc); 65898937Sdes enc = &newkeys[mode]->enc; 65998937Sdes mac = &newkeys[mode]->mac; 660106130Sdes comp = &newkeys[mode]->comp; 66198937Sdes mac_clear(mac); 66298937Sdes xfree(enc->name); 66398937Sdes xfree(enc->iv); 66498937Sdes xfree(enc->key); 66598937Sdes xfree(mac->name); 666106130Sdes xfree(mac->key); 66798937Sdes xfree(comp->name); 66898937Sdes xfree(newkeys[mode]); 66998937Sdes } 67098937Sdes newkeys[mode] = kex_get_newkeys(mode); 67198937Sdes if (newkeys[mode] == NULL) 67298937Sdes fatal("newkeys: no keys for mode %d", mode); 67398937Sdes enc = &newkeys[mode]->enc; 67498937Sdes mac = &newkeys[mode]->mac; 67598937Sdes comp = &newkeys[mode]->comp; 67698937Sdes if (mac_init(mac) == 0) 67798937Sdes mac->enabled = 1; 67898937Sdes DBG(debug("cipher_init_context: %d", mode)); 67998937Sdes cipher_init(cc, enc->cipher, enc->key, enc->key_len, 68098937Sdes enc->iv, enc->block_size, crypt_type); 68198937Sdes /* Deleting the keys does not gain extra security */ 682147005Sdes /* memset(enc->iv, 0, enc->block_size); 68398937Sdes memset(enc->key, 0, enc->key_len); 68498937Sdes memset(mac->key, 0, mac->key_len); */ 68598937Sdes if ((comp->type == COMP_ZLIB || 68698937Sdes (comp->type == COMP_DELAYED && after_authentication)) && 68798937Sdes comp->enabled == 0) { 68898937Sdes packet_init_compression(); 68998937Sdes if (mode == MODE_OUT) 690147005Sdes buffer_compress_init_send(6); 691147005Sdes else 69298937Sdes buffer_compress_init_recv(); 693184122Sdes comp->enabled = 1; 694184122Sdes } 69598937Sdes /* 69698937Sdes * The 2^(blocksize*2) limit is too expensive for 3DES, 69798937Sdes * blowfish, etc, so enforce a 1GB limit for small blocksizes. 69898937Sdes */ 69998937Sdes if (enc->block_size >= 16) 70098937Sdes *max_blocks = (u_int64_t)1 << (enc->block_size*2); 701113911Sdes else 702113911Sdes *max_blocks = ((u_int64_t)1 << 30) / enc->block_size; 703113911Sdes if (rekey_limit) 704113911Sdes *max_blocks = MIN(*max_blocks, rekey_limit / enc->block_size); 705113911Sdes} 706113911Sdes 707113911Sdes/* 708113911Sdes * Delayed compression for SSH2 is enabled after authentication: 709113911Sdes * This happens on the server side after a SSH2_MSG_USERAUTH_SUCCESS is sent, 710113911Sdes * and on the client side after a SSH2_MSG_USERAUTH_SUCCESS is received. 711113911Sdes */ 712113911Sdesstatic void 713113911Sdespacket_enable_delayed_compress(void) 71498937Sdes{ 71598937Sdes Comp *comp = NULL; 71698937Sdes int mode; 71798937Sdes 71898937Sdes /* 71998937Sdes * Remember that we are past the authentication step, so rekeying 72098937Sdes * with COMP_DELAYED will turn on compression immediately. 72198937Sdes */ 72298937Sdes after_authentication = 1; 72398937Sdes for (mode = 0; mode < MODE_MAX; mode++) { 72498937Sdes /* protocol error: USERAUTH_SUCCESS received before NEWKEYS */ 72598937Sdes if (newkeys[mode] == NULL) 72698937Sdes continue; 72798937Sdes comp = &newkeys[mode]->comp; 72898937Sdes if (comp && !comp->enabled && comp->type == COMP_DELAYED) { 729147005Sdes packet_init_compression(); 73098937Sdes if (mode == MODE_OUT) 73198937Sdes buffer_compress_init_send(6); 732147005Sdes else 73398937Sdes buffer_compress_init_recv(); 734147005Sdes comp->enabled = 1; 73598937Sdes } 73698937Sdes } 73798937Sdes} 73898937Sdes 73998937Sdes/* 740113911Sdes * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue) 741113911Sdes */ 742113911Sdesstatic void 74398937Sdespacket_send2_wrapped(void) 744147005Sdes{ 74598937Sdes u_char type, *cp, *macbuf = NULL; 74698937Sdes u_char padlen, pad; 74798937Sdes u_int packet_length = 0; 74898937Sdes u_int i, len; 74998937Sdes u_int32_t rnd = 0; 75098937Sdes Enc *enc = NULL; 75198937Sdes Mac *mac = NULL; 75298937Sdes Comp *comp = NULL; 75398937Sdes int block_size; 75498937Sdes 75598937Sdes if (newkeys[MODE_OUT] != NULL) { 75698937Sdes enc = &newkeys[MODE_OUT]->enc; 75798937Sdes mac = &newkeys[MODE_OUT]->mac; 75898937Sdes comp = &newkeys[MODE_OUT]->comp; 75998937Sdes } 76098937Sdes block_size = enc ? enc->block_size : 8; 761147005Sdes 76298937Sdes cp = buffer_ptr(&outgoing_packet); 763202213Sed type = cp[5]; 764202213Sed 76598937Sdes#ifdef PACKET_DEBUG 76698937Sdes fprintf(stderr, "plain: "); 76798937Sdes buffer_dump(&outgoing_packet); 76898937Sdes#endif 76998937Sdes 77098937Sdes if (comp && comp->enabled) { 77198937Sdes len = buffer_len(&outgoing_packet); 77298937Sdes /* skip header, compress only payload */ 77398937Sdes buffer_consume(&outgoing_packet, 5); 77498937Sdes buffer_clear(&compression_buffer); 775147005Sdes buffer_compress(&outgoing_packet, &compression_buffer); 776147005Sdes buffer_clear(&outgoing_packet); 77798937Sdes buffer_append(&outgoing_packet, "\0\0\0\0\0", 5); 77898937Sdes buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), 77998937Sdes buffer_len(&compression_buffer)); 78098937Sdes DBG(debug("compression: raw %d compressed %d", len, 78198937Sdes buffer_len(&outgoing_packet))); 78298937Sdes } 783113911Sdes 784113911Sdes /* sizeof (packet_len + pad_len + payload) */ 785113911Sdes len = buffer_len(&outgoing_packet); 786113911Sdes 787113911Sdes /* 788113911Sdes * calc size of padding, alloc space, get random data, 789113911Sdes * minimum padding is 4 bytes 790113911Sdes */ 791113911Sdes padlen = block_size - (len % block_size); 792113911Sdes if (padlen < 4) 793113911Sdes padlen += block_size; 794113911Sdes if (extra_pad) { 795113911Sdes /* will wrap if extra_pad+padlen > 255 */ 79698937Sdes extra_pad = roundup(extra_pad, block_size); 79798937Sdes pad = extra_pad - ((len + padlen) % extra_pad); 79898937Sdes debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)", 79998937Sdes pad, len, padlen, extra_pad); 80098937Sdes padlen += pad; 80198937Sdes extra_pad = 0; 80298937Sdes } 80398937Sdes cp = buffer_append_space(&outgoing_packet, padlen); 80498937Sdes if (enc && !send_context.plaintext) { 80598937Sdes /* random padding */ 80698937Sdes for (i = 0; i < padlen; i++) { 80798937Sdes if (i % 4 == 0) 80898937Sdes rnd = arc4random(); 80998937Sdes cp[i] = rnd & 0xff; 81098937Sdes rnd >>= 8; 81198937Sdes } 81298937Sdes } else { 81398937Sdes /* clear padding */ 81498937Sdes memset(cp, 0, padlen); 81598937Sdes } 81698937Sdes /* packet_length includes payload, padding and padding length field */ 81798937Sdes packet_length = buffer_len(&outgoing_packet) - 4; 81898937Sdes cp = buffer_ptr(&outgoing_packet); 81998937Sdes put_u32(cp, packet_length); 82098937Sdes cp[4] = padlen; 82198937Sdes DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen)); 82298937Sdes 82398937Sdes /* compute MAC over seqnr and packet(length fields, payload, padding) */ 82498937Sdes if (mac && mac->enabled) { 82598937Sdes macbuf = mac_compute(mac, p_send.seqnr, 82698937Sdes buffer_ptr(&outgoing_packet), 827147005Sdes buffer_len(&outgoing_packet)); 82898937Sdes DBG(debug("done calc MAC out #%d", p_send.seqnr)); 82998937Sdes } 83098937Sdes /* encrypt packet and append to output buffer. */ 831149753Sdes cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); 832147005Sdes cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), 833147005Sdes buffer_len(&outgoing_packet)); 834147005Sdes /* append unencrypted MAC */ 83598937Sdes if (mac && mac->enabled) 83698937Sdes buffer_append(&output, macbuf, mac->mac_len); 83798937Sdes#ifdef PACKET_DEBUG 83898937Sdes fprintf(stderr, "encrypted: "); 83998937Sdes buffer_dump(&output); 84098937Sdes#endif 84198937Sdes /* increment sequence number for outgoing packets */ 84298937Sdes if (++p_send.seqnr == 0) 84398937Sdes logit("outgoing seqnr wraps around"); 84498937Sdes if (++p_send.packets == 0) 845147005Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 84698937Sdes fatal("XXX too many packets with same key"); 84798937Sdes p_send.blocks += (packet_length + 4) / block_size; 84898937Sdes p_send.bytes += packet_length + 4; 849147005Sdes buffer_clear(&outgoing_packet); 85098937Sdes 85198937Sdes if (type == SSH2_MSG_NEWKEYS) 85298937Sdes set_newkeys(MODE_OUT); 85398937Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && server_side) 85498937Sdes packet_enable_delayed_compress(); 85598937Sdes} 856147005Sdes 857137019Sdesstatic void 858137019Sdespacket_send2(void) 85998937Sdes{ 86098937Sdes static int rekeying = 0; 86198937Sdes struct packet *p; 86298937Sdes u_char type, *cp; 86398937Sdes 86498937Sdes cp = buffer_ptr(&outgoing_packet); 86598937Sdes type = cp[5]; 86698937Sdes 867137019Sdes /* during rekeying we can only send key exchange messages */ 868137019Sdes if (rekeying) { 869137019Sdes if (!((type >= SSH2_MSG_TRANSPORT_MIN) && 870137019Sdes (type <= SSH2_MSG_TRANSPORT_MAX))) { 871147005Sdes debug("enqueue packet: %u", type); 872221420Sdes p = xmalloc(sizeof(*p)); 873137019Sdes p->type = type; 874137019Sdes memcpy(&p->payload, &outgoing_packet, sizeof(Buffer)); 875137019Sdes buffer_init(&outgoing_packet); 876149753Sdes TAILQ_INSERT_TAIL(&outgoing, p, next); 877147005Sdes return; 878221420Sdes } 879137019Sdes } 880137019Sdes 88198937Sdes /* rekeying starts with sending KEXINIT */ 88298937Sdes if (type == SSH2_MSG_KEXINIT) 88398937Sdes rekeying = 1; 88498937Sdes 88598937Sdes packet_send2_wrapped(); 88698937Sdes 887147005Sdes /* after a NEWKEYS message we can send the complete queue */ 888147005Sdes if (type == SSH2_MSG_NEWKEYS) { 889147005Sdes rekeying = 0; 890147005Sdes while ((p = TAILQ_FIRST(&outgoing))) { 89198937Sdes type = p->type; 892137019Sdes debug("dequeue packet: %u", type); 893147005Sdes buffer_free(&outgoing_packet); 894221420Sdes memcpy(&outgoing_packet, &p->payload, 895137019Sdes sizeof(Buffer)); 896137019Sdes TAILQ_REMOVE(&outgoing, p, next); 897137019Sdes xfree(p); 898147005Sdes packet_send2_wrapped(); 899137019Sdes } 900221420Sdes } 901137019Sdes} 902137019Sdes 903147005Sdesvoid 904137019Sdespacket_send(void) 90598937Sdes{ 906221420Sdes if (compat20) 907221420Sdes packet_send2(); 908147005Sdes else 90998937Sdes packet_send1(); 910147005Sdes DBG(debug("packet_send done")); 911147005Sdes} 91298937Sdes 913147005Sdes/* 91498937Sdes * Waits until a packet has been received, and returns its type. Note that 91598937Sdes * no other data is processed until this returns, so this function should not 91698937Sdes * be used during the interactive session. 91798937Sdes */ 91898937Sdes 91998937Sdesint 92098937Sdespacket_read_seqnr(u_int32_t *seqnr_p) 92198937Sdes{ 92298937Sdes int type, len, ret, ms_remain; 92398937Sdes fd_set *setp; 92498937Sdes char buf[8192]; 92598937Sdes struct timeval timeout, start, *timeoutp = NULL; 926147005Sdes 927147005Sdes DBG(debug("packet_read()")); 92898937Sdes 92998937Sdes setp = (fd_set *)xcalloc(howmany(connection_in+1, NFDBITS), 93098937Sdes sizeof(fd_mask)); 931147005Sdes 932147005Sdes /* Since we are blocking, ensure that all written packets have been sent. */ 93398937Sdes packet_write_wait(); 93498937Sdes 935147005Sdes /* Stay in the loop until we have received a complete packet. */ 93698937Sdes for (;;) { 93798937Sdes /* Try to read a packet from the buffer. */ 93898937Sdes type = packet_read_poll_seqnr(seqnr_p); 93998937Sdes if (!compat20 && ( 94098937Sdes type == SSH_SMSG_SUCCESS 94198937Sdes || type == SSH_SMSG_FAILURE 94298937Sdes || type == SSH_CMSG_EOF 94398937Sdes || type == SSH_CMSG_EXIT_CONFIRMATION)) 94498937Sdes packet_check_eom(); 94598937Sdes /* If we got a packet, return it. */ 94698937Sdes if (type != SSH_MSG_NONE) { 947147005Sdes xfree(setp); 948147005Sdes return type; 94998937Sdes } 95098937Sdes /* 95198937Sdes * Otherwise, wait for some data to arrive, add it to the 952147005Sdes * buffer, and try again. 953147005Sdes */ 95498937Sdes memset(setp, 0, howmany(connection_in + 1, NFDBITS) * 95598937Sdes sizeof(fd_mask)); 956147005Sdes FD_SET(connection_in, setp); 95798937Sdes 95898937Sdes if (packet_timeout_ms > 0) { 95998937Sdes ms_remain = packet_timeout_ms; 96098937Sdes timeoutp = &timeout; 96198937Sdes } 96298937Sdes /* Wait for some data to arrive. */ 96398937Sdes for (;;) { 96498937Sdes if (packet_timeout_ms != -1) { 965147005Sdes ms_to_timeval(&timeout, ms_remain); 96698937Sdes gettimeofday(&start, NULL); 96798937Sdes } 968147005Sdes if ((ret = select(connection_in + 1, setp, NULL, 96998937Sdes NULL, timeoutp)) >= 0) 97098937Sdes break; 971147005Sdes if (errno != EAGAIN && errno != EINTR && 972147005Sdes errno != EWOULDBLOCK) 97398937Sdes break; 97498937Sdes if (packet_timeout_ms == -1) 97598937Sdes continue; 97698937Sdes ms_subtract_diff(&start, &ms_remain); 97798937Sdes if (ms_remain <= 0) { 97898937Sdes ret = 0; 97998937Sdes break; 98098937Sdes } 98198937Sdes } 98298937Sdes if (ret == 0) { 98398937Sdes logit("Connection to %.200s timed out while " 98498937Sdes "waiting to read", get_remote_ipaddr()); 98598937Sdes cleanup_exit(255); 98698937Sdes } 98798937Sdes /* Read data from the socket. */ 98898937Sdes len = read(connection_in, buf, sizeof(buf)); 98998937Sdes if (len == 0) { 99098937Sdes logit("Connection closed by %.200s", get_remote_ipaddr()); 99198937Sdes cleanup_exit(255); 99298937Sdes } 99398937Sdes if (len < 0) 99498937Sdes fatal("Read from socket failed: %.100s", strerror(errno)); 99598937Sdes /* Append it to the buffer. */ 99698937Sdes packet_process_incoming(buf, len); 99798937Sdes } 99898937Sdes /* NOTREACHED */ 99998937Sdes} 100098937Sdes 100198937Sdesint 100298937Sdespacket_read(void) 1003147005Sdes{ 100498937Sdes return packet_read_seqnr(NULL); 100598937Sdes} 100698937Sdes 100798937Sdes/* 100898937Sdes * Waits until a packet has been received, verifies that its type matches 100998937Sdes * that given, and gives a fatal error and exits if there is a mismatch. 101098937Sdes */ 101198937Sdes 1012147005Sdesvoid 1013147005Sdespacket_read_expect(int expected_type) 101498937Sdes{ 101598937Sdes int type; 101698937Sdes 101798937Sdes type = packet_read(); 101898937Sdes if (type != expected_type) 101998937Sdes packet_disconnect("Protocol error: expected packet type %d, got %d", 102098937Sdes expected_type, type); 102198937Sdes} 102298937Sdes 102398937Sdes/* Checks if a full packet is available in the data received so far via 102498937Sdes * packet_process_incoming. If so, reads the packet; otherwise returns 1025147005Sdes * SSH_MSG_NONE. This does not wait for data from the connection. 1026147005Sdes * 102798937Sdes * SSH_MSG_DISCONNECT is handled specially here. Also, 102898937Sdes * SSH_MSG_IGNORE messages are skipped by this function and are never returned 102998937Sdes * to higher levels. 1030147005Sdes */ 1031147005Sdes 103298937Sdesstatic int 103398937Sdespacket_read_poll1(void) 1034147005Sdes{ 103598937Sdes u_int len, padded_len; 103698937Sdes u_char *cp, type; 103798937Sdes u_int checksum, stored_checksum; 103898937Sdes 103998937Sdes /* Check if input size is less than minimum packet size. */ 104098937Sdes if (buffer_len(&input) < 4 + 8) 104198937Sdes return SSH_MSG_NONE; 104298937Sdes /* Get length of incoming packet. */ 104398937Sdes cp = buffer_ptr(&input); 104498937Sdes len = get_u32(cp); 104598937Sdes if (len < 1 + 2 + 2 || len > 256 * 1024) 104698937Sdes packet_disconnect("Bad packet length %u.", len); 104798937Sdes padded_len = (len + 8) & ~7; 104898937Sdes 104998937Sdes /* Check if the packet has been entirely received. */ 105098937Sdes if (buffer_len(&input) < 4 + padded_len) 105198937Sdes return SSH_MSG_NONE; 105298937Sdes 105398937Sdes /* The entire packet is in buffer. */ 105498937Sdes 105598937Sdes /* Consume packet length. */ 1056147005Sdes buffer_consume(&input, 4); 105798937Sdes 105898937Sdes /* 105998937Sdes * Cryptographic attack detector for ssh 106098937Sdes * (C)1998 CORE-SDI, Buenos Aires Argentina 106198937Sdes * Ariel Futoransky(futo@core-sdi.com) 106298937Sdes */ 106398937Sdes if (!receive_context.plaintext) { 1064147005Sdes switch (detect_attack(buffer_ptr(&input), padded_len)) { 106598937Sdes case DEATTACK_DETECTED: 1066147005Sdes packet_disconnect("crc32 compensation attack: " 106798937Sdes "network attack detected"); 1068147005Sdes case DEATTACK_DOS_DETECTED: 1069147005Sdes packet_disconnect("deattack denial of " 107098937Sdes "service detected"); 107198937Sdes } 107298937Sdes } 107398937Sdes 107498937Sdes /* Decrypt data to incoming_packet. */ 107598937Sdes buffer_clear(&incoming_packet); 107698937Sdes cp = buffer_append_space(&incoming_packet, padded_len); 107798937Sdes cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len); 107898937Sdes 107998937Sdes buffer_consume(&input, padded_len); 108098937Sdes 1081149753Sdes#ifdef PACKET_DEBUG 1082147005Sdes fprintf(stderr, "read_poll plain: "); 1083147005Sdes buffer_dump(&incoming_packet); 1084147005Sdes#endif 108598937Sdes 108698937Sdes /* Compute packet checksum. */ 108798937Sdes checksum = ssh_crc32(buffer_ptr(&incoming_packet), 108898937Sdes buffer_len(&incoming_packet) - 4); 108998937Sdes 109098937Sdes /* Skip padding. */ 109198937Sdes buffer_consume(&incoming_packet, 8 - len % 8); 1092147005Sdes 109398937Sdes /* Test check bytes. */ 1094147005Sdes if (len != buffer_len(&incoming_packet)) 109598937Sdes packet_disconnect("packet_read_poll1: len %d != buffer_len %d.", 109698937Sdes len, buffer_len(&incoming_packet)); 1097124211Sdes 109898937Sdes cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4; 1099147005Sdes stored_checksum = get_u32(cp); 110098937Sdes if (checksum != stored_checksum) 110198937Sdes packet_disconnect("Corrupted check bytes on input."); 110298937Sdes buffer_consume_end(&incoming_packet, 4); 1103147005Sdes 1104147005Sdes if (packet_compression) { 110598937Sdes buffer_clear(&compression_buffer); 110698937Sdes buffer_uncompress(&incoming_packet, &compression_buffer); 110798937Sdes buffer_clear(&incoming_packet); 110898937Sdes buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), 110998937Sdes buffer_len(&compression_buffer)); 111098937Sdes } 111198937Sdes p_read.packets++; 111298937Sdes p_read.bytes += padded_len + 4; 1113147005Sdes type = buffer_get_char(&incoming_packet); 111498937Sdes if (type < SSH_MSG_MIN || type > SSH_MSG_MAX) 111598937Sdes packet_disconnect("Invalid ssh1 packet type: %d", type); 111698937Sdes return type; 111798937Sdes} 111898937Sdes 111998937Sdesstatic int 112098937Sdespacket_read_poll2(u_int32_t *seqnr_p) 112198937Sdes{ 112298937Sdes static u_int packet_length = 0; 1123147005Sdes u_int padlen, need; 112498937Sdes u_char *macbuf, *cp, type; 112598937Sdes u_int maclen, block_size; 112698937Sdes Enc *enc = NULL; 112798937Sdes Mac *mac = NULL; 112898937Sdes Comp *comp = NULL; 112998937Sdes 113098937Sdes if (newkeys[MODE_IN] != NULL) { 113198937Sdes enc = &newkeys[MODE_IN]->enc; 1132147005Sdes mac = &newkeys[MODE_IN]->mac; 113398937Sdes comp = &newkeys[MODE_IN]->comp; 1134147005Sdes } 113598937Sdes maclen = mac && mac->enabled ? mac->mac_len : 0; 1136147005Sdes block_size = enc ? enc->block_size : 8; 1137147005Sdes 113898937Sdes if (packet_length == 0) { 113998937Sdes /* 114098937Sdes * check if input size is less than the cipher block size, 114198937Sdes * decrypt first block and extract length of incoming packet 1142149753Sdes */ 1143147005Sdes if (buffer_len(&input) < block_size) 114498937Sdes return SSH_MSG_NONE; 114598937Sdes buffer_clear(&incoming_packet); 114698937Sdes cp = buffer_append_space(&incoming_packet, block_size); 114798937Sdes cipher_crypt(&receive_context, cp, buffer_ptr(&input), 114898937Sdes block_size); 114998937Sdes cp = buffer_ptr(&incoming_packet); 115098937Sdes packet_length = get_u32(cp); 115198937Sdes if (packet_length < 1 + 4 || packet_length > 256 * 1024) { 115298937Sdes#ifdef PACKET_DEBUG 115398937Sdes buffer_dump(&incoming_packet); 115498937Sdes#endif 115598937Sdes packet_disconnect("Bad packet length %u.", packet_length); 115698937Sdes } 115798937Sdes DBG(debug("input: packet len %u", packet_length+4)); 115898937Sdes buffer_consume(&input, block_size); 115998937Sdes } 116098937Sdes /* we have a partial packet of block_size bytes */ 116198937Sdes need = 4 + packet_length - block_size; 116298937Sdes DBG(debug("partial packet %d, need %d, maclen %d", block_size, 116398937Sdes need, maclen)); 1164147005Sdes if (need % block_size != 0) 116598937Sdes fatal("padding error: need %d block %d mod %d", 116698937Sdes need, block_size, need % block_size); 1167147005Sdes /* 116898937Sdes * check if the entire packet has been received and 1169147005Sdes * decrypt into incoming_packet 117098937Sdes */ 117198937Sdes if (buffer_len(&input) < need + maclen) 1172147005Sdes return SSH_MSG_NONE; 117398937Sdes#ifdef PACKET_DEBUG 117498937Sdes fprintf(stderr, "read_poll enc/full: "); 117598937Sdes buffer_dump(&input); 117698937Sdes#endif 117798937Sdes cp = buffer_append_space(&incoming_packet, need); 117898937Sdes cipher_crypt(&receive_context, cp, buffer_ptr(&input), need); 117998937Sdes buffer_consume(&input, need); 1180147005Sdes /* 118198937Sdes * compute MAC over seqnr and packet, 118298937Sdes * increment sequence number for incoming packet 118398937Sdes */ 118498937Sdes if (mac && mac->enabled) { 118598937Sdes macbuf = mac_compute(mac, p_read.seqnr, 1186149753Sdes buffer_ptr(&incoming_packet), 118798937Sdes buffer_len(&incoming_packet)); 1188147005Sdes if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0) 118998937Sdes packet_disconnect("Corrupted MAC on input."); 119098937Sdes DBG(debug("MAC #%d ok", p_read.seqnr)); 1191149753Sdes buffer_consume(&input, mac->mac_len); 119298937Sdes } 119398937Sdes if (seqnr_p != NULL) 1194147005Sdes *seqnr_p = p_read.seqnr; 119598937Sdes if (++p_read.seqnr == 0) 119698937Sdes logit("incoming seqnr wraps around"); 119798937Sdes if (++p_read.packets == 0) 119898937Sdes if (!(datafellows & SSH_BUG_NOREKEY)) 119998937Sdes fatal("XXX too many packets with same key"); 120098937Sdes p_read.blocks += (packet_length + 4) / block_size; 1201147005Sdes p_read.bytes += packet_length + 4; 120298937Sdes 120398937Sdes /* get padlen */ 120498937Sdes cp = buffer_ptr(&incoming_packet); 120598937Sdes padlen = cp[4]; 1206149753Sdes DBG(debug("input: padlen %d", padlen)); 120798937Sdes if (padlen < 4) 120898937Sdes packet_disconnect("Corrupted padlen %d on input.", padlen); 1209147005Sdes 121098937Sdes /* skip packet size + padlen, discard padding */ 1211221420Sdes buffer_consume(&incoming_packet, 4 + 1); 121298937Sdes buffer_consume_end(&incoming_packet, padlen); 1213147005Sdes 1214147005Sdes DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet))); 1215147005Sdes if (comp && comp->enabled) { 1216147005Sdes buffer_clear(&compression_buffer); 121798937Sdes buffer_uncompress(&incoming_packet, &compression_buffer); 121898937Sdes buffer_clear(&incoming_packet); 121998937Sdes buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), 122098937Sdes buffer_len(&compression_buffer)); 122198937Sdes DBG(debug("input: len after de-compress %d", 122298937Sdes buffer_len(&incoming_packet))); 122398937Sdes } 122498937Sdes /* 1225147005Sdes * get packet type, implies consume. 122698937Sdes * return length of payload (without type field) 122798937Sdes */ 1228147005Sdes type = buffer_get_char(&incoming_packet); 122998937Sdes if (type < SSH2_MSG_MIN || type >= SSH2_MSG_LOCAL_MIN) 123098937Sdes packet_disconnect("Invalid ssh2 packet type: %d", type); 123198937Sdes if (type == SSH2_MSG_NEWKEYS) 123298937Sdes set_newkeys(MODE_IN); 123398937Sdes else if (type == SSH2_MSG_USERAUTH_SUCCESS && !server_side) 123498937Sdes packet_enable_delayed_compress(); 1235147005Sdes#ifdef PACKET_DEBUG 1236147005Sdes fprintf(stderr, "read/plain[%d]:\r\n", type); 123798937Sdes buffer_dump(&incoming_packet); 123898937Sdes#endif 123998937Sdes /* reset for next packet */ 124098937Sdes packet_length = 0; 124198937Sdes return type; 1242147005Sdes} 124398937Sdes 124498937Sdesint 124598937Sdespacket_read_poll_seqnr(u_int32_t *seqnr_p) 124698937Sdes{ 124798937Sdes u_int reason, seqnr; 124898937Sdes u_char type; 124998937Sdes char *msg; 125098937Sdes 125198937Sdes for (;;) { 1252147005Sdes if (compat20) { 1253147005Sdes type = packet_read_poll2(seqnr_p); 1254147005Sdes if (type) { 1255147005Sdes keep_alive_timeouts = 0; 125698937Sdes DBG(debug("received packet type %d", type)); 125798937Sdes } 125898937Sdes switch (type) { 1259126277Sdes case SSH2_MSG_IGNORE: 126098937Sdes debug3("Received SSH2_MSG_IGNORE"); 126198937Sdes break; 126298937Sdes case SSH2_MSG_DEBUG: 126398937Sdes packet_get_char(); 1264149753Sdes msg = packet_get_string(NULL); 126598937Sdes debug("Remote: %.900s", msg); 1266147005Sdes xfree(msg); 126798937Sdes msg = packet_get_string(NULL); 126898937Sdes xfree(msg); 126998937Sdes break; 1270124211Sdes case SSH2_MSG_DISCONNECT: 127198937Sdes reason = packet_get_int(); 1272147005Sdes msg = packet_get_string(NULL); 127398937Sdes logit("Received disconnect from %s: %u: %.400s", 127498937Sdes get_remote_ipaddr(), reason, msg); 127598937Sdes xfree(msg); 1276147005Sdes cleanup_exit(255); 127798937Sdes break; 1278147005Sdes case SSH2_MSG_UNIMPLEMENTED: 1279126277Sdes seqnr = packet_get_int(); 1280126277Sdes debug("Received SSH2_MSG_UNIMPLEMENTED for %u", 1281147005Sdes seqnr); 1282126277Sdes break; 128398937Sdes default: 128498937Sdes return type; 128598937Sdes } 128698937Sdes } else { 128798937Sdes type = packet_read_poll1(); 128898937Sdes switch (type) { 128998937Sdes case SSH_MSG_IGNORE: 129098937Sdes break; 129198937Sdes case SSH_MSG_DEBUG: 1292147005Sdes msg = packet_get_string(NULL); 129398937Sdes debug("Remote: %.900s", msg); 129498937Sdes xfree(msg); 129598937Sdes break; 129698937Sdes case SSH_MSG_DISCONNECT: 129798937Sdes msg = packet_get_string(NULL); 129898937Sdes logit("Received disconnect from %s: %.400s", 129998937Sdes get_remote_ipaddr(), msg); 130098937Sdes cleanup_exit(255); 130198937Sdes break; 1302147005Sdes default: 130398937Sdes if (type) 130498937Sdes DBG(debug("received packet type %d", type)); 130598937Sdes return type; 130698937Sdes } 130798937Sdes } 130898937Sdes } 130998937Sdes} 131098937Sdes 1311147005Sdesint 131298937Sdespacket_read_poll(void) 1313147005Sdes{ 131498937Sdes return packet_read_poll_seqnr(NULL); 1315147005Sdes} 1316147005Sdes 131798937Sdes/* 131898937Sdes * Buffers the given amount of input characters. This is intended to be used 131998937Sdes * together with packet_read_poll. 132098937Sdes */ 132198937Sdes 132298937Sdesvoid 132398937Sdespacket_process_incoming(const char *buf, u_int len) 132498937Sdes{ 132598937Sdes buffer_append(&input, buf, len); 132698937Sdes} 1327204917Sdes 1328204917Sdes/* Returns a character from the packet. */ 132998937Sdes 133098937Sdesu_int 1331147005Sdespacket_get_char(void) 133298937Sdes{ 1333147005Sdes char ch; 133498937Sdes 133598937Sdes buffer_get(&incoming_packet, &ch, 1); 1336147005Sdes return (u_char) ch; 133798937Sdes} 133898937Sdes 133998937Sdes/* Returns an integer from the packet data. */ 134098937Sdes 134198937Sdesu_int 134298937Sdespacket_get_int(void) 134398937Sdes{ 134498937Sdes return buffer_get_int(&incoming_packet); 134598937Sdes} 134698937Sdes 134798937Sdes/* 134898937Sdes * Returns an arbitrary precision integer from the packet data. The integer 134998937Sdes * must have been initialized before this call. 135098937Sdes */ 1351149753Sdes 135298937Sdesvoid 1353147005Sdespacket_get_bignum(BIGNUM * value) 135498937Sdes{ 135598937Sdes buffer_get_bignum(&incoming_packet, value); 1356149753Sdes} 1357106130Sdes 135898937Sdesvoid 1359147005Sdespacket_get_bignum2(BIGNUM * value) 136098937Sdes{ 136198937Sdes buffer_get_bignum2(&incoming_packet, value); 136298937Sdes} 136398937Sdes 136498937Sdesvoid * 136598937Sdespacket_get_raw(u_int *length_ptr) 1366147005Sdes{ 136798937Sdes u_int bytes = buffer_len(&incoming_packet); 136898937Sdes 136998937Sdes if (length_ptr != NULL) 137098937Sdes *length_ptr = bytes; 1371149753Sdes return buffer_ptr(&incoming_packet); 137298937Sdes} 137398937Sdes 1374147005Sdesint 137598937Sdespacket_remaining(void) 1376147005Sdes{ 1377149753Sdes return buffer_len(&incoming_packet); 1378147005Sdes} 1379147005Sdes 1380147005Sdes/* 1381106130Sdes * Returns a string from the packet data. The string is allocated using 1382147005Sdes * xmalloc; it is the responsibility of the calling program to free it when 138398937Sdes * no longer needed. The length_ptr argument may be NULL, or point to an 1384147005Sdes * integer into which the length of the string is stored. 138598937Sdes */ 138698937Sdes 138798937Sdesvoid * 1388147005Sdespacket_get_string(u_int *length_ptr) 138998937Sdes{ 1390147005Sdes return buffer_get_string(&incoming_packet, length_ptr); 139198937Sdes} 139298937Sdes 139398937Sdesvoid * 139498937Sdespacket_get_string_ptr(u_int *length_ptr) 1395147005Sdes{ 1396147005Sdes return buffer_get_string_ptr(&incoming_packet, length_ptr); 139798937Sdes} 139898937Sdes 139998937Sdes/* 140098937Sdes * Sends a diagnostic message from the server to the client. This message 1401147005Sdes * can be sent at any time (but not while constructing another message). The 140298937Sdes * message is printed immediately, but only if the client is being executed 140398937Sdes * in verbose mode. These messages are primarily intended to ease debugging 140498937Sdes * authentication problems. The length of the formatted message must not 140598937Sdes * exceed 1024 bytes. This will automatically call packet_write_wait. 140698937Sdes */ 140798937Sdes 140898937Sdesvoid 140998937Sdespacket_send_debug(const char *fmt,...) 141098937Sdes{ 141198937Sdes char buf[1024]; 141298937Sdes va_list args; 141398937Sdes 141498937Sdes if (compat20 && (datafellows & SSH_BUG_DEBUG)) 1415147005Sdes return; 141698937Sdes 141798937Sdes va_start(args, fmt); 1418113911Sdes vsnprintf(buf, sizeof(buf), fmt, args); 141998937Sdes va_end(args); 1420147005Sdes 142198937Sdes if (compat20) { 142298937Sdes packet_start(SSH2_MSG_DEBUG); 142398937Sdes packet_put_char(0); /* bool: always display */ 142498937Sdes packet_put_cstring(buf); 142598937Sdes packet_put_cstring(""); 142698937Sdes } else { 1427128460Sdes packet_start(SSH_MSG_DEBUG); 142898937Sdes packet_put_cstring(buf); 142998937Sdes } 143098937Sdes packet_send(); 1431147005Sdes packet_write_wait(); 1432147005Sdes} 143398937Sdes 1434147005Sdes/* 143598937Sdes * Logs the error plus constructs and sends a disconnect packet, closes the 143698937Sdes * connection, and exits. This function never returns. The error message 143798937Sdes * should not contain a newline. The length of the formatted message must 143898937Sdes * not exceed 1024 bytes. 143998937Sdes */ 144098937Sdes 144198937Sdesvoid 1442147005Sdespacket_disconnect(const char *fmt,...) 144398937Sdes{ 144498937Sdes char buf[1024]; 144598937Sdes va_list args; 144698937Sdes static int disconnecting = 0; 144798937Sdes 144898937Sdes if (disconnecting) /* Guard against recursive invocations. */ 144998937Sdes fatal("packet_disconnect called recursively."); 1450147005Sdes disconnecting = 1; 145198937Sdes 1452147005Sdes /* 145398937Sdes * Format the message. Note that the caller must make sure the 1454147005Sdes * message is of limited size. 1455147005Sdes */ 145698937Sdes va_start(args, fmt); 145798937Sdes vsnprintf(buf, sizeof(buf), fmt, args); 145898937Sdes va_end(args); 145998937Sdes 146098937Sdes /* Display the error locally */ 146198937Sdes logit("Disconnecting: %.100s", buf); 146298937Sdes 146398937Sdes /* Send the disconnect message to the other side, and wait for it to get sent. */ 146498937Sdes if (compat20) { 146598937Sdes packet_start(SSH2_MSG_DISCONNECT); 146698937Sdes packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR); 146798937Sdes packet_put_cstring(buf); 1468192595Sdes packet_put_cstring(""); 1469192595Sdes } else { 147098937Sdes packet_start(SSH_MSG_DISCONNECT); 1471192595Sdes packet_put_cstring(buf); 147298937Sdes } 1473192595Sdes packet_send(); 1474192595Sdes packet_write_wait(); 147598937Sdes 147698937Sdes /* Stop listening for connections. */ 147798937Sdes channel_close_all(); 1478147005Sdes 1479147005Sdes /* Close the connection. */ 1480147005Sdes packet_close(); 148198937Sdes cleanup_exit(255); 1482192595Sdes} 1483147005Sdes 1484147005Sdes/* Checks if there is any buffered output, and tries to write some of the output. */ 1485192595Sdes 1486192595Sdesvoid 1487192595Sdespacket_write_poll(void) 1488147005Sdes{ 1489147005Sdes int len = buffer_len(&output); 1490147005Sdes 149198937Sdes if (len > 0) { 149298937Sdes len = write(connection_out, buffer_ptr(&output), len); 1493124211Sdes if (len == -1) { 1494147005Sdes if (errno == EINTR || errno == EAGAIN || 1495147005Sdes errno == EWOULDBLOCK) 149698937Sdes return; 1497147005Sdes fatal("Write failed: %.100s", strerror(errno)); 149898937Sdes } 149998937Sdes if (len == 0) 1500192595Sdes fatal("Write connection closed"); 150198937Sdes buffer_consume(&output, len); 1502221420Sdes } 150398937Sdes} 1504147005Sdes 1505147005Sdes 1506147005Sdes/* 1507221420Sdes * Calls packet_write_poll repeatedly until all pending output data has been 1508147005Sdes * written. 150998937Sdes */ 151098937Sdes 151198937Sdesvoid 1512147005Sdespacket_write_wait(void) 151398937Sdes{ 1514192595Sdes fd_set *setp; 151598937Sdes int ret, ms_remain; 1516192595Sdes struct timeval start, timeout, *timeoutp = NULL; 1517192595Sdes 1518192595Sdes setp = (fd_set *)xcalloc(howmany(connection_out + 1, NFDBITS), 151998937Sdes sizeof(fd_mask)); 1520192595Sdes packet_write_poll(); 1521192595Sdes while (packet_have_data_to_write()) { 1522192595Sdes memset(setp, 0, howmany(connection_out + 1, NFDBITS) * 1523192595Sdes sizeof(fd_mask)); 1524192595Sdes FD_SET(connection_out, setp); 1525192595Sdes 152698937Sdes if (packet_timeout_ms > 0) { 152798937Sdes ms_remain = packet_timeout_ms; 1528192595Sdes timeoutp = &timeout; 152998937Sdes } 153098937Sdes for (;;) { 153198937Sdes if (packet_timeout_ms != -1) { 1532192595Sdes ms_to_timeval(&timeout, ms_remain); 1533192595Sdes gettimeofday(&start, NULL); 1534192595Sdes } 153598937Sdes if ((ret = select(connection_out + 1, NULL, setp, 153698937Sdes NULL, timeoutp)) >= 0) 1537192595Sdes break; 1538192595Sdes if (errno != EAGAIN && errno != EINTR && 1539192595Sdes errno != EWOULDBLOCK) 1540192595Sdes break; 1541192595Sdes if (packet_timeout_ms == -1) 1542192595Sdes continue; 1543192595Sdes ms_subtract_diff(&start, &ms_remain); 1544192595Sdes if (ms_remain <= 0) { 1545192595Sdes ret = 0; 1546192595Sdes break; 1547192595Sdes } 1548192595Sdes } 1549192595Sdes if (ret == 0) { 1550192595Sdes logit("Connection to %.200s timed out while " 1551192595Sdes "waiting to write", get_remote_ipaddr()); 1552192595Sdes cleanup_exit(255); 1553192595Sdes } 1554192595Sdes packet_write_poll(); 1555192595Sdes } 1556192595Sdes xfree(setp); 155798937Sdes} 1558147005Sdes 1559147005Sdes/* Returns true if there is buffered data to write to the connection. */ 156098937Sdes 156198937Sdesint 1562192595Sdespacket_have_data_to_write(void) 156398937Sdes{ 1564192595Sdes return buffer_len(&output) != 0; 1565192595Sdes} 1566192595Sdes 156798937Sdes/* Returns true if there is not too much data to write to the connection. */ 1568192595Sdes 1569192595Sdesint 1570192595Sdespacket_not_very_much_data_to_write(void) 1571192595Sdes{ 1572192595Sdes if (interactive_mode) 1573192595Sdes return buffer_len(&output) < 16384; 1574192595Sdes else 1575192595Sdes return buffer_len(&output) < 128 * 1024; 1576192595Sdes} 1577192595Sdes 1578192595Sdes 1579192595Sdesstatic void 158098937Sdespacket_set_tos(int interactive) 1581192595Sdes{ 158298937Sdes#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN) 158398937Sdes int tos = interactive ? IPTOS_LOWDELAY : IPTOS_THROUGHPUT; 158498937Sdes 158598937Sdes if (!packet_connection_is_on_socket() || 1586113911Sdes !packet_connection_is_ipv4()) 158798937Sdes return; 158898937Sdes if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &tos, 1589113911Sdes sizeof(tos)) < 0) 159098937Sdes error("setsockopt IP_TOS %d: %.100s:", 1591113911Sdes tos, strerror(errno)); 1592113911Sdes#endif 1593113911Sdes} 1594113911Sdes 1595113911Sdes/* Informs that the current session is interactive. Sets IP flags for that. */ 1596113911Sdes 1597113911Sdesvoid 1598113911Sdespacket_set_interactive(int interactive) 1599192595Sdes{ 1600192595Sdes static int called = 0; 1601192595Sdes 1602192595Sdes if (called) 1603113911Sdes return; 1604113911Sdes called = 1; 1605126277Sdes 160698937Sdes /* Record that we are in interactive mode. */ 1607113911Sdes interactive_mode = interactive; 1608113911Sdes 1609113911Sdes /* Only set socket options if using a socket. */ 1610157019Sdes if (!packet_connection_is_on_socket()) 1611113911Sdes return; 161298937Sdes set_nodelay(connection_in); 161398937Sdes packet_set_tos(interactive); 1614113911Sdes} 1615113911Sdes 161698937Sdes/* Returns true if the current connection is interactive. */ 1617192595Sdes 161898937Sdesint 1619147005Sdespacket_is_interactive(void) 1620207319Sdes{ 1621207319Sdes return interactive_mode; 1622202213Sed} 1623202213Sed 1624202213Sedint 1625202213Sedpacket_set_maxsize(u_int s) 1626202213Sed{ 1627202213Sed static int called = 0; 1628202213Sed 1629202213Sed if (called) { 1630202213Sed logit("packet_set_maxsize: called twice: old %d new %d", 1631202213Sed max_packet_size, s); 1632202213Sed return -1; 1633202213Sed } 1634202213Sed if (s < 4 * 1024 || s > 1024 * 1024) { 1635202213Sed logit("packet_set_maxsize: bad size %d", s); 1636202213Sed return -1; 1637202213Sed } 1638202213Sed called = 1; 1639202213Sed debug("packet_set_maxsize: setting to %d", s); 1640202213Sed max_packet_size = s; 1641202213Sed return s; 1642202213Sed} 1643202213Sed 1644207319Sdes/* roundup current message to pad bytes */ 1645202213Sedvoid 1646147005Sdespacket_add_padding(u_char pad) 1647147005Sdes{ 1648147005Sdes extra_pad = pad; 1649147005Sdes} 1650147005Sdes 1651147005Sdes/* 1652147005Sdes * 9.2. Ignored Data Message 1653147005Sdes * 1654147005Sdes * byte SSH_MSG_IGNORE 1655147005Sdes * string data 1656147005Sdes * 1657147005Sdes * All implementations MUST understand (and ignore) this message at any 1658147005Sdes * time (after receiving the protocol version). No implementation is 1659147005Sdes * required to send them. This message can be used as an additional 1660147005Sdes * protection measure against advanced traffic analysis techniques. 1661157019Sdes */ 1662147005Sdesvoid 1663147005Sdespacket_send_ignore(int nbytes) 1664147005Sdes{ 1665147005Sdes u_int32_t rnd = 0; 1666147005Sdes int i; 1667147005Sdes 1668147005Sdes packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE); 1669147005Sdes packet_put_int(nbytes); 1670147005Sdes for (i = 0; i < nbytes; i++) { 1671147005Sdes if (i % 4 == 0) 1672147005Sdes rnd = arc4random(); 1673147005Sdes packet_put_char((u_char)rnd & 0xff); 1674147005Sdes rnd >>= 8; 1675147005Sdes } 1676147005Sdes} 1677147005Sdes 1678147005Sdes#define MAX_PACKETS (1U<<31) 1679221420Sdesint 1680147005Sdespacket_need_rekeying(void) 1681147005Sdes{ 1682147005Sdes if (datafellows & SSH_BUG_NOREKEY) 1683147005Sdes return 0; 1684147005Sdes return 1685147005Sdes (p_send.packets > MAX_PACKETS) || 1686147005Sdes (p_read.packets > MAX_PACKETS) || 1687147005Sdes (max_blocks_out && (p_send.blocks > max_blocks_out)) || 1688147005Sdes (max_blocks_in && (p_read.blocks > max_blocks_in)); 1689147005Sdes} 1690147005Sdes 1691147005Sdesvoid 1692147005Sdespacket_set_rekey_limit(u_int32_t bytes) 1693147005Sdes{ 1694147005Sdes rekey_limit = bytes; 1695147005Sdes} 1696147005Sdes 1697147005Sdesvoid 1698147005Sdespacket_set_server(void) 1699147005Sdes{ 1700147005Sdes server_side = 1; 1701147005Sdes} 1702147005Sdes 1703147005Sdesvoid 1704147005Sdespacket_set_authenticated(void) 1705147005Sdes{ 1706147005Sdes after_authentication = 1; 1707147005Sdes} 1708147005Sdes