Subject: bug#7155: closed (Re: bug#7155: [md5sum] does not accept)

From: [email-masked] (GNU bug Tracking System)
Date: Fri, 16 Sep 2011 13:00:04 +0000

Your bug report

#7155: [md5sum] does not accept

which was filed against the coreutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
7155: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=7155
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#7155: [md5sum] does not accept
From: Pádraig Brady <[email-masked]>
To: Rimas Kudelis <[email-masked]>
Cc: [email-masked]
Date: Fri, 16 Sep 2011 13:54:17 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

On 09/14/2011 11:43 PM, Rimas Kudelis wrote:
> 2011.09.14 17:12, Jim Meyering rašė:
>> Good point. I don't see a way to make GNU md5sum handle this automatically and safely. However, that's not a big deal: it's easy to convert from one format to the other using sed or perl. I'd be inclined to mark this "wontfix" (because we cannot) or simply to close it. 
> 
> 
> I think you could also implement this as a commandline switch, right?

Right. But that complicates the interface unnecessarily I think.

I'm going to apply the attached to give automatic support,
with the aforementioned caveat that BSD -r format checksums
where the _first_ file starts with a ' ' or '*' are not supported.
In that very unlikely case, one can always preprocess with sed 's/ /  /'

cheers,
Pádraig.
From 29904f907bfa22c8492176a0e6c2bb65deac0e9b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <[email-masked]>
Date: Fri, 16 Sep 2011 11:47:35 +0100
Subject: [PATCH] md5sum: handle BSD reversed format checksums

* src/md5sum.c (split_3): Detect and handle BSD reversed
format checksums.
* tests/misc/md5sum-bsd: Add a new test.
* tests/Makefile.am: Reference new test.
* NEWS: Mention the improvement
Suggested by Rimas Kudelis.
---
 NEWS                  |    5 +++++
 src/md5sum.c          |   26 ++++++++++++++++++++++----
 tests/Makefile.am     |    1 +
 tests/misc/md5sum-bsd |   41 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 69 insertions(+), 4 deletions(-)
 create mode 100755 tests/misc/md5sum-bsd

diff --git a/NEWS b/NEWS
index 879828e..8c218b7 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,11 @@ GNU coreutils NEWS                                    -*- outline -*-
 
 * Noteworthy changes in release ?.? (????-??-??) [?]
 
+** Improvements
+
+  md5sum --check now supports the -r format from the corresponding BSD tool.
+  This also affects sha1sum, sha224sum, sha384sum and sha512sum.
+
 
 * Noteworthy changes in release 8.13 (2011-09-08) [stable]
 
diff --git a/src/md5sum.c b/src/md5sum.c
index ff9538a..9de34a5 100644
--- a/src/md5sum.c
+++ b/src/md5sum.c
@@ -99,7 +99,7 @@
    not include any newline character at the end of a line.  */
 #define MIN_DIGEST_LINE_LENGTH \
   (DIGEST_HEX_BYTES /* length of hexadecimal message digest */ \
-   + 2 /* blank and binary indicator */ \
+   + 1 /* blank */ \
    + 1 /* minimum filename length */ )
 
 /* True if any of the files read were the standard input. */
@@ -126,6 +126,9 @@ static bool quiet = false;
    improperly formatted. */
 static bool strict = false;
 
+/* Whether a BSD reversed format checksum is detected.  */
+static int bsd_reversed = -1;
+
 /* For long options that have no equivalent short option, use a
    non-character as a pseudo short option, starting with CHAR_MAX + 1.  */
 enum
@@ -307,9 +310,24 @@ split_3 (char *s, size_t s_len,
 
   s[i++] = '\0';
 
-  if (s[i] != ' ' && s[i] != '*')
-    return false;
-  *binary = (s[i++] == '*');
+  /* If "bsd reversed" format detected.  */
+  if ((s_len - i == 1) || (s[i] != ' ' && s[i] != '*'))
+    {
+      /* Don't allow mixing bsd and standard formats,
+         to minimize security issues with attackers
+         renaming files with leading spaces.
+         This assumes that with bsd format checksums
+         that the first file name does not have
+         a leading ' ' or '*'.  */
+      if (bsd_reversed == 0)
+        return false;
+      bsd_reversed = 1;
+    }
+  else if (bsd_reversed != 1)
+    {
+      bsd_reversed = 0;
+      *binary = (s[i++] == '*');
+    }
 
   /* All characters between the type indicator and end of line are
      significant -- that includes leading and trailing white space.  */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index b920aba..eeb4cab 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -198,6 +198,7 @@ TESTS =						\
   misc/id-context				\
   misc/id-groups				\
   misc/md5sum					\
+  misc/md5sum-bsd				\
   misc/md5sum-newline				\
   misc/md5sum-parallel				\
   misc/mknod					\
diff --git a/tests/misc/md5sum-bsd b/tests/misc/md5sum-bsd
new file mode 100755
index 0000000..324530c
--- /dev/null
+++ b/tests/misc/md5sum-bsd
@@ -0,0 +1,41 @@
+#!/bin/sh
+# make sure `md5sum -c' works for alternate BSD format (md5 -r)
+
+# Copyright (C) 2011 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../src
+print_ver_ md5sum
+
+# Note we start this list with a name
+# that's unambiguous in BSD format.
+# I.E. one not starting with ' ' or '*'
+for i in 'a' ' b' '*c' 'dd' ' '; do
+  echo "$i" > "$i"
+  md5sum "$i" >> check.md5sum
+done
+sed 's/  / /' check.md5sum > check.md5
+
+# Note only a single format is supported per run
+md5sum --strict -c check.md5sum || fail=1
+md5sum --strict -c check.md5 || fail=1
+
+# If we skip the first entry in the BSD format checksums
+# then it'll be detected as standard format and error.
+# This unlikely caveat was thought better than mandating
+# an option to avoid the ambiguity.
+tail -n+2 check.md5 | md5sum --strict -c && fail=1
+
+Exit $fail
-- 
1.7.6

Subject: [md5sum] does not accept
From: Rimas Kudelis <[email-masked]>
To: [email-masked]
Date: Sun, 03 Oct 2010 22:24:31 +0300
List-Id: <debbugs-submit.debbugs.gnu.org>

Hi,

I have a little problem with md5sum.

A FreeBSD box generates an md5 sum of a file, which I'm later trying to
check on a Linux box. The problem is that what FreeBSD's md5 outputs is
slightly different from what Linux's md5sum expects, which makes md5sum
complain. The difference is really trivial: md5 outputs one space
between the sum and the file name, and md5sum outputs/expects two:

rq@garage:~/Pootle/tmp$ md5sum -c  catkeys.zip
md5sum: catkeys.zip: no properly formatted MD5 checksum lines found

rq@garage:~/Pootle/tmp$ md5sum -c  catkeys.zip.md5
md5sum: catkeys.zip.md5: no properly formatted MD5 checksum lines found

rq@garage:~/Pootle/tmp$ md5sum catkeys.zip
f653761af3137c8a631284b390bae102  catkeys.zip

rq@garage:~/Pootle/tmp$ cat catkeys.zip.md5
f653761af3137c8a631284b390bae102 catkeys.zip

I don't know which format is the "right" one, but could md5sum perhaps
be fixed to support md5's checksum files too?

Thanks!
Rimas Kudelis