ntlmpasswordauthentication.java

来自「java ftp 操作代码,程序可以直接运行」· Java 代码 · 共 445 行 · 第 1/2 页

JAVA
445
字号
        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 with raw password
 * hashes. This is used exclusively by the <tt>jcifs.http.NtlmSsp</tt>
 * class which is in turn used by NTLM HTTP authentication functionality.
 */
    public NtlmPasswordAuthentication( String domain, String username,
                    byte[] challenge, byte[] ansiHash, byte[] unicodeHash ) {
        if( domain == null || username == null ||
                                    ansiHash == null || unicodeHash == null ) {
            throw new IllegalArgumentException( "External credentials cannot be null" );
        }
        this.domain = domain;
        this.username = username;
        this.password = null;
        this.challenge = challenge;
        this.ansiHash = ansiHash;
        this.unicodeHash = unicodeHash;
        hashesExternal = true;
    }

/**
 * Returns the domain.
 */
    public String getDomain() {
        return domain;
    }
/**
 * Returns the username.
 */
    public String getUsername() {
        return username;
    }
/**
 * Returns the password in plain text or <tt>null</tt> if the raw password
 * hashes were used to construct this <tt>NtlmPasswordAuthentication</tt>
 * object which will be the case when NTLM HTTP Authentication is
 * used. There is no way to retrieve a users password in plain text unless
 * it is supplied by the user at runtime.
 */
    public String getPassword() {
        return password;
    }
/**
 * Return the domain and username in the format:
 * <tt>domain\\username</tt>. This is equivalent to <tt>toString()</tt>.
 */
    public String getName() {
        boolean d = domain.length() > 0 && domain.equals( "?" ) == false;
        return d ? domain + "\\" + username : username;
    }

/**
 * Computes the 24 byte ANSI password hash given the 8 byte server challenge.
 */
    public byte[] getAnsiHash( byte[] challenge ) {
        if( hashesExternal ) {
            return ansiHash;
        }
        switch (LM_COMPATIBILITY) {
        case 0:
        case 1:
            return getPreNTLMResponse( password, challenge );
        case 2:
            return getNTLMResponse( password, challenge );
        case 3:
        case 4:
        case 5:
            if( clientChallenge == null ) {
                clientChallenge = new byte[8];
                RANDOM.nextBytes( clientChallenge );
            }
            return getLMv2Response(domain, username, password, challenge,
                    clientChallenge);
        default:
            return getPreNTLMResponse( password, challenge );
        }
    }
/**
 * Computes the 24 byte Unicode password hash given the 8 byte server challenge.
 */
    public byte[] getUnicodeHash( byte[] challenge ) {
        if( hashesExternal ) {
            return unicodeHash;
        }
        switch (LM_COMPATIBILITY) {
        case 0:
        case 1:
        case 2:
            return getNTLMResponse( password, challenge );
        case 3:
        case 4:
        case 5:
            /*
            if( clientChallenge == null ) {
                clientChallenge = new byte[8];
                RANDOM.nextBytes( clientChallenge );
            }
            return getNTLMv2Response(domain, username, password, null,
                    challenge, clientChallenge);
            */
            return new byte[0];
        default:
            return getNTLMResponse( password, challenge );
        }
    }

    /**
     * Returns the effective user session key.
     * 
     * @param challenge The server challenge.
     * @return A <code>byte[]</code> containing the effective user session key,
     * used in SMB MAC signing and NTLMSSP signing and sealing.
     */
    public byte[] getUserSessionKey(byte[] challenge) {
        if (hashesExternal) return null;
        byte[] key = new byte[16];
        try {
            getUserSessionKey(challenge, key, 0); 
        } catch (Exception ex) {
            if( log.level > 0 )
                ex.printStackTrace( log );
        }
        return key; 
    }

    /**
     * Calculates the effective user session key.
     *
     * @param challenge The server challenge.
     * @param dest The destination array in which the user session key will be
     * placed.
     * @param offset The offset in the destination array at which the
     * session key will start.
     */
    void getUserSessionKey(byte[] challenge, byte[] dest, int offset)
            throws Exception {
        if (hashesExternal) return;
        MD4 md4 = new MD4();
        md4.update(password.getBytes("UnicodeLittleUnmarked")); 
        switch (LM_COMPATIBILITY) {
        case 0:
        case 1:
        case 2:
            md4.update(md4.digest()); 
            md4.digest(dest, offset, 16); 
            break; 
        case 3:
        case 4:
        case 5:
            if( clientChallenge == null ) {
                clientChallenge = new byte[8];
                RANDOM.nextBytes( clientChallenge );
            }

            HMACT64 hmac = new HMACT64(md4.digest());
            hmac.update(username.toUpperCase().getBytes(
                    "UnicodeLittleUnmarked"));
            hmac.update(domain.toUpperCase().getBytes(
                    "UnicodeLittleUnmarked"));
            byte[] ntlmv2Hash = hmac.digest();
            hmac = new HMACT64(ntlmv2Hash);
            hmac.update(challenge);
            hmac.update(clientChallenge); 
            HMACT64 userKey = new HMACT64(ntlmv2Hash); 
            userKey.update(hmac.digest()); 
            userKey.digest(dest, offset, 16); 
            break; 
        default: 
            md4.update(md4.digest()); 
            md4.digest(dest, offset, 16); 
            break; 
        } 
    } 

/**
 * Compares two <tt>NtlmPasswordAuthentication</tt> objects for
 * equality. Two <tt>NtlmPasswordAuthentication</tt> objects are equal if
 * their caseless domain and username fields are equal and either both hashes are external and they are equal or both internally supplied passwords are equal. If one <tt>NtlmPasswordAuthentication</tt> object has external hashes (meaning negotiated via NTLM HTTP Authentication) and the other does not they will not be equal. This is technically not correct however the server 8 byte challage would be required to compute and compare the password hashes but that it not available with this method.
 */
    public boolean equals( Object obj ) {
        if( obj instanceof NtlmPasswordAuthentication ) {
            NtlmPasswordAuthentication ntlm = (NtlmPasswordAuthentication)obj;
            if( ntlm.domain.toUpperCase().equals( domain.toUpperCase() ) &&
                        ntlm.username.toUpperCase().equals( username.toUpperCase() )) {
                if( hashesExternal && ntlm.hashesExternal ) {
                    return Arrays.equals( ansiHash, ntlm.ansiHash ) &&
                                Arrays.equals( unicodeHash, ntlm.unicodeHash );
                    /* This still isn't quite right. If one npa object does not have external
                     * hashes and the other does then they will not be considered equal even
                     * though they may be.
                     */
                } else if( !hashesExternal && password.equals( ntlm.password )) {
                    return true;
                }
            }
        }
        return false;
    }


/**
 * Return the upcased username hash code.
 */
    public int hashCode() {
        return getName().toUpperCase().hashCode();
    }
/**
 * Return the domain and username in the format:
 * <tt>domain\\username</tt>. This is equivalent to <tt>getName()</tt>.
 */
    public String toString() {
        return getName();
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?