SPDX: Mass-update to GPL-2.0-or-later
[exim.git] / src / util / cramtest.pl
1 #!/usr/bin/perl
2 # Copyright (c) The Exim Maintainers 2022
3 # SPDX-License-Identifier: GPL-2.0-or-later
4
5 # This script is contributed by Vadim Vygonets to aid in debugging CRAM-MD5
6 # authentication.
7
8 # A patch was contributed by Jon Warbrick to upgrade it to use the Digest::MD5
9 # module instead of the deprecated MD5 module.
10
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:
16 #
17 # User: tim
18 # Password: tanstaaftanstaaf
19 # Challenge: PDE4OTYuNjk3MTcwOTUyQHBvc3RvZmZpY2UucmVzdG9uLm1jaS5uZXQ+
20 # dGltIGI5MTNhNjAyYzdlZGE3YTQ5NWI0ZTZlNzMzNGQzODkw
21 #
22 # The last line is what you you would send back to the server.
23
24
25 # Copyright (c) 2002
26 #       Vadim Vygonets <vadik-exim@vygo.net>.  All rights reserved.
27 # Public domain is OK with me.
28
29 BEGIN { pop @INC if $INC[-1] eq '.' };
30
31 use MIME::Base64;
32 use Digest::MD5;
33
34 print "User: ";
35 chop($user = <>);
36 print "Password: ";
37 chop($passwd = <>);
38 print "Challenge: ";
39 chop($chal = <>);
40 $chal =~ s/^334 //;
41
42 $context = new Digest::MD5;
43 if (length($passwd) > 64) {
44         $context->add($passwd);
45         $passwd = $context->digest();
46         $context->reset();
47 }
48
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;
53 }
54 $context->add(pack("C64", @pass_ipad), decode_base64($chal));
55 $digest = $context->digest();
56 $context->reset();
57 $context->add(pack("C64", @pass_opad), $digest);
58 $digest = $context->digest();
59
60 print encode_base64($user . " " . unpack("H*", $digest));
61
62 # End