• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * $HeadURL: http://svn.apache.org/repos/asf/httpcomponents/httpclient/trunk/module-client/src/main/java/org/apache/http/impl/auth/NTLMScheme.java $
3  * $Revision: 655048 $
4  * $Date: 2008-05-10 04:22:12 -0700 (Sat, 10 May 2008) $
5  *
6  * ====================================================================
7  *
8  *  Licensed to the Apache Software Foundation (ASF) under one or more
9  *  contributor license agreements.  See the NOTICE file distributed with
10  *  this work for additional information regarding copyright ownership.
11  *  The ASF licenses this file to You under the Apache License, Version 2.0
12  *  (the "License"); you may not use this file except in compliance with
13  *  the License.  You may obtain a copy of the License at
14  *
15  *      http://www.apache.org/licenses/LICENSE-2.0
16  *
17  *  Unless required by applicable law or agreed to in writing, software
18  *  distributed under the License is distributed on an "AS IS" BASIS,
19  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  *  See the License for the specific language governing permissions and
21  *  limitations under the License.
22  * ====================================================================
23  *
24  * This software consists of voluntary contributions made by many
25  * individuals on behalf of the Apache Software Foundation.  For more
26  * information on the Apache Software Foundation, please see
27  * <http://www.apache.org/>.
28  *
29  */
30 
31 package org.apache.http.impl.auth;
32 
33 import org.apache.http.Header;
34 import org.apache.http.HttpRequest;
35 import org.apache.http.auth.AUTH;
36 import org.apache.http.auth.AuthenticationException;
37 import org.apache.http.auth.Credentials;
38 import org.apache.http.auth.InvalidCredentialsException;
39 import org.apache.http.auth.MalformedChallengeException;
40 import org.apache.http.auth.NTCredentials;
41 import org.apache.http.impl.auth.AuthSchemeBase;
42 import org.apache.http.message.BufferedHeader;
43 import org.apache.http.util.CharArrayBuffer;
44 
45 public class NTLMScheme extends AuthSchemeBase {
46 
47     enum State {
48         UNINITIATED,
49         CHALLENGE_RECEIVED,
50         MSG_TYPE1_GENERATED,
51         MSG_TYPE2_RECEVIED,
52         MSG_TYPE3_GENERATED,
53         FAILED,
54     }
55 
56     private final NTLMEngine engine;
57 
58     private State state;
59     private String challenge;
60 
NTLMScheme(final NTLMEngine engine)61     public NTLMScheme(final NTLMEngine engine) {
62         super();
63         if (engine == null) {
64             throw new IllegalArgumentException("NTLM engine may not be null");
65         }
66         this.engine = engine;
67         this.state = State.UNINITIATED;
68         this.challenge = null;
69     }
70 
getSchemeName()71     public String getSchemeName() {
72         return "ntlm";
73     }
74 
getParameter(String name)75     public String getParameter(String name) {
76         // String parameters not supported
77         return null;
78     }
79 
getRealm()80     public String getRealm() {
81         // NTLM does not support the concept of an authentication realm
82         return null;
83     }
84 
isConnectionBased()85     public boolean isConnectionBased() {
86         return true;
87     }
88 
89     @Override
parseChallenge( final CharArrayBuffer buffer, int pos, int len)90     protected void parseChallenge(
91             final CharArrayBuffer buffer, int pos, int len) throws MalformedChallengeException {
92         String challenge = buffer.substringTrimmed(pos, len);
93         if (challenge.length() == 0) {
94             if (this.state == State.UNINITIATED) {
95                 this.state = State.CHALLENGE_RECEIVED;
96             } else {
97                 this.state = State.FAILED;
98             }
99             this.challenge = null;
100         } else {
101             this.state = State.MSG_TYPE2_RECEVIED;
102             this.challenge = challenge;
103         }
104     }
105 
authenticate( final Credentials credentials, final HttpRequest request)106     public Header authenticate(
107             final Credentials credentials,
108             final HttpRequest request) throws AuthenticationException {
109         NTCredentials ntcredentials = null;
110         try {
111             ntcredentials = (NTCredentials) credentials;
112         } catch (ClassCastException e) {
113             throw new InvalidCredentialsException(
114              "Credentials cannot be used for NTLM authentication: "
115               + credentials.getClass().getName());
116         }
117         String response = null;
118         if (this.state == State.CHALLENGE_RECEIVED || this.state == State.FAILED) {
119             response = this.engine.generateType1Msg(
120                     ntcredentials.getDomain(),
121                     ntcredentials.getWorkstation());
122             this.state = State.MSG_TYPE1_GENERATED;
123         } else if (this.state == State.MSG_TYPE2_RECEVIED) {
124             response = this.engine.generateType3Msg(
125                     ntcredentials.getUserName(),
126                     ntcredentials.getPassword(),
127                     ntcredentials.getDomain(),
128                     ntcredentials.getWorkstation(),
129                     this.challenge);
130             this.state = State.MSG_TYPE3_GENERATED;
131         } else {
132             throw new AuthenticationException("Unexpected state: " + this.state);
133         }
134         CharArrayBuffer buffer = new CharArrayBuffer(32);
135         if (isProxy()) {
136             buffer.append(AUTH.PROXY_AUTH_RESP);
137         } else {
138             buffer.append(AUTH.WWW_AUTH_RESP);
139         }
140         buffer.append(": NTLM ");
141         buffer.append(response);
142         return new BufferedHeader(buffer);
143     }
144 
isComplete()145     public boolean isComplete() {
146         return this.state == State.MSG_TYPE3_GENERATED || this.state == State.FAILED;
147     }
148 
149 }
150