source: main/trunk/greenstone2/perllib/cpan/LWP/Authen/Ntlm.pm@ 27183

Last change on this file since 27183 was 27183, checked in by davidb, 11 years ago

Changing to using installed version of LWP that comes from libwww-perl, which is more self-contained than v6.x

File size: 5.3 KB
Line 
1package LWP::Authen::Ntlm;
2
3use strict;
4use vars qw/$VERSION/;
5
6$VERSION = '5.835';
7
8use Authen::NTLM "1.02";
9use MIME::Base64 "2.12";
10
11sub authenticate {
12 my($class, $ua, $proxy, $auth_param, $response,
13 $request, $arg, $size) = @_;
14
15 my($user, $pass) = $ua->get_basic_credentials($auth_param->{realm},
16 $request->uri, $proxy);
17
18 unless(defined $user and defined $pass) {
19 return $response;
20 }
21
22 if (!$ua->conn_cache()) {
23 warn "The keep_alive option must be enabled for NTLM authentication to work. NTLM authentication aborted.\n";
24 return $response;
25 }
26
27 my($domain, $username) = split(/\\/, $user);
28
29 ntlm_domain($domain);
30 ntlm_user($username);
31 ntlm_password($pass);
32
33 my $auth_header = $proxy ? "Proxy-Authorization" : "Authorization";
34
35 # my ($challenge) = $response->header('WWW-Authenticate');
36 my $challenge;
37 foreach ($response->header('WWW-Authenticate')) {
38 last if /^NTLM/ && ($challenge=$_);
39 }
40
41 if ($challenge eq 'NTLM') {
42 # First phase, send handshake
43 my $auth_value = "NTLM " . ntlm();
44 ntlm_reset();
45
46 # Need to check this isn't a repeated fail!
47 my $r = $response;
48 my $retry_count = 0;
49 while ($r) {
50 my $auth = $r->request->header($auth_header);
51 ++$retry_count if ($auth && $auth eq $auth_value);
52 if ($retry_count > 2) {
53 # here we know this failed before
54 $response->header("Client-Warning" =>
55 "Credentials for '$user' failed before");
56 return $response;
57 }
58 $r = $r->previous;
59 }
60
61 my $referral = $request->clone;
62 $referral->header($auth_header => $auth_value);
63 return $ua->request($referral, $arg, $size, $response);
64 }
65
66 else {
67 # Second phase, use the response challenge (unless non-401 code
68 # was returned, in which case, we just send back the response
69 # object, as is
70 my $auth_value;
71 if ($response->code ne '401') {
72 return $response;
73 }
74 else {
75 my $challenge;
76 foreach ($response->header('WWW-Authenticate')) {
77 last if /^NTLM/ && ($challenge=$_);
78 }
79 $challenge =~ s/^NTLM //;
80 ntlm();
81 $auth_value = "NTLM " . ntlm($challenge);
82 ntlm_reset();
83 }
84
85 my $referral = $request->clone;
86 $referral->header($auth_header => $auth_value);
87 my $response2 = $ua->request($referral, $arg, $size, $response);
88 return $response2;
89 }
90}
91
921;
93
94
95=head1 NAME
96
97LWP::Authen::Ntlm - Library for enabling NTLM authentication (Microsoft) in LWP
98
99=head1 SYNOPSIS
100
101 use LWP::UserAgent;
102 use HTTP::Request::Common;
103 my $url = 'http://www.company.com/protected_page.html';
104
105 # Set up the ntlm client and then the base64 encoded ntlm handshake message
106 my $ua = LWP::UserAgent->new(keep_alive=>1);
107 $ua->credentials('www.company.com:80', '', "MyDomain\\MyUserCode", 'MyPassword');
108
109 $request = GET $url;
110 print "--Performing request now...-----------\n";
111 $response = $ua->request($request);
112 print "--Done with request-------------------\n";
113
114 if ($response->is_success) {print "It worked!->" . $response->code . "\n"}
115 else {print "It didn't work!->" . $response->code . "\n"}
116
117=head1 DESCRIPTION
118
119C<LWP::Authen::Ntlm> allows LWP to authenticate against servers that are using the
120NTLM authentication scheme popularized by Microsoft. This type of authentication is
121common on intranets of Microsoft-centric organizations.
122
123The module takes advantage of the Authen::NTLM module by Mark Bush. Since there
124is also another Authen::NTLM module available from CPAN by Yee Man Chan with an
125entirely different interface, it is necessary to ensure that you have the correct
126NTLM module.
127
128In addition, there have been problems with incompatibilities between different
129versions of Mime::Base64, which Bush's Authen::NTLM makes use of. Therefore, it is
130necessary to ensure that your Mime::Base64 module supports exporting of the
131encode_base64 and decode_base64 functions.
132
133=head1 USAGE
134
135The module is used indirectly through LWP, rather than including it directly in your
136code. The LWP system will invoke the NTLM authentication when it encounters the
137authentication scheme while attempting to retrieve a URL from a server. In order
138for the NTLM authentication to work, you must have a few things set up in your
139code prior to attempting to retrieve the URL:
140
141=over 4
142
143=item *
144
145Enable persistent HTTP connections
146
147To do this, pass the "keep_alive=>1" option to the LWP::UserAgent when creating it, like this:
148
149 my $ua = LWP::UserAgent->new(keep_alive=>1);
150
151=item *
152
153Set the credentials on the UserAgent object
154
155The credentials must be set like this:
156
157 $ua->credentials('www.company.com:80', '', "MyDomain\\MyUserCode", 'MyPassword');
158
159Note that you cannot use the HTTP::Request object's authorization_basic() method to set
160the credentials. Note, too, that the 'www.company.com:80' portion only sets credentials
161on the specified port AND it is case-sensitive (this is due to the way LWP is coded, and
162has nothing to do with LWP::Authen::Ntlm)
163
164=back
165
166=head1 AVAILABILITY
167
168General queries regarding LWP should be made to the LWP Mailing List.
169
170Questions specific to LWP::Authen::Ntlm can be forwarded to [email protected]
171
172=head1 COPYRIGHT
173
174Copyright (c) 2002 James Tillman. All rights reserved. This
175program is free software; you can redistribute it and/or modify it
176under the same terms as Perl itself.
177
178=head1 SEE ALSO
179
180L<LWP>, L<LWP::UserAgent>, L<lwpcook>.
Note: See TracBrowser for help on using the repository browser.