source: src/router/proftpd/contrib/mod_sftp/packet.c @ 17876

Last change on this file since 17876 was 17876, checked in by BrainSlayer, 19 months ago

update proftp

File size: 44.7 KB
Line 
1/*
2 * ProFTPD - mod_sftp packet IO
3 * Copyright (c) 2008-2011 TJ Saunders
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18 *
19 * As a special exemption, TJ Saunders and other respective copyright holders
20 * give permission to link this program with OpenSSL, and distribute the
21 * resulting executable, without including the source code for OpenSSL in the
22 * source distribution.
23 *
24 * $Id: packet.c,v 1.32 2011/05/23 21:03:12 castaglia Exp $
25 */
26
27#include "mod_sftp.h"
28#include "ssh2.h"
29#include "packet.h"
30#include "msg.h"
31#include "disconnect.h"
32#include "cipher.h"
33#include "mac.h"
34#include "compress.h"
35#include "kex.h"
36#include "service.h"
37#include "auth.h"
38#include "channel.h"
39#include "tap.h"
40
41#define SFTP_PACKET_IO_RD       5
42#define SFTP_PACKET_IO_WR       7
43
44extern pr_response_t *resp_list, *resp_err_list;
45
46extern module sftp_module;
47
48static uint32_t packet_client_seqno = 0;
49static uint32_t packet_server_seqno = 0;
50
51/* Maximum length of the payload data of an SSH2 packet we're willing to
52 * accept.  Any packets reporting a payload length longer than this will be
53 * ignored/dropped.
54 */
55#define SFTP_PACKET_MAX_PAYLOAD_LEN     (256 * 1024)
56
57/* RFC4344 recommends 2^31 for the client packet sequence number at which
58 * we should request a rekey, and 2^32 for the server packet sequence number.
59 *
60 * However, the uint32_t data type may not be unsigned for some
61 * platforms/compilers.  To avoid issues on these platforms, use 2^31-1
62 * for rekeying for both client and server packet sequence numbers.
63 */
64#define SFTP_PACKET_CLIENT_REKEY_SEQNO_LIMIT            2147483647
65#define SFTP_PACKET_SERVER_REKEY_SEQNO_LIMIT            2147483647
66
67static uint32_t rekey_client_seqno = SFTP_PACKET_CLIENT_REKEY_SEQNO_LIMIT;
68static uint32_t rekey_server_seqno = SFTP_PACKET_SERVER_REKEY_SEQNO_LIMIT;
69
70static off_t rekey_client_len = 0;
71static off_t rekey_server_len = 0;
72static off_t rekey_size = 0;
73
74static int poll_timeout = -1;
75static time_t last_recvd, last_sent;
76
77static const char *version_id = SFTP_ID_STRING "\r\n";
78static int sent_version_id = FALSE;
79
80static void is_client_alive(void);
81
82/* Count of the number of "client alive" messages sent without a response. */
83static unsigned int client_alive_max = 0, client_alive_count = 0;
84static unsigned int client_alive_interval = 0;
85
86static const char *trace_channel = "ssh2";
87
88static int packet_poll(int sockfd, int io) {
89  fd_set rfds, wfds;
90  struct timeval tv;
91  int res, timeout, using_client_alive = FALSE;
92
93  if (poll_timeout == -1) {
94    /* If we have "client alive" timeout interval configured, use that --
95     * but only if we have already done the key exchange, and are not
96     * rekeying.
97     *
98     * Otherwise, we use the default (i.e. TimeoutIdle).
99     */
100
101    if (client_alive_interval > 0 &&
102        (!(sftp_sess_state & SFTP_SESS_STATE_REKEYING) &&
103         (sftp_sess_state & SFTP_SESS_STATE_HAVE_AUTH))) {
104      timeout = client_alive_interval;
105      using_client_alive = TRUE;
106
107    } else {
108      timeout = pr_data_get_timeout(PR_DATA_TIMEOUT_IDLE);
109    }
110
111  } else {
112    timeout = poll_timeout;
113  }
114
115  tv.tv_sec = timeout;
116  tv.tv_usec = 0;
117
118  pr_trace_msg(trace_channel, 19,
119    "waiting for max of %lu secs while polling socket %d using select(2)",
120    (unsigned long) tv.tv_sec, sockfd);
121
122  while (1) {
123    pr_signals_handle();
124
125    FD_ZERO(&rfds);
126    FD_ZERO(&wfds);
127
128    switch (io) {
129      case SFTP_PACKET_IO_RD: {
130        FD_SET(sockfd, &rfds);
131        res = select(sockfd + 1, &rfds, NULL, NULL, &tv);
132        break;
133      }
134
135      case SFTP_PACKET_IO_WR: {
136        FD_SET(sockfd, &wfds);
137        res = select(sockfd + 1, NULL, &wfds, NULL, &tv);
138        break;
139      }
140
141      default:
142        errno = EINVAL;
143        return -1;
144    }
145
146    if (res < 0) {
147      int xerrno = errno;
148
149      if (xerrno == EINTR) {
150        pr_signals_handle();
151        continue;
152      }
153
154      pr_trace_msg(trace_channel, 18, "error calling select(2) on fd %d: %s",
155        sockfd, strerror(xerrno));
156
157      errno = xerrno;
158      return -1;
159
160    } else if (res == 0) {
161      tv.tv_sec = timeout;
162      tv.tv_usec = 0;
163
164      if (using_client_alive) {
165        is_client_alive();
166
167      } else {
168        pr_trace_msg(trace_channel, 18,
169          "polling on socket %d timed out after %lu sec, trying again", sockfd,
170          (unsigned long) tv.tv_sec);
171        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
172          "polling on socket %d timed out after %lu sec, trying again", sockfd,
173          (unsigned long) tv.tv_sec);
174      }
175
176      continue;
177    }
178
179    break;
180  }
181
182  return 0;
183}
184
185/* The purpose of sock_read() is to loop until either we have read in the
186 * requested reqlen from the socket, or the socket gives us an I/O error.
187 * We want to prevent short reads from causing problems elsewhere (e.g.
188 * in the decipher or MAC code).
189 *
190 * It is the caller's responsibility to ensure that buf is large enough to
191 * hold reqlen bytes.
192 */
193int sftp_ssh2_packet_sock_read(int sockfd, void *buf, size_t reqlen,
194    int flags) {
195  void *ptr;
196  size_t remainlen;
197
198  if (reqlen == 0) {
199    return 0;
200  }
201
202  errno = 0;
203
204  ptr = buf;
205  remainlen = reqlen;
206
207  while (remainlen > 0) {
208    int res;
209
210    if (packet_poll(sockfd, SFTP_PACKET_IO_RD) < 0) {
211      return -1;
212    }
213
214    /* The socket we accept is blocking, thus there's no need to handle
215     * EAGAIN/EWOULDBLOCK errors.
216     */
217    res = read(sockfd, ptr, remainlen);
218
219    while (res <= 0) {
220      if (res < 0) {
221        int xerrno = errno;
222
223        if (xerrno == EINTR) {
224          pr_signals_handle();
225          continue;
226        }
227
228        pr_trace_msg(trace_channel, 16,
229          "error reading from client (fd %d): %s", sockfd, strerror(xerrno));
230        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
231          "error reading from client (fd %d): %s", sockfd, strerror(xerrno));
232
233        errno = xerrno;
234
235        /* We explicitly disconnect the client here, rather than sending
236         * a DISCONNECT message, because the errors below all indicate
237         * a problem with the TCP connection, such that trying to write
238         * more data on that connection would cause problems.
239         */
240        if (errno == ECONNRESET ||
241            errno == ECONNABORTED ||
242#ifdef ETIMEDOUT
243            errno == ETIMEDOUT ||
244#endif /* ETIMEDOUT */
245#ifdef ENOTCONN
246            errno == ENOTCONN ||
247#endif /* ENOTCONN */
248#ifdef ESHUTDOWN
249            errno == ESHUTDOWN ||
250#endif /* ESHUTDOWNN */
251            errno == EPIPE) {
252          xerrno = errno;
253
254          pr_trace_msg(trace_channel, 16,
255            "disconnecting client (%s)", strerror(xerrno));
256          (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
257            "disconnecting client (%s)", strerror(xerrno));
258          pr_session_disconnect(&sftp_module, PR_SESS_DISCONNECT_CLIENT_EOF,
259            strerror(xerrno));
260        }
261
262        return -1;
263
264      } else {
265        /* If we read zero bytes here, treat it as an EOF and hang up on
266         * the uncommunicative client.
267         */
268
269        pr_trace_msg(trace_channel, 16, "%s",
270          "disconnecting client (received EOF)");
271        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
272          "disconnecting client (received EOF)");
273        pr_session_disconnect(&sftp_module, PR_SESS_DISCONNECT_CLIENT_EOF,
274          NULL);
275      }
276    }
277
278    /* Generate an event for any interested listeners.  Since the data are
279     * probably encrypted and such, and since listeners won't/shouldn't
280     * have the facilities for handling such data, we only pass the
281     * amount of data read in.
282     */
283    pr_event_generate("ssh2.netio-read", &res);
284
285    session.total_raw_in += reqlen;
286    time(&last_recvd);
287
288    if (res == remainlen)
289      break;
290
291    if (flags & SFTP_PACKET_READ_FL_PESSIMISTIC) {
292      pr_trace_msg(trace_channel, 20, "read %lu bytes, expected %lu bytes; "
293        "pessimistically returning", (unsigned long) res,
294        (unsigned long) remainlen);
295      break;
296    }
297
298    pr_trace_msg(trace_channel, 20, "read %lu bytes, expected %lu bytes; "
299      "reading more", (unsigned long) res, (unsigned long) remainlen);
300    ptr = ((char *) ptr + res);
301    remainlen -= res;
302  }
303
304  return reqlen;
305}
306
307static char peek_mesg_type(struct ssh2_packet *pkt) {
308  char mesg_type;
309
310  memcpy(&mesg_type, pkt->payload, sizeof(char));
311  return mesg_type;
312}
313
314static void handle_debug_mesg(struct ssh2_packet *pkt) {
315  register unsigned int i;
316  char always_display;
317  char *str;
318
319  always_display = sftp_msg_read_bool(pkt->pool, &pkt->payload,
320    &pkt->payload_len);
321  str = sftp_msg_read_string(pkt->pool, &pkt->payload, &pkt->payload_len);
322
323  /* Ignore the language tag. */
324  (void) sftp_msg_read_string(pkt->pool, &pkt->payload, &pkt->payload_len);
325
326  /* Sanity-check the message for control (and other non-printable)
327   * characters.
328   */
329  for (i = 0; i < strlen(str); i++) {
330    if (iscntrl((int) str[i]) ||
331        !isprint((int) str[i])) {
332      str[i] = '?';
333    }
334  }
335
336  (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
337    "client sent SSH_MSG_DEBUG message '%s'", str);
338
339  if (always_display) {
340    pr_log_debug(DEBUG0, MOD_SFTP_VERSION
341      ": client sent SSH_MSG_DEBUG message '%s'", str);
342  }
343
344  destroy_pool(pkt->pool);
345}
346
347static void handle_disconnect_mesg(struct ssh2_packet *pkt) {
348  register unsigned int i;
349  char *explain = NULL, *lang = NULL;
350  const char *reason_str = NULL;
351  uint32_t reason_code;
352
353  reason_code = sftp_msg_read_int(pkt->pool, &pkt->payload, &pkt->payload_len);
354  reason_str = sftp_disconnect_get_str(reason_code);
355  if (reason_str == NULL) {
356    pr_trace_msg(trace_channel, 9,
357      "client sent unknown disconnect reason code %lu",
358      (unsigned long) reason_code);
359    reason_str = "Unknown reason code";
360  }
361
362  explain = sftp_msg_read_string(pkt->pool, &pkt->payload, &pkt->payload_len);
363
364  /* Not all clients send a language tag. */
365  if (pkt->payload_len > 0) {
366    lang = sftp_msg_read_string(pkt->pool, &pkt->payload, &pkt->payload_len);
367  }
368
369  /* Sanity-check the message for control characters. */
370  for (i = 0; i < strlen(explain); i++) {
371    if (iscntrl((int) explain[i])) {
372      explain[i] = '?';
373    }
374  }
375
376  /* XXX Use the language tag somehow, if provided. */
377  if (lang != NULL) {
378    pr_trace_msg(trace_channel, 19, "client sent DISCONNECT language tag '%s'",
379      lang);
380  }
381
382  (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
383    "client sent SSH_DISCONNECT message: %s (%s)", explain, reason_str);
384  pr_session_disconnect(&sftp_module, PR_SESS_DISCONNECT_CLIENT_QUIT, explain);
385}
386
387static void handle_global_request_mesg(struct ssh2_packet *pkt) {
388  char *buf, *ptr;
389  uint32_t buflen, bufsz;
390  char *request_name;
391  int want_reply;
392
393  buf = pkt->payload;
394  buflen = pkt->payload_len;
395
396  request_name = sftp_msg_read_string(pkt->pool, &buf, &buflen);
397  want_reply = sftp_msg_read_bool(pkt->pool, &buf, &buflen);
398
399  (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
400    "client sent GLOBAL_REQUEST for '%s', denying", request_name);
401
402  if (want_reply) {
403    struct ssh2_packet *pkt2;
404    int res;
405
406    buflen = bufsz = 1024;
407    ptr = buf = palloc(pkt->pool, bufsz);
408
409    sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_REQUEST_FAILURE);
410
411    pkt2 = sftp_ssh2_packet_create(pkt->pool);
412    pkt2->payload = ptr;
413    pkt2->payload_len = (bufsz - buflen);
414
415    res = sftp_ssh2_packet_write(sftp_conn->wfd, pkt2);
416    if (res < 0) {
417      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
418        "error writing REQUEST_FAILURE message: %s", strerror(errno));
419    }
420  }
421
422  destroy_pool(pkt->pool);
423}
424
425static void handle_client_alive_mesg(struct ssh2_packet *pkt, char mesg_type) {
426  const char *mesg_desc;
427
428  mesg_desc = sftp_ssh2_packet_get_mesg_type_desc(mesg_type);
429
430  pr_trace_msg(trace_channel, 12,
431    "client sent %s message, considering client alive", mesg_desc);
432
433  client_alive_count = 0;
434  destroy_pool(pkt->pool);
435}
436
437static void handle_ignore_mesg(struct ssh2_packet *pkt) {
438  char *str;
439  size_t len;
440
441  str = sftp_msg_read_string(pkt->pool, &pkt->payload, &pkt->payload_len);
442  len = strlen(str);
443
444  (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
445    "client sent SSH_MSG_IGNORE message (%u bytes)", (unsigned int) len);
446
447  destroy_pool(pkt->pool);
448}
449
450static void handle_unimplemented_mesg(struct ssh2_packet *pkt) {
451  uint32_t seqno;
452
453  seqno = sftp_msg_read_int(pkt->pool, &pkt->payload, &pkt->payload_len);
454
455  pr_trace_msg(trace_channel, 7, "received SSH_MSG_UNIMPLEMENTED for "
456    "packet #%lu", (unsigned long) seqno);
457
458  destroy_pool(pkt->pool);
459}
460
461static void is_client_alive(void) {
462  unsigned int count;
463  char *buf, *ptr;
464  uint32_t bufsz, buflen, channel_id;
465  struct ssh2_packet *pkt;
466  pool *tmp_pool;
467
468  if (++client_alive_count > client_alive_max) {
469    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
470      "SFTPClientAlive threshold (max %u checks, %u sec interval) reached, "
471      "disconnecting client", client_alive_max, client_alive_interval);   
472
473    /* XXX Generate an event for this? */
474
475    SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION,
476      "client alive threshold reached");
477  }
478
479  /* If we have any opened channels, send a CHANNEL_REQUEST to one of
480   * them.  Otherwise, send a GLOBAL_REQUEST.
481   */
482
483  tmp_pool = make_sub_pool(session.pool);
484
485  bufsz = buflen = 64;
486  ptr = buf = palloc(tmp_pool, bufsz);
487
488  count = sftp_channel_opened(&channel_id); 
489  if (count > 0) {
490    sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_CHANNEL_REQUEST);
491    sftp_msg_write_int(&buf, &buflen, channel_id);
492
493    pr_trace_msg(trace_channel, 9,
494      "sending CHANNEL_REQUEST (remote channel ID %lu, keepalive@proftpd.org)",
495      (unsigned long) channel_id);
496
497  } else {
498    sftp_msg_write_byte(&buf, &buflen, SFTP_SSH2_MSG_GLOBAL_REQUEST);
499
500    pr_trace_msg(trace_channel, 9,
501      "sending GLOBAL_REQUEST (keepalive@proftpd.org)");
502  }
503
504  sftp_msg_write_string(&buf, &buflen, "keepalive@proftpd.org");
505  sftp_msg_write_bool(&buf, &buflen, TRUE);
506
507  pkt = sftp_ssh2_packet_create(tmp_pool);
508  pkt->payload = ptr;
509  pkt->payload_len = (bufsz - buflen);
510
511  (void) sftp_ssh2_packet_write(sftp_conn->wfd, pkt);
512  destroy_pool(tmp_pool);
513}
514
515/* Attempt to read in a random amount of data (up to the maximum amount of
516 * SSH2 packet data we support) from the socket.  This is used to help
517 * mitigate the plaintext recovery attack described by CPNI-957037.
518 *
519 * Technically this is only necessary if a CBC mode cipher is in use, but
520 * there should be no harm in using for any cipher; we are going to
521 * disconnect the client after reading this data anyway.
522 */
523static void read_packet_discard(int sockfd) {
524  char buf[SFTP_MAX_PACKET_LEN];
525  size_t buflen;
526
527  buflen = SFTP_MAX_PACKET_LEN -
528    ((int) (SFTP_MAX_PACKET_LEN * (rand() / (RAND_MAX + 1.0))));
529
530  pr_trace_msg(trace_channel, 3, "reading %lu bytes of data for discarding",
531    (unsigned long) buflen);
532
533  if (buflen > 0) {
534    int flags = SFTP_PACKET_READ_FL_PESSIMISTIC;
535
536    /* We don't necessary want to wait for the entire random amount of data
537     * to be read in.
538     */
539    sftp_ssh2_packet_sock_read(sockfd, buf, buflen, flags);
540  }
541
542  return;
543}
544
545static int read_packet_len(int sockfd, struct ssh2_packet *pkt,
546    char *buf, size_t *offset, size_t *buflen, size_t bufsz) {
547  uint32_t packet_len = 0, len = 0;
548  size_t blocksz;
549  int res;
550  char *ptr = NULL;
551
552  blocksz = sftp_cipher_get_block_size();
553
554  /* Since the packet length may be encrypted, we need to read in the first
555   * cipher_block_size bytes from the socket, and try to decrypt them, to know
556   * how many more bytes there are in the packet.
557   */
558
559  res = sftp_ssh2_packet_sock_read(sockfd, buf, blocksz, 0);
560  if (res < 0)
561    return res;
562
563  len = res;
564  if (sftp_cipher_read_data(pkt->pool, (unsigned char *) buf, blocksz, &ptr,
565      &len) < 0) {
566    return -1;
567  }
568
569  memcpy(&packet_len, ptr, sizeof(uint32_t));
570  pkt->packet_len = ntohl(packet_len);
571
572  ptr += sizeof(uint32_t);
573  len -= sizeof(uint32_t);
574
575  /* Copy the remaining unencrypted bytes from the block into the given
576   * buffer.
577   */
578  if (len > 0) {
579    memcpy(buf, ptr, len);
580    *buflen = (size_t) len;
581  }
582
583  *offset = 0;
584  return 0;
585}
586
587static int read_packet_padding_len(int sockfd, struct ssh2_packet *pkt,
588    char *buf, size_t *offset, size_t *buflen, size_t bufsz) {
589
590  if (*buflen > sizeof(char)) {
591    /* XXX Assume the data in the buffer is unecrypted, and thus usable. */
592    memcpy(&pkt->padding_len, buf + *offset, sizeof(char));
593
594    /* Advance the buffer past the byte we just read off. */
595    *offset += sizeof(char);
596    *buflen -= sizeof(char);
597
598    return 0;
599  }
600
601  (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
602    "unable to read padding len: not enough data in buffer (%u bytes)",
603    (unsigned int) *buflen);
604  return -1;
605}
606
607static int read_packet_payload(int sockfd, struct ssh2_packet *pkt,
608    char *buf, size_t *offset, size_t *buflen, size_t bufsz) {
609  char *ptr = NULL;
610  int res;
611  uint32_t payload_len = pkt->payload_len, padding_len = pkt->padding_len,
612    data_len, len = 0;
613
614  if (payload_len + padding_len == 0)
615    return 0;
616
617  if (payload_len > 0) {
618    /* We don't want to reject the packet outright yet; but we can ignore
619     * the payload data we're going to read in.  This packet will fail
620     * eventually anyway.
621     */
622    if (payload_len > SFTP_PACKET_MAX_PAYLOAD_LEN) {
623      pr_trace_msg(trace_channel, 20,
624        "payload len (%lu bytes) exceeds max payload len (%lu), "
625        "ignoring payload", (unsigned long) payload_len,
626        (unsigned long) SFTP_PACKET_MAX_PAYLOAD_LEN);
627
628      pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
629        "client sent buggy/malicious packet payload length, ignoring");
630
631      errno = EPERM;
632      return -1;
633    }
634
635    pkt->payload = pcalloc(pkt->pool, payload_len);
636  }
637
638  /* If there's data in the buffer we received, it's probably already part
639   * of the payload, unencrypted.  That will leave the remaining payload
640   * data, if any, to be read in and decrypted.
641   */
642  if (*buflen > 0) {
643    if (*buflen < payload_len) {
644      memcpy(pkt->payload, buf + *offset, *buflen);
645
646      payload_len -= *buflen;
647      *offset = 0;
648      *buflen = 0;
649
650    } else {
651      /* There's enough already for the payload length.  Nice. */
652      memcpy(pkt->payload, buf + *offset, payload_len);
653
654      *offset += payload_len;
655      *buflen -= payload_len;
656      payload_len = 0;
657    }
658  }
659
660  /* The padding length is required to be greater than zero. */
661  pkt->padding = pcalloc(pkt->pool, padding_len);
662
663  /* If there's data in the buffer we received, it's probably already part
664   * of the padding, unencrypted.  That will leave the remaining padding
665   * data, if any, to be read in and decrypted.
666   */
667  if (*buflen > 0) {
668    if (*buflen < padding_len) {
669      memcpy(pkt->padding, buf + *offset, *buflen);
670
671      padding_len -= *buflen;
672      *offset = 0;
673      *buflen = 0;
674
675    } else {
676      /* There's enough already for the padding length.  Nice. */
677      memcpy(pkt->padding, buf + *offset, padding_len);
678
679      *offset += padding_len;
680      *buflen -= padding_len;
681      padding_len = 0;
682    }
683  }
684
685  data_len = payload_len + padding_len;
686  if (data_len == 0)
687    return 0;
688
689  if (data_len > bufsz) {
690    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
691      "remaining packet data (%lu bytes) exceeds packet buffer size (%lu "
692      "bytes)", (unsigned long) data_len, (unsigned long) bufsz);
693    errno = EPERM;
694    return -1;
695  }
696
697  res = sftp_ssh2_packet_sock_read(sockfd, buf + *offset, data_len, 0);
698  if (res < 0) {
699    return res;
700  }
701 
702  len = res;
703  if (sftp_cipher_read_data(pkt->pool, (unsigned char *) buf + *offset,
704      data_len, &ptr, &len) < 0) {
705    return -1;
706  }
707
708  if (payload_len > 0) {
709    memcpy(pkt->payload + (pkt->payload_len - payload_len), ptr,
710      payload_len);
711  }
712
713  memcpy(pkt->padding + (pkt->padding_len - padding_len), ptr + payload_len,
714    padding_len);
715  return 0;
716}
717
718static int read_packet_mac(int sockfd, struct ssh2_packet *pkt, char *buf) {
719  int res;
720  uint32_t mac_len = pkt->mac_len;
721
722  if (mac_len == 0)
723    return 0;
724
725  res = sftp_ssh2_packet_sock_read(sockfd, buf, mac_len, 0);
726  if (res < 0)
727    return res;
728
729  pkt->mac = palloc(pkt->pool, pkt->mac_len);
730  memcpy(pkt->mac, buf, res);
731
732  return 0;
733}
734
735struct ssh2_packet *sftp_ssh2_packet_create(pool *p) {
736  pool *tmp_pool;
737  struct ssh2_packet *pkt;
738
739  tmp_pool = pr_pool_create_sz(p, 128);
740  pr_pool_tag(tmp_pool, "SSH2 packet pool");
741
742  pkt = pcalloc(tmp_pool, sizeof(struct ssh2_packet));
743  pkt->pool = tmp_pool;
744  pkt->packet_len = 0;
745  pkt->payload = NULL;
746  pkt->payload_len = 0;
747  pkt->padding_len = 0;
748
749  return pkt;
750}
751
752int sftp_ssh2_packet_get_last_recvd(time_t *tp) {
753  if (tp == NULL) {
754    errno = EINVAL;
755    return -1;
756  }
757
758  memcpy(tp, &last_recvd, sizeof(time_t));
759  return 0;
760}
761
762int sftp_ssh2_packet_get_last_sent(time_t *tp) {
763  if (tp == NULL) {
764    errno = EINVAL;
765    return -1;
766  }
767
768  memcpy(tp, &last_sent, sizeof(time_t));
769  return 0;
770}
771
772char sftp_ssh2_packet_get_mesg_type(struct ssh2_packet *pkt) {
773  char mesg_type;
774
775  memcpy(&mesg_type, pkt->payload, sizeof(char));
776  pkt->payload += sizeof(char);
777  pkt->payload_len -= sizeof(char);
778
779  return mesg_type;
780}
781
782const char *sftp_ssh2_packet_get_mesg_type_desc(char mesg_type) {
783  switch (mesg_type) {
784    case SFTP_SSH2_MSG_DISCONNECT:
785      return "SSH_MSG_DISCONNECT";
786
787    case SFTP_SSH2_MSG_IGNORE:
788      return "SSH_MSG_IGNORE";
789
790    case SFTP_SSH2_MSG_UNIMPLEMENTED:
791      return "SSH_MSG_UNIMPLEMENTED";
792
793    case SFTP_SSH2_MSG_DEBUG:
794      return "SSH_MSG_DEBUG";
795
796    case SFTP_SSH2_MSG_SERVICE_REQUEST:
797      return "SSH_MSG_SERVICE_REQUEST";
798
799    case SFTP_SSH2_MSG_SERVICE_ACCEPT:
800      return "SSH_MSG_SERVICE_ACCEPT";
801
802    case SFTP_SSH2_MSG_KEXINIT:
803      return "SSH_MSG_KEXINIT";
804
805    case SFTP_SSH2_MSG_NEWKEYS:
806      return "SSH_MSG_NEWKEYS";
807
808    case SFTP_SSH2_MSG_KEX_DH_INIT:
809      return "SSH_MSG_KEX_DH_INIT";
810
811    case SFTP_SSH2_MSG_KEX_DH_REPLY:
812      return "SSH_MSG_KEX_DH_REPLY";
813
814    case SFTP_SSH2_MSG_KEX_DH_GEX_INIT:
815      return "SSH_MSG_KEX_DH_GEX_INIT";
816
817    case SFTP_SSH2_MSG_KEX_DH_GEX_REPLY:
818      return "SSH_MSG_KEX_DH_GEX_REPLY";
819
820    case SFTP_SSH2_MSG_KEX_DH_GEX_REQUEST:
821      return "SSH_MSG_KEX_DH_GEX_REQUEST";
822
823    case SFTP_SSH2_MSG_USER_AUTH_REQUEST:
824      return "SSH_MSG_USER_AUTH_REQUEST";
825
826    case SFTP_SSH2_MSG_USER_AUTH_FAILURE:
827      return "SSH_MSG_USER_AUTH_FAILURE";
828
829    case SFTP_SSH2_MSG_USER_AUTH_SUCCESS:
830      return "SSH_MSG_USER_AUTH_SUCCESS";
831
832    case SFTP_SSH2_MSG_USER_AUTH_BANNER:
833      return "SSH_MSG_USER_AUTH_BANNER";
834
835    case SFTP_SSH2_MSG_USER_AUTH_PASSWD:
836      return "SSH_MSG_USER_AUTH_PASSWD";
837
838    case SFTP_SSH2_MSG_USER_AUTH_INFO_RESP:
839      return "SSH_MSG_USER_AUTH_INFO_RESP";
840
841    case SFTP_SSH2_MSG_GLOBAL_REQUEST:
842      return "SSH_MSG_GLOBAL_REQUEST";
843
844    case SFTP_SSH2_MSG_REQUEST_SUCCESS:
845      return "SSH_MSG_REQUEST_SUCCESS";
846
847    case SFTP_SSH2_MSG_REQUEST_FAILURE:
848      return "SSH_MSG_REQUEST_FAILURE";
849
850    case SFTP_SSH2_MSG_CHANNEL_OPEN:
851      return "SSH_MSG_CHANNEL_OPEN";
852
853    case SFTP_SSH2_MSG_CHANNEL_OPEN_CONFIRMATION:
854      return "SSH_MSG_CHANNEL_OPEN_CONFIRMATION";
855
856    case SFTP_SSH2_MSG_CHANNEL_OPEN_FAILURE:
857      return "SSH_MSG_CHANNEL_OPEN_FAILURE";
858
859    case SFTP_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
860      return "SSH_MSG_CHANNEL_WINDOW_ADJUST";
861
862    case SFTP_SSH2_MSG_CHANNEL_DATA:
863      return "SSH_MSG_CHANNEL_DATA";
864
865    case SFTP_SSH2_MSG_CHANNEL_EXTENDED_DATA:
866      return "SSH_MSG_CHANNEL_EXTENDED_DATA";
867
868    case SFTP_SSH2_MSG_CHANNEL_EOF:
869      return "SSH_MSG_CHANNEL_EOF";
870
871    case SFTP_SSH2_MSG_CHANNEL_CLOSE:
872      return "SSH_MSG_CHANNEL_CLOSE";
873
874    case SFTP_SSH2_MSG_CHANNEL_REQUEST:
875      return "SSH_MSG_CHANNEL_REQUEST";
876
877    case SFTP_SSH2_MSG_CHANNEL_SUCCESS:
878      return "SSH_MSG_CHANNEL_SUCCESS";
879
880    case SFTP_SSH2_MSG_CHANNEL_FAILURE:
881      return "SSH_MSG_CHANNEL_FAILURE";
882  }
883
884  return "(unknown)";
885}
886
887int sftp_ssh2_packet_set_poll_timeout(int timeout) {
888  if (timeout <= 0) {
889    poll_timeout = -1;
890
891  } else {
892    poll_timeout = timeout;
893  }
894
895  return 0;
896}
897
898int sftp_ssh2_packet_set_client_alive(unsigned int max, unsigned int interval) {
899  client_alive_max = max;
900  client_alive_interval = interval;
901  return 0;
902}
903
904int sftp_ssh2_packet_read(int sockfd, struct ssh2_packet *pkt) {
905  char buf[SFTP_MAX_PACKET_LEN];
906  size_t buflen, bufsz = SFTP_MAX_PACKET_LEN, offset = 0;
907
908  pr_session_set_idle();
909
910  while (1) {
911    uint32_t req_blocksz;
912
913    pr_signals_handle();
914
915    /* This is in a while loop in order to consume any debug/ignore
916     * messages which the client may send.
917     */
918
919    buflen = 0;
920    memset(buf, 0, sizeof(buf));
921
922    if (read_packet_len(sockfd, pkt, buf, &offset, &buflen, bufsz) < 0) {
923      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
924        "no data to be read from socket %d", sockfd);
925      return -1;
926    }
927
928    pr_trace_msg(trace_channel, 20, "SSH2 packet len = %lu bytes",
929      (unsigned long) pkt->packet_len);
930
931    /* In order to mitigate the plaintext recovery attack described in
932     * CPNI-957037:
933     *
934     *  http://www.cpni.gov.uk/Docs/Vulnerability_Advisory_SSH.txt
935     *
936     * we do NOT check that the packet length is sane here; we have to
937     * wait until the MAC check succeeds.
938     */
939 
940    /* Note: Checking for the RFC4253-recommended minimum packet length
941     * of 16 bytes causes KEX to fail (the NEWKEYS packet is 12 bytes).
942     * Thus that particular check is omitted.
943     */
944
945    if (read_packet_padding_len(sockfd, pkt, buf, &offset, &buflen,
946        bufsz) < 0) {
947      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
948        "no data to be read from socket %d", sockfd);
949      read_packet_discard(sockfd);
950      return -1;
951    }
952
953    pr_trace_msg(trace_channel, 20, "SSH2 packet padding len = %u bytes",
954      (unsigned int) pkt->padding_len);
955
956    pkt->payload_len = (pkt->packet_len - pkt->padding_len - 1);
957
958    pr_trace_msg(trace_channel, 20, "SSH2 packet payload len = %lu bytes",
959      (unsigned long) pkt->payload_len);
960
961    /* Read both payload and padding, since we may need to have both before
962     * decrypting the data.
963     */
964    if (read_packet_payload(sockfd, pkt, buf, &offset, &buflen, bufsz) < 0) {
965      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
966        "unable to read payload from socket %d", sockfd);
967      read_packet_discard(sockfd);
968      return -1;
969    }
970
971    memset(buf, 0, sizeof(buf));
972    pkt->mac_len = sftp_mac_get_block_size();
973
974    pr_trace_msg(trace_channel, 20, "SSH2 packet MAC len = %lu bytes",
975      (unsigned long) pkt->mac_len);
976
977    if (read_packet_mac(sockfd, pkt, buf) < 0) {
978      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
979        "unable to read MAC from socket %d", sockfd);
980      read_packet_discard(sockfd);
981      return -1;
982    }
983
984    pkt->seqno = packet_client_seqno;
985    if (sftp_mac_read_data(pkt) < 0) {
986      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
987        "unable to verify MAC on packet from socket %d", sockfd);
988
989      /* In order to further mitigate CPNI-957037, we will read in a
990       * random amount of more data from the network before closing
991       * the connection.
992       */
993      read_packet_discard(sockfd);
994      return -1;
995    }
996
997    /* Now that the MAC check has passed, we can do sanity checks based
998     * on the fields we have read in, and trust that those fields are
999     * correct.
1000     */
1001
1002    if (pkt->packet_len < 5) {
1003      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1004        "packet length too long (%lu), less than minimum packet length (5)",
1005        (unsigned long) pkt->packet_len);
1006      return -1;
1007    }
1008
1009    if (pkt->packet_len > SFTP_MAX_PACKET_LEN) {
1010      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1011        "packet length too long (%lu), exceeds maximum packet length (%lu)",
1012        (unsigned long) pkt->packet_len, (unsigned long) SFTP_MAX_PACKET_LEN);
1013      return -1;
1014    }
1015
1016    /* Per Section 6 of RFC4253, the minimum padding length is 4, the
1017     * maximum padding length is 255.
1018     */
1019
1020    if (pkt->padding_len < SFTP_MIN_PADDING_LEN) {
1021      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1022        "padding length too short (%u), less than minimum padding length (%u)",
1023        (unsigned int) pkt->padding_len, (unsigned int) SFTP_MIN_PADDING_LEN);
1024      read_packet_discard(sockfd);
1025      return -1;
1026    }
1027
1028    if (pkt->padding_len > pkt->packet_len) {
1029      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1030        "padding length too long (%u), exceeds packet length (%lu)",
1031        (unsigned int) pkt->padding_len, (unsigned long) pkt->packet_len);
1032      read_packet_discard(sockfd);
1033      return -1;
1034    }
1035
1036    /* From RFC4253, Section 6:
1037     *
1038     * random padding
1039     *   Arbitrary-length padding, such that the total length of
1040     *   (packet_length || padding_length || payload || random padding)
1041     *   is a multiple of the cipher block size or 8, whichever is
1042     *   larger.
1043     *
1044     * Thus packet_len + sizeof(uint32_t) (for the actual packet length field)
1045     * is that "(packet_length || padding_length || payload || padding)"
1046     * value.
1047     */
1048
1049    req_blocksz = MAX(8, sftp_cipher_get_block_size());
1050
1051    if ((pkt->packet_len + sizeof(uint32_t)) % req_blocksz != 0) {
1052      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1053        "packet length (%lu) not a multiple of the required block size (%lu)",
1054        (unsigned long) pkt->packet_len + sizeof(uint32_t),
1055        (unsigned long) req_blocksz);
1056      read_packet_discard(sockfd);
1057      return -1;
1058    }
1059
1060    /* XXX I'm not so sure about this check; we SHOULD have a maximum
1061     * payload check, but using the max packet length check for the payload
1062     * length seems awkward.
1063     */
1064    if (pkt->payload_len > SFTP_MAX_PACKET_LEN) {
1065      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1066        "payload length too long (%lu), exceeds maximum payload length (%lu) "
1067        "(packet len %lu, padding len %u)", (unsigned long) pkt->payload_len,
1068        (unsigned long) SFTP_MAX_PACKET_LEN, (unsigned long) pkt->packet_len,
1069        (unsigned int) pkt->padding_len);
1070      read_packet_discard(sockfd);
1071      return -1;
1072    }
1073
1074    /* Sanity checks passed; move on to the reading the packet payload. */
1075    if (sftp_compress_read_data(pkt) < 0) {
1076      return -1;
1077    }
1078
1079    packet_client_seqno++;
1080    pr_timer_reset(PR_TIMER_IDLE, ANY_MODULE);
1081
1082    break;
1083  }
1084
1085  if (rekey_size > 0) {
1086    rekey_client_len += pkt->packet_len;
1087
1088    if (rekey_client_len >= rekey_size) {
1089      pr_trace_msg(trace_channel, 17, "client packet bytes recvd (%" PR_LU
1090        ") reached rekey bytes limit (%" PR_LU "), requesting rekey",
1091        (pr_off_t) rekey_client_len, (pr_off_t) rekey_size);
1092      sftp_kex_rekey();
1093    }
1094  }
1095
1096  if (rekey_client_seqno > 0 &&
1097      packet_client_seqno == rekey_client_seqno) {
1098    pr_trace_msg(trace_channel, 17, "client packet sequence number (%lu) "
1099      "reached rekey packet number %lu, requesting rekey",
1100      (unsigned long) packet_client_seqno, (unsigned long) rekey_client_seqno);
1101    sftp_kex_rekey();
1102  }
1103
1104  return 0;
1105}
1106
1107static int write_packet_padding(struct ssh2_packet *pkt) {
1108  register unsigned int i;
1109  uint32_t packet_len = 0;
1110  size_t blocksz;
1111
1112  blocksz = sftp_cipher_get_block_size();
1113
1114  /* RFC 4253, section 6, says that the random padding is calculated
1115   * as follows:
1116   *
1117   *  random padding
1118   *     Arbitrary-length padding, such that the total length of
1119   *     (packet_length || padding_length || payload || random padding)
1120   *     is a multiple of the cipher block size or 8, whichever is
1121   *     larger.  There MUST be at least four bytes of padding.  The
1122   *     padding SHOULD consist of random bytes.  The maximum amount of
1123   *     padding is 255 bytes.
1124   *
1125   * This means:
1126   *
1127   *  packet len = sizeof(packet_len field) + sizeof(padding_len field) +
1128   *    sizeof(payload field) + sizeof(padding field)
1129   */
1130
1131  packet_len = sizeof(uint32_t) + sizeof(char) + pkt->payload_len;
1132
1133  pkt->padding_len = (char) (blocksz - (packet_len % blocksz));
1134  if (pkt->padding_len < 4) {
1135    /* As per RFC, there must be at least 4 bytes of padding.  So if the
1136     * above calculated less, then we need to add another block's worth
1137     * of padding.
1138     */
1139    pkt->padding_len += blocksz;
1140  }
1141
1142  pkt->padding = palloc(pkt->pool, pkt->padding_len);
1143
1144  /* Fill the padding with pseudo-random data. */
1145  for (i = 0; i < pkt->padding_len; i++) {
1146    pkt->padding[i] = rand();
1147  }
1148
1149  return 0;
1150}
1151
1152#define SFTP_SSH2_PACKET_IOVSZ          12
1153static struct iovec packet_iov[SFTP_SSH2_PACKET_IOVSZ];
1154static unsigned int packet_niov = 0;
1155
1156int sftp_ssh2_packet_send(int sockfd, struct ssh2_packet *pkt) {
1157  char buf[SFTP_MAX_PACKET_LEN * 2], mesg_type;
1158  size_t buflen = 0, bufsz = SFTP_MAX_PACKET_LEN;
1159  uint32_t packet_len = 0;
1160  int res, write_len = 0;
1161
1162  /* Clear the iovec array before sending the data, if possible. */
1163  if (packet_niov == 0) {
1164    memset(packet_iov, 0, sizeof(packet_iov));
1165  }
1166
1167  mesg_type = peek_mesg_type(pkt);
1168
1169  if (sftp_compress_write_data(pkt) < 0) {
1170    return -1;
1171  }
1172
1173  if (write_packet_padding(pkt) < 0) {
1174    return -1;
1175  }
1176
1177  /* Packet length: padding len + payload + padding */
1178  pkt->packet_len = packet_len = sizeof(char) + pkt->payload_len +
1179    pkt->padding_len;
1180
1181  pkt->seqno = packet_server_seqno;
1182
1183  if (sftp_mac_write_data(pkt) < 0) {
1184    return -1;
1185  }
1186
1187  memset(buf, 0, sizeof(buf));
1188  buflen = bufsz;
1189
1190  if (sftp_cipher_write_data(pkt, buf, &buflen) < 0) {
1191    return -1;
1192  }
1193
1194  if (buflen > 0) {
1195    /* We have encrypted data, which means we don't need as many of the
1196     * iovec slots as for unecrypted data.
1197     */
1198
1199    if (!sent_version_id) {
1200      packet_iov[packet_niov].iov_base = (void *) version_id;
1201      packet_iov[packet_niov].iov_len = strlen(version_id);
1202      write_len += packet_iov[packet_niov].iov_len;
1203      packet_niov++;
1204    }
1205
1206    packet_iov[packet_niov].iov_base = (void *) buf;
1207    packet_iov[packet_niov].iov_len = buflen;
1208    write_len += packet_iov[packet_niov].iov_len;
1209    packet_niov++;
1210
1211    if (pkt->mac_len > 0) {
1212      packet_iov[packet_niov].iov_base = (void *) pkt->mac;
1213      packet_iov[packet_niov].iov_len = pkt->mac_len;
1214      write_len += packet_iov[packet_niov].iov_len;
1215      packet_niov++;
1216    }
1217
1218  } else {
1219    /* Don't forget to convert the packet len to network-byte order, since
1220     * this length is sent over the wire.
1221     */
1222    packet_len = htonl(packet_len);
1223
1224    if (!sent_version_id) {
1225      packet_iov[packet_niov].iov_base = (void *) version_id;
1226      packet_iov[packet_niov].iov_len = strlen(version_id);
1227      write_len += packet_iov[packet_niov].iov_len;
1228      packet_niov++;
1229    }
1230
1231    packet_iov[packet_niov].iov_base = (void *) &packet_len;
1232    packet_iov[packet_niov].iov_len = sizeof(uint32_t);
1233    write_len += packet_iov[packet_niov].iov_len;
1234    packet_niov++;
1235
1236    packet_iov[packet_niov].iov_base = (void *) &(pkt->padding_len);
1237    packet_iov[packet_niov].iov_len = sizeof(char);
1238    write_len += packet_iov[packet_niov].iov_len;
1239    packet_niov++;
1240
1241    packet_iov[packet_niov].iov_base = (void *) pkt->payload;
1242    packet_iov[packet_niov].iov_len = pkt->payload_len;
1243    write_len += packet_iov[packet_niov].iov_len;
1244    packet_niov++;
1245
1246    packet_iov[packet_niov].iov_base = (void *) pkt->padding;
1247    packet_iov[packet_niov].iov_len = pkt->padding_len;
1248    write_len += packet_iov[packet_niov].iov_len;
1249    packet_niov++;
1250
1251    if (pkt->mac_len > 0) {
1252      packet_iov[packet_niov].iov_base = (void *) pkt->mac;
1253      packet_iov[packet_niov].iov_len = pkt->mac_len;
1254      write_len += packet_iov[packet_niov].iov_len;
1255      packet_niov++;
1256    }
1257  }
1258
1259  /* Generate an event for any interested listeners.  Since the data are
1260   * probably encrypted and such, and since listeners won't/shouldn't
1261   * have the facilities for handling such data, we only pass the
1262   * amount of data to be written out.
1263   */
1264  pr_event_generate("ssh2.netio-write", &write_len);
1265
1266  if (packet_poll(sockfd, SFTP_PACKET_IO_WR) < 0) {
1267    return -1;
1268  }
1269
1270  /* The socket we accept is blocking, thus there's no need to handle
1271   * EAGAIN/EWOULDBLOCK errors.
1272   */
1273  res = writev(sockfd, packet_iov, packet_niov);
1274  while (res < 0) {
1275    if (errno == EINTR) {
1276      pr_signals_handle();
1277
1278      res = writev(sockfd, packet_iov, packet_niov);
1279      continue;
1280    }
1281
1282    (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1283      "error writing packet (fd %d): %s", sockfd, strerror(errno));
1284
1285    if (errno == ECONNRESET ||
1286        errno == ECONNABORTED ||
1287        errno == EPIPE) {
1288      int xerrno = errno;
1289
1290      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1291        "disconnecting client (%s)", strerror(xerrno));
1292      pr_session_disconnect(&sftp_module, PR_SESS_DISCONNECT_BY_APPLICATION,
1293        strerror(xerrno));
1294    }
1295
1296    /* Always clear the iovec array after sending the data. */
1297    memset(packet_iov, 0, sizeof(packet_iov));
1298    packet_niov = 0;
1299
1300    return -1;
1301  }
1302
1303  session.total_raw_out += res;
1304
1305  /* Always clear the iovec array after sending the data. */
1306  memset(packet_iov, 0, sizeof(packet_iov));
1307  packet_niov = 0;
1308
1309  sent_version_id = TRUE;
1310  time(&last_sent);
1311
1312  packet_server_seqno++;
1313
1314  if (rekey_size > 0) {
1315    rekey_server_len += pkt->packet_len;
1316
1317    if (rekey_server_len >= rekey_size) {
1318      pr_trace_msg(trace_channel, 17, "server packet bytes sent (%" PR_LU
1319        ") reached rekey bytes limit (%" PR_LU "), requesting rekey",
1320        (pr_off_t) rekey_server_len, (pr_off_t) rekey_size);
1321      sftp_kex_rekey();
1322    }
1323  }
1324
1325  if (rekey_server_seqno > 0 &&
1326      packet_server_seqno == rekey_server_seqno) {
1327    pr_trace_msg(trace_channel, 17, "server packet sequence number (%lu) "
1328      "reached rekey packet number %lu, requesting rekey",
1329      (unsigned long) packet_server_seqno, (unsigned long) rekey_server_seqno);
1330    sftp_kex_rekey();
1331  }
1332
1333  pr_trace_msg(trace_channel, 3, "sent %s (%d) packet (%d bytes)",
1334    sftp_ssh2_packet_get_mesg_type_desc(mesg_type), mesg_type, res);
1335 
1336  return 0;
1337}
1338
1339int sftp_ssh2_packet_write(int sockfd, struct ssh2_packet *pkt) {
1340  int res;
1341
1342  /* For future reference, I tried buffering up the possible TAP message
1343   * and the given message using TCP_CORK/TCP_NOPUSH.  I tried this test
1344   * on a Mac OSX 10.5 box.  It was for this test that I refactored the
1345   * core pr_inet_* functions, creating pr_inet_set_proto_cork().
1346   *
1347   * Turned out to be a very bad idea.  Using sftp(1), the login process
1348   * itself was incredibly slow.  mod_sftp was behaving as if the
1349   * "uncorking" call was not causing any flushing of the partially-full
1350   * network buffer to be written out, and instead was waiting until the
1351   * buffer was full before writing it out.
1352   *
1353   * Now, this could be due to a bug in Mac OSX's handling of TCP_NOPUSH;
1354   * there are articles about such a problem in earlier Mac OSX versions.
1355   * I should try this test again, on a Linux (TCP_CORK) and FreeBSD
1356   * (TCP_NOPUSH), to see if this can be done at least on those platforms.
1357   */
1358
1359  if (sent_version_id) {
1360    res = sftp_tap_send_packet();
1361    if (res < 0) {
1362      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1363        "error sending TAP packet: %s", strerror(errno));
1364    }
1365  }
1366
1367  return sftp_ssh2_packet_send(sockfd, pkt);
1368}
1369
1370int sftp_ssh2_packet_handle(void) {
1371  struct ssh2_packet *pkt;
1372  char mesg_type;
1373  int res;
1374
1375  pkt = sftp_ssh2_packet_create(sftp_pool);
1376
1377  res = sftp_ssh2_packet_read(sftp_conn->rfd, pkt);
1378  if (res < 0) {
1379    SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
1380  }
1381
1382  mesg_type = sftp_ssh2_packet_get_mesg_type(pkt);
1383  pr_trace_msg(trace_channel, 3, "received %s (%d) packet",
1384    sftp_ssh2_packet_get_mesg_type_desc(mesg_type), mesg_type);
1385
1386  pr_response_clear(&resp_list);
1387  pr_response_clear(&resp_err_list);
1388
1389  /* Note: Some of the SSH messages will be handled regardless of the
1390   * sftp_sess_state flags; this is intentional, and is the way that
1391   * the protocol is supposed to work.
1392   */
1393 
1394  switch (mesg_type) {
1395    case SFTP_SSH2_MSG_DEBUG:
1396      handle_debug_mesg(pkt);
1397      break;
1398
1399    case SFTP_SSH2_MSG_DISCONNECT:
1400      handle_disconnect_mesg(pkt);
1401      break;
1402
1403    case SFTP_SSH2_MSG_GLOBAL_REQUEST:
1404      handle_global_request_mesg(pkt);
1405      break;
1406
1407    case SFTP_SSH2_MSG_REQUEST_SUCCESS:
1408    case SFTP_SSH2_MSG_REQUEST_FAILURE:
1409    case SFTP_SSH2_MSG_CHANNEL_SUCCESS:
1410    case SFTP_SSH2_MSG_CHANNEL_FAILURE:
1411      handle_client_alive_mesg(pkt, mesg_type);
1412      break;
1413
1414    case SFTP_SSH2_MSG_IGNORE:
1415      handle_ignore_mesg(pkt);
1416      break;
1417
1418    case SFTP_SSH2_MSG_UNIMPLEMENTED:
1419      handle_unimplemented_mesg(pkt);
1420      break;
1421
1422    case SFTP_SSH2_MSG_KEXINIT:
1423      /* The client might be initiating a rekey; watch for this. */
1424      if (sftp_sess_state & SFTP_SESS_STATE_HAVE_KEX) {
1425        sftp_sess_state |= SFTP_SESS_STATE_REKEYING;
1426      }
1427 
1428      /* Clear any current "have KEX" state. */
1429      sftp_sess_state &= ~SFTP_SESS_STATE_HAVE_KEX;
1430
1431      if (sftp_kex_handle(pkt) < 0) {
1432        SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
1433      }
1434
1435      sftp_sess_state |= SFTP_SESS_STATE_HAVE_KEX;
1436
1437      /* If we just finished rekeying, drain any of the pending channel
1438       * data which may have built up during the rekeying exchange.
1439       */
1440      if (sftp_sess_state & SFTP_SESS_STATE_REKEYING) {
1441        sftp_sess_state &= ~SFTP_SESS_STATE_REKEYING;
1442        sftp_channel_drain_data();
1443      }
1444      break;
1445
1446    case SFTP_SSH2_MSG_SERVICE_REQUEST:
1447      if (sftp_sess_state & SFTP_SESS_STATE_HAVE_KEX) {
1448        if (sftp_service_handle(pkt) < 0) {
1449          SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
1450        }
1451
1452        sftp_sess_state |= SFTP_SESS_STATE_HAVE_SERVICE;
1453        break;
1454
1455      } else {
1456        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1457          "unable to handle %s (%d) message: Key exchange required",
1458          sftp_ssh2_packet_get_mesg_type_desc(mesg_type), mesg_type);
1459      }
1460
1461    case SFTP_SSH2_MSG_USER_AUTH_REQUEST:
1462      if (sftp_sess_state & SFTP_SESS_STATE_HAVE_SERVICE) {
1463        int ok;
1464
1465        ok = sftp_auth_handle(pkt);
1466        if (ok == 1) {
1467          sftp_sess_state |= SFTP_SESS_STATE_HAVE_AUTH;
1468
1469        } else if (ok < 0) {
1470          SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
1471        }
1472
1473        break;
1474
1475      } else {
1476        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1477          "unable to handle %s (%d) message: Service request required",
1478          sftp_ssh2_packet_get_mesg_type_desc(mesg_type), mesg_type);
1479      }
1480
1481    case SFTP_SSH2_MSG_CHANNEL_OPEN:
1482    case SFTP_SSH2_MSG_CHANNEL_REQUEST:
1483    case SFTP_SSH2_MSG_CHANNEL_CLOSE:
1484    case SFTP_SSH2_MSG_CHANNEL_DATA:
1485    case SFTP_SSH2_MSG_CHANNEL_EOF:
1486    case SFTP_SSH2_MSG_CHANNEL_WINDOW_ADJUST:
1487      if (sftp_sess_state & SFTP_SESS_STATE_HAVE_AUTH) {
1488        if (sftp_channel_handle(pkt, mesg_type) < 0) {
1489          SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION, NULL);
1490        }
1491
1492        break;
1493
1494      } else {
1495        (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1496          "unable to handle %s (%d) message: User authentication required",
1497          sftp_ssh2_packet_get_mesg_type_desc(mesg_type), mesg_type);
1498      }
1499
1500    default:
1501      pr_event_generate("ssh2.invalid-packet", pkt);
1502
1503      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1504        "unhandled %s (%d) message, disconnecting",
1505        sftp_ssh2_packet_get_mesg_type_desc(mesg_type), mesg_type);
1506      SFTP_DISCONNECT_CONN(SFTP_SSH2_DISCONNECT_BY_APPLICATION,
1507        "Unsupported protocol sequence");
1508  }
1509
1510  return 0;
1511}
1512
1513int sftp_ssh2_packet_rekey_reset(void) {
1514  rekey_client_len = 0;
1515  rekey_server_len = 0;
1516
1517  /* Add the rekey seqno limit to the current sequence numbers. */
1518
1519  if (rekey_client_seqno > 0) {
1520    rekey_client_seqno = packet_client_seqno + SFTP_PACKET_CLIENT_REKEY_SEQNO_LIMIT;
1521
1522    if (rekey_client_seqno == 0)
1523      rekey_client_seqno++;
1524  }
1525
1526  if (rekey_server_seqno > 0) {
1527    rekey_server_seqno = packet_client_seqno + SFTP_PACKET_SERVER_REKEY_SEQNO_LIMIT;
1528
1529    if (rekey_server_seqno == 0)
1530      rekey_server_seqno++;
1531  }
1532
1533  return 0;
1534}
1535
1536int sftp_ssh2_packet_rekey_set_seqno(uint32_t seqno) {
1537  rekey_client_seqno = seqno;
1538  rekey_server_seqno = seqno;
1539  return 0;
1540}
1541
1542int sftp_ssh2_packet_rekey_set_size(off_t size) {
1543  rekey_size = size;
1544  return 0;
1545}
1546
1547int sftp_ssh2_packet_send_version(void) {
1548  if (!sent_version_id) {
1549    int res;
1550    size_t version_len;
1551
1552    version_len = strlen(version_id);
1553
1554    res = write(sftp_conn->wfd, version_id, version_len);
1555    while (res < 0) {
1556      if (errno == EINTR) {
1557        pr_signals_handle();
1558
1559        res = write(sftp_conn->wfd, version_id, version_len);
1560        continue;
1561      }
1562
1563      (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
1564        "error sending version to client wfd %d: %s", sftp_conn->wfd,
1565        strerror(errno));
1566      return res;
1567    }
1568
1569    sent_version_id = TRUE;
1570    session.total_raw_out += res;
1571  }
1572
1573  return 0;
1574}
1575
Note: See TracBrowser for help on using the repository browser.