[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