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