1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 package org.apache.hc.client5.http.impl.auth;
28
29 import java.security.Principal;
30
31 import org.apache.hc.client5.http.auth.AuthChallenge;
32 import org.apache.hc.client5.http.auth.AuthScheme;
33 import org.apache.hc.client5.http.auth.AuthScope;
34 import org.apache.hc.client5.http.auth.AuthenticationException;
35 import org.apache.hc.client5.http.auth.Credentials;
36 import org.apache.hc.client5.http.auth.CredentialsProvider;
37 import org.apache.hc.client5.http.auth.MalformedChallengeException;
38 import org.apache.hc.client5.http.auth.StandardAuthScheme;
39 import org.apache.hc.client5.http.protocol.HttpClientContext;
40 import org.apache.hc.core5.http.HttpHost;
41 import org.apache.hc.core5.http.HttpRequest;
42 import org.apache.hc.core5.http.protocol.HttpContext;
43 import org.apache.hc.core5.util.Args;
44 import org.slf4j.Logger;
45 import org.slf4j.LoggerFactory;
46
47
48
49
50
51
52
53
54
55
56
57
58
59 @Deprecated
60 public final class NTLMScheme implements AuthScheme {
61
62 private static final Logger LOG = LoggerFactory.getLogger(NTLMScheme.class);
63
64 enum State {
65 UNINITIATED,
66 CHALLENGE_RECEIVED,
67 MSG_TYPE1_GENERATED,
68 MSG_TYPE2_RECEIVED,
69 MSG_TYPE3_GENERATED,
70 FAILED,
71 }
72
73 private final NTLMEngine engine;
74
75 private State state;
76 private String challenge;
77 private org.apache.hc.client5.http.auth.NTCredentials credentials;
78
79 public NTLMScheme(final NTLMEngine engine) {
80 super();
81 Args.notNull(engine, "NTLM engine");
82 this.engine = engine;
83 this.state = State.UNINITIATED;
84 }
85
86
87
88
89 public NTLMScheme() {
90 this(new NTLMEngineImpl());
91 }
92
93 @Override
94 public String getName() {
95 return StandardAuthScheme.NTLM;
96 }
97
98 @Override
99 public boolean isConnectionBased() {
100 return true;
101 }
102
103 @Override
104 public String getRealm() {
105 return null;
106 }
107
108 @Override
109 public void processChallenge(
110 final AuthChallenge authChallenge,
111 final HttpContext context) throws MalformedChallengeException {
112 Args.notNull(authChallenge, "AuthChallenge");
113
114 this.challenge = authChallenge.getValue();
115 if (this.challenge == null || this.challenge.isEmpty()) {
116 if (this.state == State.UNINITIATED) {
117 this.state = State.CHALLENGE_RECEIVED;
118 } else {
119 this.state = State.FAILED;
120 }
121 } else {
122 if (this.state.compareTo(State.MSG_TYPE1_GENERATED) < 0) {
123 this.state = State.FAILED;
124 throw new MalformedChallengeException("Out of sequence NTLM response message");
125 } else if (this.state == State.MSG_TYPE1_GENERATED) {
126 this.state = State.MSG_TYPE2_RECEIVED;
127 }
128 }
129 }
130
131 @Override
132 public boolean isResponseReady(
133 final HttpHost host,
134 final CredentialsProvider credentialsProvider,
135 final HttpContext context) throws AuthenticationException {
136
137 Args.notNull(host, "Auth host");
138 Args.notNull(credentialsProvider, "CredentialsProvider");
139
140 final AuthScope authScope = new AuthScope(host, null, getName());
141 final Credentials credentials = credentialsProvider.getCredentials(
142 authScope, context);
143 if (credentials instanceof org.apache.hc.client5.http.auth.NTCredentials) {
144 this.credentials = (org.apache.hc.client5.http.auth.NTCredentials) credentials;
145 return true;
146 }
147
148 if (LOG.isDebugEnabled()) {
149 final HttpClientContext clientContext = HttpClientContext.cast(context);
150 final String exchangeId = clientContext.getExchangeId();
151 LOG.debug("{} No credentials found for auth scope [{}]", exchangeId, authScope);
152 }
153 return false;
154 }
155
156 @Override
157 public Principal getPrincipal() {
158 return this.credentials != null ? this.credentials.getUserPrincipal() : null;
159 }
160
161 @Override
162 public String generateAuthResponse(
163 final HttpHost host,
164 final HttpRequest request,
165 final HttpContext context) throws AuthenticationException {
166 if (this.credentials == null) {
167 throw new AuthenticationException("NT credentials not available");
168 }
169 final String response;
170 if (this.state == State.FAILED) {
171 throw new AuthenticationException("NTLM authentication failed");
172 } else if (this.state == State.CHALLENGE_RECEIVED) {
173 response = this.engine.generateType1Msg(
174 this.credentials.getNetbiosDomain(),
175 this.credentials.getWorkstation());
176 this.state = State.MSG_TYPE1_GENERATED;
177 } else if (this.state == State.MSG_TYPE2_RECEIVED) {
178 response = this.engine.generateType3Msg(
179 this.credentials.getUserName(),
180 this.credentials.getPassword(),
181 this.credentials.getNetbiosDomain(),
182 this.credentials.getWorkstation(),
183 this.challenge);
184 this.state = State.MSG_TYPE3_GENERATED;
185 } else {
186 throw new AuthenticationException("Unexpected state: " + this.state);
187 }
188 return StandardAuthScheme.NTLM + " " + response;
189 }
190
191 @Override
192 public boolean isChallengeComplete() {
193 return this.state == State.MSG_TYPE3_GENERATED || this.state == State.FAILED;
194 }
195
196 @Override
197 public String toString() {
198 return getName() + "{" + this.state + " " + challenge + '}';
199 }
200
201 }