📄 ntlmauthorization.java
字号:
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*
* NTLMAuthorizationHandler.java
* Copyright (C) 2002 Luigi Dragone
*
*/
package net.matuschek.http;
import java.io.*;
import java.security.Provider;
import java.security.Security;
import com.luigidragone.net.ntlm.NTLM;
import net.matuschek.util.Base64;
/**
* <p>
* This is an NTLM protocol authorization module for
* <a href="http://www.matuschek.net/software/jobo/index.html">JOBO</a>.
* </p>
* <p>
* NTLM is a Microsoft proprietary network authentication protocol used in many
* situations and HTTPClient is a versatile and extendible component for
* implementing HTTP client applications.
* </p>
* <p>
* This class relies on {@link NTLM NTLM} class. It also requires a JCE
* compliant library (e.g., <a href="http://www.cryptix.org/"> Cryptix JCE</a>)
* that implements MD4 and DES algorithms.
* </p>
* To perform an authentication the following information are needed:
* <ul>
* <li>the host name (with its own domain);</li>
* <li>the user name (with its own domain);</li>
* <li>the user password.</li>
* </ul>
* Alternatively, the user password can be replaced with its Lan Manager and
* NT hashed versions. On a Windows system these can be collected in the registry
* (with a bit of JNI, so), otherwise can be extracted from a SAMBA password
* file.<br>
* Notice that the host and user domain could not be the same.
* </p>
*
* @author Luigi Dragone (<a href="mailto:luigi@luigidragone. com">luigi@luigidragone.com</a>)
* @author oliver_schmidt
*
* @see <a href="http://www.innovation.ch/java/ntlm.html">NTLM Authentication Scheme for HTTP</a>
* @see <a href="http://www.innovation.ch/">HTTPClient</a>
* @see <a href="http://rfc.net/rfc2616.html">Hypertext Transfer Protocol -- HTTP/1.1</a>
* @see <a href="http://rfc.net/rfc2617.html">HTTP Authentication: Basic and Digest Access Authentication</a>
*
* @version $Id: NTLMAuthorization.java,v 1.2 2003/05/23 17:00:00 oliver_schmidt
* Exp $
* </p>
*/
public class NTLMAuthorization implements Serializable, Cloneable {
// if nothing in data structure has changed, keep this UID:
// otherwise calculate new
static final long serialVersionUID = -1347968095010834437L;
public class MissingJceException extends Exception {
private static final long serialVersionUID = -6580761514651447918L;
MissingJceException(String msg) { super(msg); }
};
public static final String NTLM_TAG = "NTLM";
public static final String PROXY_AUTHENTICATE_HEADER = "Proxy-Authenticate";
public static final String WWW_AUTHENTICATE_HEADER = "WWW-Authenticate";
transient byte[] nonce = null;
private String host = null;
private String user = null;
private String hostDomain = null;
private String userDomain = null;
private String securityProvider = null;
private byte[] lmPassword = null;
private byte[] ntPassword = null;
private static boolean securityProviderAdded = false;
/**
* Default constructor requires setting of attributes.
*/
public NTLMAuthorization() {
}
/**
* <p>
* Build an NTLM authorization handler for the specified authentication credentials.
* </p>
* <p>
* All the arguments are mandatory (null value are not allowed).
* </p>
*
* @param host the name of the host that is authenticating
* @param hostDomain the name of the domain to which the host belongs
* @param user the name of the user
* @param userDomain the name of the domain to which the user belongs
* @param lmPassword a 16-bytes array containing the Lan Manager hashed password
* @param ntPassword a 16-bytes array containing the NT hashed password
*
* @exception IllegalArgumentException if a supplied argument is invalid
*/
public NTLMAuthorization(String host, String hostDomain, String user, String userDomain, byte[] lmPassword, byte[] ntPassword) {
setHost(host);
setHostDomain(hostDomain);
setUser(user);
setUserDomain(userDomain);
setLmPasswordHash(lmPassword);
setNtPasswordHash(ntPassword);
}
/**
* <p>
* Build an NTLM authorization handler for the specified authentication credentials.
* </p>
* <p>
* All the arguments are mandatory (null value are not allowed).
* </p>
*
* @param host the name of the host that is authenticating
* @param hostDomain the name of the domain to which the host belongs
* @param user the name of the user
* @param userDomain the name of the domain to which the user belongs
* @param password the user's password
*
* @exception IllegalArgumentException if a supplied argument is invalid
* @exception javax.crypto.NoSuchPaddingException if there isn't any suitable padding method
* @exception NoSuchAlgorithmException if there isn't any suitable cipher algorithm
*/
public NTLMAuthorization(String host, String hostDomain, String user, String userDomain, String password) throws MissingJceException {
setHost(host);
setHostDomain(hostDomain);
setUser(user);
setUserDomain(userDomain);
setPassword(password);
}
public String getResponse() throws MissingJceException {
try {
return new String(Base64.encode(NTLM.formatResponse(host, user, userDomain, lmPassword, ntPassword, nonce)));
} catch (Exception e) {
throw new MissingJceException(e.getMessage());
}
}
public String getRequest() throws IOException {
return new String(Base64.encode(NTLM.formatRequest(host, hostDomain)));
}
public void extractNonce(String challenge) throws java.io.IOException {
nonce = null;
try {
// String challenge = parm1.getHeader(PROXY_AUTHENTICATE_HEADER);
if((challenge != null) && challenge.startsWith(NTLM_TAG) && challenge.length() > 4)
nonce = NTLM.getNonce(Base64.decode(challenge.substring(challenge.indexOf(' ') + 1).trim()));
/* else {
challenge = parm1.getHeader(WWW_AUTHENTICATE_HEADER);
if((challenge != null) && challenge.startsWith(NTLM_TAG) && challenge.length() > 4)
nonce = NTLM.getNonce(Codecs.base64Decode(challenge.substring(challenge.indexOf(' ') + 1).trim()).getBytes());
} */
} catch(Exception ex) {
ex.printStackTrace();
}
}
public void setHost(String host) {
if(host == null)
throw new IllegalArgumentException("host : null value not allowed");
this.host = host;
}
public String getHost() {
return host;
}
public void setHostDomain(String hostDomain) {
if(hostDomain == null)
throw new IllegalArgumentException("hostDomain : null value not allowed");
this.hostDomain = hostDomain;
}
public String getHostDomain() {
return hostDomain;
}
public void setUser(String user) {
if(user == null)
throw new IllegalArgumentException("user : null value not allowed");
this.user = user;
}
public String getUser() {
return user;
}
public void setUserDomain(String userDomain) {
if(userDomain == null)
throw new IllegalArgumentException("userDomain : null value not allowed");
this.userDomain = userDomain;
}
public void setPassword(String password) throws MissingJceException {
setLmPassword(password);
setNtPassword(password);
}
public String getUserDomain() {
return userDomain;
}
public String getDomain() {
return userDomain;
}
public void setDomain(String domain) {
setUserDomain(domain);
setHostDomain(domain);
}
public void setLmPassword(String password) throws MissingJceException {
addStandardSecurityProvider();
if(password == null)
throw new IllegalArgumentException("lmPassword : null value not allowed");
try {
this.lmPassword = NTLM.computeLMPassword(password);
} catch (Exception e) {
throw new MissingJceException(e.getMessage());
}
}
public String getLmPassword() { return lmPassword.toString(); };
public String getNtPassword() { return ntPassword.toString(); };
public String getPassword() { return ntPassword.toString(); };
public byte[] getLmPasswordHash() { return lmPassword; };
public byte[] getNtPasswordHash() { return ntPassword; };
public void setLmPasswordHash(byte[] password) {
if(password == null)
throw new IllegalArgumentException("lmPassword : null value not allowed");
if(password.length != 16)
throw new IllegalArgumentException("lmPassword : illegal size");
this.lmPassword = password;
}
public void setNtPassword(String password) throws MissingJceException {
addStandardSecurityProvider();
if(password == null)
throw new IllegalArgumentException("ntPassword : null value not allowed");
try {
this.ntPassword = NTLM.computeNTPassword(password);
} catch (Exception e) {
throw new MissingJceException(e.getMessage());
}
}
public void setNtPasswordHash(byte[] password) {
if(password == null)
throw new IllegalArgumentException("ntPassword : null value not allowed");
if(password.length != 16)
throw new IllegalArgumentException("ntPassword : illegal size");
this.ntPassword = password;
}
public String toString() {
return "Host=" + host
+ ", HostDomain=" + hostDomain
+ ", User=" + user
+ ", UserDomain=" + userDomain
+ ", lmPwd=" + lmPassword
+ ", ntPwd=" + ntPassword
+ ", Nonce=" + nonce;
}
/**
* Adds a standard security provider "cryptix.jce. provider.CryptixCrypto".
*/
public final void addStandardSecurityProvider() {
if (!securityProviderAdded) {
try {
setSecurityProvider("cryptix.jce.provider.CryptixCrypto");
} catch (Exception ex) {
// Ignore errors. Hopefully a provider is available.
}
securityProviderAdded = true;
}
}
public void setSecurityProvider(String securityProviderClassName) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
this.securityProvider = securityProviderClassName;
if(securityProviderClassName != null) {
Class securityProvider = Class.forName(securityProviderClassName);
Security.addProvider((Provider)securityProvider.newInstance());
securityProviderAdded = true;
}
}
public String getSecurityProvider() {
return securityProvider;
}
public boolean isComplete() {
return lmPassword != null && ntPassword != null && hostDomain!= null && userDomain != null && user != null;
}
public void writeToFile(String filename) throws FileNotFoundException, IOException {
ObjectOutputStream os = new ObjectOutputStream(
new FileOutputStream(filename));
os.writeObject(this);
os.close();
}
public static NTLMAuthorization readFromFile(String filename) throws OptionalDataException, ClassNotFoundException, IOException {
ObjectInputStream is = new ObjectInputStream(new FileInputStream(filename));
NTLMAuthorization auth = (NTLMAuthorization)is.readObject();
return auth;
}
public void setFilename(String filename) throws OptionalDataException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
NTLMAuthorization auth = readFromFile(filename);
host = auth.host;
hostDomain = auth.hostDomain;
lmPassword = auth.lmPassword;
ntPassword = auth.ntPassword;
setSecurityProvider(auth.securityProvider);
user = auth.user;
userDomain = auth.userDomain;
}
public String getFilename() { return null; }
public static void main(String[] args) {
NTLMAuthorization auth = new NTLMAuthorization();
try {
String filename = "";
for (int i = 0; i < args.length; i++) {
String s = args[i];
int sep = s.indexOf("=");
String left = sep >= 0 ? s.substring(0, sep).toLowerCase() : null;
String right = sep >= 0 ? s.substring(sep + 1) : s;
if (left == null) { filename = s;}
else if (left.equals("-domain")) { auth.setDomain(right); }
else if (left.equals("-host")) { auth.setHost(right); }
else if (left.equals("-hostdomain")) { auth.setHostDomain(right); }
else if (left.equals("-lmpassword")) { auth.setLmPassword(right); }
else if (left.equals("-ntpassword")) { auth.setNtPassword(right); }
else if (left.equals("-password")) { auth.setPassword(right); }
else if (left.equals("-securityprovider")) { auth.setSecurityProvider(right); }
else if (left.equals("-user")) { auth.setUser(right); }
else if (left.equals("-userDomain")) { auth.setUserDomain(right); }
else {
System.err.println("Unrecognized parameter: " + left);
}
}
if (!auth.isComplete() || filename == null) {
System.err.println("Syntax: <filename> <-parameter=value>*");
System.err.println("Required parameters: domain | (hostDomain, userDomain),");
System.err.println(" user,");
System.err.println(" password | (lmPassword, ntPassword)");
System.err.println("Optional parameters: securityprovider\n");
System.err.println("Example : ntAuth.dat -user=NTLM -domain=TEAMSPORT -password=NTLMNTLM");
System.exit(0);
}
auth.writeToFile(filename);
System.out.println(filename + " successfully written.");
auth = readFromFile(filename);
System.out.println(filename + " successfully read:");
System.out.println(auth);
} catch (Exception e) {
e.printStackTrace();
}
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null; // Can磘 happen
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -