packet.c revision 76259
1193323Sed/*
2193323Sed * Author: Tatu Ylonen <ylo@cs.hut.fi>
3193323Sed * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4193323Sed *                    All rights reserved
5193323Sed * This file contains code implementing the packet protocol and communication
6193323Sed * with the other side.  This same code is used both on client and server side.
7193323Sed *
8193323Sed * As far as I am concerned, the code I have written for this software
9193323Sed * can be used freely for any purpose.  Any derived versions of this
10193323Sed * software must be clearly marked as such, and if the derived work is
11193323Sed * incompatible with the protocol description in the RFC file, it must be
12193323Sed * called by a name other than "ssh" or "Secure Shell".
13193323Sed *
14193323Sed *
15193323Sed * SSH2 packet format added by Markus Friedl.
16193323Sed * Copyright (c) 2000 Markus Friedl.  All rights reserved.
17193323Sed *
18193323Sed * Redistribution and use in source and binary forms, with or without
19193323Sed * modification, are permitted provided that the following conditions
20193323Sed * are met:
21193323Sed * 1. Redistributions of source code must retain the above copyright
22193323Sed *    notice, this list of conditions and the following disclaimer.
23198090Srdivacky * 2. Redistributions in binary form must reproduce the above copyright
24198090Srdivacky *    notice, this list of conditions and the following disclaimer in the
25193323Sed *    documentation and/or other materials provided with the distribution.
26193323Sed *
27193323Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28193323Sed * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29193323Sed * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30193323Sed * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31193323Sed * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32193323Sed * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33193323Sed * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34193323Sed * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35193323Sed * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36193323Sed * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37207618Srdivacky */
38193323Sed
39193323Sed#include "includes.h"
40193323SedRCSID("$OpenBSD: packet.c,v 1.61 2001/04/05 10:42:51 markus Exp $");
41193323Sed
42193323Sed#include "xmalloc.h"
43249423Sdim#include "buffer.h"
44193323Sed#include "packet.h"
45193323Sed#include "bufaux.h"
46193323Sed#include "crc32.h"
47193323Sed#include "getput.h"
48193323Sed
49193323Sed#include "compress.h"
50193323Sed#include "deattack.h"
51193323Sed#include "channels.h"
52193323Sed
53193323Sed#include "compat.h"
54193323Sed#include "ssh1.h"
55193323Sed#include "ssh2.h"
56193323Sed
57193323Sed#include "cipher.h"
58193323Sed#include "kex.h"
59193323Sed#include "mac.h"
60193323Sed#include "log.h"
61221345Sdim#include "canohost.h"
62221345Sdim
63221345Sdim#ifdef PACKET_DEBUG
64249423Sdim#define DBG(x) x
65249423Sdim#else
66226633Sdim#define DBG(x)
67226633Sdim#endif
68226633Sdim
69243830Sdim/*
70234353Sdim * This variable contains the file descriptors used for communicating with
71234353Sdim * the other side.  connection_in is used for reading; connection_out for
72193323Sed * writing.  These can be the same descriptor, in which case it is assumed to
73193323Sed * be a socket.
74193323Sed */
75193323Sedstatic int connection_in = -1;
76193323Sedstatic int connection_out = -1;
77239462Sdim
78239462Sdim/*
79239462Sdim * Cipher type.  This value is only used to determine whether to pad the
80193323Sed * packets with zeroes or random data.
81193323Sed */
82193323Sedstatic int cipher_type = SSH_CIPHER_NONE;
83193323Sed
84193323Sed/* Protocol flags for the remote side. */
85193323Sedstatic u_int remote_protocol_flags = 0;
86193323Sed
87193323Sed/* Encryption context for receiving data.  This is only used for decryption. */
88249423Sdimstatic CipherContext receive_context;
89249423Sdim
90249423Sdim/* Encryption context for sending data.  This is only used for encryption. */
91249423Sdimstatic CipherContext send_context;
92249423Sdim
93249423Sdim/* Buffer for raw input data from the socket. */
94249423Sdimstatic Buffer input;
95249423Sdim
96249423Sdim/* Buffer for raw output data going to the socket. */
97249423Sdimstatic Buffer output;
98249423Sdim
99249423Sdim/* Buffer for the partial outgoing packet being constructed. */
100249423Sdimstatic Buffer outgoing_packet;
101249423Sdim
102249423Sdim/* Buffer for the incoming packet currently being processed. */
103249423Sdimstatic Buffer incoming_packet;
104249423Sdim
105249423Sdim/* Scratch buffer for packet compression/decompression. */
106249423Sdimstatic Buffer compression_buffer;
107193323Sedstatic int compression_buffer_ready = 0;
108193323Sed
109193323Sed/* Flag indicating whether packet compression/decompression is enabled. */
110193323Sedstatic int packet_compression = 0;
111193323Sed
112193323Sed/* default maximum packet size */
113193323Sedint max_packet_size = 32768;
114193323Sed
115200581Srdivacky/* Flag indicating whether this module has been initialized. */
116193323Sedstatic int initialized = 0;
117193323Sed
118193323Sed/* Set to true if the connection is interactive. */
119193323Sedstatic int interactive_mode = 0;
120193323Sed
121193323Sed/* True if SSH2 packet format is used */
122193323Sedint use_ssh2_packet_format = 0;
123193323Sed
124193323Sed/* Session key information for Encryption and MAC */
125193323SedNewkeys *newkeys[MODE_MAX];
126193323Sed
127193323Sedvoid
128193323Sedpacket_set_ssh2_format(void)
129193323Sed{
130193323Sed	DBG(debug("use_ssh2_packet_format"));
131193323Sed	use_ssh2_packet_format = 1;
132193323Sed	newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
133193323Sed}
134193323Sed
135193323Sed/*
136193323Sed * Sets the descriptors used for communication.  Disables encryption until
137193323Sed * packet_set_encryption_key is called.
138193323Sed */
139193323Sedvoid
140193323Sedpacket_set_connection(int fd_in, int fd_out)
141193323Sed{
142193323Sed	Cipher *none = cipher_by_name("none");
143193323Sed	if (none == NULL)
144193323Sed		fatal("packet_set_connection: cannot load cipher 'none'");
145193323Sed	connection_in = fd_in;
146193323Sed	connection_out = fd_out;
147193323Sed	cipher_type = SSH_CIPHER_NONE;
148193323Sed	cipher_init(&send_context, none, (u_char *) "", 0, NULL, 0);
149193323Sed	cipher_init(&receive_context, none, (u_char *) "", 0, NULL, 0);
150193323Sed	if (!initialized) {
151193323Sed		initialized = 1;
152210299Sed		buffer_init(&input);
153193323Sed		buffer_init(&output);
154234353Sdim		buffer_init(&outgoing_packet);
155234353Sdim		buffer_init(&incoming_packet);
156234353Sdim	}
157234353Sdim	/* Kludge: arrange the close function to be called from fatal(). */
158234353Sdim	fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
159234353Sdim}
160234353Sdim
161234353Sdim/* Returns 1 if remote host is connected via socket, 0 if not. */
162234353Sdim
163234353Sdimint
164234353Sdimpacket_connection_is_on_socket()
165234353Sdim{
166249423Sdim	struct sockaddr_storage from, to;
167234353Sdim	socklen_t fromlen, tolen;
168249423Sdim
169234353Sdim	/* filedescriptors in and out are the same, so it's a socket */
170234353Sdim	if (connection_in == connection_out)
171234353Sdim		return 1;
172234353Sdim	fromlen = sizeof(from);
173234353Sdim	memset(&from, 0, sizeof(from));
174263508Sdim	if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0)
175234353Sdim		return 0;
176234353Sdim	tolen = sizeof(to);
177234353Sdim	memset(&to, 0, sizeof(to));
178234353Sdim	if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0)
179234353Sdim		return 0;
180234353Sdim	if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
181193323Sed		return 0;
182193323Sed	if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
183193323Sed		return 0;
184193323Sed	return 1;
185193323Sed}
186193323Sed
187193323Sed/* returns 1 if connection is via ipv4 */
188193323Sed
189198090Srdivackyint
190193323Sedpacket_connection_is_ipv4()
191193323Sed{
192193323Sed	struct sockaddr_storage to;
193193323Sed	socklen_t tolen = sizeof(to);
194193323Sed
195193323Sed	memset(&to, 0, sizeof(to));
196193323Sed	if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0)
197193323Sed		return 0;
198193323Sed	if (to.ss_family != AF_INET)
199193323Sed		return 0;
200193323Sed	return 1;
201193323Sed}
202193323Sed
203193323Sed/* Sets the connection into non-blocking mode. */
204193323Sed
205193323Sedvoid
206193323Sedpacket_set_nonblocking()
207193323Sed{
208193323Sed	/* Set the socket into non-blocking mode. */
209193323Sed	if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0)
210193323Sed		error("fcntl O_NONBLOCK: %.100s", strerror(errno));
211193323Sed
212193323Sed	if (connection_out != connection_in) {
213266715Sdim		if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0)
214234353Sdim			error("fcntl O_NONBLOCK: %.100s", strerror(errno));
215193323Sed	}
216234353Sdim}
217234353Sdim
218193323Sed/* Returns the socket used for reading. */
219193323Sed
220226633Sdimint
221193323Sedpacket_get_connection_in()
222226633Sdim{
223193323Sed	return connection_in;
224193323Sed}
225193323Sed
226193323Sed/* Returns the descriptor used for writing. */
227193323Sed
228193323Sedint
229193323Sedpacket_get_connection_out()
230193323Sed{
231263508Sdim	return connection_out;
232193323Sed}
233193323Sed
234193323Sed/* Closes the connection and clears and frees internal data structures. */
235193323Sed
236193323Sedvoid
237193323Sedpacket_close()
238193323Sed{
239193323Sed	if (!initialized)
240193323Sed		return;
241193323Sed	initialized = 0;
242193323Sed	if (connection_in == connection_out) {
243193323Sed		shutdown(connection_out, SHUT_RDWR);
244193323Sed		close(connection_out);
245193323Sed	} else {
246263508Sdim		close(connection_in);
247193323Sed		close(connection_out);
248249423Sdim	}
249249423Sdim	buffer_free(&input);
250243830Sdim	buffer_free(&output);
251224145Sdim	buffer_free(&outgoing_packet);
252193574Sed	buffer_free(&incoming_packet);
253193323Sed	if (compression_buffer_ready) {
254202375Srdivacky		buffer_free(&compression_buffer);
255202375Srdivacky		buffer_compress_uninit();
256202375Srdivacky	}
257193574Sed}
258193574Sed
259193574Sed/* Sets remote side protocol flags. */
260193574Sed
261193323Sedvoid
262193323Sedpacket_set_protocol_flags(u_int protocol_flags)
263193574Sed{
264193323Sed	remote_protocol_flags = protocol_flags;
265239462Sdim	channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0);
266239462Sdim}
267239462Sdim
268239462Sdim/* Returns the remote protocol flags set earlier by the above function. */
269239462Sdim
270239462Sdimu_int
271239462Sdimpacket_get_protocol_flags()
272239462Sdim{
273239462Sdim	return remote_protocol_flags;
274239462Sdim}
275239462Sdim
276239462Sdim/*
277239462Sdim * Starts packet compression from the next packet on in both directions.
278193323Sed * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip.
279193323Sed */
280193323Sed
281193323Sedvoid
282193323Sedpacket_init_compression()
283193323Sed{
284193323Sed	if (compression_buffer_ready == 1)
285193323Sed		return;
286193323Sed	compression_buffer_ready = 1;
287193323Sed	buffer_init(&compression_buffer);
288193323Sed}
289249423Sdim
290249423Sdimvoid
291249423Sdimpacket_start_compression(int level)
292226633Sdim{
293243830Sdim	if (packet_compression && !use_ssh2_packet_format)
294243830Sdim		fatal("Compression already enabled.");
295226633Sdim	packet_compression = 1;
296221345Sdim	packet_init_compression();
297221345Sdim	buffer_compress_init_send(level);
298193323Sed	buffer_compress_init_recv();
299226633Sdim}
300193323Sed
301193323Sed/*
302199989Srdivacky * Encrypts the given number of bytes, copying from src to dest. bytes is
303193323Sed * known to be a multiple of 8.
304193323Sed */
305193323Sed
306193323Sedvoid
307193323Sedpacket_encrypt(CipherContext * cc, void *dest, void *src,
308193323Sed    u_int bytes)
309193323Sed{
310193323Sed	cipher_encrypt(cc, dest, src, bytes);
311193323Sed}
312193323Sed
313193323Sed/*
314193323Sed * Decrypts the given number of bytes, copying from src to dest. bytes is
315193323Sed * known to be a multiple of 8.
316193323Sed */
317193323Sed
318193323Sedvoid
319193323Sedpacket_decrypt(CipherContext *context, void *dest, void *src, u_int bytes)
320193323Sed{
321193323Sed	/*
322249423Sdim	 * Cryptographic attack detector for ssh - Modifications for packet.c
323193323Sed	 * (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com)
324193323Sed	 */
325249423Sdim	if (!compat20 &&
326263508Sdim	    context->cipher->number != SSH_CIPHER_NONE &&
327193323Sed	    detect_attack(src, bytes, NULL) == DEATTACK_DETECTED)
328193323Sed		packet_disconnect("crc32 compensation attack: network attack detected");
329193323Sed
330193323Sed	cipher_decrypt(context, dest, src, bytes);
331218893Sdim}
332193323Sed
333193323Sed/*
334193323Sed * Causes any further packets to be encrypted using the given key.  The same
335193323Sed * key is used for both sending and reception.  However, both directions are
336193323Sed * encrypted independently of each other.
337193323Sed */
338218893Sdim
339193323Sedvoid
340193323Sedpacket_set_encryption_key(const u_char *key, u_int keylen,
341239462Sdim    int number)
342239462Sdim{
343239462Sdim	Cipher *cipher = cipher_by_number(number);
344239462Sdim	if (cipher == NULL)
345239462Sdim		fatal("packet_set_encryption_key: unknown cipher number %d", number);
346239462Sdim	if (keylen < 20)
347234353Sdim		fatal("packet_set_encryption_key: keylen too small: %d", keylen);
348239462Sdim	cipher_init(&receive_context, cipher, key, keylen, NULL, 0);
349239462Sdim	cipher_init(&send_context, cipher, key, keylen, NULL, 0);
350239462Sdim}
351239462Sdim
352239462Sdim/* Starts constructing a packet to send. */
353239462Sdim
354239462Sdimvoid
355239462Sdimpacket_start1(int type)
356239462Sdim{
357239462Sdim	char buf[9];
358239462Sdim
359239462Sdim	buffer_clear(&outgoing_packet);
360239462Sdim	memset(buf, 0, 8);
361239462Sdim	buf[8] = type;
362239462Sdim	buffer_append(&outgoing_packet, buf, 9);
363263508Sdim}
364239462Sdim
365239462Sdimvoid
366239462Sdimpacket_start2(int type)
367239462Sdim{
368239462Sdim	char buf[4+1+1];
369239462Sdim
370239462Sdim	buffer_clear(&outgoing_packet);
371239462Sdim	memset(buf, 0, sizeof buf);
372239462Sdim	/* buf[0..3] = payload_len; */
373239462Sdim	/* buf[4] =    pad_len; */
374239462Sdim	buf[5] = type & 0xff;
375239462Sdim	buffer_append(&outgoing_packet, buf, sizeof buf);
376239462Sdim}
377239462Sdim
378239462Sdimvoid
379239462Sdimpacket_start(int type)
380234353Sdim{
381263508Sdim	DBG(debug("packet_start[%d]", type));
382234353Sdim	if (use_ssh2_packet_format)
383234353Sdim		packet_start2(type);
384234353Sdim	else
385234353Sdim		packet_start1(type);
386234353Sdim}
387234353Sdim
388249423Sdim/* Appends a character to the packet data. */
389234353Sdim
390234353Sdimvoid
391234353Sdimpacket_put_char(int value)
392249423Sdim{
393249423Sdim	char ch = value;
394234353Sdim	buffer_append(&outgoing_packet, &ch, 1);
395249423Sdim}
396249423Sdim
397249423Sdim/* Appends an integer to the packet data. */
398249423Sdim
399249423Sdimvoid
400249423Sdimpacket_put_int(u_int value)
401249423Sdim{
402234353Sdim	buffer_put_int(&outgoing_packet, value);
403249423Sdim}
404249423Sdim
405249423Sdim/* Appends a string to packet data. */
406249423Sdim
407249423Sdimvoid
408249423Sdimpacket_put_string(const char *buf, u_int len)
409249423Sdim{
410249423Sdim	buffer_put_string(&outgoing_packet, buf, len);
411249423Sdim}
412249423Sdimvoid
413249423Sdimpacket_put_cstring(const char *str)
414249423Sdim{
415249423Sdim	buffer_put_string(&outgoing_packet, str, strlen(str));
416249423Sdim}
417249423Sdim
418249423Sdimvoid
419249423Sdimpacket_put_raw(const char *buf, u_int len)
420249423Sdim{
421249423Sdim	buffer_append(&outgoing_packet, buf, len);
422263508Sdim}
423263508Sdim
424249423Sdim
425249423Sdim/* Appends an arbitrary precision integer to packet data. */
426249423Sdim
427249423Sdimvoid
428249423Sdimpacket_put_bignum(BIGNUM * value)
429249423Sdim{
430249423Sdim	buffer_put_bignum(&outgoing_packet, value);
431249423Sdim}
432249423Sdimvoid
433263508Sdimpacket_put_bignum2(BIGNUM * value)
434263508Sdim{
435249423Sdim	buffer_put_bignum2(&outgoing_packet, value);
436249423Sdim}
437249423Sdim
438249423Sdim/*
439249423Sdim * Finalizes and sends the packet.  If the encryption key has been set,
440263508Sdim * encrypts the packet before sending.
441249423Sdim */
442249423Sdim
443249423Sdimvoid
444249423Sdimpacket_send1(void)
445249423Sdim{
446249423Sdim	char buf[8], *cp;
447249423Sdim	int i, padding, len;
448249423Sdim	u_int checksum;
449249423Sdim	u_int32_t rand = 0;
450249423Sdim
451249423Sdim	/*
452249423Sdim	 * If using packet compression, compress the payload of the outgoing
453249423Sdim	 * packet.
454249423Sdim	 */
455249423Sdim	if (packet_compression) {
456249423Sdim		buffer_clear(&compression_buffer);
457249423Sdim		/* Skip padding. */
458249423Sdim		buffer_consume(&outgoing_packet, 8);
459249423Sdim		/* padding */
460249423Sdim		buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8);
461249423Sdim		buffer_compress(&outgoing_packet, &compression_buffer);
462249423Sdim		buffer_clear(&outgoing_packet);
463249423Sdim		buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
464249423Sdim			      buffer_len(&compression_buffer));
465249423Sdim	}
466249423Sdim	/* Compute packet length without padding (add checksum, remove padding). */
467249423Sdim	len = buffer_len(&outgoing_packet) + 4 - 8;
468249423Sdim
469249423Sdim	/* Insert padding. Initialized to zero in packet_start1() */
470249423Sdim	padding = 8 - len % 8;
471249423Sdim	if (cipher_type != SSH_CIPHER_NONE) {
472249423Sdim		cp = buffer_ptr(&outgoing_packet);
473249423Sdim		for (i = 0; i < padding; i++) {
474249423Sdim			if (i % 4 == 0)
475249423Sdim				rand = arc4random();
476249423Sdim			cp[7 - i] = rand & 0xff;
477249423Sdim			rand >>= 8;
478249423Sdim		}
479249423Sdim	}
480249423Sdim	buffer_consume(&outgoing_packet, 8 - padding);
481249423Sdim
482249423Sdim	/* Add check bytes. */
483249423Sdim	checksum = ssh_crc32((u_char *) buffer_ptr(&outgoing_packet),
484249423Sdim	    buffer_len(&outgoing_packet));
485249423Sdim	PUT_32BIT(buf, checksum);
486249423Sdim	buffer_append(&outgoing_packet, buf, 4);
487249423Sdim
488249423Sdim#ifdef PACKET_DEBUG
489249423Sdim	fprintf(stderr, "packet_send plain: ");
490249423Sdim	buffer_dump(&outgoing_packet);
491249423Sdim#endif
492249423Sdim
493249423Sdim	/* Append to output. */
494249423Sdim	PUT_32BIT(buf, len);
495249423Sdim	buffer_append(&output, buf, 4);
496249423Sdim	buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
497249423Sdim	packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
498249423Sdim		       buffer_len(&outgoing_packet));
499249423Sdim
500249423Sdim#ifdef PACKET_DEBUG
501249423Sdim	fprintf(stderr, "encrypted: ");
502249423Sdim	buffer_dump(&output);
503249423Sdim#endif
504249423Sdim
505263508Sdim	buffer_clear(&outgoing_packet);
506249423Sdim
507249423Sdim	/*
508263508Sdim	 * Note that the packet is now only buffered in output.  It won\'t be
509249423Sdim	 * actually sent until packet_write_wait or packet_write_poll is
510249423Sdim	 * called.
511249423Sdim	 */
512249423Sdim}
513234353Sdim
514234353Sdimvoid
515234353Sdimset_newkeys(int mode)
516234353Sdim{
517234353Sdim	Enc *enc;
518249423Sdim	Mac *mac;
519234353Sdim	Comp *comp;
520234353Sdim	CipherContext *cc;
521234353Sdim
522234353Sdim	debug("newkeys: mode %d", mode);
523234353Sdim
524234353Sdim	cc = (mode == MODE_OUT) ? &send_context : &receive_context;
525234353Sdim	if (newkeys[mode] != NULL) {
526234353Sdim		debug("newkeys: rekeying");
527263508Sdim		/* todo: free old keys, reset compression/cipher-ctxt; */
528234353Sdim		memset(cc, 0, sizeof(*cc));
529234353Sdim		enc  = &newkeys[mode]->enc;
530234353Sdim		mac  = &newkeys[mode]->mac;
531234353Sdim		comp = &newkeys[mode]->comp;
532234353Sdim		memset(mac->key, 0, mac->key_len);
533234353Sdim		xfree(enc->name);
534234353Sdim		xfree(enc->iv);
535234353Sdim		xfree(enc->key);
536234353Sdim		xfree(mac->name);
537263508Sdim		xfree(mac->key);
538234353Sdim		xfree(comp->name);
539234353Sdim		xfree(newkeys[mode]);
540234353Sdim	}
541234353Sdim	newkeys[mode] = kex_get_newkeys(mode);
542234353Sdim	if (newkeys[mode] == NULL)
543234353Sdim		fatal("newkeys: no keys for mode %d", mode);
544234353Sdim	enc  = &newkeys[mode]->enc;
545234353Sdim	mac  = &newkeys[mode]->mac;
546234353Sdim	comp = &newkeys[mode]->comp;
547234353Sdim	if (mac->md != NULL)
548234353Sdim		mac->enabled = 1;
549234353Sdim	DBG(debug("cipher_init_context: %d", mode));
550234353Sdim	cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len,
551234353Sdim	    enc->iv, enc->cipher->block_size);
552234353Sdim	memset(enc->iv,  0, enc->cipher->block_size);
553234353Sdim	memset(enc->key, 0, enc->cipher->key_len);
554234353Sdim	if (comp->type != 0 && comp->enabled == 0) {
555234353Sdim		packet_init_compression();
556234353Sdim		if (mode == MODE_OUT)
557234353Sdim			buffer_compress_init_send(6);
558234353Sdim		else
559234353Sdim			buffer_compress_init_recv();
560263508Sdim		comp->enabled = 1;
561234353Sdim	}
562234353Sdim}
563234353Sdim
564234353Sdim/*
565263508Sdim * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
566234353Sdim */
567234353Sdimvoid
568263508Sdimpacket_send2(void)
569234353Sdim{
570234353Sdim	static u_int32_t seqnr = 0;
571234353Sdim	u_char *macbuf = NULL;
572234353Sdim	char *cp;
573234353Sdim	u_int packet_length = 0;
574234353Sdim	u_int i, padlen, len;
575234353Sdim	u_int32_t rand = 0;
576234353Sdim	int type;
577234353Sdim	Enc *enc   = NULL;
578243830Sdim	Mac *mac   = NULL;
579243830Sdim	Comp *comp = NULL;
580243830Sdim	int block_size;
581263508Sdim
582243830Sdim	if (newkeys[MODE_OUT] != NULL) {
583263508Sdim		enc  = &newkeys[MODE_OUT]->enc;
584243830Sdim		mac  = &newkeys[MODE_OUT]->mac;
585243830Sdim		comp = &newkeys[MODE_OUT]->comp;
586243830Sdim	}
587243830Sdim	block_size = enc ? enc->cipher->block_size : 8;
588243830Sdim
589243830Sdim	cp = buffer_ptr(&outgoing_packet);
590243830Sdim	type = cp[5] & 0xff;
591243830Sdim
592243830Sdim#ifdef PACKET_DEBUG
593243830Sdim	fprintf(stderr, "plain:     ");
594243830Sdim	buffer_dump(&outgoing_packet);
595243830Sdim#endif
596243830Sdim
597243830Sdim	if (comp && comp->enabled) {
598243830Sdim		len = buffer_len(&outgoing_packet);
599243830Sdim		/* skip header, compress only payload */
600243830Sdim		buffer_consume(&outgoing_packet, 5);
601243830Sdim		buffer_clear(&compression_buffer);
602243830Sdim		buffer_compress(&outgoing_packet, &compression_buffer);
603243830Sdim		buffer_clear(&outgoing_packet);
604243830Sdim		buffer_append(&outgoing_packet, "\0\0\0\0\0", 5);
605243830Sdim		buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
606263508Sdim		    buffer_len(&compression_buffer));
607243830Sdim		DBG(debug("compression: raw %d compressed %d", len,
608243830Sdim		    buffer_len(&outgoing_packet)));
609243830Sdim	}
610243830Sdim
611263508Sdim	/* sizeof (packet_len + pad_len + payload) */
612243830Sdim	len = buffer_len(&outgoing_packet);
613243830Sdim
614243830Sdim	/*
615243830Sdim	 * calc size of padding, alloc space, get random data,
616243830Sdim	 * minimum padding is 4 bytes
617243830Sdim	 */
618243830Sdim	padlen = block_size - (len % block_size);
619243830Sdim	if (padlen < 4)
620243830Sdim		padlen += block_size;
621243830Sdim	buffer_append_space(&outgoing_packet, &cp, padlen);
622243830Sdim	if (enc && enc->cipher->number != SSH_CIPHER_NONE) {
623243830Sdim		/* random padding */
624243830Sdim		for (i = 0; i < padlen; i++) {
625243830Sdim			if (i % 4 == 0)
626243830Sdim				rand = arc4random();
627243830Sdim			cp[i] = rand & 0xff;
628243830Sdim			rand >>= 8;
629243830Sdim		}
630243830Sdim	} else {
631243830Sdim		/* clear padding */
632243830Sdim		memset(cp, 0, padlen);
633243830Sdim	}
634243830Sdim	/* packet_length includes payload, padding and padding length field */
635249423Sdim	packet_length = buffer_len(&outgoing_packet) - 4;
636249423Sdim	cp = buffer_ptr(&outgoing_packet);
637249423Sdim	PUT_32BIT(cp, packet_length);
638249423Sdim	cp[4] = padlen & 0xff;
639249423Sdim	DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
640249423Sdim
641249423Sdim	/* compute MAC over seqnr and packet(length fields, payload, padding) */
642249423Sdim	if (mac && mac->enabled) {
643263508Sdim		macbuf = mac_compute(mac, seqnr,
644249423Sdim		    (u_char *) buffer_ptr(&outgoing_packet),
645249423Sdim		    buffer_len(&outgoing_packet));
646249423Sdim		DBG(debug("done calc MAC out #%d", seqnr));
647249423Sdim	}
648249423Sdim	/* encrypt packet and append to output buffer. */
649249423Sdim	buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
650249423Sdim	packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
651249423Sdim	    buffer_len(&outgoing_packet));
652249423Sdim	/* append unencrypted MAC */
653249423Sdim	if (mac && mac->enabled)
654249423Sdim		buffer_append(&output, (char *)macbuf, mac->mac_len);
655226633Sdim#ifdef PACKET_DEBUG
656226633Sdim	fprintf(stderr, "encrypted: ");
657226633Sdim	buffer_dump(&output);
658263508Sdim#endif
659221345Sdim	/* increment sequence number for outgoing packets */
660226633Sdim	if (++seqnr == 0)
661226633Sdim		log("outgoing seqnr wraps around");
662226633Sdim	buffer_clear(&outgoing_packet);
663221345Sdim
664263508Sdim	if (type == SSH2_MSG_NEWKEYS)
665263508Sdim		set_newkeys(MODE_OUT);
666226633Sdim}
667226633Sdim
668234353Sdimvoid
669234353Sdimpacket_send()
670243830Sdim{
671243830Sdim	if (use_ssh2_packet_format)
672243830Sdim		packet_send2();
673234353Sdim	else
674234353Sdim		packet_send1();
675243830Sdim	DBG(debug("packet_send done"));
676243830Sdim}
677243830Sdim
678234353Sdim/*
679226633Sdim * Waits until a packet has been received, and returns its type.  Note that
680263508Sdim * no other data is processed until this returns, so this function should not
681263508Sdim * be used during the interactive session.
682263508Sdim */
683263508Sdim
684263508Sdimint
685263508Sdimpacket_read(int *payload_len_ptr)
686226633Sdim{
687226633Sdim	int type, len;
688226633Sdim	fd_set *setp;
689226633Sdim	char buf[8192];
690226633Sdim	DBG(debug("packet_read()"));
691226633Sdim
692226633Sdim	setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) *
693226633Sdim	    sizeof(fd_mask));
694226633Sdim
695226633Sdim	/* Since we are blocking, ensure that all written packets have been sent. */
696226633Sdim	packet_write_wait();
697226633Sdim
698234982Sdim	/* Stay in the loop until we have received a complete packet. */
699234982Sdim	for (;;) {
700226633Sdim		/* Try to read a packet from the buffer. */
701226633Sdim		type = packet_read_poll(payload_len_ptr);
702226633Sdim		if (!use_ssh2_packet_format && (
703221345Sdim		    type == SSH_SMSG_SUCCESS
704263508Sdim		    || type == SSH_SMSG_FAILURE
705221345Sdim		    || type == SSH_CMSG_EOF
706221345Sdim		    || type == SSH_CMSG_EXIT_CONFIRMATION))
707234353Sdim			packet_integrity_check(*payload_len_ptr, 0, type);
708234353Sdim		/* If we got a packet, return it. */
709234353Sdim		if (type != SSH_MSG_NONE) {
710221345Sdim			xfree(setp);
711221345Sdim			return type;
712221345Sdim		}
713221345Sdim		/*
714221345Sdim		 * Otherwise, wait for some data to arrive, add it to the
715221345Sdim		 * buffer, and try again.
716221345Sdim		 */
717221345Sdim		memset(setp, 0, howmany(connection_in + 1, NFDBITS) *
718221345Sdim		    sizeof(fd_mask));
719221345Sdim		FD_SET(connection_in, setp);
720221345Sdim
721221345Sdim		/* Wait for some data to arrive. */
722221345Sdim		while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 &&
723221345Sdim		    (errno == EAGAIN || errno == EINTR))
724221345Sdim			;
725221345Sdim
726221345Sdim		/* Read data from the socket. */
727221345Sdim		len = read(connection_in, buf, sizeof(buf));
728221345Sdim		if (len == 0) {
729221345Sdim			log("Connection closed by %.200s", get_remote_ipaddr());
730221345Sdim			fatal_cleanup();
731221345Sdim		}
732221345Sdim		if (len < 0)
733221345Sdim			fatal("Read from socket failed: %.100s", strerror(errno));
734221345Sdim		/* Append it to the buffer. */
735221345Sdim		packet_process_incoming(buf, len);
736221345Sdim	}
737221345Sdim	/* NOTREACHED */
738221345Sdim}
739221345Sdim
740221345Sdim/*
741221345Sdim * Waits until a packet has been received, verifies that its type matches
742193323Sed * that given, and gives a fatal error and exits if there is a mismatch.
743193323Sed */
744193323Sed
745263508Sdimvoid
746193323Sedpacket_read_expect(int *payload_len_ptr, int expected_type)
747193323Sed{
748199989Srdivacky	int type;
749193323Sed
750193323Sed	type = packet_read(payload_len_ptr);
751193323Sed	if (type != expected_type)
752198090Srdivacky		packet_disconnect("Protocol error: expected packet type %d, got %d",
753193323Sed		    expected_type, type);
754198090Srdivacky}
755193323Sed
756198090Srdivacky/* Checks if a full packet is available in the data received so far via
757263508Sdim * packet_process_incoming.  If so, reads the packet; otherwise returns
758193323Sed * SSH_MSG_NONE.  This does not wait for data from the connection.
759193323Sed *
760193323Sed * SSH_MSG_DISCONNECT is handled specially here.  Also,
761263508Sdim * SSH_MSG_IGNORE messages are skipped by this function and are never returned
762193323Sed * to higher levels.
763263508Sdim *
764263508Sdim * The returned payload_len does include space consumed by:
765263508Sdim * 	Packet length
766193323Sed * 	Padding
767263508Sdim * 	Packet type
768263508Sdim * 	Check bytes
769263508Sdim */
770263508Sdim
771193323Sedint
772193323Sedpacket_read_poll1(int *payload_len_ptr)
773193323Sed{
774193323Sed	u_int len, padded_len;
775193323Sed	u_char *ucp;
776193323Sed	char buf[8], *cp;
777193323Sed	u_int checksum, stored_checksum;
778193323Sed
779193323Sed	/* Check if input size is less than minimum packet size. */
780	if (buffer_len(&input) < 4 + 8)
781		return SSH_MSG_NONE;
782	/* Get length of incoming packet. */
783	ucp = (u_char *) buffer_ptr(&input);
784	len = GET_32BIT(ucp);
785	if (len < 1 + 2 + 2 || len > 256 * 1024)
786		packet_disconnect("Bad packet length %d.", len);
787	padded_len = (len + 8) & ~7;
788
789	/* Check if the packet has been entirely received. */
790	if (buffer_len(&input) < 4 + padded_len)
791		return SSH_MSG_NONE;
792
793	/* The entire packet is in buffer. */
794
795	/* Consume packet length. */
796	buffer_consume(&input, 4);
797
798	/* Copy data to incoming_packet. */
799	buffer_clear(&incoming_packet);
800	buffer_append_space(&incoming_packet, &cp, padded_len);
801	packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len);
802	buffer_consume(&input, padded_len);
803
804#ifdef PACKET_DEBUG
805	fprintf(stderr, "read_poll plain: ");
806	buffer_dump(&incoming_packet);
807#endif
808
809	/* Compute packet checksum. */
810	checksum = ssh_crc32((u_char *) buffer_ptr(&incoming_packet),
811	    buffer_len(&incoming_packet) - 4);
812
813	/* Skip padding. */
814	buffer_consume(&incoming_packet, 8 - len % 8);
815
816	/* Test check bytes. */
817
818	if (len != buffer_len(&incoming_packet))
819		packet_disconnect("packet_read_poll: len %d != buffer_len %d.",
820		    len, buffer_len(&incoming_packet));
821
822	ucp = (u_char *) buffer_ptr(&incoming_packet) + len - 4;
823	stored_checksum = GET_32BIT(ucp);
824	if (checksum != stored_checksum)
825		packet_disconnect("Corrupted check bytes on input.");
826	buffer_consume_end(&incoming_packet, 4);
827
828	/* If using packet compression, decompress the packet. */
829	if (packet_compression) {
830		buffer_clear(&compression_buffer);
831		buffer_uncompress(&incoming_packet, &compression_buffer);
832		buffer_clear(&incoming_packet);
833		buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
834		    buffer_len(&compression_buffer));
835	}
836	/* Get packet type. */
837	buffer_get(&incoming_packet, &buf[0], 1);
838
839	/* Return length of payload (without type field). */
840	*payload_len_ptr = buffer_len(&incoming_packet);
841
842	/* Return type. */
843	return (u_char) buf[0];
844}
845
846int
847packet_read_poll2(int *payload_len_ptr)
848{
849	static u_int32_t seqnr = 0;
850	static u_int packet_length = 0;
851	u_int padlen, need;
852	u_char buf[8], *macbuf;
853	u_char *ucp;
854	char *cp;
855	int type;
856	int maclen, block_size;
857	Enc *enc   = NULL;
858	Mac *mac   = NULL;
859	Comp *comp = NULL;
860
861	if (newkeys[MODE_IN] != NULL) {
862		enc  = &newkeys[MODE_IN]->enc;
863		mac  = &newkeys[MODE_IN]->mac;
864		comp = &newkeys[MODE_IN]->comp;
865	}
866	maclen = mac && mac->enabled ? mac->mac_len : 0;
867	block_size = enc ? enc->cipher->block_size : 8;
868
869	if (packet_length == 0) {
870		/*
871		 * check if input size is less than the cipher block size,
872		 * decrypt first block and extract length of incoming packet
873		 */
874		if (buffer_len(&input) < block_size)
875			return SSH_MSG_NONE;
876		buffer_clear(&incoming_packet);
877		buffer_append_space(&incoming_packet, &cp, block_size);
878		packet_decrypt(&receive_context, cp, buffer_ptr(&input),
879		    block_size);
880		ucp = (u_char *) buffer_ptr(&incoming_packet);
881		packet_length = GET_32BIT(ucp);
882		if (packet_length < 1 + 4 || packet_length > 256 * 1024) {
883			buffer_dump(&incoming_packet);
884			packet_disconnect("Bad packet length %d.", packet_length);
885		}
886		DBG(debug("input: packet len %d", packet_length+4));
887		buffer_consume(&input, block_size);
888	}
889	/* we have a partial packet of block_size bytes */
890	need = 4 + packet_length - block_size;
891	DBG(debug("partial packet %d, need %d, maclen %d", block_size,
892	    need, maclen));
893	if (need % block_size != 0)
894		fatal("padding error: need %d block %d mod %d",
895		    need, block_size, need % block_size);
896	/*
897	 * check if the entire packet has been received and
898	 * decrypt into incoming_packet
899	 */
900	if (buffer_len(&input) < need + maclen)
901		return SSH_MSG_NONE;
902#ifdef PACKET_DEBUG
903	fprintf(stderr, "read_poll enc/full: ");
904	buffer_dump(&input);
905#endif
906	buffer_append_space(&incoming_packet, &cp, need);
907	packet_decrypt(&receive_context, cp, buffer_ptr(&input), need);
908	buffer_consume(&input, need);
909	/*
910	 * compute MAC over seqnr and packet,
911	 * increment sequence number for incoming packet
912	 */
913	if (mac && mac->enabled) {
914		macbuf = mac_compute(mac, seqnr,
915		    (u_char *) buffer_ptr(&incoming_packet),
916		    buffer_len(&incoming_packet));
917		if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
918			packet_disconnect("Corrupted MAC on input.");
919		DBG(debug("MAC #%d ok", seqnr));
920		buffer_consume(&input, mac->mac_len);
921	}
922	if (++seqnr == 0)
923		log("incoming seqnr wraps around");
924
925	/* get padlen */
926	cp = buffer_ptr(&incoming_packet) + 4;
927	padlen = *cp & 0xff;
928	DBG(debug("input: padlen %d", padlen));
929	if (padlen < 4)
930		packet_disconnect("Corrupted padlen %d on input.", padlen);
931
932	/* skip packet size + padlen, discard padding */
933	buffer_consume(&incoming_packet, 4 + 1);
934	buffer_consume_end(&incoming_packet, padlen);
935
936	DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet)));
937	if (comp && comp->enabled) {
938		buffer_clear(&compression_buffer);
939		buffer_uncompress(&incoming_packet, &compression_buffer);
940		buffer_clear(&incoming_packet);
941		buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
942		    buffer_len(&compression_buffer));
943		DBG(debug("input: len after de-compress %d", buffer_len(&incoming_packet)));
944	}
945	/*
946	 * get packet type, implies consume.
947	 * return length of payload (without type field)
948	 */
949	buffer_get(&incoming_packet, (char *)&buf[0], 1);
950	*payload_len_ptr = buffer_len(&incoming_packet);
951
952	/* reset for next packet */
953	packet_length = 0;
954
955	/* extract packet type */
956	type = (u_char)buf[0];
957
958	if (type == SSH2_MSG_NEWKEYS)
959		set_newkeys(MODE_IN);
960
961#ifdef PACKET_DEBUG
962	fprintf(stderr, "read/plain[%d]:\r\n", type);
963	buffer_dump(&incoming_packet);
964#endif
965	return (u_char)type;
966}
967
968int
969packet_read_poll(int *payload_len_ptr)
970{
971	char *msg;
972	for (;;) {
973		int type = use_ssh2_packet_format ?
974		    packet_read_poll2(payload_len_ptr):
975		    packet_read_poll1(payload_len_ptr);
976
977		if(compat20) {
978			int reason;
979			if (type != 0)
980				DBG(debug("received packet type %d", type));
981			switch(type) {
982			case SSH2_MSG_IGNORE:
983				break;
984			case SSH2_MSG_DEBUG:
985				packet_get_char();
986				msg = packet_get_string(NULL);
987				debug("Remote: %.900s", msg);
988				xfree(msg);
989				msg = packet_get_string(NULL);
990				xfree(msg);
991				break;
992			case SSH2_MSG_DISCONNECT:
993				reason = packet_get_int();
994				msg = packet_get_string(NULL);
995				log("Received disconnect from %s: %d: %.400s", get_remote_ipaddr(),
996					reason, msg);
997				xfree(msg);
998				fatal_cleanup();
999				break;
1000			default:
1001				return type;
1002				break;
1003			}
1004		} else {
1005			switch(type) {
1006			case SSH_MSG_IGNORE:
1007				break;
1008			case SSH_MSG_DEBUG:
1009				msg = packet_get_string(NULL);
1010				debug("Remote: %.900s", msg);
1011				xfree(msg);
1012				break;
1013			case SSH_MSG_DISCONNECT:
1014				msg = packet_get_string(NULL);
1015				log("Received disconnect from %s: %.400s", get_remote_ipaddr(),
1016					msg);
1017				fatal_cleanup();
1018				xfree(msg);
1019				break;
1020			default:
1021				if (type != 0)
1022					DBG(debug("received packet type %d", type));
1023				return type;
1024				break;
1025			}
1026		}
1027	}
1028}
1029
1030/*
1031 * Buffers the given amount of input characters.  This is intended to be used
1032 * together with packet_read_poll.
1033 */
1034
1035void
1036packet_process_incoming(const char *buf, u_int len)
1037{
1038	buffer_append(&input, buf, len);
1039}
1040
1041/* Returns a character from the packet. */
1042
1043u_int
1044packet_get_char()
1045{
1046	char ch;
1047	buffer_get(&incoming_packet, &ch, 1);
1048	return (u_char) ch;
1049}
1050
1051/* Returns an integer from the packet data. */
1052
1053u_int
1054packet_get_int()
1055{
1056	return buffer_get_int(&incoming_packet);
1057}
1058
1059/*
1060 * Returns an arbitrary precision integer from the packet data.  The integer
1061 * must have been initialized before this call.
1062 */
1063
1064void
1065packet_get_bignum(BIGNUM * value, int *length_ptr)
1066{
1067	*length_ptr = buffer_get_bignum(&incoming_packet, value);
1068}
1069
1070void
1071packet_get_bignum2(BIGNUM * value, int *length_ptr)
1072{
1073	*length_ptr = buffer_get_bignum2(&incoming_packet, value);
1074}
1075
1076char *
1077packet_get_raw(int *length_ptr)
1078{
1079	int bytes = buffer_len(&incoming_packet);
1080	if (length_ptr != NULL)
1081		*length_ptr = bytes;
1082	return buffer_ptr(&incoming_packet);
1083}
1084
1085int
1086packet_remaining(void)
1087{
1088	return buffer_len(&incoming_packet);
1089}
1090
1091/*
1092 * Returns a string from the packet data.  The string is allocated using
1093 * xmalloc; it is the responsibility of the calling program to free it when
1094 * no longer needed.  The length_ptr argument may be NULL, or point to an
1095 * integer into which the length of the string is stored.
1096 */
1097
1098char *
1099packet_get_string(u_int *length_ptr)
1100{
1101	return buffer_get_string(&incoming_packet, length_ptr);
1102}
1103
1104/*
1105 * Sends a diagnostic message from the server to the client.  This message
1106 * can be sent at any time (but not while constructing another message). The
1107 * message is printed immediately, but only if the client is being executed
1108 * in verbose mode.  These messages are primarily intended to ease debugging
1109 * authentication problems.   The length of the formatted message must not
1110 * exceed 1024 bytes.  This will automatically call packet_write_wait.
1111 */
1112
1113void
1114packet_send_debug(const char *fmt,...)
1115{
1116	char buf[1024];
1117	va_list args;
1118
1119	if (compat20 && (datafellows & SSH_BUG_DEBUG))
1120		return;
1121
1122	va_start(args, fmt);
1123	vsnprintf(buf, sizeof(buf), fmt, args);
1124	va_end(args);
1125
1126	if (compat20) {
1127		packet_start(SSH2_MSG_DEBUG);
1128		packet_put_char(0);	/* bool: always display */
1129		packet_put_cstring(buf);
1130		packet_put_cstring("");
1131	} else {
1132		packet_start(SSH_MSG_DEBUG);
1133		packet_put_cstring(buf);
1134	}
1135	packet_send();
1136	packet_write_wait();
1137}
1138
1139/*
1140 * Logs the error plus constructs and sends a disconnect packet, closes the
1141 * connection, and exits.  This function never returns. The error message
1142 * should not contain a newline.  The length of the formatted message must
1143 * not exceed 1024 bytes.
1144 */
1145
1146void
1147packet_disconnect(const char *fmt,...)
1148{
1149	char buf[1024];
1150	va_list args;
1151	static int disconnecting = 0;
1152	if (disconnecting)	/* Guard against recursive invocations. */
1153		fatal("packet_disconnect called recursively.");
1154	disconnecting = 1;
1155
1156	/*
1157	 * Format the message.  Note that the caller must make sure the
1158	 * message is of limited size.
1159	 */
1160	va_start(args, fmt);
1161	vsnprintf(buf, sizeof(buf), fmt, args);
1162	va_end(args);
1163
1164	/* Send the disconnect message to the other side, and wait for it to get sent. */
1165	if (compat20) {
1166		packet_start(SSH2_MSG_DISCONNECT);
1167		packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR);
1168		packet_put_cstring(buf);
1169		packet_put_cstring("");
1170	} else {
1171		packet_start(SSH_MSG_DISCONNECT);
1172		packet_put_string(buf, strlen(buf));
1173	}
1174	packet_send();
1175	packet_write_wait();
1176
1177	/* Stop listening for connections. */
1178	channel_stop_listening();
1179
1180	/* Close the connection. */
1181	packet_close();
1182
1183	/* Display the error locally and exit. */
1184	log("Disconnecting: %.100s", buf);
1185	fatal_cleanup();
1186}
1187
1188/* Checks if there is any buffered output, and tries to write some of the output. */
1189
1190void
1191packet_write_poll()
1192{
1193	int len = buffer_len(&output);
1194	if (len > 0) {
1195		len = write(connection_out, buffer_ptr(&output), len);
1196		if (len <= 0) {
1197			if (errno == EAGAIN)
1198				return;
1199			else
1200				fatal("Write failed: %.100s", strerror(errno));
1201		}
1202		buffer_consume(&output, len);
1203	}
1204}
1205
1206/*
1207 * Calls packet_write_poll repeatedly until all pending output data has been
1208 * written.
1209 */
1210
1211void
1212packet_write_wait()
1213{
1214	fd_set *setp;
1215
1216	setp = (fd_set *)xmalloc(howmany(connection_out + 1, NFDBITS) *
1217	    sizeof(fd_mask));
1218	packet_write_poll();
1219	while (packet_have_data_to_write()) {
1220		memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
1221		    sizeof(fd_mask));
1222		FD_SET(connection_out, setp);
1223		while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 &&
1224		    (errno == EAGAIN || errno == EINTR))
1225			;
1226		packet_write_poll();
1227	}
1228	xfree(setp);
1229}
1230
1231/* Returns true if there is buffered data to write to the connection. */
1232
1233int
1234packet_have_data_to_write()
1235{
1236	return buffer_len(&output) != 0;
1237}
1238
1239/* Returns true if there is not too much data to write to the connection. */
1240
1241int
1242packet_not_very_much_data_to_write()
1243{
1244	if (interactive_mode)
1245		return buffer_len(&output) < 16384;
1246	else
1247		return buffer_len(&output) < 128 * 1024;
1248}
1249
1250/* Informs that the current session is interactive.  Sets IP flags for that. */
1251
1252void
1253packet_set_interactive(int interactive)
1254{
1255	static int called = 0;
1256	int lowdelay = IPTOS_LOWDELAY;
1257	int throughput = IPTOS_THROUGHPUT;
1258	int on = 1;
1259
1260	if (called)
1261		return;
1262	called = 1;
1263
1264	/* Record that we are in interactive mode. */
1265	interactive_mode = interactive;
1266
1267	/* Only set socket options if using a socket.  */
1268	if (!packet_connection_is_on_socket())
1269		return;
1270	/*
1271	 * IPTOS_LOWDELAY and IPTOS_THROUGHPUT are IPv4 only
1272	 */
1273	if (interactive) {
1274		/*
1275		 * Set IP options for an interactive connection.  Use
1276		 * IPTOS_LOWDELAY and TCP_NODELAY.
1277		 */
1278		if (packet_connection_is_ipv4()) {
1279			if (setsockopt(connection_in, IPPROTO_IP, IP_TOS,
1280			    (void *) &lowdelay, sizeof(lowdelay)) < 0)
1281				error("setsockopt IPTOS_LOWDELAY: %.100s",
1282				    strerror(errno));
1283		}
1284		if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on,
1285		    sizeof(on)) < 0)
1286			error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
1287	} else if (packet_connection_is_ipv4()) {
1288		/*
1289		 * Set IP options for a non-interactive connection.  Use
1290		 * IPTOS_THROUGHPUT.
1291		 */
1292		if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput,
1293		    sizeof(throughput)) < 0)
1294			error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
1295	}
1296}
1297
1298/* Returns true if the current connection is interactive. */
1299
1300int
1301packet_is_interactive()
1302{
1303	return interactive_mode;
1304}
1305
1306int
1307packet_set_maxsize(int s)
1308{
1309	static int called = 0;
1310	if (called) {
1311		log("packet_set_maxsize: called twice: old %d new %d",
1312		    max_packet_size, s);
1313		return -1;
1314	}
1315	if (s < 4 * 1024 || s > 1024 * 1024) {
1316		log("packet_set_maxsize: bad size %d", s);
1317		return -1;
1318	}
1319	log("packet_set_maxsize: setting to %d", s);
1320	max_packet_size = s;
1321	return s;
1322}
1323
1324/*
1325 * 9.2.  Ignored Data Message
1326 *
1327 *   byte      SSH_MSG_IGNORE
1328 *   string    data
1329 *
1330 * All implementations MUST understand (and ignore) this message at any
1331 * time (after receiving the protocol version). No implementation is
1332 * required to send them. This message can be used as an additional
1333 * protection measure against advanced traffic analysis techniques.
1334 */
1335/* size of current + ignore message should be n*sumlen bytes (w/o mac) */
1336void
1337packet_inject_ignore(int sumlen)
1338{
1339	int blocksize, padlen, have, need, nb, mini, nbytes;
1340	Enc *enc = NULL;
1341
1342	if (use_ssh2_packet_format == 0)
1343		return;
1344
1345	have = buffer_len(&outgoing_packet);
1346	debug2("packet_inject_ignore: current %d", have);
1347	if (newkeys[MODE_OUT] != NULL)
1348		enc  = &newkeys[MODE_OUT]->enc;
1349	blocksize = enc ? enc->cipher->block_size : 8;
1350	padlen = blocksize - (have % blocksize);
1351	if (padlen < 4)
1352		padlen += blocksize;
1353	have += padlen;
1354	have /= blocksize;	/* # of blocks for current message */
1355
1356	nb   = roundup(sumlen,  blocksize) / blocksize;	/* blocks for both */
1357	mini = roundup(5+1+4+4, blocksize) / blocksize; /* minsize ignore msg */
1358	need = nb - (have % nb);			/* blocks for ignore */
1359	if (need <= mini)
1360		need += nb;
1361	nbytes = (need - mini) * blocksize;	/* size of ignore payload */
1362	debug2("packet_inject_ignore: block %d have %d nb %d mini %d need %d",
1363	    blocksize, have, nb, mini, need);
1364
1365	/* enqueue current message and append a ignore message */
1366	packet_send();
1367	packet_send_ignore(nbytes);
1368}
1369
1370void
1371packet_send_ignore(int nbytes)
1372{
1373	u_int32_t rand = 0;
1374	int i;
1375
1376	packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE);
1377	packet_put_int(nbytes);
1378	for(i = 0; i < nbytes; i++) {
1379		if (i % 4 == 0)
1380			rand = arc4random();
1381		packet_put_char(rand & 0xff);
1382		rand >>= 8;
1383	}
1384}
1385