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 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 71 public String getSchemeName() { 72 return "ntlm"; 73 } 74 75 public String getParameter(String name) { 76 // String parameters not supported 77 return null; 78 } 79 80 public String getRealm() { 81 // NTLM does not support the concept of an authentication realm 82 return null; 83 } 84 85 public boolean isConnectionBased() { 86 return true; 87 } 88 89 @Override 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 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 145 public boolean isComplete() { 146 return this.state == State.MSG_TYPE3_GENERATED || this.state == State.FAILED; 147 } 148 149 } 150