1
2
3
4
5
6
7
8
9
10 package org.mule.transport.http.ntlm;
11
12 import jcifs.ntlmssp.NtlmMessage;
13 import jcifs.ntlmssp.Type2Message;
14 import org.apache.commons.httpclient.Credentials;
15 import org.apache.commons.httpclient.HttpMethod;
16 import org.apache.commons.httpclient.NTCredentials;
17 import org.apache.commons.httpclient.auth.AuthChallengeParser;
18 import org.apache.commons.httpclient.auth.AuthScheme;
19 import org.apache.commons.httpclient.auth.AuthenticationException;
20 import org.apache.commons.httpclient.auth.InvalidCredentialsException;
21 import org.apache.commons.httpclient.auth.MalformedChallengeException;
22
23 import static jcifs.util.Base64.encode;
24
25
26
27
28
29
30
31
32
33 public class NTLMScheme implements AuthScheme
34 {
35
36 private static enum AUTHENTICATION_STATE
37 {
38 UNINITIATED, INITIATED, TYPE1_MSG_GENERATED, TYPE2_MSG_RECEIVED, TYPE3_MSG_GENERATED, FAILED
39 }
40
41 private static final String NOT_IMPLEMENTED_ERROR = "Not implemented as it is deprecated anyway in Httpclient 3.x";
42
43
44
45
46 private AUTHENTICATION_STATE authenticationState = AUTHENTICATION_STATE.UNINITIATED;
47
48
49
50
51 private String receivedNtlmChallenge = null;
52
53
54
55
56 private final NtlmMessageFactory ntlmMessageFactory = new NtlmMessageFactory();
57
58 public String authenticate(Credentials credentials, HttpMethod method) throws AuthenticationException
59 {
60 if (authenticationState == AUTHENTICATION_STATE.UNINITIATED)
61 {
62 throw new IllegalStateException("NTLM authentication process has not been initiated");
63 }
64
65 NtlmMessage response;
66
67 NTCredentials ntcredentials = getNTCredentials(credentials);
68 if (authenticationState == AUTHENTICATION_STATE.INITIATED || authenticationState == AUTHENTICATION_STATE.FAILED)
69 {
70
71 response = ntlmMessageFactory.createType1Message(null, null);
72 authenticationState = AUTHENTICATION_STATE.TYPE1_MSG_GENERATED;
73 }
74 else
75 {
76 Type2Message type2MessageFromChallenge = ntlmMessageFactory.createType2Message(receivedNtlmChallenge);
77 response = ntlmMessageFactory.createType3Message(ntcredentials, type2MessageFromChallenge);
78 authenticationState = AUTHENTICATION_STATE.TYPE3_MSG_GENERATED;
79 }
80
81 return ntlmMessageToString(response);
82 }
83
84 private NTCredentials getNTCredentials(Credentials credentials) throws InvalidCredentialsException
85 {
86 try
87 {
88 return (NTCredentials) credentials;
89 }
90 catch (ClassCastException e)
91 {
92 throw new InvalidCredentialsException("Credentials cannot be used for NTLM authentication: "
93 + credentials.getClass().getName());
94 }
95 }
96
97 public String authenticate(Credentials credentials, String method, String uri) throws AuthenticationException
98 {
99 throw new RuntimeException(NOT_IMPLEMENTED_ERROR);
100 }
101
102 public String getID()
103 {
104 throw new RuntimeException(NOT_IMPLEMENTED_ERROR);
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118 public String getParameter(String name)
119 {
120 if (name == null)
121 {
122 throw new IllegalArgumentException("Parameter name may not be null");
123 }
124
125 return null;
126 }
127
128
129
130
131
132
133
134
135 public String getRealm()
136 {
137 return null;
138 }
139
140
141
142
143
144
145 public String getSchemeName()
146 {
147 return "ntlm";
148 }
149
150
151
152
153
154
155
156 public boolean isComplete()
157 {
158 return authenticationState == AUTHENTICATION_STATE.TYPE3_MSG_GENERATED || authenticationState == AUTHENTICATION_STATE.FAILED;
159 }
160
161
162
163
164
165
166 public boolean isConnectionBased()
167 {
168 return true;
169 }
170
171
172
173
174
175
176
177 public void processChallenge(final String challenge) throws MalformedChallengeException
178 {
179 String s = AuthChallengeParser.extractScheme(challenge);
180
181 if (!s.equalsIgnoreCase(getSchemeName()))
182 {
183 throw new MalformedChallengeException("Invalid NTLM challenge: " + challenge);
184 }
185
186 int i = challenge.indexOf(' ');
187
188 if (i != -1)
189 {
190 s = challenge.substring(i, challenge.length());
191 receivedNtlmChallenge = s.trim();
192 authenticationState = AUTHENTICATION_STATE.TYPE2_MSG_RECEIVED;
193 }
194 else
195 {
196 receivedNtlmChallenge = null;
197 authenticationState = authenticationState == AUTHENTICATION_STATE.UNINITIATED ? AUTHENTICATION_STATE.INITIATED : AUTHENTICATION_STATE.FAILED;
198 }
199 }
200
201 private String ntlmMessageToString(NtlmMessage ntlmMessage)
202 {
203 return "NTLM " + encode(ntlmMessage.toByteArray());
204 }
205 }