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