Commit a7d37198 authored by Jan Pavlinec's avatar Jan Pavlinec

rsync: patch version 3.1.2 (security issue)

CVE-2017-17434 - check for fnamecmp filenames in the daemon_filter_list data structure
and sanitize_paths protection mechanism to pathnames
parent b07e53b7
if PACKAGE_rsync
config RSYNC_xattr
bool
prompt "Enable xattr support"
default y if USE_FS_ACL_ATTR
default n
config RSYNC_acl
bool
prompt "Enable ACL support"
default y if USE_FS_ACL_ATTR
default n
config RSYNC_zlib
bool
prompt "Enable system zlib"
help
Use the system's zlib library instead of rsync's internal copy. Enabling
this may create compatibility errors when using compression with older
clients, or those using the current default of the bundled zlib.
rsync's upstream default is to use their bundled zlib. OpenWrt uses the
system zlib for space reasons. The system zlib will eventually become
default for upstream as well.
default y
endif
#
# Copyright (C) 2007-2014 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
PKG_NAME:=rsync
PKG_VERSION:=3.1.2
PKG_RELEASE:=4
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://download.samba.org/pub/rsync/src
PKG_MD5SUM:=ecfa62a7fa3c4c18b9eccd8c16eaddee4bd308a76ea50b5c02a5840f09c0a1c2
PKG_MAINTAINER:=Maxim Storchak <m.storchak@gmail.com>
PKG_LICENSE:=GPL-3.0
PKG_LICENSE_FILES:=COPYING
PKG_INSTALL:=1
PKG_BUILD_PARALLEL:=1
include $(INCLUDE_DIR)/package.mk
define Package/rsync
SECTION:=net
CATEGORY:=Network
SUBMENU:=File Transfer
TITLE:=Fast remote file copy program (like rcp)
DEPENDS:=+libpopt +RSYNC_xattr:libattr +RSYNC_acl:libacl +RSYNC_zlib:zlib
URL:=http://rsync.samba.org/
MENU:=1
endef
define Package/rsync/config
source "$(SOURCE)/Config.in"
endef
CONFIGURE_ARGS += \
--with-included-popt=no \
--disable-debug \
--disable-locale \
ifeq ($(CONFIG_RSYNC_xattr),y)
CONFIGURE_ARGS+= --enable-xattr-support
else
CONFIGURE_ARGS+= --disable-xattr-support
endif
ifeq ($(CONFIG_RSYNC_acl),y)
CONFIGURE_ARGS+= --enable-acl-support
else
CONFIGURE_ARGS+= --disable-acl-support
endif
ifeq ($(CONFIG_RSYNC_zlib),y)
CONFIGURE_ARGS+= --with-included-zlib=no
else
CONFIGURE_ARGS+= --with-included-zlib=yes
endif
define Package/rsyncd
SECTION:=net
CATEGORY:=Network
SUBMENU:=File Transfer
TITLE:=Rsync daemon
DEPENDS:=+rsync
URL:=http://rsync.samba.org/
endef
define Package/rsync/description
rsync is a program that allows files to be copied to and from remote machines
in much the same way as rcp. It has many more options than rcp, and uses the
rsync remote-update protocol to greatly speed up file transfers when the
destination file already exists.
The rsync remote-update protocol allows rsync to transfer just the differences
between two sets of files across the network link.
endef
define Package/rsync/install
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/usr/bin/
endef
define Package/rsyncd/description
rsyncd is a configuration file and initscript to utilize rsync as a daemon. It
uses the same binary as rsync.
endef
define Package/rsyncd/conffiles
/etc/rsyncd.conf
endef
define Package/rsyncd/install
$(INSTALL_DIR) $(1)/etc
$(INSTALL_DATA) ./files/rsyncd.conf $(1)/etc/
$(INSTALL_DIR) $(1)/etc/init.d
$(INSTALL_BIN) ./files/rsyncd.init $(1)/etc/init.d/rsyncd
endef
$(eval $(call BuildPackage,rsync))
$(eval $(call BuildPackage,rsyncd))
# /etc/rsyncd.conf
# Minimal configuration for rsync daemon
# Next line required for init script
pid file = /var/run/rsyncd.pid
log file = /var/log/rsyncd.log
use chroot = yes
uid = nobody
gid = nogroup
read only = yes
# Simple example to configure server
#[openwrt-etc]
#path = /etc
#comment = OpenWrt Configuration Files
#exclude = /init.d
#!/bin/sh /etc/rc.common
# Copyright (C) 2011-2014 OpenWrt.org
START=90
STOP=10
USE_PROCD=1
PROG=/usr/bin/rsync
start_service() {
procd_open_instance
procd_set_param command "$PROG" --daemon --no-detach
procd_close_instance
}
This diff is collapsed.
commit 4fc78878e01451d6465e2072f3f0653182f885c1
Author: Wayne Davison <wayned@samba.org>
Date: Sun May 1 16:29:34 2016 -0700
Tweak indentation only.
diff --git a/checksum.c b/checksum.c
index 6ebb56b..bac775d 100644
--- a/checksum.c
+++ b/checksum.c
@@ -188,32 +188,31 @@ void sum_update(const char *p, int32 len)
{
if (protocol_version >= 30) {
md5_update(&md, (uchar *)p, len);
- return;
- }
+ } else {
+ if (len + sumresidue < CSUM_CHUNK) {
+ memcpy(md.buffer + sumresidue, p, len);
+ sumresidue += len;
+ return;
+ }
- if (len + sumresidue < CSUM_CHUNK) {
- memcpy(md.buffer + sumresidue, p, len);
- sumresidue += len;
- return;
- }
+ if (sumresidue) {
+ int32 i = CSUM_CHUNK - sumresidue;
+ memcpy(md.buffer + sumresidue, p, i);
+ mdfour_update(&md, (uchar *)md.buffer, CSUM_CHUNK);
+ len -= i;
+ p += i;
+ }
- if (sumresidue) {
- int32 i = CSUM_CHUNK - sumresidue;
- memcpy(md.buffer + sumresidue, p, i);
- mdfour_update(&md, (uchar *)md.buffer, CSUM_CHUNK);
- len -= i;
- p += i;
- }
+ while (len >= CSUM_CHUNK) {
+ mdfour_update(&md, (uchar *)p, CSUM_CHUNK);
+ len -= CSUM_CHUNK;
+ p += CSUM_CHUNK;
+ }
- while (len >= CSUM_CHUNK) {
- mdfour_update(&md, (uchar *)p, CSUM_CHUNK);
- len -= CSUM_CHUNK;
- p += CSUM_CHUNK;
+ sumresidue = len;
+ if (sumresidue)
+ memcpy(md.buffer, p, sumresidue);
}
-
- sumresidue = len;
- if (sumresidue)
- memcpy(md.buffer, p, sumresidue);
}
int sum_end(char *sum)
@@ -221,12 +220,12 @@ int sum_end(char *sum)
if (protocol_version >= 30) {
md5_result(&md, (uchar *)sum);
return MD5_DIGEST_LEN;
- }
-
- if (sumresidue || protocol_version >= 27)
- mdfour_update(&md, (uchar *)md.buffer, sumresidue);
+ } else {
+ if (sumresidue || protocol_version >= 27)
+ mdfour_update(&md, (uchar *)md.buffer, sumresidue);
- mdfour_result(&md, (uchar *)sum);
+ mdfour_result(&md, (uchar *)sum);
- return MD4_DIGEST_LEN;
+ return MD4_DIGEST_LEN;
+ }
}
This diff is collapsed.
This diff is collapsed.
commit e02b89d0d35ab8acbd522983c08d2519d8bd12d4
Author: Wayne Davison <wayned@samba.org>
Date: Sat Oct 29 14:33:44 2016 -0700
We need a LF after filelist-progress with a CR.
Fixes bug 12367.
diff --git a/flist.c b/flist.c
index acb95f7..4a9f4e6 100644
--- a/flist.c
+++ b/flist.c
@@ -156,7 +156,9 @@ static void start_filelist_progress(char *kind)
static void emit_filelist_progress(int count)
{
+ output_needs_newline = 0; /* avoid a newline in the middle of this filelist-progress output */
rprintf(FCLIENT, " %d files...\r", count);
+ output_needs_newline = 1;
}
static void maybe_emit_filelist_progress(int count)
commit ff66fd4bb6cc76488c6ea1e4b651a869847f6375
Author: Wayne Davison <wayned@samba.org>
Date: Sat Oct 29 14:47:58 2016 -0700
More fixes for --progress quirks.
This patch avoids inconsistent evaluation of options in the
show_filelist_p() function by turning it into a var. We
also avoid setting "output_needs_newline" if --quiet was
specified.
diff --git a/flist.c b/flist.c
index 4a9f4e6..54ced36 100644
--- a/flist.c
+++ b/flist.c
@@ -37,6 +37,7 @@ extern int checksum_type;
extern int module_id;
extern int ignore_errors;
extern int numeric_ids;
+extern int quiet;
extern int recurse;
extern int use_qsort;
extern int xfer_dirs;
@@ -128,6 +129,7 @@ static char tmp_sum[MAX_DIGEST_LEN];
static char empty_sum[MAX_DIGEST_LEN];
static int flist_count_offset; /* for --delete --progress */
+static int show_filelist_progress;
static void flist_sort_and_clean(struct file_list *flist, int strip_root);
static void output_flist(struct file_list *flist);
@@ -140,15 +142,14 @@ void init_flist(void)
}
parse_checksum_choice(); /* Sets checksum_type && xfersum_type */
checksum_len = csum_len_for_type(checksum_type);
-}
-static int show_filelist_p(void)
-{
- return INFO_GTE(FLIST, 1) && xfer_dirs && !am_server && !inc_recurse;
+ show_filelist_progress = INFO_GTE(FLIST, 1) && xfer_dirs && !am_server && !inc_recurse;
}
static void start_filelist_progress(char *kind)
{
+ if (quiet)
+ return;
rprintf(FCLIENT, "%s ... ", kind);
output_needs_newline = 1;
rflush(FINFO);
@@ -156,25 +157,28 @@ static void start_filelist_progress(char *kind)
static void emit_filelist_progress(int count)
{
- output_needs_newline = 0; /* avoid a newline in the middle of this filelist-progress output */
+ if (quiet)
+ return;
+ if (output_needs_newline == 2) /* avoid a newline in the middle of this filelist-progress output */
+ output_needs_newline = 0;
rprintf(FCLIENT, " %d files...\r", count);
- output_needs_newline = 1;
+ output_needs_newline = 2;
}
static void maybe_emit_filelist_progress(int count)
{
- if (INFO_GTE(FLIST, 2) && show_filelist_p() && (count % 100) == 0)
+ if (INFO_GTE(FLIST, 2) && show_filelist_progress && (count % 100) == 0)
emit_filelist_progress(count);
}
static void finish_filelist_progress(const struct file_list *flist)
{
+ output_needs_newline = 0;
if (INFO_GTE(FLIST, 2)) {
/* This overwrites the progress line */
rprintf(FINFO, "%d file%sto consider\n",
flist->used, flist->used == 1 ? " " : "s ");
} else {
- output_needs_newline = 0;
rprintf(FINFO, "done\n");
}
}
@@ -2089,7 +2093,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
int implied_dot_dir = 0;
rprintf(FLOG, "building file list\n");
- if (show_filelist_p())
+ if (show_filelist_progress)
start_filelist_progress("building file list");
else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server)
rprintf(FCLIENT, "sending incremental file list\n");
@@ -2363,7 +2367,7 @@ struct file_list *send_file_list(int f, int argc, char *argv[])
idev_destroy();
#endif
- if (show_filelist_p())
+ if (show_filelist_progress)
finish_filelist_progress(flist);
gettimeofday(&end_tv, NULL);
@@ -2445,7 +2449,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
int64 start_read;
if (!first_flist) {
- if (show_filelist_p())
+ if (show_filelist_progress)
start_filelist_progress("receiving file list");
else if (inc_recurse && INFO_GTE(FLIST, 1) && !am_server)
rprintf(FCLIENT, "receiving incremental file list\n");
@@ -2541,7 +2545,7 @@ struct file_list *recv_file_list(int f, int dir_ndx)
if (DEBUG_GTE(FLIST, 2))
rprintf(FINFO, "received %d names\n", flist->used);
- if (show_filelist_p())
+ if (show_filelist_progress)
finish_filelist_progress(flist);
if (need_unsorted_flist) {
diff --git a/progress.c b/progress.c
index 3858fc4..d19fa25 100644
--- a/progress.c
+++ b/progress.c
@@ -25,6 +25,7 @@
extern int am_server;
extern int flist_eof;
+extern int quiet;
extern int need_unsorted_flist;
extern int output_needs_newline;
extern struct stats stats;
@@ -127,7 +128,7 @@ static void rprint_progress(OFF_T ofs, OFF_T size, struct timeval *now,
pct = ofs == size ? 100 : (int) (100.0 * ofs / size);
rprintf(FCLIENT, "\r%15s %3d%% %7.2f%s %s%s",
human_num(ofs), pct, rate, units, rembuf, eol);
- if (!is_last) {
+ if (!is_last && !quiet) {
output_needs_newline = 1;
rflush(FCLIENT);
}
commit 7b8a4ecd6ff9cdf4e5d3850ebf822f1e989255b3
Author: Wayne Davison <wayned@samba.org>
Date: Tue Oct 24 15:40:37 2017 -0700
Handle archaic checksums properly.
diff --git a/checksum.c b/checksum.c
index 8b38833..9382694 100644
--- a/checksum.c
+++ b/checksum.c
@@ -27,7 +27,7 @@ extern int proper_seed_order;
extern char *checksum_choice;
#define CSUM_NONE 0
-#define CSUM_ARCHAIC 1
+#define CSUM_MD4_ARCHAIC 1
#define CSUM_MD4_BUSTED 2
#define CSUM_MD4_OLD 3
#define CSUM_MD4 4
@@ -60,7 +60,7 @@ int parse_csum_name(const char *name, int len)
return CSUM_MD4_OLD;
if (protocol_version >= 21)
return CSUM_MD4_BUSTED;
- return CSUM_ARCHAIC;
+ return CSUM_MD4_ARCHAIC;
}
if (len == 3 && strncasecmp(name, "md4", 3) == 0)
return CSUM_MD4;
@@ -78,7 +78,7 @@ int csum_len_for_type(int cst)
switch (cst) {
case CSUM_NONE:
return 1;
- case CSUM_ARCHAIC:
+ case CSUM_MD4_ARCHAIC:
return 2;
case CSUM_MD4:
case CSUM_MD4_OLD:
@@ -143,7 +143,8 @@ void get_checksum2(char *buf, int32 len, char *sum)
}
case CSUM_MD4:
case CSUM_MD4_OLD:
- case CSUM_MD4_BUSTED: {
+ case CSUM_MD4_BUSTED:
+ case CSUM_MD4_ARCHAIC: {
int32 i;
static char *buf1;
static int32 len1;
@@ -174,7 +175,7 @@ void get_checksum2(char *buf, int32 len, char *sum)
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes.
*/
- if (len - i > 0 || xfersum_type != CSUM_MD4_BUSTED)
+ if (len - i > 0 || xfersum_type > CSUM_MD4_BUSTED)
mdfour_update(&m, (uchar *)(buf1+i), len-i);
mdfour_result(&m, (uchar *)sum);
@@ -217,6 +218,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
+ case CSUM_MD4_ARCHAIC:
mdfour_begin(&m);
for (i = 0; i + CSUM_CHUNK <= len; i += CSUM_CHUNK) {
@@ -229,7 +231,7 @@ void file_checksum(const char *fname, const STRUCT_STAT *st_p, char *sum)
* are multiples of 64. This is fixed by calling mdfour_update()
* even when there are no more bytes. */
remainder = (int32)(len - i);
- if (remainder > 0 || checksum_type != CSUM_MD4_BUSTED)
+ if (remainder > 0 || checksum_type > CSUM_MD4_BUSTED)
mdfour_update(&m, (uchar *)map_ptr(buf, i, remainder), remainder);
mdfour_result(&m, (uchar *)sum);
@@ -265,6 +267,7 @@ void sum_init(int csum_type, int seed)
break;
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
+ case CSUM_MD4_ARCHAIC:
mdfour_begin(&md);
sumresidue = 0;
SIVAL(s, 0, seed);
@@ -321,6 +324,10 @@ void sum_update(const char *p, int32 len)
}
}
+/* NOTE: all the callers of sum_end() pass in a pointer to a buffer that is
+ * MAX_DIGEST_LEN in size, so even if the csum-len is shorter that that (i.e.
+ * CSUM_MD4_ARCHAIC), we don't have to worry about limiting the data we write
+ * into the "sum" buffer. */
int sum_end(char *sum)
{
switch (cursum_type) {
@@ -333,6 +340,7 @@ int sum_end(char *sum)
mdfour_result(&md, (uchar *)sum);
break;
case CSUM_MD4_BUSTED:
+ case CSUM_MD4_ARCHAIC:
if (sumresidue)
mdfour_update(&md, (uchar *)md.buffer, sumresidue);
mdfour_result(&md, (uchar *)sum);
commit c252546ceeb0925eb8a4061315e3ff0a8c55b48b
Author: Wayne Davison <wayned@samba.org>
Date: Tue Oct 24 20:42:41 2017 -0700
Don't forget to tweak sum_update().
diff --git a/checksum.c b/checksum.c
index 9382694..c119f97 100644
--- a/checksum.c
+++ b/checksum.c
@@ -295,6 +295,7 @@ void sum_update(const char *p, int32 len)
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
+ case CSUM_MD4_ARCHAIC:
if (len + sumresidue < CSUM_CHUNK) {
memcpy(md.buffer + sumresidue, p, len);
sumresidue += len;
commit 9a480deec4d20277d8e20bc55515ef0640ca1e55
Author: Wayne Davison <wayned@samba.org>
Date: Tue Oct 24 20:44:37 2017 -0700
Only allow a modern checksum method for passwords.
diff --git a/authenticate.c b/authenticate.c
index d60ee20..a106b0f 100644
--- a/authenticate.c
+++ b/authenticate.c
@@ -22,6 +22,7 @@
#include "itypes.h"
extern int read_only;
+extern int protocol_version;
extern char *password_file;
/***************************************************************************
@@ -237,6 +238,11 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
if (!users || !*users)
return "";
+ if (protocol_version < 21) { /* Don't allow a weak checksum for the password. */
+ rprintf(FERROR, "ERROR: protocol version is too old!\n");
+ exit_cleanup(RERR_PROTOCOL);
+ }
+
gen_challenge(addr, challenge);
io_printf(f_out, "%s%s\n", leader, challenge);
commit bc112b0e7feece62ce98708092306639a8a53cce
Author: Wayne Davison <wayned@samba.org>
Date: Mon Oct 30 09:11:16 2017 -0700
Use full MD4 len for archaic protocol auth.
diff --git a/authenticate.c b/authenticate.c
index a106b0f..519429d 100644
--- a/authenticate.c
+++ b/authenticate.c
@@ -22,7 +22,6 @@
#include "itypes.h"
extern int read_only;
-extern int protocol_version;
extern char *password_file;
/***************************************************************************
@@ -75,6 +74,8 @@ static void gen_challenge(const char *addr, char *challenge)
sum_init(-1, 0);
sum_update(input, sizeof input);
len = sum_end(digest);
+ if (len == 2) /* The archaic checksum is 2 bytes, but sum_end() filled in the full MD4 checksum for us. */
+ len = MD4_DIGEST_LEN;
base64_encode(digest, len, challenge, 0);
}
@@ -90,6 +91,8 @@ static void generate_hash(const char *in, const char *challenge, char *out)
sum_update(in, strlen(in));
sum_update(challenge, strlen(challenge));
len = sum_end(buf);
+ if (len == 2) /* The archaic checksum is 2 bytes, but sum_end() filled in the full MD4 checksum for us. */
+ len = MD4_DIGEST_LEN;
base64_encode(buf, len, out, 0);
}
@@ -238,11 +241,6 @@ char *auth_server(int f_in, int f_out, int module, const char *host,
if (!users || !*users)
return "";
- if (protocol_version < 21) { /* Don't allow a weak checksum for the password. */
- rprintf(FERROR, "ERROR: protocol version is too old!\n");
- exit_cleanup(RERR_PROTOCOL);
- }
-
gen_challenge(addr, challenge);
io_printf(f_out, "%s%s\n", leader, challenge);
diff --git a/checksum.c b/checksum.c
index c119f97..741ad7d 100644
--- a/checksum.c
+++ b/checksum.c
@@ -86,6 +86,8 @@ int csum_len_for_type(int cst)
return MD4_DIGEST_LEN;
case CSUM_MD5:
return MD5_DIGEST_LEN;
+ default: /* paranoia to prevent missing case values */
+ exit_cleanup(RERR_UNSUPPORTED);
}
return 0;
}
@@ -181,6 +183,8 @@ void get_checksum2(char *buf, int32 len, char *sum)
mdfour_result(&m, (uchar *)sum);
break;
}
+ default: /* paranoia to prevent missing case values */
+ exit_cleanup(RERR_UNSUPPORTED);
}
}
@@ -275,6 +279,8 @@ void sum_init(int csum_type, int seed)
break;
case CSUM_NONE:
break;
+ default: /* paranoia to prevent missing case values */
+ exit_cleanup(RERR_UNSUPPORTED);
}
}
@@ -322,6 +328,8 @@ void sum_update(const char *p, int32 len)
break;
case CSUM_NONE:
break;
+ default: /* paranoia to prevent missing case values */
+ exit_cleanup(RERR_UNSUPPORTED);
}
}
@@ -349,6 +357,8 @@ int sum_end(char *sum)
case CSUM_NONE:
*sum = '\0';
break;
+ default: /* paranoia to prevent missing case values */
+ exit_cleanup(RERR_UNSUPPORTED);
}
return csum_len_for_type(cursum_type);
commit 47a63d90e71d3e19e0e96052bb8c6b9cb140ecc1
Author: Wayne Davison <wayned@samba.org>
Date: Sun Nov 5 11:33:15 2017 -0800
Enforce trailing \0 when receiving xattr name values.
Fixes bug 13112.
diff --git a/xattrs.c b/xattrs.c
index 68305d7..4867e6f 100644
--- a/xattrs.c
+++ b/xattrs.c
@@ -824,6 +824,10 @@ void receive_xattr(int f, struct file_struct *file)
out_of_memory("receive_xattr");
name = ptr + dget_len + extra_len;
read_buf(f, name, name_len);
+ if (name_len < 1 || name[name_len-1] != '\0') {
+ rprintf(FERROR, "Invalid xattr name received (missing trailing \\0).\n");
+ exit_cleanup(RERR_FILEIO);
+ }
if (dget_len == datum_len)
read_buf(f, ptr, dget_len);
else {
commit 416e719bea4f5466c8dd2b34cac0059b6ff84ff3
Author: Wayne Davison <wayned@samba.org>
Date: Tue Nov 7 14:01:13 2017 -0800
More archaic-checksum improvements. This makes the len vars clearer
and ensures that only the flist code gets the 2-byte digest len.
diff --git a/authenticate.c b/authenticate.c
index 519429d..d60ee20 100644
--- a/authenticate.c
+++ b/authenticate.c
@@ -74,8 +74,6 @@ static void gen_challenge(const char *addr, char *challenge)
sum_init(-1, 0);
sum_update(input, sizeof input);
len = sum_end(digest);
- if (len == 2) /* The archaic checksum is 2 bytes, but sum_end() filled in the full MD4 checksum for us. */
- len = MD4_DIGEST_LEN;
base64_encode(digest, len, challenge, 0);
}
@@ -91,8 +89,6 @@ static void generate_hash(const char *in, const char *challenge, char *out)
sum_update(in, strlen(in));
sum_update(challenge, strlen(challenge));
len = sum_end(buf);
- if (len == 2) /* The archaic checksum is 2 bytes, but sum_end() filled in the full MD4 checksum for us. */
- len = MD4_DIGEST_LEN;
base64_encode(buf, len, out, 0);
}
diff --git a/checksum.c b/checksum.c
index 741ad7d..4c9351c 100644
--- a/checksum.c
+++ b/checksum.c
@@ -73,13 +73,15 @@ int parse_csum_name(const char *name, int len)
exit_cleanup(RERR_UNSUPPORTED);
}
-int csum_len_for_type(int cst)
+int csum_len_for_type(int cst, int flist_csum)
{
switch (cst) {
case CSUM_NONE:
return 1;
case CSUM_MD4_ARCHAIC:
- return 2;
+ /* The oldest checksum code is rather weird: the file-list code only sent
+ * 2-byte checksums, but all other checksums were full MD4 length. */
+ return flist_csum ? 2 : MD4_DIGEST_LEN;
case CSUM_MD4:
case CSUM_MD4_OLD:
case CSUM_MD4_BUSTED:
@@ -361,5 +363,5 @@ int sum_end(char *sum)
exit_cleanup(RERR_UNSUPPORTED);
}