summaryrefslogtreecommitdiff
path: root/packet.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
committerDamien Miller <djm@mindrot.org>1999-11-25 00:26:21 +1100
commit95def09838fc61b37b6ea7cd5c234a465b4b129b (patch)
tree042744f76f40a326b873cb1c3690a6d7d966bc3e /packet.c
parent4d2f15f895f4c795afc008aeff3fd2ceffbc44f4 (diff)
- Merged very large OpenBSD source code reformat
- OpenBSD CVS updates - [channels.c cipher.c compat.c log-client.c scp.c serverloop.c] [ssh.h sshd.8 sshd.c] syslog changes: * Unified Logmessage for all auth-types, for success and for failed * Standard connections get only ONE line in the LOG when level==LOG: Auth-attempts are logged only, if authentication is: a) successfull or b) with passwd or c) we had more than AUTH_FAIL_LOG failues * many log() became verbose() * old behaviour with level=VERBOSE - [readconf.c readconf.h ssh.1 ssh.h sshconnect.c sshd.c] tranfer s/key challenge/response data in SSH_SMSG_AUTH_TIS_CHALLENGE messages. allows use of s/key in windows (ttssh, securecrt) and ssh-1.2.27 clients without 'ssh -v', ok: niels@ - [sshd.8] -V, for fallback to openssh in SSH2 compatibility mode - [sshd.c] fix sigchld race; cjc5@po.cwru.edu
Diffstat (limited to 'packet.c')
-rw-r--r--packet.c859
1 files changed, 419 insertions, 440 deletions
diff --git a/packet.c b/packet.c
index 74bb38230..0e60dd5ec 100644
--- a/packet.c
+++ b/packet.c
@@ -1,21 +1,21 @@
1/* 1/*
2 2 *
3packet.c 3 * packet.c
4 4 *
5Author: Tatu Ylonen <ylo@cs.hut.fi> 5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 6 *
7Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 All rights reserved 8 * All rights reserved
9 9 *
10Created: Sat Mar 18 02:40:40 1995 ylo 10 * Created: Sat Mar 18 02:40:40 1995 ylo
11 11 *
12This file contains code implementing the packet protocol and communication 12 * This file contains code implementing the packet protocol and communication
13with the other side. This same code is used both on client and server side. 13 * with the other side. This same code is used both on client and server side.
14 14 *
15*/ 15 */
16 16
17#include "includes.h" 17#include "includes.h"
18RCSID("$Id: packet.c,v 1.4 1999/11/21 02:23:53 damien Exp $"); 18RCSID("$Id: packet.c,v 1.5 1999/11/24 13:26:22 damien Exp $");
19 19
20#include "xmalloc.h" 20#include "xmalloc.h"
21#include "buffer.h" 21#include "buffer.h"
@@ -45,7 +45,8 @@ static unsigned int remote_protocol_flags = 0;
45 45
46/* Encryption context for receiving data. This is only used for decryption. */ 46/* Encryption context for receiving data. This is only used for decryption. */
47static CipherContext receive_context; 47static CipherContext receive_context;
48/* Encryption coontext for sending data. This is only used for encryption. */ 48
49/* Encryption context for sending data. This is only used for encryption. */
49static CipherContext send_context; 50static CipherContext send_context;
50 51
51/* Buffer for raw input data from the socket. */ 52/* Buffer for raw input data from the socket. */
@@ -81,22 +82,20 @@ static int interactive_mode = 0;
81void 82void
82packet_set_connection(int fd_in, int fd_out) 83packet_set_connection(int fd_in, int fd_out)
83{ 84{
84 connection_in = fd_in; 85 connection_in = fd_in;
85 connection_out = fd_out; 86 connection_out = fd_out;
86 cipher_type = SSH_CIPHER_NONE; 87 cipher_type = SSH_CIPHER_NONE;
87 cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *)"", 0, 1); 88 cipher_set_key(&send_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 1);
88 cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *)"", 0, 0); 89 cipher_set_key(&receive_context, SSH_CIPHER_NONE, (unsigned char *) "", 0, 0);
89 if (!initialized) 90 if (!initialized) {
90 { 91 initialized = 1;
91 initialized = 1; 92 buffer_init(&input);
92 buffer_init(&input); 93 buffer_init(&output);
93 buffer_init(&output); 94 buffer_init(&outgoing_packet);
94 buffer_init(&outgoing_packet); 95 buffer_init(&incoming_packet);
95 buffer_init(&incoming_packet); 96 }
96 } 97 /* Kludge: arrange the close function to be called from fatal(). */
97 98 fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
98 /* Kludge: arrange the close function to be called from fatal(). */
99 fatal_add_cleanup((void (*)(void *))packet_close, NULL);
100} 99}
101 100
102/* Sets the connection into non-blocking mode. */ 101/* Sets the connection into non-blocking mode. */
@@ -104,15 +103,14 @@ packet_set_connection(int fd_in, int fd_out)
104void 103void
105packet_set_nonblocking() 104packet_set_nonblocking()
106{ 105{
107 /* Set the socket into non-blocking mode. */ 106 /* Set the socket into non-blocking mode. */
108 if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0) 107 if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0)
109 error("fcntl O_NONBLOCK: %.100s", strerror(errno)); 108 error("fcntl O_NONBLOCK: %.100s", strerror(errno));
110 109
111 if (connection_out != connection_in) 110 if (connection_out != connection_in) {
112 { 111 if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0)
113 if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0) 112 error("fcntl O_NONBLOCK: %.100s", strerror(errno));
114 error("fcntl O_NONBLOCK: %.100s", strerror(errno)); 113 }
115 }
116} 114}
117 115
118/* Returns the socket used for reading. */ 116/* Returns the socket used for reading. */
@@ -120,7 +118,7 @@ packet_set_nonblocking()
120int 118int
121packet_get_connection_in() 119packet_get_connection_in()
122{ 120{
123 return connection_in; 121 return connection_in;
124} 122}
125 123
126/* Returns the descriptor used for writing. */ 124/* Returns the descriptor used for writing. */
@@ -128,7 +126,7 @@ packet_get_connection_in()
128int 126int
129packet_get_connection_out() 127packet_get_connection_out()
130{ 128{
131 return connection_out; 129 return connection_out;
132} 130}
133 131
134/* Closes the connection and clears and frees internal data structures. */ 132/* Closes the connection and clears and frees internal data structures. */
@@ -136,28 +134,24 @@ packet_get_connection_out()
136void 134void
137packet_close() 135packet_close()
138{ 136{
139 if (!initialized) 137 if (!initialized)
140 return; 138 return;
141 initialized = 0; 139 initialized = 0;
142 if (connection_in == connection_out) 140 if (connection_in == connection_out) {
143 { 141 shutdown(connection_out, SHUT_RDWR);
144 shutdown(connection_out, SHUT_RDWR); 142 close(connection_out);
145 close(connection_out); 143 } else {
146 } 144 close(connection_in);
147 else 145 close(connection_out);
148 { 146 }
149 close(connection_in); 147 buffer_free(&input);
150 close(connection_out); 148 buffer_free(&output);
151 } 149 buffer_free(&outgoing_packet);
152 buffer_free(&input); 150 buffer_free(&incoming_packet);
153 buffer_free(&output); 151 if (packet_compression) {
154 buffer_free(&outgoing_packet); 152 buffer_free(&compression_buffer);
155 buffer_free(&incoming_packet); 153 buffer_compress_uninit();
156 if (packet_compression) 154 }
157 {
158 buffer_free(&compression_buffer);
159 buffer_compress_uninit();
160 }
161} 155}
162 156
163/* Sets remote side protocol flags. */ 157/* Sets remote side protocol flags. */
@@ -165,8 +159,8 @@ packet_close()
165void 159void
166packet_set_protocol_flags(unsigned int protocol_flags) 160packet_set_protocol_flags(unsigned int protocol_flags)
167{ 161{
168 remote_protocol_flags = protocol_flags; 162 remote_protocol_flags = protocol_flags;
169 channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0); 163 channel_set_options((protocol_flags & SSH_PROTOFLAG_HOST_IN_FWD_OPEN) != 0);
170} 164}
171 165
172/* Returns the remote protocol flags set earlier by the above function. */ 166/* Returns the remote protocol flags set earlier by the above function. */
@@ -174,63 +168,60 @@ packet_set_protocol_flags(unsigned int protocol_flags)
174unsigned int 168unsigned int
175packet_get_protocol_flags() 169packet_get_protocol_flags()
176{ 170{
177 return remote_protocol_flags; 171 return remote_protocol_flags;
178} 172}
179 173
180/* Starts packet compression from the next packet on in both directions. 174/* Starts packet compression from the next packet on in both directions.
181 Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. */ 175 Level is compression level 1 (fastest) - 9 (slow, best) as in gzip. */
182 176
183void 177void
184packet_start_compression(int level) 178packet_start_compression(int level)
185{ 179{
186 if (packet_compression) 180 if (packet_compression)
187 fatal("Compression already enabled."); 181 fatal("Compression already enabled.");
188 packet_compression = 1; 182 packet_compression = 1;
189 buffer_init(&compression_buffer); 183 buffer_init(&compression_buffer);
190 buffer_compress_init(level); 184 buffer_compress_init(level);
191} 185}
192 186
193/* Encrypts the given number of bytes, copying from src to dest. 187/* Encrypts the given number of bytes, copying from src to dest.
194 bytes is known to be a multiple of 8. */ 188 bytes is known to be a multiple of 8. */
195 189
196void 190void
197packet_encrypt(CipherContext *cc, void *dest, void *src, 191packet_encrypt(CipherContext * cc, void *dest, void *src,
198 unsigned int bytes) 192 unsigned int bytes)
199{ 193{
200 cipher_encrypt(cc, dest, src, bytes); 194 cipher_encrypt(cc, dest, src, bytes);
201} 195}
202 196
203/* Decrypts the given number of bytes, copying from src to dest. 197/* Decrypts the given number of bytes, copying from src to dest.
204 bytes is known to be a multiple of 8. */ 198 bytes is known to be a multiple of 8. */
205 199
206void 200void
207packet_decrypt(CipherContext *cc, void *dest, void *src, 201packet_decrypt(CipherContext * cc, void *dest, void *src,
208 unsigned int bytes) 202 unsigned int bytes)
209{ 203{
210 int i; 204 int i;
211 205
212 if ((bytes % 8) != 0) 206 if ((bytes % 8) != 0)
213 fatal("packet_decrypt: bad ciphertext length %d", bytes); 207 fatal("packet_decrypt: bad ciphertext length %d", bytes);
214 208
215 /* 209 /* Cryptographic attack detector for ssh - Modifications for packet.c
216 Cryptographic attack detector for ssh - Modifications for packet.c 210 (C)1998 CORE-SDI, Buenos Aires Argentina Ariel Futoransky(futo@core-sdi.com) */
217 (C)1998 CORE-SDI, Buenos Aires Argentina 211
218 Ariel Futoransky(futo@core-sdi.com) 212 switch (cc->type) {
219 */ 213 case SSH_CIPHER_NONE:
220 switch (cc->type) 214 i = DEATTACK_OK;
221 { 215 break;
222 case SSH_CIPHER_NONE: 216 default:
223 i = DEATTACK_OK; 217 i = detect_attack(src, bytes, NULL);
224 break; 218 break;
225 default: 219 }
226 i = detect_attack(src, bytes, NULL); 220
227 break; 221 if (i == DEATTACK_DETECTED)
228 } 222 packet_disconnect("crc32 compensation attack: network attack detected");
229 223
230 if (i == DEATTACK_DETECTED) 224 cipher_decrypt(cc, dest, src, bytes);
231 packet_disconnect("crc32 compensation attack: network attack detected");
232
233 cipher_decrypt(cc, dest, src, bytes);
234} 225}
235 226
236/* Causes any further packets to be encrypted using the given key. The same 227/* Causes any further packets to be encrypted using the given key. The same
@@ -241,9 +232,9 @@ void
241packet_set_encryption_key(const unsigned char *key, unsigned int keylen, 232packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
242 int cipher) 233 int cipher)
243{ 234{
244 /* All other ciphers use the same key in both directions for now. */ 235 /* All other ciphers use the same key in both directions for now. */
245 cipher_set_key(&receive_context, cipher, key, keylen, 0); 236 cipher_set_key(&receive_context, cipher, key, keylen, 0);
246 cipher_set_key(&send_context, cipher, key, keylen, 1); 237 cipher_set_key(&send_context, cipher, key, keylen, 1);
247} 238}
248 239
249/* Starts constructing a packet to send. */ 240/* Starts constructing a packet to send. */
@@ -251,12 +242,12 @@ packet_set_encryption_key(const unsigned char *key, unsigned int keylen,
251void 242void
252packet_start(int type) 243packet_start(int type)
253{ 244{
254 char buf[9]; 245 char buf[9];
255 246
256 buffer_clear(&outgoing_packet); 247 buffer_clear(&outgoing_packet);
257 memset(buf, 0, 8); 248 memset(buf, 0, 8);
258 buf[8] = type; 249 buf[8] = type;
259 buffer_append(&outgoing_packet, buf, 9); 250 buffer_append(&outgoing_packet, buf, 9);
260} 251}
261 252
262/* Appends a character to the packet data. */ 253/* Appends a character to the packet data. */
@@ -264,8 +255,8 @@ packet_start(int type)
264void 255void
265packet_put_char(int value) 256packet_put_char(int value)
266{ 257{
267 char ch = value; 258 char ch = value;
268 buffer_append(&outgoing_packet, &ch, 1); 259 buffer_append(&outgoing_packet, &ch, 1);
269} 260}
270 261
271/* Appends an integer to the packet data. */ 262/* Appends an integer to the packet data. */
@@ -273,7 +264,7 @@ packet_put_char(int value)
273void 264void
274packet_put_int(unsigned int value) 265packet_put_int(unsigned int value)
275{ 266{
276 buffer_put_int(&outgoing_packet, value); 267 buffer_put_int(&outgoing_packet, value);
277} 268}
278 269
279/* Appends a string to packet data. */ 270/* Appends a string to packet data. */
@@ -281,84 +272,85 @@ packet_put_int(unsigned int value)
281void 272void
282packet_put_string(const char *buf, unsigned int len) 273packet_put_string(const char *buf, unsigned int len)
283{ 274{
284 buffer_put_string(&outgoing_packet, buf, len); 275 buffer_put_string(&outgoing_packet, buf, len);
285} 276}
286 277
287/* Appends an arbitrary precision integer to packet data. */ 278/* Appends an arbitrary precision integer to packet data. */
288 279
289void 280void
290packet_put_bignum(BIGNUM *value) 281packet_put_bignum(BIGNUM * value)
291{ 282{
292 buffer_put_bignum(&outgoing_packet, value); 283 buffer_put_bignum(&outgoing_packet, value);
293} 284}
294 285
295/* Finalizes and sends the packet. If the encryption key has been set, 286/* Finalizes and sends the packet. If the encryption key has been set,
296 encrypts the packet before sending. */ 287 encrypts the packet before sending. */
297 288
298void 289void
299packet_send() 290packet_send()
300{ 291{
301 char buf[8], *cp; 292 char buf[8], *cp;
302 int i, padding, len; 293 int i, padding, len;
303 unsigned int checksum; 294 unsigned int checksum;
304 u_int32_t rand = 0; 295 u_int32_t rand = 0;
305 296
306 /* If using packet compression, compress the payload of the outgoing 297 /* If using packet compression, compress the payload of the
307 packet. */ 298 outgoing packet. */
308 if (packet_compression) 299 if (packet_compression) {
309 { 300 buffer_clear(&compression_buffer);
310 buffer_clear(&compression_buffer); 301 /* Skip padding. */
311 buffer_consume(&outgoing_packet, 8); /* Skip padding. */ 302 buffer_consume(&outgoing_packet, 8);
312 buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8); /* padding */ 303 /* padding */
313 buffer_compress(&outgoing_packet, &compression_buffer); 304 buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8);
314 buffer_clear(&outgoing_packet); 305 buffer_compress(&outgoing_packet, &compression_buffer);
315 buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer), 306 buffer_clear(&outgoing_packet);
316 buffer_len(&compression_buffer)); 307 buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
317 } 308 buffer_len(&compression_buffer));
318 309 }
319 /* Compute packet length without padding (add checksum, remove padding). */ 310 /* Compute packet length without padding (add checksum, remove padding). */
320 len = buffer_len(&outgoing_packet) + 4 - 8; 311 len = buffer_len(&outgoing_packet) + 4 - 8;
321 312
322 /* Insert padding. */ 313 /* Insert padding. */
323 padding = 8 - len % 8; 314 padding = 8 - len % 8;
324 if (cipher_type != SSH_CIPHER_NONE) 315 if (cipher_type != SSH_CIPHER_NONE) {
325 { 316 cp = buffer_ptr(&outgoing_packet);
326 cp = buffer_ptr(&outgoing_packet); 317 for (i = 0; i < padding; i++) {
327 for (i = 0; i < padding; i++) { 318 if (i % 4 == 0)
328 if (i % 4 == 0) 319 rand = arc4random();
329 rand = arc4random(); 320 cp[7 - i] = rand & 0xff;
330 cp[7 - i] = rand & 0xff; 321 rand >>= 8;
331 rand >>= 8; 322 }
332 } 323 }
333 } 324 buffer_consume(&outgoing_packet, 8 - padding);
334 buffer_consume(&outgoing_packet, 8 - padding); 325
335 326 /* Add check bytes. */
336 /* Add check bytes. */ 327 checksum = crc32((unsigned char *) buffer_ptr(&outgoing_packet),
337 checksum = crc32((unsigned char *)buffer_ptr(&outgoing_packet), 328 buffer_len(&outgoing_packet));
338 buffer_len(&outgoing_packet)); 329 PUT_32BIT(buf, checksum);
339 PUT_32BIT(buf, checksum); 330 buffer_append(&outgoing_packet, buf, 4);
340 buffer_append(&outgoing_packet, buf, 4);
341 331
342#ifdef PACKET_DEBUG 332#ifdef PACKET_DEBUG
343 fprintf(stderr, "packet_send plain: "); 333 fprintf(stderr, "packet_send plain: ");
344 buffer_dump(&outgoing_packet); 334 buffer_dump(&outgoing_packet);
345#endif 335#endif
346 336
347 /* Append to output. */ 337 /* Append to output. */
348 PUT_32BIT(buf, len); 338 PUT_32BIT(buf, len);
349 buffer_append(&output, buf, 4); 339 buffer_append(&output, buf, 4);
350 buffer_append_space(&output, &cp, buffer_len(&outgoing_packet)); 340 buffer_append_space(&output, &cp, buffer_len(&outgoing_packet));
351 packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), 341 packet_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
352 buffer_len(&outgoing_packet)); 342 buffer_len(&outgoing_packet));
353 343
354#ifdef PACKET_DEBUG 344#ifdef PACKET_DEBUG
355 fprintf(stderr, "encrypted: "); buffer_dump(&output); 345 fprintf(stderr, "encrypted: ");
346 buffer_dump(&output);
356#endif 347#endif
357 348
358 buffer_clear(&outgoing_packet); 349 buffer_clear(&outgoing_packet);
359 350
360 /* Note that the packet is now only buffered in output. It won\'t be 351 /* Note that the packet is now only buffered in output. It won\'t
361 actually sent until packet_write_wait or packet_write_poll is called. */ 352 be actually sent until packet_write_wait or packet_write_poll
353 is called. */
362} 354}
363 355
364/* Waits until a packet has been received, and returns its type. Note that 356/* Waits until a packet has been received, and returns its type. Note that
@@ -368,42 +360,41 @@ packet_send()
368int 360int
369packet_read(int *payload_len_ptr) 361packet_read(int *payload_len_ptr)
370{ 362{
371 int type, len; 363 int type, len;
372 fd_set set; 364 fd_set set;
373 char buf[8192]; 365 char buf[8192];
374 366
375 /* Since we are blocking, ensure that all written packets have been sent. */ 367 /* Since we are blocking, ensure that all written packets have been sent. */
376 packet_write_wait(); 368 packet_write_wait();
377 369
378 /* Stay in the loop until we have received a complete packet. */ 370 /* Stay in the loop until we have received a complete packet. */
379 for (;;) 371 for (;;) {
380 { 372 /* Try to read a packet from the buffer. */
381 /* Try to read a packet from the buffer. */ 373 type = packet_read_poll(payload_len_ptr);
382 type = packet_read_poll(payload_len_ptr); 374 if (type == SSH_SMSG_SUCCESS
383 if (type == SSH_SMSG_SUCCESS 375 || type == SSH_SMSG_FAILURE
384 || type == SSH_SMSG_FAILURE 376 || type == SSH_CMSG_EOF
385 || type == SSH_CMSG_EOF 377 || type == SSH_CMSG_EXIT_CONFIRMATION)
386 || type == SSH_CMSG_EXIT_CONFIRMATION) 378 packet_integrity_check(*payload_len_ptr, 0, type);
387 packet_integrity_check(*payload_len_ptr, 0, type); 379 /* If we got a packet, return it. */
388 /* If we got a packet, return it. */ 380 if (type != SSH_MSG_NONE)
389 if (type != SSH_MSG_NONE) 381 return type;
390 return type; 382 /* Otherwise, wait for some data to arrive, add it to the
391 /* Otherwise, wait for some data to arrive, add it to the buffer, 383 buffer, and try again. */
392 and try again. */ 384 FD_ZERO(&set);
393 FD_ZERO(&set); 385 FD_SET(connection_in, &set);
394 FD_SET(connection_in, &set); 386 /* Wait for some data to arrive. */
395 /* Wait for some data to arrive. */ 387 select(connection_in + 1, &set, NULL, NULL, NULL);
396 select(connection_in + 1, &set, NULL, NULL, NULL); 388 /* Read data from the socket. */
397 /* Read data from the socket. */ 389 len = read(connection_in, buf, sizeof(buf));
398 len = read(connection_in, buf, sizeof(buf)); 390 if (len == 0)
399 if (len == 0) 391 fatal("Connection closed by %.200s", get_remote_ipaddr());
400 fatal("Connection closed by remote host."); 392 if (len < 0)
401 if (len < 0) 393 fatal("Read from socket failed: %.100s", strerror(errno));
402 fatal("Read from socket failed: %.100s", strerror(errno)); 394 /* Append it to the buffer. */
403 /* Append it to the buffer. */ 395 packet_process_incoming(buf, len);
404 packet_process_incoming(buf, len); 396 }
405 } 397 /* NOTREACHED */
406 /*NOTREACHED*/
407} 398}
408 399
409/* Waits until a packet has been received, verifies that its type matches 400/* Waits until a packet has been received, verifies that its type matches
@@ -412,131 +403,126 @@ packet_read(int *payload_len_ptr)
412void 403void
413packet_read_expect(int *payload_len_ptr, int expected_type) 404packet_read_expect(int *payload_len_ptr, int expected_type)
414{ 405{
415 int type; 406 int type;
416 407
417 type = packet_read(payload_len_ptr); 408 type = packet_read(payload_len_ptr);
418 if (type != expected_type) 409 if (type != expected_type)
419 packet_disconnect("Protocol error: expected packet type %d, got %d", 410 packet_disconnect("Protocol error: expected packet type %d, got %d",
420 expected_type, type); 411 expected_type, type);
421} 412}
422 413
423/* Checks if a full packet is available in the data received so far via 414/* Checks if a full packet is available in the data received so far via
424 packet_process_incoming. If so, reads the packet; otherwise returns 415 * packet_process_incoming. If so, reads the packet; otherwise returns
425 SSH_MSG_NONE. This does not wait for data from the connection. 416 * SSH_MSG_NONE. This does not wait for data from the connection.
426 417 *
427 SSH_MSG_DISCONNECT is handled specially here. Also, 418 * SSH_MSG_DISCONNECT is handled specially here. Also,
428 SSH_MSG_IGNORE messages are skipped by this function and are never returned 419 * SSH_MSG_IGNORE messages are skipped by this function and are never returned
429 to higher levels. 420 * to higher levels.
430 421 *
431 The returned payload_len does include space consumed by: 422 * The returned payload_len does include space consumed by:
432 Packet length 423 * Packet length
433 Padding 424 * Padding
434 Packet type 425 * Packet type
435 Check bytes 426 * Check bytes
436 427 */
437
438 */
439 428
440int 429int
441packet_read_poll(int *payload_len_ptr) 430packet_read_poll(int *payload_len_ptr)
442{ 431{
443 unsigned int len, padded_len; 432 unsigned int len, padded_len;
444 unsigned char *ucp; 433 unsigned char *ucp;
445 char buf[8], *cp; 434 char buf[8], *cp;
446 unsigned int checksum, stored_checksum; 435 unsigned int checksum, stored_checksum;
447 436
448 restart: 437restart:
449 438
450 /* Check if input size is less than minimum packet size. */ 439 /* Check if input size is less than minimum packet size. */
451 if (buffer_len(&input) < 4 + 8) 440 if (buffer_len(&input) < 4 + 8)
452 return SSH_MSG_NONE; 441 return SSH_MSG_NONE;
453 /* Get length of incoming packet. */ 442 /* Get length of incoming packet. */
454 ucp = (unsigned char *)buffer_ptr(&input); 443 ucp = (unsigned char *) buffer_ptr(&input);
455 len = GET_32BIT(ucp); 444 len = GET_32BIT(ucp);
456 if (len < 1 + 2 + 2 || len > 256*1024) 445 if (len < 1 + 2 + 2 || len > 256 * 1024)
457 packet_disconnect("Bad packet length %d.", len); 446 packet_disconnect("Bad packet length %d.", len);
458 padded_len = (len + 8) & ~7; 447 padded_len = (len + 8) & ~7;
459 448
460 /* Check if the packet has been entirely received. */ 449 /* Check if the packet has been entirely received. */
461 if (buffer_len(&input) < 4 + padded_len) 450 if (buffer_len(&input) < 4 + padded_len)
462 return SSH_MSG_NONE; 451 return SSH_MSG_NONE;
463 452
464 /* The entire packet is in buffer. */ 453 /* The entire packet is in buffer. */
465 454
466 /* Consume packet length. */ 455 /* Consume packet length. */
467 buffer_consume(&input, 4); 456 buffer_consume(&input, 4);
468 457
469 /* Copy data to incoming_packet. */ 458 /* Copy data to incoming_packet. */
470 buffer_clear(&incoming_packet); 459 buffer_clear(&incoming_packet);
471 buffer_append_space(&incoming_packet, &cp, padded_len); 460 buffer_append_space(&incoming_packet, &cp, padded_len);
472 packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len); 461 packet_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len);
473 buffer_consume(&input, padded_len); 462 buffer_consume(&input, padded_len);
474 463
475#ifdef PACKET_DEBUG 464#ifdef PACKET_DEBUG
476 fprintf(stderr, "read_poll plain: "); buffer_dump(&incoming_packet); 465 fprintf(stderr, "read_poll plain: ");
466 buffer_dump(&incoming_packet);
477#endif 467#endif
478 468
479 /* Compute packet checksum. */ 469 /* Compute packet checksum. */
480 checksum = crc32((unsigned char *)buffer_ptr(&incoming_packet), 470 checksum = crc32((unsigned char *) buffer_ptr(&incoming_packet),
481 buffer_len(&incoming_packet) - 4); 471 buffer_len(&incoming_packet) - 4);
482 472
483 /* Skip padding. */ 473 /* Skip padding. */
484 buffer_consume(&incoming_packet, 8 - len % 8); 474 buffer_consume(&incoming_packet, 8 - len % 8);
485 475
486 /* Test check bytes. */ 476 /* Test check bytes. */
487 477
488 if (len != buffer_len(&incoming_packet)) 478 if (len != buffer_len(&incoming_packet))
489 packet_disconnect("packet_read_poll: len %d != buffer_len %d.", 479 packet_disconnect("packet_read_poll: len %d != buffer_len %d.",
490 len, buffer_len(&incoming_packet)); 480 len, buffer_len(&incoming_packet));
491 481
492 ucp = (unsigned char *)buffer_ptr(&incoming_packet) + len - 4; 482 ucp = (unsigned char *) buffer_ptr(&incoming_packet) + len - 4;
493 stored_checksum = GET_32BIT(ucp); 483 stored_checksum = GET_32BIT(ucp);
494 if (checksum != stored_checksum) 484 if (checksum != stored_checksum)
495 packet_disconnect("Corrupted check bytes on input."); 485 packet_disconnect("Corrupted check bytes on input.");
496 buffer_consume_end(&incoming_packet, 4); 486 buffer_consume_end(&incoming_packet, 4);
497 487
498 /* If using packet compression, decompress the packet. */ 488 /* If using packet compression, decompress the packet. */
499 if (packet_compression) 489 if (packet_compression) {
500 { 490 buffer_clear(&compression_buffer);
501 buffer_clear(&compression_buffer); 491 buffer_uncompress(&incoming_packet, &compression_buffer);
502 buffer_uncompress(&incoming_packet, &compression_buffer); 492 buffer_clear(&incoming_packet);
503 buffer_clear(&incoming_packet); 493 buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
504 buffer_append(&incoming_packet, buffer_ptr(&compression_buffer), 494 buffer_len(&compression_buffer));
505 buffer_len(&compression_buffer)); 495 }
506 } 496 /* Get packet type. */
507 497 buffer_get(&incoming_packet, &buf[0], 1);
508 /* Get packet type. */ 498
509 buffer_get(&incoming_packet, &buf[0], 1); 499 /* Return length of payload (without type field). */
510 500 *payload_len_ptr = buffer_len(&incoming_packet);
511 /* Return length of payload (without type field). */ 501
512 *payload_len_ptr = buffer_len(&incoming_packet); 502 /* Handle disconnect message. */
513 503 if ((unsigned char) buf[0] == SSH_MSG_DISCONNECT)
514 /* Handle disconnect message. */ 504 fatal("Received disconnect: %.900s", packet_get_string(NULL));
515 if ((unsigned char)buf[0] == SSH_MSG_DISCONNECT) 505
516 fatal("%.900s", packet_get_string(NULL)); 506 /* Ignore ignore messages. */
517 507 if ((unsigned char) buf[0] == SSH_MSG_IGNORE)
518 /* Ignore ignore messages. */ 508 goto restart;
519 if ((unsigned char)buf[0] == SSH_MSG_IGNORE) 509
520 goto restart; 510 /* Send debug messages as debugging output. */
521 511 if ((unsigned char) buf[0] == SSH_MSG_DEBUG) {
522 /* Send debug messages as debugging output. */ 512 debug("Remote: %.900s", packet_get_string(NULL));
523 if ((unsigned char)buf[0] == SSH_MSG_DEBUG) 513 goto restart;
524 { 514 }
525 debug("Remote: %.900s", packet_get_string(NULL)); 515 /* Return type. */
526 goto restart; 516 return (unsigned char) buf[0];
527 } 517}
528 518
529 /* Return type. */
530 return (unsigned char)buf[0];
531}
532
533/* Buffers the given amount of input characters. This is intended to be 519/* Buffers the given amount of input characters. This is intended to be
534 used together with packet_read_poll. */ 520 used together with packet_read_poll. */
535 521
536void 522void
537packet_process_incoming(const char *buf, unsigned int len) 523packet_process_incoming(const char *buf, unsigned int len)
538{ 524{
539 buffer_append(&input, buf, len); 525 buffer_append(&input, buf, len);
540} 526}
541 527
542/* Returns a character from the packet. */ 528/* Returns a character from the packet. */
@@ -544,9 +530,9 @@ packet_process_incoming(const char *buf, unsigned int len)
544unsigned int 530unsigned int
545packet_get_char() 531packet_get_char()
546{ 532{
547 char ch; 533 char ch;
548 buffer_get(&incoming_packet, &ch, 1); 534 buffer_get(&incoming_packet, &ch, 1);
549 return (unsigned char)ch; 535 return (unsigned char) ch;
550} 536}
551 537
552/* Returns an integer from the packet data. */ 538/* Returns an integer from the packet data. */
@@ -554,16 +540,16 @@ packet_get_char()
554unsigned int 540unsigned int
555packet_get_int() 541packet_get_int()
556{ 542{
557 return buffer_get_int(&incoming_packet); 543 return buffer_get_int(&incoming_packet);
558} 544}
559 545
560/* Returns an arbitrary precision integer from the packet data. The integer 546/* Returns an arbitrary precision integer from the packet data. The integer
561 must have been initialized before this call. */ 547 must have been initialized before this call. */
562 548
563void 549void
564packet_get_bignum(BIGNUM *value, int *length_ptr) 550packet_get_bignum(BIGNUM * value, int *length_ptr)
565{ 551{
566 *length_ptr = buffer_get_bignum(&incoming_packet, value); 552 *length_ptr = buffer_get_bignum(&incoming_packet, value);
567} 553}
568 554
569/* Returns a string from the packet data. The string is allocated using 555/* Returns a string from the packet data. The string is allocated using
@@ -572,9 +558,10 @@ packet_get_bignum(BIGNUM *value, int *length_ptr)
572 integer into which the length of the string is stored. */ 558 integer into which the length of the string is stored. */
573 559
574char 560char
575*packet_get_string(unsigned int *length_ptr) 561*
562packet_get_string(unsigned int *length_ptr)
576{ 563{
577 return buffer_get_string(&incoming_packet, length_ptr); 564 return buffer_get_string(&incoming_packet, length_ptr);
578} 565}
579 566
580/* Sends a diagnostic message from the server to the client. This message 567/* Sends a diagnostic message from the server to the client. This message
@@ -586,19 +573,19 @@ char
586 packet_write_wait. */ 573 packet_write_wait. */
587 574
588void 575void
589packet_send_debug(const char *fmt, ...) 576packet_send_debug(const char *fmt,...)
590{ 577{
591 char buf[1024]; 578 char buf[1024];
592 va_list args; 579 va_list args;
593 580
594 va_start(args, fmt); 581 va_start(args, fmt);
595 vsnprintf(buf, sizeof(buf), fmt, args); 582 vsnprintf(buf, sizeof(buf), fmt, args);
596 va_end(args); 583 va_end(args);
597 584
598 packet_start(SSH_MSG_DEBUG); 585 packet_start(SSH_MSG_DEBUG);
599 packet_put_string(buf, strlen(buf)); 586 packet_put_string(buf, strlen(buf));
600 packet_send(); 587 packet_send();
601 packet_write_wait(); 588 packet_write_wait();
602} 589}
603 590
604/* Logs the error plus constructs and sends a disconnect 591/* Logs the error plus constructs and sends a disconnect
@@ -607,36 +594,35 @@ packet_send_debug(const char *fmt, ...)
607 formatted message must not exceed 1024 bytes. */ 594 formatted message must not exceed 1024 bytes. */
608 595
609void 596void
610packet_disconnect(const char *fmt, ...) 597packet_disconnect(const char *fmt,...)
611{ 598{
612 char buf[1024]; 599 char buf[1024];
613 va_list args; 600 va_list args;
614 static int disconnecting = 0; 601 static int disconnecting = 0;
615 if (disconnecting) /* Guard against recursive invocations. */ 602 if (disconnecting) /* Guard against recursive invocations. */
616 fatal("packet_disconnect called recursively."); 603 fatal("packet_disconnect called recursively.");
617 disconnecting = 1; 604 disconnecting = 1;
618 605
619 /* Format the message. Note that the caller must make sure the message 606 /* Format the message. Note that the caller must make sure the
620 is of limited size. */ 607 message is of limited size. */
621 va_start(args, fmt); 608 va_start(args, fmt);
622 vsnprintf(buf, sizeof(buf), fmt, args); 609 vsnprintf(buf, sizeof(buf), fmt, args);
623 va_end(args); 610 va_end(args);
624 611
625 /* Send the disconnect message to the other side, and wait for it to get 612 /* Send the disconnect message to the other side, and wait for it to get sent. */
626 sent. */ 613 packet_start(SSH_MSG_DISCONNECT);
627 packet_start(SSH_MSG_DISCONNECT); 614 packet_put_string(buf, strlen(buf));
628 packet_put_string(buf, strlen(buf)); 615 packet_send();
629 packet_send(); 616 packet_write_wait();
630 packet_write_wait(); 617
631 618 /* Stop listening for connections. */
632 /* Stop listening for connections. */ 619 channel_stop_listening();
633 channel_stop_listening(); 620
634 621 /* Close the connection. */
635 /* Close the connection. */ 622 packet_close();
636 packet_close(); 623
637 624 /* Display the error locally and exit. */
638 /* Display the error locally and exit. */ 625 fatal("Disconnecting: %.100s", buf);
639 fatal("Local: %.100s", buf);
640} 626}
641 627
642/* Checks if there is any buffered output, and tries to write some of the 628/* Checks if there is any buffered output, and tries to write some of the
@@ -645,18 +631,17 @@ packet_disconnect(const char *fmt, ...)
645void 631void
646packet_write_poll() 632packet_write_poll()
647{ 633{
648 int len = buffer_len(&output); 634 int len = buffer_len(&output);
649 if (len > 0) 635 if (len > 0) {
650 { 636 len = write(connection_out, buffer_ptr(&output), len);
651 len = write(connection_out, buffer_ptr(&output), len); 637 if (len <= 0) {
652 if (len <= 0) { 638 if (errno == EAGAIN)
653 if (errno == EAGAIN) 639 return;
654 return; 640 else
655 else 641 fatal("Write failed: %.100s", strerror(errno));
656 fatal("Write failed: %.100s", strerror(errno)); 642 }
657 } 643 buffer_consume(&output, len);
658 buffer_consume(&output, len); 644 }
659 }
660} 645}
661 646
662/* Calls packet_write_poll repeatedly until all pending output data has 647/* Calls packet_write_poll repeatedly until all pending output data has
@@ -665,15 +650,14 @@ packet_write_poll()
665void 650void
666packet_write_wait() 651packet_write_wait()
667{ 652{
668 packet_write_poll(); 653 packet_write_poll();
669 while (packet_have_data_to_write()) 654 while (packet_have_data_to_write()) {
670 { 655 fd_set set;
671 fd_set set; 656 FD_ZERO(&set);
672 FD_ZERO(&set); 657 FD_SET(connection_out, &set);
673 FD_SET(connection_out, &set); 658 select(connection_out + 1, NULL, &set, NULL, NULL);
674 select(connection_out + 1, NULL, &set, NULL, NULL); 659 packet_write_poll();
675 packet_write_poll(); 660 }
676 }
677} 661}
678 662
679/* Returns true if there is buffered data to write to the connection. */ 663/* Returns true if there is buffered data to write to the connection. */
@@ -681,7 +665,7 @@ packet_write_wait()
681int 665int
682packet_have_data_to_write() 666packet_have_data_to_write()
683{ 667{
684 return buffer_len(&output) != 0; 668 return buffer_len(&output) != 0;
685} 669}
686 670
687/* Returns true if there is not too much data to write to the connection. */ 671/* Returns true if there is not too much data to write to the connection. */
@@ -689,10 +673,10 @@ packet_have_data_to_write()
689int 673int
690packet_not_very_much_data_to_write() 674packet_not_very_much_data_to_write()
691{ 675{
692 if (interactive_mode) 676 if (interactive_mode)
693 return buffer_len(&output) < 16384; 677 return buffer_len(&output) < 16384;
694 else 678 else
695 return buffer_len(&output) < 128*1024; 679 return buffer_len(&output) < 128 * 1024;
696} 680}
697 681
698/* Informs that the current session is interactive. Sets IP flags for that. */ 682/* Informs that the current session is interactive. Sets IP flags for that. */
@@ -700,45 +684,40 @@ packet_not_very_much_data_to_write()
700void 684void
701packet_set_interactive(int interactive, int keepalives) 685packet_set_interactive(int interactive, int keepalives)
702{ 686{
703 int on = 1; 687 int on = 1;
704 688
705 /* Record that we are in interactive mode. */ 689 /* Record that we are in interactive mode. */
706 interactive_mode = interactive; 690 interactive_mode = interactive;
707 691
708 /* Only set socket options if using a socket (as indicated by the descriptors 692 /* Only set socket options if using a socket (as indicated by the
709 being the same). */ 693 descriptors being the same). */
710 if (connection_in != connection_out) 694 if (connection_in != connection_out)
711 return; 695 return;
712 696
713 if (keepalives) 697 if (keepalives) {
714 { 698 /* Set keepalives if requested. */
715 /* Set keepalives if requested. */ 699 if (setsockopt(connection_in, SOL_SOCKET, SO_KEEPALIVE, (void *) &on,
716 if (setsockopt(connection_in, SOL_SOCKET, SO_KEEPALIVE, (void *)&on, 700 sizeof(on)) < 0)
717 sizeof(on)) < 0) 701 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno));
718 error("setsockopt SO_KEEPALIVE: %.100s", strerror(errno)); 702 }
719 } 703 if (interactive) {
720 704 /* Set IP options for an interactive connection. Use
721 if (interactive) 705 IPTOS_LOWDELAY and TCP_NODELAY. */
722 { 706 int lowdelay = IPTOS_LOWDELAY;
723 /* Set IP options for an interactive connection. Use IPTOS_LOWDELAY 707 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &lowdelay,
724 and TCP_NODELAY. */ 708 sizeof(lowdelay)) < 0)
725 int lowdelay = IPTOS_LOWDELAY; 709 error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno));
726 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *)&lowdelay, 710 if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *) &on,
727 sizeof(lowdelay)) < 0) 711 sizeof(on)) < 0)
728 error("setsockopt IPTOS_LOWDELAY: %.100s", strerror(errno)); 712 error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
729 if (setsockopt(connection_in, IPPROTO_TCP, TCP_NODELAY, (void *)&on, 713 } else {
730 sizeof(on)) < 0) 714 /* Set IP options for a non-interactive connection. Use
731 error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); 715 IPTOS_THROUGHPUT. */
732 } 716 int throughput = IPTOS_THROUGHPUT;
733 else 717 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *) &throughput,
734 { 718 sizeof(throughput)) < 0)
735 /* Set IP options for a non-interactive connection. Use 719 error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
736 IPTOS_THROUGHPUT. */ 720 }
737 int throughput = IPTOS_THROUGHPUT;
738 if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, (void *)&throughput,
739 sizeof(throughput)) < 0)
740 error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
741 }
742} 721}
743 722
744/* Returns true if the current connection is interactive. */ 723/* Returns true if the current connection is interactive. */
@@ -746,22 +725,22 @@ packet_set_interactive(int interactive, int keepalives)
746int 725int
747packet_is_interactive() 726packet_is_interactive()
748{ 727{
749 return interactive_mode; 728 return interactive_mode;
750} 729}
751 730
752int 731int
753packet_set_maxsize(int s) 732packet_set_maxsize(int s)
754{ 733{
755 static int called = 0; 734 static int called = 0;
756 if (called) { 735 if (called) {
757 log("packet_set_maxsize: called twice: old %d new %d", max_packet_size, s); 736 log("packet_set_maxsize: called twice: old %d new %d", max_packet_size, s);
758 return -1; 737 return -1;
759 } 738 }
760 if (s < 4*1024 || s > 1024*1024) { 739 if (s < 4 * 1024 || s > 1024 * 1024) {
761 log("packet_set_maxsize: bad size %d", s); 740 log("packet_set_maxsize: bad size %d", s);
762 return -1; 741 return -1;
763 } 742 }
764 log("packet_set_maxsize: setting to %d", s); 743 log("packet_set_maxsize: setting to %d", s);
765 max_packet_size = s; 744 max_packet_size = s;
766 return s; 745 return s;
767} 746}