1 /* Compute checksums of files or strings.
2 Copyright (C) 1995-2013 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17 /* Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>. */
22 #include <sys/types.h>
32 #if HASH_ALGO_SHA256 || HASH_ALGO_SHA224
35 #if HASH_ALGO_SHA512 || HASH_ALGO_SHA384
43 /* The official name of this program (e.g., no 'g' prefix). */
45 # define PROGRAM_NAME "md5sum"
46 # define DIGEST_TYPE_STRING "MD5"
47 # define DIGEST_STREAM md5_stream
48 # define DIGEST_BITS 128
49 # define DIGEST_REFERENCE "RFC 1321"
50 # define DIGEST_ALIGN 4
52 # define PROGRAM_NAME "sha1sum"
53 # define DIGEST_TYPE_STRING "SHA1"
54 # define DIGEST_STREAM sha1_stream
55 # define DIGEST_BITS 160
56 # define DIGEST_REFERENCE "FIPS-180-1"
57 # define DIGEST_ALIGN 4
58 #elif HASH_ALGO_SHA256
59 # define PROGRAM_NAME "sha256sum"
60 # define DIGEST_TYPE_STRING "SHA256"
61 # define DIGEST_STREAM sha256_stream
62 # define DIGEST_BITS 256
63 # define DIGEST_REFERENCE "FIPS-180-2"
64 # define DIGEST_ALIGN 4
65 #elif HASH_ALGO_SHA224
66 # define PROGRAM_NAME "sha224sum"
67 # define DIGEST_TYPE_STRING "SHA224"
68 # define DIGEST_STREAM sha224_stream
69 # define DIGEST_BITS 224
70 # define DIGEST_REFERENCE "RFC 3874"
71 # define DIGEST_ALIGN 4
72 #elif HASH_ALGO_SHA512
73 # define PROGRAM_NAME "sha512sum"
74 # define DIGEST_TYPE_STRING "SHA512"
75 # define DIGEST_STREAM sha512_stream
76 # define DIGEST_BITS 512
77 # define DIGEST_REFERENCE "FIPS-180-2"
78 # define DIGEST_ALIGN 8
79 #elif HASH_ALGO_SHA384
80 # define PROGRAM_NAME "sha384sum"
81 # define DIGEST_TYPE_STRING "SHA384"
82 # define DIGEST_STREAM sha384_stream
83 # define DIGEST_BITS 384
84 # define DIGEST_REFERENCE "FIPS-180-2"
85 # define DIGEST_ALIGN 8
87 # error "Can't decide which hash algorithm to compile."
90 #define DIGEST_HEX_BYTES (DIGEST_BITS / 4)
91 #define DIGEST_BIN_BYTES (DIGEST_BITS / 8)
94 proper_name ("Ulrich Drepper"), \
95 proper_name ("Scott Miller"), \
96 proper_name ("David Madore")
98 /* The minimum length of a valid digest line. This length does
99 not include any newline character at the end of a line. */
100 #define MIN_DIGEST_LINE_LENGTH \
101 (DIGEST_HEX_BYTES /* length of hexadecimal message digest */ \
103 + 1 /* minimum filename length */ )
105 /* True if any of the files read were the standard input. */
106 static bool have_read_stdin
;
108 /* The minimum length of a valid checksum line for the selected algorithm. */
109 static size_t min_digest_line_length
;
111 /* Set to the length of a digest hex string for the selected algorithm. */
112 static size_t digest_hex_bytes
;
114 /* With --check, don't generate any output.
115 The exit code indicates success or failure. */
116 static bool status_only
= false;
118 /* With --check, print a message to standard error warning about each
119 improperly formatted checksum line. */
120 static bool warn
= false;
122 /* With --check, suppress the "OK" printed for each verified file. */
123 static bool quiet
= false;
125 /* With --check, exit with a non-zero return code if any line is
126 improperly formatted. */
127 static bool strict
= false;
129 /* Whether a BSD reversed format checksum is detected. */
130 static int bsd_reversed
= -1;
132 /* For long options that have no equivalent short option, use a
133 non-character as a pseudo short option, starting with CHAR_MAX + 1. */
136 STATUS_OPTION
= CHAR_MAX
+ 1,
142 static struct option
const long_options
[] =
144 { "binary", no_argument
, NULL
, 'b' },
145 { "check", no_argument
, NULL
, 'c' },
146 { "quiet", no_argument
, NULL
, QUIET_OPTION
},
147 { "status", no_argument
, NULL
, STATUS_OPTION
},
148 { "text", no_argument
, NULL
, 't' },
149 { "warn", no_argument
, NULL
, 'w' },
150 { "strict", no_argument
, NULL
, STRICT_OPTION
},
151 { "tag", no_argument
, NULL
, TAG_OPTION
},
152 { GETOPT_HELP_OPTION_DECL
},
153 { GETOPT_VERSION_OPTION_DECL
},
160 if (status
!= EXIT_SUCCESS
)
165 Usage: %s [OPTION]... [FILE]...\n\
166 Print or check %s (%d-bit) checksums.\n\
167 With no FILE, or when FILE is -, read standard input.\n\
175 -b, --binary read in binary mode (default unless reading tty stdin)\n\
179 -b, --binary read in binary mode\n\
182 -c, --check read %s sums from the FILEs and check them\n"),
185 --tag create a BSD-style checksum\n\
189 -t, --text read in text mode (default if reading tty stdin)\n\
193 -t, --text read in text mode (default)\n\
197 The following four options are useful only when verifying checksums:\n\
198 --quiet don't print OK for each successfully verified file\n\
199 --status don't output anything, status code shows success\n\
200 --strict exit non-zero for improperly formatted checksum lines\n\
201 -w, --warn warn about improperly formatted checksum lines\n\
204 fputs (HELP_OPTION_DESCRIPTION
, stdout
);
205 fputs (VERSION_OPTION_DESCRIPTION
, stdout
);
208 The sums are computed as described in %s. When checking, the input\n\
209 should be a former output of this program. The default mode is to print\n\
210 a line with checksum, a character indicating input mode ('*' for binary,\n\
211 space for text), and name for each FILE.\n"),
213 emit_ancillary_info ();
219 #define ISWHITE(c) ((c) == ' ' || (c) == '\t')
221 /* Given a file name, S of length S_LEN, that is not NUL-terminated,
222 modify it in place, performing the equivalent of this sed substitution:
223 's/\\n/\n/g;s/\\\\/\\/g' i.e., replacing each "\\n" string with a newline
224 and each "\\\\" with a single backslash, NUL-terminate it and return S.
225 If S is not a valid escaped file name, i.e., if it ends with an odd number
226 of backslashes or if it contains a backslash followed by anything other
227 than "n" or another backslash, return NULL. */
230 filename_unescape (char *s
, size_t s_len
)
234 for (size_t i
= 0; i
< s_len
; i
++)
241 /* File name ends with an unescaped backslash: invalid. */
254 /* Only '\' or 'n' may follow a backslash. */
260 /* The file name may not contain a NUL. */
274 /* Split the checksum string S (of length S_LEN) from a BSD 'md5' or
275 'sha1' command into two parts: a hexadecimal digest, and the file
276 name. S is modified. Return true if successful. */
279 bsd_split_3 (char *s
, size_t s_len
, unsigned char **hex_digest
,
280 char **file_name
, bool escaped_filename
)
287 /* Find end of filename. */
289 while (i
&& s
[i
] != ')')
297 if (escaped_filename
&& filename_unescape (s
, i
) == NULL
)
302 while (ISWHITE (s
[i
]))
310 while (ISWHITE (s
[i
]))
313 *hex_digest
= (unsigned char *) &s
[i
];
317 /* Split the string S (of length S_LEN) into three parts:
318 a hexadecimal digest, binary flag, and the file name.
319 S is modified. Return true if successful. */
322 split_3 (char *s
, size_t s_len
,
323 unsigned char **hex_digest
, int *binary
, char **file_name
)
325 bool escaped_filename
= false;
326 size_t algo_name_len
;
329 while (ISWHITE (s
[i
]))
335 escaped_filename
= true;
338 /* Check for BSD-style checksum line. */
340 algo_name_len
= strlen (DIGEST_TYPE_STRING
);
341 if (STREQ_LEN (s
+ i
, DIGEST_TYPE_STRING
, algo_name_len
))
343 if (s
[i
+ algo_name_len
] == ' ')
345 if (s
[i
+ algo_name_len
] == '(')
348 return bsd_split_3 (s
+ i
+ algo_name_len
+ 1,
349 s_len
- (i
+ algo_name_len
+ 1),
350 hex_digest
, file_name
, escaped_filename
);
354 /* Ignore this line if it is too short.
355 Each line must have at least 'min_digest_line_length - 1' (or one more, if
356 the first is a backslash) more characters to contain correct message digest
358 if (s_len
- i
< min_digest_line_length
+ (s
[i
] == '\\'))
361 *hex_digest
= (unsigned char *) &s
[i
];
363 /* The first field has to be the n-character hexadecimal
364 representation of the message digest. If it is not followed
365 immediately by a white space it's an error. */
366 i
+= digest_hex_bytes
;
372 /* If "bsd reversed" format detected. */
373 if ((s_len
- i
== 1) || (s
[i
] != ' ' && s
[i
] != '*'))
375 /* Don't allow mixing bsd and standard formats,
376 to minimize security issues with attackers
377 renaming files with leading spaces.
378 This assumes that with bsd format checksums
379 that the first file name does not have
380 a leading ' ' or '*'. */
381 if (bsd_reversed
== 0)
385 else if (bsd_reversed
!= 1)
388 *binary
= (s
[i
++] == '*');
391 /* All characters between the type indicator and end of line are
392 significant -- that includes leading and trailing white space. */
395 if (escaped_filename
)
396 return filename_unescape (&s
[i
], s_len
- i
) != NULL
;
401 /* Return true if S is a NUL-terminated string of DIGEST_HEX_BYTES hex digits.
402 Otherwise, return false. */
403 static bool _GL_ATTRIBUTE_PURE
404 hex_digits (unsigned char const *s
)
407 for (i
= 0; i
< digest_hex_bytes
; i
++)
416 /* An interface to the function, DIGEST_STREAM.
417 Operate on FILENAME (it may be "-").
419 *BINARY indicates whether the file is binary. BINARY < 0 means it
420 depends on whether binary mode makes any difference and the file is
421 a terminal; in that case, clear *BINARY if the file was treated as
422 text because it was a terminal.
424 Put the checksum in *BIN_RESULT, which must be properly aligned.
425 Return true if successful. */
428 digest_file (const char *filename
, int *binary
, unsigned char *bin_result
)
432 bool is_stdin
= STREQ (filename
, "-");
436 have_read_stdin
= true;
438 if (O_BINARY
&& *binary
)
441 *binary
= ! isatty (STDIN_FILENO
);
443 xfreopen (NULL
, "rb", stdin
);
448 fp
= fopen (filename
, (O_BINARY
&& *binary
? "rb" : "r"));
451 error (0, errno
, "%s", filename
);
456 fadvise (fp
, FADVISE_SEQUENTIAL
);
458 err
= DIGEST_STREAM (fp
, bin_result
);
461 error (0, errno
, "%s", filename
);
467 if (!is_stdin
&& fclose (fp
) != 0)
469 error (0, errno
, "%s", filename
);
477 digest_check (const char *checkfile_name
)
479 FILE *checkfile_stream
;
480 uintmax_t n_misformatted_lines
= 0;
481 uintmax_t n_properly_formatted_lines
= 0;
482 uintmax_t n_improperly_formatted_lines
= 0;
483 uintmax_t n_mismatched_checksums
= 0;
484 uintmax_t n_open_or_read_failures
= 0;
485 unsigned char bin_buffer_unaligned
[DIGEST_BIN_BYTES
+ DIGEST_ALIGN
];
486 /* Make sure bin_buffer is properly aligned. */
487 unsigned char *bin_buffer
= ptr_align (bin_buffer_unaligned
, DIGEST_ALIGN
);
488 uintmax_t line_number
;
490 size_t line_chars_allocated
;
491 bool is_stdin
= STREQ (checkfile_name
, "-");
495 have_read_stdin
= true;
496 checkfile_name
= _("standard input");
497 checkfile_stream
= stdin
;
501 checkfile_stream
= fopen (checkfile_name
, "r");
502 if (checkfile_stream
== NULL
)
504 error (0, errno
, "%s", checkfile_name
);
511 line_chars_allocated
= 0;
514 char *filename
IF_LINT ( = NULL
);
516 unsigned char *hex_digest
IF_LINT ( = NULL
);
520 if (line_number
== 0)
521 error (EXIT_FAILURE
, 0, _("%s: too many checksum lines"),
524 line_length
= getline (&line
, &line_chars_allocated
, checkfile_stream
);
525 if (line_length
<= 0)
528 /* Ignore comment lines, which begin with a '#' character. */
532 /* Remove any trailing newline. */
533 if (line
[line_length
- 1] == '\n')
534 line
[--line_length
] = '\0';
536 if (! (split_3 (line
, line_length
, &hex_digest
, &binary
, &filename
)
537 && ! (is_stdin
&& STREQ (filename
, "-"))
538 && hex_digits (hex_digest
)))
540 ++n_misformatted_lines
;
546 ": improperly formatted %s checksum line"),
547 checkfile_name
, line_number
,
551 ++n_improperly_formatted_lines
;
555 static const char bin2hex
[] = { '0', '1', '2', '3',
558 'c', 'd', 'e', 'f' };
561 ++n_properly_formatted_lines
;
563 ok
= digest_file (filename
, &binary
, bin_buffer
);
567 ++n_open_or_read_failures
;
570 printf (_("%s: FAILED open or read\n"), filename
);
575 size_t digest_bin_bytes
= digest_hex_bytes
/ 2;
577 /* Compare generated binary number with text representation
578 in check file. Ignore case of hex digits. */
579 for (cnt
= 0; cnt
< digest_bin_bytes
; ++cnt
)
581 if (tolower (hex_digest
[2 * cnt
])
582 != bin2hex
[bin_buffer
[cnt
] >> 4]
583 || (tolower (hex_digest
[2 * cnt
+ 1])
584 != (bin2hex
[bin_buffer
[cnt
] & 0xf])))
587 if (cnt
!= digest_bin_bytes
)
588 ++n_mismatched_checksums
;
592 if (cnt
!= digest_bin_bytes
)
593 printf ("%s: %s\n", filename
, _("FAILED"));
595 printf ("%s: %s\n", filename
, _("OK"));
600 while (!feof (checkfile_stream
) && !ferror (checkfile_stream
));
604 if (ferror (checkfile_stream
))
606 error (0, 0, _("%s: read error"), checkfile_name
);
610 if (!is_stdin
&& fclose (checkfile_stream
) != 0)
612 error (0, errno
, "%s", checkfile_name
);
616 if (n_properly_formatted_lines
== 0)
618 /* Warn if no tests are found. */
619 error (0, 0, _("%s: no properly formatted %s checksum lines found"),
620 checkfile_name
, DIGEST_TYPE_STRING
);
626 if (n_misformatted_lines
!= 0)
629 ("WARNING: %" PRIuMAX
" line is improperly formatted",
630 "WARNING: %" PRIuMAX
" lines are improperly formatted",
631 select_plural (n_misformatted_lines
))),
632 n_misformatted_lines
);
634 if (n_open_or_read_failures
!= 0)
637 ("WARNING: %" PRIuMAX
" listed file could not be read",
638 "WARNING: %" PRIuMAX
" listed files could not be read",
639 select_plural (n_open_or_read_failures
))),
640 n_open_or_read_failures
);
642 if (n_mismatched_checksums
!= 0)
645 ("WARNING: %" PRIuMAX
" computed checksum did NOT match",
646 "WARNING: %" PRIuMAX
" computed checksums did NOT match",
647 select_plural (n_mismatched_checksums
))),
648 n_mismatched_checksums
);
652 return (n_properly_formatted_lines
!= 0
653 && n_mismatched_checksums
== 0
654 && n_open_or_read_failures
== 0
655 && (!strict
|| n_improperly_formatted_lines
== 0));
658 /* If ESCAPE is true, then translate each NEWLINE byte to the string, "\\n",
659 and each backslash to "\\\\". */
661 print_filename (char const *file
, bool escape
)
665 fputs (file
, stdout
);
674 fputs ("\\n", stdout
);
678 fputs ("\\\\", stdout
);
690 main (int argc
, char **argv
)
692 unsigned char bin_buffer_unaligned
[DIGEST_BIN_BYTES
+ DIGEST_ALIGN
];
693 /* Make sure bin_buffer is properly aligned. */
694 unsigned char *bin_buffer
= ptr_align (bin_buffer_unaligned
, DIGEST_ALIGN
);
695 bool do_check
= false;
699 bool prefix_tag
= false;
701 /* Setting values of global variables. */
702 initialize_main (&argc
, &argv
);
703 set_program_name (argv
[0]);
704 setlocale (LC_ALL
, "");
705 bindtextdomain (PACKAGE
, LOCALEDIR
);
706 textdomain (PACKAGE
);
708 atexit (close_stdout
);
710 /* Line buffer stdout to ensure lines are written atomically and immediately
711 so that processes running in parallel do not intersperse their output. */
712 setvbuf (stdout
, NULL
, _IOLBF
, 0);
714 while ((opt
= getopt_long (argc
, argv
, "bctw", long_options
, NULL
)) != -1)
748 case_GETOPT_HELP_CHAR
;
749 case_GETOPT_VERSION_CHAR (PROGRAM_NAME
, AUTHORS
);
751 usage (EXIT_FAILURE
);
754 min_digest_line_length
= MIN_DIGEST_LINE_LENGTH
;
755 digest_hex_bytes
= DIGEST_HEX_BYTES
;
757 if (prefix_tag
&& !binary
)
759 /* This could be supported in a backwards compatible way
760 by prefixing the output line with a space in text mode.
761 However that's invasive enough that it was agreed to
762 not support this mode with --tag, as --text use cases
763 are adequately supported by the default output format. */
764 error (0, 0, _("--tag does not support --text mode"));
765 usage (EXIT_FAILURE
);
768 if (prefix_tag
&& do_check
)
770 error (0, 0, _("the --tag option is meaningless when "
771 "verifying checksums"));
772 usage (EXIT_FAILURE
);
775 if (0 <= binary
&& do_check
)
777 error (0, 0, _("the --binary and --text options are meaningless when "
778 "verifying checksums"));
779 usage (EXIT_FAILURE
);
782 if (status_only
&& !do_check
)
785 _("the --status option is meaningful only when verifying checksums"));
786 usage (EXIT_FAILURE
);
789 if (warn
&& !do_check
)
792 _("the --warn option is meaningful only when verifying checksums"));
793 usage (EXIT_FAILURE
);
796 if (quiet
&& !do_check
)
799 _("the --quiet option is meaningful only when verifying checksums"));
800 usage (EXIT_FAILURE
);
803 if (strict
& !do_check
)
806 _("the --strict option is meaningful only when verifying checksums"));
807 usage (EXIT_FAILURE
);
810 if (!O_BINARY
&& binary
< 0)
814 argv
[argc
++] = bad_cast ("-");
816 for (; optind
< argc
; ++optind
)
818 char *file
= argv
[optind
];
821 ok
&= digest_check (file
);
824 int file_is_binary
= binary
;
826 if (! digest_file (file
, &file_is_binary
, bin_buffer
))
830 /* We don't really need to escape, and hence detect, the '\\'
831 char, and not doing so should be both forwards and backwards
832 compatible, since only escaped lines would have a '\\' char at
833 the start. However just in case users are directly comparing
834 against old (hashed) outputs, in the presence of files
835 containing '\\' characters, we decided to not simplify the
836 output in this case. */
837 bool needs_escape
= strchr (file
, '\\') || strchr (file
, '\n');
844 fputs (DIGEST_TYPE_STRING
, stdout
);
845 fputs (" (", stdout
);
846 print_filename (file
, needs_escape
);
847 fputs (") = ", stdout
);
852 /* Output a leading backslash if the file name contains
853 a newline or backslash. */
854 if (!prefix_tag
&& needs_escape
)
857 for (i
= 0; i
< (digest_hex_bytes
/ 2); ++i
)
858 printf ("%02x", bin_buffer
[i
]);
864 putchar (file_is_binary
? '*' : ' ');
866 print_filename (file
, needs_escape
);
874 if (have_read_stdin
&& fclose (stdin
) == EOF
)
875 error (EXIT_FAILURE
, errno
, _("standard input"));
877 exit (ok
? EXIT_SUCCESS
: EXIT_FAILURE
);