📄 ntlmpasswordauthentication.java.orig
字号:
/* jcifs smb client library in Java * Copyright (C) 2002 "Michael B. Allen" <jcifs at samba dot org> * "Eric Glass" <jcifs at samba dot org> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */package jcifs.smb;import java.io.UnsupportedEncodingException;import java.io.Serializable;import java.security.Principal;import java.util.Random;import java.util.Arrays;import jcifs.Config;import jcifs.util.*;/** * This class stores and encrypts NTLM user credentials. The default * credentials are retrieved from the <tt>jcifs.smb.client.domain</tt>, * <tt>jcifs.smb.client.username</tt>, and <tt>jcifs.smb.client.password</tt> * properties. * <p> * Read <a href="../../../authhandler.html">jCIFS Exceptions and * NtlmAuthenticator</a> for related information. */public final class NtlmPasswordAuthentication implements Principal, Serializable { private static final int LM_COMPATIBILITY = Config.getInt("jcifs.smb.lmCompatibility", 0); private static final Random RANDOM = new Random(); private static LogStream log = LogStream.getInstance(); // KGS!@#$% private static final byte[] S8 = { (byte)0x4b, (byte)0x47, (byte)0x53, (byte)0x21, (byte)0x40, (byte)0x23, (byte)0x24, (byte)0x25 }; private static void E( byte[] key, byte[] data, byte[] e ) { byte[] key7 = new byte[7]; byte[] e8 = new byte[8]; for( int i = 0; i < key.length / 7; i++ ) { System.arraycopy( key, i * 7, key7, 0, 7 ); DES des = new DES( key7 ); des.encrypt( data, e8 ); System.arraycopy( e8, 0, e, i * 8, 8 ); } } static String DEFAULT_DOMAIN; static String DEFAULT_USERNAME; static String DEFAULT_PASSWORD; static final String BLANK = ""; static void initDefaults() { if (DEFAULT_DOMAIN != null) return; DEFAULT_DOMAIN = Config.getProperty("jcifs.smb.client.domain", "?"); DEFAULT_USERNAME = Config.getProperty("jcifs.smb.client.username", "GUEST"); DEFAULT_PASSWORD = Config.getProperty("jcifs.smb.client.password", BLANK); }/** * Generate the ANSI DES hash for the password associated with these credentials. */ static public byte[] getPreNTLMResponse( String password, byte[] challenge ) { byte[] p14 = new byte[14]; byte[] p21 = new byte[21]; byte[] p24 = new byte[24]; byte[] passwordBytes; try { passwordBytes = password.toUpperCase().getBytes( ServerMessageBlock.OEM_ENCODING ); } catch( UnsupportedEncodingException uee ) { throw new RuntimeException("Try setting jcifs.encoding=US-ASCII", uee); } int passwordLength = passwordBytes.length; // Only encrypt the first 14 bytes of the password for Pre 0.12 NT LM if( passwordLength > 14) { passwordLength = 14; } System.arraycopy( passwordBytes, 0, p14, 0, passwordLength ); E( p14, S8, p21); E( p21, challenge, p24); return p24; }/** * Generate the Unicode MD4 hash for the password associated with these credentials. */ static public byte[] getNTLMResponse( String password, byte[] challenge ) { byte[] uni = null; byte[] p21 = new byte[21]; byte[] p24 = new byte[24]; try { uni = password.getBytes( "UnicodeLittleUnmarked" ); } catch( UnsupportedEncodingException uee ) { if( log.level > 0 ) uee.printStackTrace( log ); } MD4 md4 = new MD4(); md4.update( uni ); try { md4.digest(p21, 0, 16); } catch (Exception ex) { if( log.level > 0 ) ex.printStackTrace( log ); } E( p21, challenge, p24 ); return p24; } /** * Creates the LMv2 response for the supplied information. * * @param domain The domain in which the username exists. * @param user The username. * @param password The user's password. * @param challenge The server challenge. * @param clientChallenge The client challenge (nonce). */ public static byte[] getLMv2Response(String domain, String user, String password, byte[] challenge, byte[] clientChallenge) { try { byte[] hash = new byte[16]; byte[] response = new byte[24]; MD4 md4 = new MD4(); md4.update(password.getBytes("UnicodeLittleUnmarked")); HMACT64 hmac = new HMACT64(md4.digest()); hmac.update(user.toUpperCase().getBytes("UnicodeLittleUnmarked")); hmac.update(domain.toUpperCase().getBytes("UnicodeLittleUnmarked")); hmac = new HMACT64(hmac.digest()); hmac.update(challenge); hmac.update(clientChallenge); hmac.digest(response, 0, 16); System.arraycopy(clientChallenge, 0, response, 16, 8); return response; } catch (Exception ex) { if( log.level > 0 ) ex.printStackTrace( log ); return null; } } static final NtlmPasswordAuthentication NULL = new NtlmPasswordAuthentication( "", "", "" ); static final NtlmPasswordAuthentication GUEST = new NtlmPasswordAuthentication( "?", "GUEST", "" ); static final NtlmPasswordAuthentication DEFAULT = new NtlmPasswordAuthentication( null ); String domain; String username; String password; byte[] ansiHash; byte[] unicodeHash; boolean hashesExternal = false; byte[] clientChallenge = null; byte[] challenge = null;/** * Create an <tt>NtlmPasswordAuthentication</tt> object from the userinfo * component of an SMB URL like "<tt>domain;user:pass</tt>". This constructor * is used internally be jCIFS when parsing SMB URLs. */ public NtlmPasswordAuthentication( String userInfo ) { domain = username = password = null; if( userInfo != null ) { int i, u, end; char c; end = userInfo.length(); for( i = 0, u = 0; i < end; i++ ) { c = userInfo.charAt( i ); if( c == ';' ) { domain = userInfo.substring( 0, i ); u = i + 1; } else if( c == ':' ) { password = userInfo.substring( i + 1 ); break; } } username = userInfo.substring( u, i ); } initDefaults(); if( domain == null ) this.domain = DEFAULT_DOMAIN; if( username == null ) this.username = DEFAULT_USERNAME; if( password == null ) this.password = DEFAULT_PASSWORD; }/** * Create an <tt>NtlmPasswordAuthentication</tt> object from a * domain, username, and password. Parameters that are <tt>null</tt> * will be substituted with <tt>jcifs.smb.client.domain</tt>, * <tt>jcifs.smb.client.username</tt>, <tt>jcifs.smb.client.password</tt> * property values. */ public NtlmPasswordAuthentication( String domain, String username, String password ) { this.domain = domain; this.username = username; this.password = password; initDefaults();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -