2 # Copyright (c) The Exim Maintainers 2022
3 # SPDX-License-Identifier: GPL-2.0-or-later
5 # This script is contributed by Vadim Vygonets to aid in debugging CRAM-MD5
8 # A patch was contributed by Jon Warbrick to upgrade it to use the Digest::MD5
9 # module instead of the deprecated MD5 module.
11 # The script prompts for three data values: a user name, a password, and the
12 # challenge as sent out by an SMTP server. The challenge is a base-64 string.
13 # It should be copied (cut-and-pasted) literally as the third data item. The
14 # output of the program is the base-64 string that is to be returned as the
15 # response to the challenge. Using the example in RFC 2195:
18 # Password: tanstaaftanstaaf
19 # Challenge: PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
20 # dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
22 # The last line is what you you would send back to the server.
26 # Vadim Vygonets <vadik-exim@vygo.net>. All rights reserved.
27 # Public domain is OK with me.
29 BEGIN { pop @INC if $INC[-1] eq '.' };
42 $context = new Digest::MD5;
43 if (length($passwd) > 64) {
44 $context->add($passwd);
45 $passwd = $context->digest();
49 @passwd = unpack("C*", pack("a64", $passwd));
50 for ($i = 0; $i < 64; $i++) {
51 $pass_ipad[$i] = $passwd[$i] ^ 0x36;
52 $pass_opad[$i] = $passwd[$i] ^ 0x5C;
54 $context->add(pack("C64", @pass_ipad), decode_base64($chal));
55 $digest = $context->digest();
57 $context->add(pack("C64", @pass_opad), $digest);
58 $digest = $context->digest();
60 print encode_base64($user . " " . unpack("H*", $digest));