source: trunk/third/openssh/packet.c @ 18759

Revision 18759, 34.9 KB checked in by zacheiss, 22 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r18758, which included commits to RCS files with non-trunk default branches.
Line 
1/*
2 * Author: Tatu Ylonen <ylo@cs.hut.fi>
3 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
4 *                    All rights reserved
5 * This file contains code implementing the packet protocol and communication
6 * with the other side.  This same code is used both on client and server side.
7 *
8 * As far as I am concerned, the code I have written for this software
9 * can be used freely for any purpose.  Any derived versions of this
10 * software must be clearly marked as such, and if the derived work is
11 * incompatible with the protocol description in the RFC file, it must be
12 * called by a name other than "ssh" or "Secure Shell".
13 *
14 *
15 * SSH2 packet format added by Markus Friedl.
16 * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 *    notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 *    notice, this list of conditions and the following disclaimer in the
25 *    documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
28 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
29 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
30 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
31 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
32 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
36 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 */
38
39#include "includes.h"
40RCSID("$OpenBSD: packet.c,v 1.97 2002/07/04 08:12:15 deraadt Exp $");
41
42#include "xmalloc.h"
43#include "buffer.h"
44#include "packet.h"
45#include "bufaux.h"
46#include "crc32.h"
47#include "getput.h"
48
49#include "compress.h"
50#include "deattack.h"
51#include "channels.h"
52
53#include "compat.h"
54#include "ssh1.h"
55#include "ssh2.h"
56
57#include "cipher.h"
58#include "kex.h"
59#include "mac.h"
60#include "log.h"
61#include "canohost.h"
62#include "misc.h"
63#include "ssh.h"
64
65#ifdef PACKET_DEBUG
66#define DBG(x) x
67#else
68#define DBG(x)
69#endif
70
71/*
72 * This variable contains the file descriptors used for communicating with
73 * the other side.  connection_in is used for reading; connection_out for
74 * writing.  These can be the same descriptor, in which case it is assumed to
75 * be a socket.
76 */
77static int connection_in = -1;
78static int connection_out = -1;
79
80/* Protocol flags for the remote side. */
81static u_int remote_protocol_flags = 0;
82
83/* Encryption context for receiving data.  This is only used for decryption. */
84static CipherContext receive_context;
85
86/* Encryption context for sending data.  This is only used for encryption. */
87static CipherContext send_context;
88
89/* Buffer for raw input data from the socket. */
90Buffer input;
91
92/* Buffer for raw output data going to the socket. */
93Buffer output;
94
95/* Buffer for the partial outgoing packet being constructed. */
96static Buffer outgoing_packet;
97
98/* Buffer for the incoming packet currently being processed. */
99static Buffer incoming_packet;
100
101/* Scratch buffer for packet compression/decompression. */
102static Buffer compression_buffer;
103static int compression_buffer_ready = 0;
104
105/* Flag indicating whether packet compression/decompression is enabled. */
106static int packet_compression = 0;
107
108/* default maximum packet size */
109int max_packet_size = 32768;
110
111/* Flag indicating whether this module has been initialized. */
112static int initialized = 0;
113
114/* Set to true if the connection is interactive. */
115static int interactive_mode = 0;
116
117/* Session key information for Encryption and MAC */
118Newkeys *newkeys[MODE_MAX];
119static u_int32_t read_seqnr = 0;
120static u_int32_t send_seqnr = 0;
121
122/* Session key for protocol v1 */
123static u_char ssh1_key[SSH_SESSION_KEY_LENGTH];
124static u_int ssh1_keylen;
125
126/* roundup current message to extra_pad bytes */
127static u_char extra_pad = 0;
128
129/*
130 * Sets the descriptors used for communication.  Disables encryption until
131 * packet_set_encryption_key is called.
132 */
133void
134packet_set_connection(int fd_in, int fd_out)
135{
136        Cipher *none = cipher_by_name("none");
137
138        if (none == NULL)
139                fatal("packet_set_connection: cannot load cipher 'none'");
140        connection_in = fd_in;
141        connection_out = fd_out;
142        cipher_init(&send_context, none, "", 0, NULL, 0, CIPHER_ENCRYPT);
143        cipher_init(&receive_context, none, "", 0, NULL, 0, CIPHER_DECRYPT);
144        newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
145        if (!initialized) {
146                initialized = 1;
147                buffer_init(&input);
148                buffer_init(&output);
149                buffer_init(&outgoing_packet);
150                buffer_init(&incoming_packet);
151        }
152        /* Kludge: arrange the close function to be called from fatal(). */
153        fatal_add_cleanup((void (*) (void *)) packet_close, NULL);
154}
155
156/* Returns 1 if remote host is connected via socket, 0 if not. */
157
158int
159packet_connection_is_on_socket(void)
160{
161        struct sockaddr_storage from, to;
162        socklen_t fromlen, tolen;
163
164        /* filedescriptors in and out are the same, so it's a socket */
165        if (connection_in == connection_out)
166                return 1;
167        fromlen = sizeof(from);
168        memset(&from, 0, sizeof(from));
169        if (getpeername(connection_in, (struct sockaddr *)&from, &fromlen) < 0)
170                return 0;
171        tolen = sizeof(to);
172        memset(&to, 0, sizeof(to));
173        if (getpeername(connection_out, (struct sockaddr *)&to, &tolen) < 0)
174                return 0;
175        if (fromlen != tolen || memcmp(&from, &to, fromlen) != 0)
176                return 0;
177        if (from.ss_family != AF_INET && from.ss_family != AF_INET6)
178                return 0;
179        return 1;
180}
181
182/*
183 * Exports an IV from the CipherContext required to export the key
184 * state back from the unprivileged child to the privileged parent
185 * process.
186 */
187
188void
189packet_get_keyiv(int mode, u_char *iv, u_int len)
190{
191        CipherContext *cc;
192
193        if (mode == MODE_OUT)
194                cc = &send_context;
195        else
196                cc = &receive_context;
197
198        cipher_get_keyiv(cc, iv, len);
199}
200
201int
202packet_get_keycontext(int mode, u_char *dat)
203{
204        CipherContext *cc;
205
206        if (mode == MODE_OUT)
207                cc = &send_context;
208        else
209                cc = &receive_context;
210
211        return (cipher_get_keycontext(cc, dat));
212}
213
214void
215packet_set_keycontext(int mode, u_char *dat)
216{
217        CipherContext *cc;
218
219        if (mode == MODE_OUT)
220                cc = &send_context;
221        else
222                cc = &receive_context;
223
224        cipher_set_keycontext(cc, dat);
225}
226
227int
228packet_get_keyiv_len(int mode)
229{
230        CipherContext *cc;
231
232        if (mode == MODE_OUT)
233                cc = &send_context;
234        else
235                cc = &receive_context;
236
237        return (cipher_get_keyiv_len(cc));
238}
239void
240packet_set_iv(int mode, u_char *dat)
241{
242        CipherContext *cc;
243
244        if (mode == MODE_OUT)
245                cc = &send_context;
246        else
247                cc = &receive_context;
248
249        cipher_set_keyiv(cc, dat);
250}
251int
252packet_get_ssh1_cipher()
253{
254        return (cipher_get_number(receive_context.cipher));
255}
256
257
258u_int32_t
259packet_get_seqnr(int mode)
260{
261        return (mode == MODE_IN ? read_seqnr : send_seqnr);
262}
263
264void
265packet_set_seqnr(int mode, u_int32_t seqnr)
266{
267        if (mode == MODE_IN)
268                read_seqnr = seqnr;
269        else if (mode == MODE_OUT)
270                send_seqnr = seqnr;
271        else
272                fatal("packet_set_seqnr: bad mode %d", mode);
273}
274
275/* returns 1 if connection is via ipv4 */
276
277int
278packet_connection_is_ipv4(void)
279{
280        struct sockaddr_storage to;
281        socklen_t tolen = sizeof(to);
282
283        memset(&to, 0, sizeof(to));
284        if (getsockname(connection_out, (struct sockaddr *)&to, &tolen) < 0)
285                return 0;
286        if (to.ss_family == AF_INET)
287                return 1;
288#ifdef IPV4_IN_IPV6
289        if (to.ss_family == AF_INET6 &&
290            IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)&to)->sin6_addr))
291                return 1;
292#endif
293        return 0;
294}
295
296/* Sets the connection into non-blocking mode. */
297
298void
299packet_set_nonblocking(void)
300{
301        /* Set the socket into non-blocking mode. */
302        if (fcntl(connection_in, F_SETFL, O_NONBLOCK) < 0)
303                error("fcntl O_NONBLOCK: %.100s", strerror(errno));
304
305        if (connection_out != connection_in) {
306                if (fcntl(connection_out, F_SETFL, O_NONBLOCK) < 0)
307                        error("fcntl O_NONBLOCK: %.100s", strerror(errno));
308        }
309}
310
311/* Returns the socket used for reading. */
312
313int
314packet_get_connection_in(void)
315{
316        return connection_in;
317}
318
319/* Returns the descriptor used for writing. */
320
321int
322packet_get_connection_out(void)
323{
324        return connection_out;
325}
326
327/* Closes the connection and clears and frees internal data structures. */
328
329void
330packet_close(void)
331{
332        if (!initialized)
333                return;
334        initialized = 0;
335        if (connection_in == connection_out) {
336                shutdown(connection_out, SHUT_RDWR);
337                close(connection_out);
338        } else {
339                close(connection_in);
340                close(connection_out);
341        }
342        buffer_free(&input);
343        buffer_free(&output);
344        buffer_free(&outgoing_packet);
345        buffer_free(&incoming_packet);
346        if (compression_buffer_ready) {
347                buffer_free(&compression_buffer);
348                buffer_compress_uninit();
349        }
350        cipher_cleanup(&send_context);
351        cipher_cleanup(&receive_context);
352}
353
354/* Sets remote side protocol flags. */
355
356void
357packet_set_protocol_flags(u_int protocol_flags)
358{
359        remote_protocol_flags = protocol_flags;
360}
361
362/* Returns the remote protocol flags set earlier by the above function. */
363
364u_int
365packet_get_protocol_flags(void)
366{
367        return remote_protocol_flags;
368}
369
370/*
371 * Starts packet compression from the next packet on in both directions.
372 * Level is compression level 1 (fastest) - 9 (slow, best) as in gzip.
373 */
374
375static void
376packet_init_compression(void)
377{
378        if (compression_buffer_ready == 1)
379                return;
380        compression_buffer_ready = 1;
381        buffer_init(&compression_buffer);
382}
383
384void
385packet_start_compression(int level)
386{
387        if (packet_compression && !compat20)
388                fatal("Compression already enabled.");
389        packet_compression = 1;
390        packet_init_compression();
391        buffer_compress_init_send(level);
392        buffer_compress_init_recv();
393}
394
395/*
396 * Causes any further packets to be encrypted using the given key.  The same
397 * key is used for both sending and reception.  However, both directions are
398 * encrypted independently of each other.
399 */
400
401void
402packet_set_encryption_key(const u_char *key, u_int keylen,
403    int number)
404{
405        Cipher *cipher = cipher_by_number(number);
406
407        if (cipher == NULL)
408                fatal("packet_set_encryption_key: unknown cipher number %d", number);
409        if (keylen < 20)
410                fatal("packet_set_encryption_key: keylen too small: %d", keylen);
411        if (keylen > SSH_SESSION_KEY_LENGTH)
412                fatal("packet_set_encryption_key: keylen too big: %d", keylen);
413        memcpy(ssh1_key, key, keylen);
414        ssh1_keylen = keylen;
415        cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
416        cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
417}
418
419u_int
420packet_get_encryption_key(u_char *key)
421{
422        if (key == NULL)
423                return (ssh1_keylen);
424        memcpy(key, ssh1_key, ssh1_keylen);
425        return (ssh1_keylen);
426}
427
428/* Start constructing a packet to send. */
429void
430packet_start(u_char type)
431{
432        u_char buf[9];
433        int len;
434
435        DBG(debug("packet_start[%d]", type));
436        len = compat20 ? 6 : 9;
437        memset(buf, 0, len - 1);
438        buf[len - 1] = type;
439        buffer_clear(&outgoing_packet);
440        buffer_append(&outgoing_packet, buf, len);
441}
442
443/* Append payload. */
444void
445packet_put_char(int value)
446{
447        char ch = value;
448
449        buffer_append(&outgoing_packet, &ch, 1);
450}
451void
452packet_put_int(u_int value)
453{
454        buffer_put_int(&outgoing_packet, value);
455}
456void
457packet_put_string(const void *buf, u_int len)
458{
459        buffer_put_string(&outgoing_packet, buf, len);
460}
461void
462packet_put_cstring(const char *str)
463{
464        buffer_put_cstring(&outgoing_packet, str);
465}
466void
467packet_put_raw(const void *buf, u_int len)
468{
469        buffer_append(&outgoing_packet, buf, len);
470}
471void
472packet_put_bignum(BIGNUM * value)
473{
474        buffer_put_bignum(&outgoing_packet, value);
475}
476void
477packet_put_bignum2(BIGNUM * value)
478{
479        buffer_put_bignum2(&outgoing_packet, value);
480}
481
482/*
483 * Finalizes and sends the packet.  If the encryption key has been set,
484 * encrypts the packet before sending.
485 */
486
487static void
488packet_send1(void)
489{
490        u_char buf[8], *cp;
491        int i, padding, len;
492        u_int checksum;
493        u_int32_t rand = 0;
494
495        /*
496         * If using packet compression, compress the payload of the outgoing
497         * packet.
498         */
499        if (packet_compression) {
500                buffer_clear(&compression_buffer);
501                /* Skip padding. */
502                buffer_consume(&outgoing_packet, 8);
503                /* padding */
504                buffer_append(&compression_buffer, "\0\0\0\0\0\0\0\0", 8);
505                buffer_compress(&outgoing_packet, &compression_buffer);
506                buffer_clear(&outgoing_packet);
507                buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
508                    buffer_len(&compression_buffer));
509        }
510        /* Compute packet length without padding (add checksum, remove padding). */
511        len = buffer_len(&outgoing_packet) + 4 - 8;
512
513        /* Insert padding. Initialized to zero in packet_start1() */
514        padding = 8 - len % 8;
515        if (!send_context.plaintext) {
516                cp = buffer_ptr(&outgoing_packet);
517                for (i = 0; i < padding; i++) {
518                        if (i % 4 == 0)
519                                rand = arc4random();
520                        cp[7 - i] = rand & 0xff;
521                        rand >>= 8;
522                }
523        }
524        buffer_consume(&outgoing_packet, 8 - padding);
525
526        /* Add check bytes. */
527        checksum = ssh_crc32(buffer_ptr(&outgoing_packet),
528            buffer_len(&outgoing_packet));
529        PUT_32BIT(buf, checksum);
530        buffer_append(&outgoing_packet, buf, 4);
531
532#ifdef PACKET_DEBUG
533        fprintf(stderr, "packet_send plain: ");
534        buffer_dump(&outgoing_packet);
535#endif
536
537        /* Append to output. */
538        PUT_32BIT(buf, len);
539        buffer_append(&output, buf, 4);
540        cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
541        cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
542            buffer_len(&outgoing_packet));
543
544#ifdef PACKET_DEBUG
545        fprintf(stderr, "encrypted: ");
546        buffer_dump(&output);
547#endif
548
549        buffer_clear(&outgoing_packet);
550
551        /*
552         * Note that the packet is now only buffered in output.  It won\'t be
553         * actually sent until packet_write_wait or packet_write_poll is
554         * called.
555         */
556}
557
558void
559set_newkeys(int mode)
560{
561        Enc *enc;
562        Mac *mac;
563        Comp *comp;
564        CipherContext *cc;
565        int encrypt;
566
567        debug("newkeys: mode %d", mode);
568
569        if (mode == MODE_OUT) {
570                cc = &send_context;
571                encrypt = CIPHER_ENCRYPT;
572        } else {
573                cc = &receive_context;
574                encrypt = CIPHER_DECRYPT;
575        }
576        if (newkeys[mode] != NULL) {
577                debug("newkeys: rekeying");
578                cipher_cleanup(cc);
579                enc  = &newkeys[mode]->enc;
580                mac  = &newkeys[mode]->mac;
581                comp = &newkeys[mode]->comp;
582                memset(mac->key, 0, mac->key_len);
583                xfree(enc->name);
584                xfree(enc->iv);
585                xfree(enc->key);
586                xfree(mac->name);
587                xfree(mac->key);
588                xfree(comp->name);
589                xfree(newkeys[mode]);
590        }
591        newkeys[mode] = kex_get_newkeys(mode);
592        if (newkeys[mode] == NULL)
593                fatal("newkeys: no keys for mode %d", mode);
594        enc  = &newkeys[mode]->enc;
595        mac  = &newkeys[mode]->mac;
596        comp = &newkeys[mode]->comp;
597        if (mac->md != NULL)
598                mac->enabled = 1;
599        DBG(debug("cipher_init_context: %d", mode));
600        cipher_init(cc, enc->cipher, enc->key, enc->key_len,
601            enc->iv, enc->block_size, encrypt);
602        /* Deleting the keys does not gain extra security */
603        /* memset(enc->iv,  0, enc->block_size);
604           memset(enc->key, 0, enc->key_len); */
605        if (comp->type != 0 && comp->enabled == 0) {
606                packet_init_compression();
607                if (mode == MODE_OUT)
608                        buffer_compress_init_send(6);
609                else
610                        buffer_compress_init_recv();
611                comp->enabled = 1;
612        }
613}
614
615/*
616 * Finalize packet in SSH2 format (compress, mac, encrypt, enqueue)
617 */
618static void
619packet_send2(void)
620{
621        u_char type, *cp, *macbuf = NULL;
622        u_char padlen, pad;
623        u_int packet_length = 0;
624        u_int i, len;
625        u_int32_t rand = 0;
626        Enc *enc   = NULL;
627        Mac *mac   = NULL;
628        Comp *comp = NULL;
629        int block_size;
630
631        if (newkeys[MODE_OUT] != NULL) {
632                enc  = &newkeys[MODE_OUT]->enc;
633                mac  = &newkeys[MODE_OUT]->mac;
634                comp = &newkeys[MODE_OUT]->comp;
635        }
636        block_size = enc ? enc->block_size : 8;
637
638        cp = buffer_ptr(&outgoing_packet);
639        type = cp[5];
640
641#ifdef PACKET_DEBUG
642        fprintf(stderr, "plain:     ");
643        buffer_dump(&outgoing_packet);
644#endif
645
646        if (comp && comp->enabled) {
647                len = buffer_len(&outgoing_packet);
648                /* skip header, compress only payload */
649                buffer_consume(&outgoing_packet, 5);
650                buffer_clear(&compression_buffer);
651                buffer_compress(&outgoing_packet, &compression_buffer);
652                buffer_clear(&outgoing_packet);
653                buffer_append(&outgoing_packet, "\0\0\0\0\0", 5);
654                buffer_append(&outgoing_packet, buffer_ptr(&compression_buffer),
655                    buffer_len(&compression_buffer));
656                DBG(debug("compression: raw %d compressed %d", len,
657                    buffer_len(&outgoing_packet)));
658        }
659
660        /* sizeof (packet_len + pad_len + payload) */
661        len = buffer_len(&outgoing_packet);
662
663        /*
664         * calc size of padding, alloc space, get random data,
665         * minimum padding is 4 bytes
666         */
667        padlen = block_size - (len % block_size);
668        if (padlen < 4)
669                padlen += block_size;
670        if (extra_pad) {
671                /* will wrap if extra_pad+padlen > 255 */
672                extra_pad  = roundup(extra_pad, block_size);
673                pad = extra_pad - ((len + padlen) % extra_pad);
674                debug3("packet_send2: adding %d (len %d padlen %d extra_pad %d)",
675                    pad, len, padlen, extra_pad);
676                padlen += pad;
677                extra_pad = 0;
678        }
679        cp = buffer_append_space(&outgoing_packet, padlen);
680        if (enc && !send_context.plaintext) {
681                /* random padding */
682                for (i = 0; i < padlen; i++) {
683                        if (i % 4 == 0)
684                                rand = arc4random();
685                        cp[i] = rand & 0xff;
686                        rand >>= 8;
687                }
688        } else {
689                /* clear padding */
690                memset(cp, 0, padlen);
691        }
692        /* packet_length includes payload, padding and padding length field */
693        packet_length = buffer_len(&outgoing_packet) - 4;
694        cp = buffer_ptr(&outgoing_packet);
695        PUT_32BIT(cp, packet_length);
696        cp[4] = padlen;
697        DBG(debug("send: len %d (includes padlen %d)", packet_length+4, padlen));
698
699        /* compute MAC over seqnr and packet(length fields, payload, padding) */
700        if (mac && mac->enabled) {
701                macbuf = mac_compute(mac, send_seqnr,
702                    buffer_ptr(&outgoing_packet),
703                    buffer_len(&outgoing_packet));
704                DBG(debug("done calc MAC out #%d", send_seqnr));
705        }
706        /* encrypt packet and append to output buffer. */
707        cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
708        cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
709            buffer_len(&outgoing_packet));
710        /* append unencrypted MAC */
711        if (mac && mac->enabled)
712                buffer_append(&output, (char *)macbuf, mac->mac_len);
713#ifdef PACKET_DEBUG
714        fprintf(stderr, "encrypted: ");
715        buffer_dump(&output);
716#endif
717        /* increment sequence number for outgoing packets */
718        if (++send_seqnr == 0)
719                log("outgoing seqnr wraps around");
720        buffer_clear(&outgoing_packet);
721
722        if (type == SSH2_MSG_NEWKEYS)
723                set_newkeys(MODE_OUT);
724}
725
726void
727packet_send(void)
728{
729        if (compat20)
730                packet_send2();
731        else
732                packet_send1();
733        DBG(debug("packet_send done"));
734}
735
736/*
737 * Waits until a packet has been received, and returns its type.  Note that
738 * no other data is processed until this returns, so this function should not
739 * be used during the interactive session.
740 */
741
742int
743packet_read_seqnr(u_int32_t *seqnr_p)
744{
745        int type, len;
746        fd_set *setp;
747        char buf[8192];
748        DBG(debug("packet_read()"));
749
750        setp = (fd_set *)xmalloc(howmany(connection_in+1, NFDBITS) *
751            sizeof(fd_mask));
752
753        /* Since we are blocking, ensure that all written packets have been sent. */
754        packet_write_wait();
755
756        /* Stay in the loop until we have received a complete packet. */
757        for (;;) {
758                /* Try to read a packet from the buffer. */
759                type = packet_read_poll_seqnr(seqnr_p);
760                if (!compat20 && (
761                    type == SSH_SMSG_SUCCESS
762                    || type == SSH_SMSG_FAILURE
763                    || type == SSH_CMSG_EOF
764                    || type == SSH_CMSG_EXIT_CONFIRMATION))
765                        packet_check_eom();
766                /* If we got a packet, return it. */
767                if (type != SSH_MSG_NONE) {
768                        xfree(setp);
769                        return type;
770                }
771                /*
772                 * Otherwise, wait for some data to arrive, add it to the
773                 * buffer, and try again.
774                 */
775                memset(setp, 0, howmany(connection_in + 1, NFDBITS) *
776                    sizeof(fd_mask));
777                FD_SET(connection_in, setp);
778
779                /* Wait for some data to arrive. */
780                while (select(connection_in + 1, setp, NULL, NULL, NULL) == -1 &&
781                    (errno == EAGAIN || errno == EINTR))
782                        ;
783
784                /* Read data from the socket. */
785                len = read(connection_in, buf, sizeof(buf));
786                if (len == 0) {
787                        log("Connection closed by %.200s", get_remote_ipaddr());
788                        fatal_cleanup();
789                }
790                if (len < 0)
791                        fatal("Read from socket failed: %.100s", strerror(errno));
792                /* Append it to the buffer. */
793                packet_process_incoming(buf, len);
794        }
795        /* NOTREACHED */
796}
797
798int
799packet_read(void)
800{
801        return packet_read_seqnr(NULL);
802}
803
804/*
805 * Waits until a packet has been received, verifies that its type matches
806 * that given, and gives a fatal error and exits if there is a mismatch.
807 */
808
809void
810packet_read_expect(int expected_type)
811{
812        int type;
813
814        type = packet_read();
815        if (type != expected_type)
816                packet_disconnect("Protocol error: expected packet type %d, got %d",
817                    expected_type, type);
818}
819
820/* Checks if a full packet is available in the data received so far via
821 * packet_process_incoming.  If so, reads the packet; otherwise returns
822 * SSH_MSG_NONE.  This does not wait for data from the connection.
823 *
824 * SSH_MSG_DISCONNECT is handled specially here.  Also,
825 * SSH_MSG_IGNORE messages are skipped by this function and are never returned
826 * to higher levels.
827 */
828
829static int
830packet_read_poll1(void)
831{
832        u_int len, padded_len;
833        u_char *cp, type;
834        u_int checksum, stored_checksum;
835
836        /* Check if input size is less than minimum packet size. */
837        if (buffer_len(&input) < 4 + 8)
838                return SSH_MSG_NONE;
839        /* Get length of incoming packet. */
840        cp = buffer_ptr(&input);
841        len = GET_32BIT(cp);
842        if (len < 1 + 2 + 2 || len > 256 * 1024)
843                packet_disconnect("Bad packet length %d.", len);
844        padded_len = (len + 8) & ~7;
845
846        /* Check if the packet has been entirely received. */
847        if (buffer_len(&input) < 4 + padded_len)
848                return SSH_MSG_NONE;
849
850        /* The entire packet is in buffer. */
851
852        /* Consume packet length. */
853        buffer_consume(&input, 4);
854
855        /*
856         * Cryptographic attack detector for ssh
857         * (C)1998 CORE-SDI, Buenos Aires Argentina
858         * Ariel Futoransky(futo@core-sdi.com)
859         */
860        if (!receive_context.plaintext &&
861            detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED)
862                packet_disconnect("crc32 compensation attack: network attack detected");
863
864        /* Decrypt data to incoming_packet. */
865        buffer_clear(&incoming_packet);
866        cp = buffer_append_space(&incoming_packet, padded_len);
867        cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len);
868
869        buffer_consume(&input, padded_len);
870
871#ifdef PACKET_DEBUG
872        fprintf(stderr, "read_poll plain: ");
873        buffer_dump(&incoming_packet);
874#endif
875
876        /* Compute packet checksum. */
877        checksum = ssh_crc32(buffer_ptr(&incoming_packet),
878            buffer_len(&incoming_packet) - 4);
879
880        /* Skip padding. */
881        buffer_consume(&incoming_packet, 8 - len % 8);
882
883        /* Test check bytes. */
884        if (len != buffer_len(&incoming_packet))
885                packet_disconnect("packet_read_poll1: len %d != buffer_len %d.",
886                    len, buffer_len(&incoming_packet));
887
888        cp = (u_char *)buffer_ptr(&incoming_packet) + len - 4;
889        stored_checksum = GET_32BIT(cp);
890        if (checksum != stored_checksum)
891                packet_disconnect("Corrupted check bytes on input.");
892        buffer_consume_end(&incoming_packet, 4);
893
894        if (packet_compression) {
895                buffer_clear(&compression_buffer);
896                buffer_uncompress(&incoming_packet, &compression_buffer);
897                buffer_clear(&incoming_packet);
898                buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
899                    buffer_len(&compression_buffer));
900        }
901        type = buffer_get_char(&incoming_packet);
902        return type;
903}
904
905static int
906packet_read_poll2(u_int32_t *seqnr_p)
907{
908        static u_int packet_length = 0;
909        u_int padlen, need;
910        u_char *macbuf, *cp, type;
911        int maclen, block_size;
912        Enc *enc   = NULL;
913        Mac *mac   = NULL;
914        Comp *comp = NULL;
915
916        if (newkeys[MODE_IN] != NULL) {
917                enc  = &newkeys[MODE_IN]->enc;
918                mac  = &newkeys[MODE_IN]->mac;
919                comp = &newkeys[MODE_IN]->comp;
920        }
921        maclen = mac && mac->enabled ? mac->mac_len : 0;
922        block_size = enc ? enc->block_size : 8;
923
924        if (packet_length == 0) {
925                /*
926                 * check if input size is less than the cipher block size,
927                 * decrypt first block and extract length of incoming packet
928                 */
929                if (buffer_len(&input) < block_size)
930                        return SSH_MSG_NONE;
931                buffer_clear(&incoming_packet);
932                cp = buffer_append_space(&incoming_packet, block_size);
933                cipher_crypt(&receive_context, cp, buffer_ptr(&input),
934                    block_size);
935                cp = buffer_ptr(&incoming_packet);
936                packet_length = GET_32BIT(cp);
937                if (packet_length < 1 + 4 || packet_length > 256 * 1024) {
938                        buffer_dump(&incoming_packet);
939                        packet_disconnect("Bad packet length %d.", packet_length);
940                }
941                DBG(debug("input: packet len %d", packet_length+4));
942                buffer_consume(&input, block_size);
943        }
944        /* we have a partial packet of block_size bytes */
945        need = 4 + packet_length - block_size;
946        DBG(debug("partial packet %d, need %d, maclen %d", block_size,
947            need, maclen));
948        if (need % block_size != 0)
949                fatal("padding error: need %d block %d mod %d",
950                    need, block_size, need % block_size);
951        /*
952         * check if the entire packet has been received and
953         * decrypt into incoming_packet
954         */
955        if (buffer_len(&input) < need + maclen)
956                return SSH_MSG_NONE;
957#ifdef PACKET_DEBUG
958        fprintf(stderr, "read_poll enc/full: ");
959        buffer_dump(&input);
960#endif
961        cp = buffer_append_space(&incoming_packet, need);
962        cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);
963        buffer_consume(&input, need);
964        /*
965         * compute MAC over seqnr and packet,
966         * increment sequence number for incoming packet
967         */
968        if (mac && mac->enabled) {
969                macbuf = mac_compute(mac, read_seqnr,
970                    buffer_ptr(&incoming_packet),
971                    buffer_len(&incoming_packet));
972                if (memcmp(macbuf, buffer_ptr(&input), mac->mac_len) != 0)
973                        packet_disconnect("Corrupted MAC on input.");
974                DBG(debug("MAC #%d ok", read_seqnr));
975                buffer_consume(&input, mac->mac_len);
976        }
977        if (seqnr_p != NULL)
978                *seqnr_p = read_seqnr;
979        if (++read_seqnr == 0)
980                log("incoming seqnr wraps around");
981
982        /* get padlen */
983        cp = buffer_ptr(&incoming_packet);
984        padlen = cp[4];
985        DBG(debug("input: padlen %d", padlen));
986        if (padlen < 4)
987                packet_disconnect("Corrupted padlen %d on input.", padlen);
988
989        /* skip packet size + padlen, discard padding */
990        buffer_consume(&incoming_packet, 4 + 1);
991        buffer_consume_end(&incoming_packet, padlen);
992
993        DBG(debug("input: len before de-compress %d", buffer_len(&incoming_packet)));
994        if (comp && comp->enabled) {
995                buffer_clear(&compression_buffer);
996                buffer_uncompress(&incoming_packet, &compression_buffer);
997                buffer_clear(&incoming_packet);
998                buffer_append(&incoming_packet, buffer_ptr(&compression_buffer),
999                    buffer_len(&compression_buffer));
1000                DBG(debug("input: len after de-compress %d",
1001                    buffer_len(&incoming_packet)));
1002        }
1003        /*
1004         * get packet type, implies consume.
1005         * return length of payload (without type field)
1006         */
1007        type = buffer_get_char(&incoming_packet);
1008        if (type == SSH2_MSG_NEWKEYS)
1009                set_newkeys(MODE_IN);
1010#ifdef PACKET_DEBUG
1011        fprintf(stderr, "read/plain[%d]:\r\n", type);
1012        buffer_dump(&incoming_packet);
1013#endif
1014        /* reset for next packet */
1015        packet_length = 0;
1016        return type;
1017}
1018
1019int
1020packet_read_poll_seqnr(u_int32_t *seqnr_p)
1021{
1022        u_int reason, seqnr;
1023        u_char type;
1024        char *msg;
1025
1026        for (;;) {
1027                if (compat20) {
1028                        type = packet_read_poll2(seqnr_p);
1029                        if (type)
1030                                DBG(debug("received packet type %d", type));
1031                        switch (type) {
1032                        case SSH2_MSG_IGNORE:
1033                                break;
1034                        case SSH2_MSG_DEBUG:
1035                                packet_get_char();
1036                                msg = packet_get_string(NULL);
1037                                debug("Remote: %.900s", msg);
1038                                xfree(msg);
1039                                msg = packet_get_string(NULL);
1040                                xfree(msg);
1041                                break;
1042                        case SSH2_MSG_DISCONNECT:
1043                                reason = packet_get_int();
1044                                msg = packet_get_string(NULL);
1045                                log("Received disconnect from %s: %u: %.400s",
1046                                    get_remote_ipaddr(), reason, msg);
1047                                xfree(msg);
1048                                fatal_cleanup();
1049                                break;
1050                        case SSH2_MSG_UNIMPLEMENTED:
1051                                seqnr = packet_get_int();
1052                                debug("Received SSH2_MSG_UNIMPLEMENTED for %u",
1053                                    seqnr);
1054                                break;
1055                        default:
1056                                return type;
1057                                break;
1058                        }
1059                } else {
1060                        type = packet_read_poll1();
1061                        switch (type) {
1062                        case SSH_MSG_IGNORE:
1063                                break;
1064                        case SSH_MSG_DEBUG:
1065                                msg = packet_get_string(NULL);
1066                                debug("Remote: %.900s", msg);
1067                                xfree(msg);
1068                                break;
1069                        case SSH_MSG_DISCONNECT:
1070                                msg = packet_get_string(NULL);
1071                                log("Received disconnect from %s: %.400s",
1072                                    get_remote_ipaddr(), msg);
1073                                fatal_cleanup();
1074                                xfree(msg);
1075                                break;
1076                        default:
1077                                if (type)
1078                                        DBG(debug("received packet type %d", type));
1079                                return type;
1080                                break;
1081                        }
1082                }
1083        }
1084}
1085
1086int
1087packet_read_poll(void)
1088{
1089        return packet_read_poll_seqnr(NULL);
1090}
1091
1092/*
1093 * Buffers the given amount of input characters.  This is intended to be used
1094 * together with packet_read_poll.
1095 */
1096
1097void
1098packet_process_incoming(const char *buf, u_int len)
1099{
1100        buffer_append(&input, buf, len);
1101}
1102
1103/* Returns a character from the packet. */
1104
1105u_int
1106packet_get_char(void)
1107{
1108        char ch;
1109
1110        buffer_get(&incoming_packet, &ch, 1);
1111        return (u_char) ch;
1112}
1113
1114/* Returns an integer from the packet data. */
1115
1116u_int
1117packet_get_int(void)
1118{
1119        return buffer_get_int(&incoming_packet);
1120}
1121
1122/*
1123 * Returns an arbitrary precision integer from the packet data.  The integer
1124 * must have been initialized before this call.
1125 */
1126
1127void
1128packet_get_bignum(BIGNUM * value)
1129{
1130        buffer_get_bignum(&incoming_packet, value);
1131}
1132
1133void
1134packet_get_bignum2(BIGNUM * value)
1135{
1136        buffer_get_bignum2(&incoming_packet, value);
1137}
1138
1139void *
1140packet_get_raw(int *length_ptr)
1141{
1142        int bytes = buffer_len(&incoming_packet);
1143
1144        if (length_ptr != NULL)
1145                *length_ptr = bytes;
1146        return buffer_ptr(&incoming_packet);
1147}
1148
1149int
1150packet_remaining(void)
1151{
1152        return buffer_len(&incoming_packet);
1153}
1154
1155/*
1156 * Returns a string from the packet data.  The string is allocated using
1157 * xmalloc; it is the responsibility of the calling program to free it when
1158 * no longer needed.  The length_ptr argument may be NULL, or point to an
1159 * integer into which the length of the string is stored.
1160 */
1161
1162void *
1163packet_get_string(u_int *length_ptr)
1164{
1165        return buffer_get_string(&incoming_packet, length_ptr);
1166}
1167
1168/*
1169 * Sends a diagnostic message from the server to the client.  This message
1170 * can be sent at any time (but not while constructing another message). The
1171 * message is printed immediately, but only if the client is being executed
1172 * in verbose mode.  These messages are primarily intended to ease debugging
1173 * authentication problems.   The length of the formatted message must not
1174 * exceed 1024 bytes.  This will automatically call packet_write_wait.
1175 */
1176
1177void
1178packet_send_debug(const char *fmt,...)
1179{
1180        char buf[1024];
1181        va_list args;
1182
1183        if (compat20 && (datafellows & SSH_BUG_DEBUG))
1184                return;
1185
1186        va_start(args, fmt);
1187        vsnprintf(buf, sizeof(buf), fmt, args);
1188        va_end(args);
1189
1190        if (compat20) {
1191                packet_start(SSH2_MSG_DEBUG);
1192                packet_put_char(0);     /* bool: always display */
1193                packet_put_cstring(buf);
1194                packet_put_cstring("");
1195        } else {
1196                packet_start(SSH_MSG_DEBUG);
1197                packet_put_cstring(buf);
1198        }
1199        packet_send();
1200        packet_write_wait();
1201}
1202
1203/*
1204 * Logs the error plus constructs and sends a disconnect packet, closes the
1205 * connection, and exits.  This function never returns. The error message
1206 * should not contain a newline.  The length of the formatted message must
1207 * not exceed 1024 bytes.
1208 */
1209
1210void
1211packet_disconnect(const char *fmt,...)
1212{
1213        char buf[1024];
1214        va_list args;
1215        static int disconnecting = 0;
1216
1217        if (disconnecting)      /* Guard against recursive invocations. */
1218                fatal("packet_disconnect called recursively.");
1219        disconnecting = 1;
1220
1221        /*
1222         * Format the message.  Note that the caller must make sure the
1223         * message is of limited size.
1224         */
1225        va_start(args, fmt);
1226        vsnprintf(buf, sizeof(buf), fmt, args);
1227        va_end(args);
1228
1229        /* Send the disconnect message to the other side, and wait for it to get sent. */
1230        if (compat20) {
1231                packet_start(SSH2_MSG_DISCONNECT);
1232                packet_put_int(SSH2_DISCONNECT_PROTOCOL_ERROR);
1233                packet_put_cstring(buf);
1234                packet_put_cstring("");
1235        } else {
1236                packet_start(SSH_MSG_DISCONNECT);
1237                packet_put_cstring(buf);
1238        }
1239        packet_send();
1240        packet_write_wait();
1241
1242        /* Stop listening for connections. */
1243        channel_close_all();
1244
1245        /* Close the connection. */
1246        packet_close();
1247
1248        /* Display the error locally and exit. */
1249        log("Disconnecting: %.100s", buf);
1250        fatal_cleanup();
1251}
1252
1253/* Checks if there is any buffered output, and tries to write some of the output. */
1254
1255void
1256packet_write_poll(void)
1257{
1258        int len = buffer_len(&output);
1259
1260        if (len > 0) {
1261                len = write(connection_out, buffer_ptr(&output), len);
1262                if (len <= 0) {
1263                        if (errno == EAGAIN)
1264                                return;
1265                        else
1266                                fatal("Write failed: %.100s", strerror(errno));
1267                }
1268                buffer_consume(&output, len);
1269        }
1270}
1271
1272/*
1273 * Calls packet_write_poll repeatedly until all pending output data has been
1274 * written.
1275 */
1276
1277void
1278packet_write_wait(void)
1279{
1280        fd_set *setp;
1281
1282        setp = (fd_set *)xmalloc(howmany(connection_out + 1, NFDBITS) *
1283            sizeof(fd_mask));
1284        packet_write_poll();
1285        while (packet_have_data_to_write()) {
1286                memset(setp, 0, howmany(connection_out + 1, NFDBITS) *
1287                    sizeof(fd_mask));
1288                FD_SET(connection_out, setp);
1289                while (select(connection_out + 1, NULL, setp, NULL, NULL) == -1 &&
1290                    (errno == EAGAIN || errno == EINTR))
1291                        ;
1292                packet_write_poll();
1293        }
1294        xfree(setp);
1295}
1296
1297/* Returns true if there is buffered data to write to the connection. */
1298
1299int
1300packet_have_data_to_write(void)
1301{
1302        return buffer_len(&output) != 0;
1303}
1304
1305/* Returns true if there is not too much data to write to the connection. */
1306
1307int
1308packet_not_very_much_data_to_write(void)
1309{
1310        if (interactive_mode)
1311                return buffer_len(&output) < 16384;
1312        else
1313                return buffer_len(&output) < 128 * 1024;
1314}
1315
1316/* Informs that the current session is interactive.  Sets IP flags for that. */
1317
1318void
1319packet_set_interactive(int interactive)
1320{
1321        static int called = 0;
1322#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
1323        int lowdelay = IPTOS_LOWDELAY;
1324        int throughput = IPTOS_THROUGHPUT;
1325#endif
1326
1327        if (called)
1328                return;
1329        called = 1;
1330
1331        /* Record that we are in interactive mode. */
1332        interactive_mode = interactive;
1333
1334        /* Only set socket options if using a socket.  */
1335        if (!packet_connection_is_on_socket())
1336                return;
1337        /*
1338         * IPTOS_LOWDELAY and IPTOS_THROUGHPUT are IPv4 only
1339         */
1340        if (interactive) {
1341                /*
1342                 * Set IP options for an interactive connection.  Use
1343                 * IPTOS_LOWDELAY and TCP_NODELAY.
1344                 */
1345#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
1346                if (packet_connection_is_ipv4()) {
1347                        if (setsockopt(connection_in, IPPROTO_IP, IP_TOS,
1348                            &lowdelay, sizeof(lowdelay)) < 0)
1349                                error("setsockopt IPTOS_LOWDELAY: %.100s",
1350                                    strerror(errno));
1351                }
1352#endif
1353                set_nodelay(connection_in);
1354        } else if (packet_connection_is_ipv4()) {
1355                /*
1356                 * Set IP options for a non-interactive connection.  Use
1357                 * IPTOS_THROUGHPUT.
1358                 */
1359#if defined(IP_TOS) && !defined(IP_TOS_IS_BROKEN)
1360                if (setsockopt(connection_in, IPPROTO_IP, IP_TOS, &throughput,
1361                    sizeof(throughput)) < 0)
1362                        error("setsockopt IPTOS_THROUGHPUT: %.100s", strerror(errno));
1363#endif
1364        }
1365}
1366
1367/* Returns true if the current connection is interactive. */
1368
1369int
1370packet_is_interactive(void)
1371{
1372        return interactive_mode;
1373}
1374
1375int
1376packet_set_maxsize(int s)
1377{
1378        static int called = 0;
1379
1380        if (called) {
1381                log("packet_set_maxsize: called twice: old %d new %d",
1382                    max_packet_size, s);
1383                return -1;
1384        }
1385        if (s < 4 * 1024 || s > 1024 * 1024) {
1386                log("packet_set_maxsize: bad size %d", s);
1387                return -1;
1388        }
1389        called = 1;
1390        debug("packet_set_maxsize: setting to %d", s);
1391        max_packet_size = s;
1392        return s;
1393}
1394
1395/* roundup current message to pad bytes */
1396void
1397packet_add_padding(u_char pad)
1398{
1399        extra_pad = pad;
1400}
1401
1402/*
1403 * 9.2.  Ignored Data Message
1404 *
1405 *   byte      SSH_MSG_IGNORE
1406 *   string    data
1407 *
1408 * All implementations MUST understand (and ignore) this message at any
1409 * time (after receiving the protocol version). No implementation is
1410 * required to send them. This message can be used as an additional
1411 * protection measure against advanced traffic analysis techniques.
1412 */
1413void
1414packet_send_ignore(int nbytes)
1415{
1416        u_int32_t rand = 0;
1417        int i;
1418
1419        packet_start(compat20 ? SSH2_MSG_IGNORE : SSH_MSG_IGNORE);
1420        packet_put_int(nbytes);
1421        for (i = 0; i < nbytes; i++) {
1422                if (i % 4 == 0)
1423                        rand = arc4random();
1424                packet_put_char(rand & 0xff);
1425                rand >>= 8;
1426        }
1427}
Note: See TracBrowser for help on using the repository browser.