[proftpd-dfsg] 01/01: Apply patch to allow transfer large files (more than 1 GB) with SFTP module (Closes: #809068).

Hilmar Preuße hilmar-guest at moszumanska.debian.org
Sun Sep 4 13:26:42 UTC 2016


This is an automated email from the git hooks/post-receive script.

hilmar-guest pushed a commit to branch master
in repository proftpd-dfsg.

commit 9d893de02910210864d3a133359e83434f1bf6cf
Author: Hilmar Preuße <hille42 at web.de>
Date:   Sun Sep 4 15:26:28 2016 +0200

    Apply patch to allow transfer large files (more than 1 GB) with SFTP module (Closes: #809068).
---
 debian/changelog                     |   2 +
 debian/patches/large_files_SFTP.diff | 389 +++++++++++++++++++++++++++++++++++
 debian/patches/series                |   1 +
 3 files changed, 392 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 90fdf50..597e5d9 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -6,6 +6,8 @@ proftpd-dfsg (1.3.5a-2) UNRELEASED; urgency=medium
 
   [Hilmar Preuße]
   * Apply patch for ftpasswd.8 (Closes: #774390)
+  * Apply patch to allow transfer large files (more than 1 GB)
+    with SFTP module (Closes: #809068), large_files_SFTP.diff
 
  -- Mahyuddin Susanto <udienz at gmail.com>  Wed, 24 Aug 2016 15:23:38 -0700
 
diff --git a/debian/patches/large_files_SFTP.diff b/debian/patches/large_files_SFTP.diff
new file mode 100644
index 0000000..e6d49bc
--- /dev/null
+++ b/debian/patches/large_files_SFTP.diff
@@ -0,0 +1,389 @@
+Description: Unable to transfer large files (more than 1 GB) with SFTP module.
+Author: proftpd upstream
+Forwarded: bug #4097, fixed in 1.3.5.b.
+Bug-Debian: http://bugs.debian.org/809068
+
+Index: proftpd-dfsg/contrib/mod_sftp/kex.c
+===================================================================
+--- proftpd-dfsg.orig/contrib/mod_sftp/kex.c	2016-08-25 12:25:34.000000000 +0200
++++ proftpd-dfsg/contrib/mod_sftp/kex.c	2016-09-04 15:06:00.000000000 +0200
+@@ -39,8 +39,6 @@
+ #include "interop.h"
+ #include "tap.h"
+ 
+-#define SFTP_DH_PRIV_KEY_RANDOM_BITS	2048
+-
+ extern module sftp_module;
+ 
+ /* For managing the kexinit process */
+@@ -621,8 +619,94 @@
+   return 0;
+ }
+ 
++static int get_dh_nbits(struct sftp_kex *kex) {
++  int dh_nbits = 0, dh_size = 0;
++  const char *algo;
++  const EVP_CIPHER *cipher;
++  const EVP_MD *digest;
++
++  algo = kex->session_names->c2s_encrypt_algo;
++  cipher = sftp_crypto_get_cipher(algo, NULL, NULL);
++  if (cipher != NULL) {
++    int block_size, key_len;
++
++    key_len = EVP_CIPHER_key_length(cipher);
++    if (dh_size < key_len) {
++      dh_size = key_len;
++      pr_trace_msg(trace_channel, 19,
++        "set DH size to %d bytes, matching client-to-server '%s' cipher "
++        "key length", dh_size, algo);
++    }
++
++    block_size = EVP_CIPHER_block_size(cipher);
++    if (dh_size < block_size) {
++      dh_size = block_size;
++      pr_trace_msg(trace_channel, 19,
++        "set DH size to %d bytes, matching client-to-server '%s' cipher "
++        "block size", dh_size, algo);
++    }
++  }
++
++  algo = kex->session_names->s2c_encrypt_algo;
++  cipher = sftp_crypto_get_cipher(algo, NULL, NULL);
++  if (cipher != NULL) {
++    int block_size, key_len;
++
++    key_len = EVP_CIPHER_key_length(cipher);
++    if (dh_size < key_len) {
++      dh_size = key_len;
++      pr_trace_msg(trace_channel, 19,
++        "set DH size to %d bytes, matching server-to-client '%s' cipher "
++        "key length", dh_size, algo);
++    }
++
++    block_size = EVP_CIPHER_block_size(cipher);
++    if (dh_size < block_size) {
++      dh_size = block_size;
++      pr_trace_msg(trace_channel, 19,
++        "set DH size to %d bytes, matching server-to-client '%s' cipher "
++        "block size", dh_size, algo);
++    }
++  }
++
++  algo = kex->session_names->c2s_mac_algo;
++  digest = sftp_crypto_get_digest(algo, NULL);
++  if (digest != NULL) {
++    int mac_len;
++
++    mac_len = EVP_MD_size(digest);
++    if (dh_size < mac_len) {
++      dh_size = mac_len;
++      pr_trace_msg(trace_channel, 19,
++        "set DH size to %d bytes, matching client-to-server '%s' digest size",
++        dh_size, algo);
++    }
++  }
++
++  algo = kex->session_names->s2c_mac_algo;
++  digest = sftp_crypto_get_digest(algo, NULL);
++  if (digest != NULL) {
++    int mac_len;
++
++    mac_len = EVP_MD_size(digest);
++    if (dh_size < mac_len) {
++      dh_size = mac_len;
++      pr_trace_msg(trace_channel, 19,
++        "set DH size to %d bytes, matching server-to-client '%s' digest size",
++        dh_size, algo);
++    }
++  }
++
++  /* We want to return bits, not bytes. */
++  dh_nbits = dh_size * 8;
++
++  pr_trace_msg(trace_channel, 8, "requesting DH size of %d bits", dh_nbits);
++  return dh_nbits;
++}
++
+ static int create_dh(struct sftp_kex *kex, int type) {
+   unsigned int attempts = 0;
++  int dh_nbits;
+   DH *dh;
+ 
+   if (type != SFTP_DH_GROUP1_SHA1 &&
+@@ -656,6 +740,8 @@
+     kex->dh = NULL;
+   }
+ 
++  dh_nbits = get_dh_nbits(kex);
++
+   /* We have 10 attempts to make a DH key which passes muster. */
+   while (attempts <= 10) {
+     pr_signals_handle();
+@@ -665,7 +751,7 @@
+       attempts);
+ 
+     dh = DH_new();
+-    if (!dh) {
++    if (dh == NULL) {
+       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+         "error creating DH: %s", sftp_crypto_get_errors());
+       return -1;
+@@ -699,10 +785,11 @@
+       return -1;
+     }
+ 
+-    if (!BN_rand(dh->priv_key, SFTP_DH_PRIV_KEY_RANDOM_BITS, 0, 0)) {
++    /* Generate a random private exponent of the desired size, in bits. */
++    if (!BN_rand(dh->priv_key, dh_nbits, 0, 0)) {
+       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+-        "error generating DH random key (%d bytes): %s",
+-        SFTP_DH_PRIV_KEY_RANDOM_BITS, sftp_crypto_get_errors());
++        "error generating DH random key (%d bits): %s", dh_nbits,
++        sftp_crypto_get_errors());
+       DH_free(dh);
+       return -1;
+     }
+@@ -787,6 +874,9 @@
+ 
+ static int finish_dh(struct sftp_kex *kex) {
+   unsigned int attempts = 0;
++  int dh_nbits;
++
++  dh_nbits = get_dh_nbits(kex);
+ 
+   /* We have 10 attempts to make a DH key which passes muster. */
+   while (attempts <= 10) {
+@@ -797,11 +887,12 @@
+       attempts);
+ 
+     kex->dh->priv_key = BN_new();
+-  
+-    if (!BN_rand(kex->dh->priv_key, SFTP_DH_PRIV_KEY_RANDOM_BITS, 0, 0)) {
++ 
++    /* Generate a random private exponent of the desired size, in bits. */ 
++    if (!BN_rand(kex->dh->priv_key, dh_nbits, 0, 0)) {
+       (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+-        "error generating DH random key (%d bytes): %s",
+-        SFTP_DH_PRIV_KEY_RANDOM_BITS, sftp_crypto_get_errors());
++        "error generating DH random key (%d bits): %s", dh_nbits,
++        sftp_crypto_get_errors());
+       return -1;
+     }
+ 
+@@ -1514,77 +1605,71 @@
+ }
+ 
+ static int setup_c2s_encrypt_algo(struct sftp_kex *kex, const char *algo) {
+-  (void) kex;
+-
+-  if (sftp_cipher_set_read_algo(algo) < 0)
++  if (sftp_cipher_set_read_algo(algo) < 0) {
+     return -1;
++  }
+ 
++  kex->session_names->c2s_encrypt_algo = algo;
+   return 0;
+ }
+ 
+ static int setup_s2c_encrypt_algo(struct sftp_kex *kex, const char *algo) {
+-  (void) kex;
+-
+-  if (sftp_cipher_set_write_algo(algo) < 0)
++  if (sftp_cipher_set_write_algo(algo) < 0) {
+     return -1;
++  }
+ 
++  kex->session_names->s2c_encrypt_algo = algo;
+   return 0;
+ }
+ 
+ static int setup_c2s_mac_algo(struct sftp_kex *kex, const char *algo) {
+-  (void) kex;
+-
+-  if (sftp_mac_set_read_algo(algo) < 0)
++  if (sftp_mac_set_read_algo(algo) < 0) {
+     return -1;
++  }
+ 
++  kex->session_names->c2s_mac_algo = algo;
+   return 0;
+ }
+ 
+ static int setup_s2c_mac_algo(struct sftp_kex *kex, const char *algo) {
+-  (void) kex;
+-
+-  if (sftp_mac_set_write_algo(algo) < 0)
++  if (sftp_mac_set_write_algo(algo) < 0) {
+     return -1;
++  }
+ 
++  kex->session_names->s2c_mac_algo = algo;
+   return 0;
+ }
+ 
+ static int setup_c2s_comp_algo(struct sftp_kex *kex, const char *algo) {
+-  (void) kex;
+-
+-  if (sftp_compress_set_read_algo(algo) < 0)
++  if (sftp_compress_set_read_algo(algo) < 0) {
+     return -1;
++  }
+ 
++  kex->session_names->c2s_comp_algo = algo;
+   return 0;
+ }
+ 
+ static int setup_s2c_comp_algo(struct sftp_kex *kex, const char *algo) {
+-  (void) kex;
+-
+-  if (sftp_compress_set_write_algo(algo) < 0)
++  if (sftp_compress_set_write_algo(algo) < 0) {
+     return -1;
++  }
+ 
++  kex->session_names->s2c_comp_algo = algo;
+   return 0;
+ }
+ 
+ static int setup_c2s_lang(struct sftp_kex *kex, const char *lang) {
+-  (void) kex;
+-
+-  /* XXX Need to implement the functionality here. */
+-
++  kex->session_names->c2s_lang = lang;
+   return 0;
+ }
+ 
+ static int setup_s2c_lang(struct sftp_kex *kex, const char *lang) {
+-  (void) kex;
+-
+-  /* XXX Need to implement the functionality here. */
+-
++  kex->session_names->s2c_lang = lang;
+   return 0;
+ }
+ 
+ static int get_session_names(struct sftp_kex *kex, int *correct_guess) {
+-  const char *shared, *client_list, *server_list;
++  const char *kex_algo, *shared, *client_list, *server_list;
+   const char *client_pref, *server_pref;
+   pool *tmp_pool;
+ 
+@@ -1624,17 +1709,16 @@
+     }
+   }
+ 
+-  shared = get_shared_name(kex_pool, client_list, server_list);
+-  if (shared) {
+-    if (setup_kex_algo(kex, shared) < 0) {
+-      destroy_pool(tmp_pool);
+-      return -1;
+-    }
+-
++  kex_algo = get_shared_name(kex_pool, client_list, server_list);
++  if (kex_algo != NULL) {
++    /* Unlike the following algorithms, we wait to setup the chosen kex algo
++     * until the end.  Why?  The kex algo setup may require knowledge of the
++     * ciphers chosen for encryption, MAC, etc (Bug#4097).
++     */
+     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+-      " + Session key exchange: %s", shared);
++      " + Session key exchange: %s", kex_algo);
+     pr_trace_msg(trace_channel, 20, "session key exchange algorithm: %s",
+-      shared);
++      kex_algo);
+ 
+   } else {
+     (void) pr_log_writefile(sftp_logfd, MOD_SFTP_VERSION,
+@@ -1902,6 +1986,14 @@
+ #endif
+   }
+ 
++  /* Now that we've finished setting up the other bits, we can set up the
++   * kex algo.
++   */
++  if (setup_kex_algo(kex, kex_algo) < 0) {
++    destroy_pool(tmp_pool);
++    return -1;
++  }
++
+   destroy_pool(tmp_pool);
+   return 0;
+ }
+Index: proftpd-dfsg/contrib/mod_sftp/keys.c
+===================================================================
+--- proftpd-dfsg.orig/contrib/mod_sftp/keys.c	2016-08-25 12:25:34.000000000 +0200
++++ proftpd-dfsg/contrib/mod_sftp/keys.c	2016-09-04 15:06:00.000000000 +0200
+@@ -36,6 +36,7 @@
+ extern xaset_t *server_list;
+ extern module sftp_module;
+ 
++/* Note: Should this size be made bigger, in light of larger hostkeys? */
+ #define SFTP_DEFAULT_HOSTKEY_SZ		4096
+ #define SFTP_MAX_SIG_SZ			4096
+ 
+@@ -2028,7 +2029,7 @@
+       }
+ 
+       /* XXX Is this buffer large enough?  Too large? */
+-      ptr = buf = sftp_msg_getbuf(p, buflen);
++      ptr = buf = palloc(p, buflen);
+       sftp_msg_write_string(&buf, &buflen, "ssh-rsa");
+       sftp_msg_write_mpint(&buf, &buflen, rsa->e);
+       sftp_msg_write_mpint(&buf, &buflen, rsa->n);
+@@ -2048,7 +2049,7 @@
+       }
+ 
+       /* XXX Is this buffer large enough?  Too large? */
+-      ptr = buf = sftp_msg_getbuf(p, buflen);
++      ptr = buf = palloc(p, buflen);
+       sftp_msg_write_string(&buf, &buflen, "ssh-dss");
+       sftp_msg_write_mpint(&buf, &buflen, dsa->p);
+       sftp_msg_write_mpint(&buf, &buflen, dsa->q);
+@@ -2071,8 +2072,7 @@
+       }
+ 
+       /* XXX Is this buffer large enough?  Too large? */
+-      ptr = buf = sftp_msg_getbuf(p, buflen);
+-
++      ptr = buf = palloc(p, buflen);
+       sftp_msg_write_string(&buf, &buflen, "ecdsa-sha2-nistp256");
+       sftp_msg_write_string(&buf, &buflen, "nistp256");
+       sftp_msg_write_ecpoint(&buf, &buflen, EC_KEY_get0_group(ec),
+@@ -2093,8 +2093,7 @@
+       }
+ 
+       /* XXX Is this buffer large enough?  Too large? */
+-      ptr = buf = sftp_msg_getbuf(p, buflen);
+-
++      ptr = buf = palloc(p, buflen);
+       sftp_msg_write_string(&buf, &buflen, "ecdsa-sha2-nistp384");
+       sftp_msg_write_string(&buf, &buflen, "nistp384");
+       sftp_msg_write_ecpoint(&buf, &buflen, EC_KEY_get0_group(ec),
+@@ -2115,8 +2114,7 @@
+       }
+ 
+       /* XXX Is this buffer large enough?  Too large? */
+-      ptr = buf = sftp_msg_getbuf(p, buflen);
+-
++      ptr = buf = palloc(p, buflen);
+       sftp_msg_write_string(&buf, &buflen, "ecdsa-sha2-nistp521");
+       sftp_msg_write_string(&buf, &buflen, "nistp521");
+       sftp_msg_write_ecpoint(&buf, &buflen, EC_KEY_get0_group(ec),
+@@ -2137,8 +2135,14 @@
+   *datalen = SFTP_DEFAULT_HOSTKEY_SZ - buflen;
+ 
+   /* If the caller provided a pool, make a copy of the data from the
+-   * given pool, and return the copy.  Make sure the scrub the original
++   * given pool, and return the copy.  Make sure to scrub the original
+    * after making the copy.
++   *
++   * Note that we do this copy, even though we use the given pool, since
++   * we only know the actual size of the data after the fact.  And we need
++   * to provide the size of the data to the caller, NOT the optimistic size
++   * we allocate out of the pool for writing the data in the first place.
++   * Hence the copy.
+    */
+   if (p) {
+     buf = palloc(p, *datalen);
diff --git a/debian/patches/series b/debian/patches/series
index 01d4f10..5fa359f 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -11,3 +11,4 @@ odbc
 silent
 use_hypen_in_manpage
 contrib_hardening_flags
+large_files_SFTP.diff

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-proftpd/proftpd-dfsg.git



More information about the Pkg-proftpd-maintainers mailing list