Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * ====================================================================
   * Copyright (c) 2004-2006 TMate Software Ltd.  All rights reserved.
   *
   * This software is licensed as described in the file COPYING, which
   * you should have received as part of this distribution.  The terms
   * are also available at http://svnkit.com/license.html
   * If newer versions of this license are posted there, you may use a
   * newer version instead, at your option.
  * ====================================================================
  */
 package org.tmatesoft.svn.core.internal.io.dav.http;
 
 import java.util.Map;
 
 

Author(s):
TMate Software Ltd.
Version:
1.1.0
 
 
     private static final String NTLM_CASE_CONVERTION_PROPERTY = "svnkit.http.ntlm.uppercase";
     private static final String OLD_NTLM_CASE_CONVERTION_PROPERTY = "javasvn.http.ntlm.uppercase";
     
     private static final String DEFAULT_CHARSET = "ASCII";
     private static final String PROTOCOL_NAME = "NTLMSSP";
     private static final int LM_RESPONSE_LENGTH = 24;
     private static final int UNINITIATED = 0;
     private static final int TYPE1 = 1;
     private static final int TYPE3 = 3;
     private static byte[] ourMagicBytes = {
         (byte) 0x4B, (byte) 0x47, (byte) 0x53, (byte) 0x21, 
         (byte) 0x40, (byte) 0x23, (byte) 0x24, (byte) 0x25
     };
     
     private static final long NEGOTIATE_UNICODE = 0x00000001L;  
     private static final long NEGOTIATE_OEM = 0x00000002L;  
     private static final long REQUEST_TARGET = 0x00000004L;  
     private static final long NEGOTIATE_SIGN = 0x00000010L;  
     private static final long NEGOTIATE_SEAL = 0x00000020L;  
     private static final long NEGOTIATE_DATAGRAM_STYLE = 0x00000040L;  
     private static final long NEGOTIATE_LAN_MANAGER_KEY = 0x00000080L;  
     private static final long NEGOTIATE_NETWARE = 0x00000100L;  
     private static final long NEGOTIATE_NTLM = 0x00000200L;  
     private static final long NEGOTIATE_DOMAIN_SUPPLIED = 0x00001000L;  
     private static final long NEGOTIATE_WORKSTATION_SUPPLIED = 0x00002000L;  
     private static final long NEGOTIATE_LOCAL_CALL = 0x00004000L;  
     private static final long NEGOTIATE_ALWAYS_SIGN = 0x00008000L;  
     private static final long TARGET_TYPE_DOMAIN = 0x00010000L;  
     private static final long TARGET_TYPE_SERVER = 0x00020000L;  
     private static final long TARGET_TYPE_SHARE = 0x00040000L;  
     private static final long NEGOTIATE_NTLM2_KEY = 0x00080000L;  
     private static final long REQUEST_INIT_RESPONSE = 0x00100000L;  
     private static final long REQUEST_ACCEPT_RESPONSE = 0x00200000L;  
     private static final long REQUEST_NON_NT_SESSION_KEY = 0x00400000L;  
     private static final long NEGOTIATE_TARGET_INFO = 0x00800000L;  
     private static final long NEGOTIATE_128 = 0x20000000L;  
     private static final long NEGOTIATE_KEY_EXCHANGE = 0x40000000L;  
     private static final long NEGOTIATE_56 = 0x80000000L;  
     
     private static Map ourFlags = new TreeMap();
     static {
         .put(new Long(), "0x00000001 (Negotiate Unicode)");
         .put(new Long(), "0x00000002 (Negotiate OEM)");
         .put(new Long(), "0x00000004 (Request Target)");
         .put(new Long(0x00000008L), "0x00000008 (Unknown)");
         .put(new Long(), "0x00000010 (Negotiate Sign)");
         .put(new Long(), "0x00000020 (Negotiate Seal)");
         .put(new Long(), "0x00000040 (Negotiate Datagram Style)");
         .put(new Long(), "0x00000080 (Negotiate Lan Manager Key)");
         .put(new Long(), "0x00000100 (Negotiate Netware)");
         .put(new Long(), "0x00000200 (Negotiate NTLM)");
         .put(new Long(0x00000400L), "0x00000400 (Unknown)");
         .put(new Long(0x00000800L), "0x00000800 (Unknown)");
         .put(new Long(), "0x00001000 (Negotiate Domain Supplied)");
         .put(new Long(), "0x00002000 (Negotiate Workstation Supplied)");
         .put(new Long(), "0x00004000 (Negotiate Local Call)");
         .put(new Long(), "0x00008000 (Negotiate Always Sign)");
         .put(new Long(), "0x00010000 (Target Type Domain)");
         .put(new Long(), "0x00020000 (Target Type Server)");
        .put(new Long(), "0x00040000 (Target Type Share)");
        .put(new Long(), "0x00080000 (Negotiate NTLM2 Key)");
        .put(new Long(), "0x00100000 (Request Init Response)");
        .put(new Long(), "0x00200000 (Request Accept Response)");
        .put(new Long(), "0x00400000 (Request Non-NT Session Key)");
        .put(new Long(), "0x00800000 (Negotiate Target Info)");
        .put(new Long(0x01000000L), "0x01000000 (Unknown)");
        .put(new Long(0x02000000L), "0x02000000 (Unknown)");
        .put(new Long(0x04000000L), "0x04000000 (Unknown)");
        .put(new Long(0x08000000L), "0x08000000 (Unknown)");
        .put(new Long(0x10000000L), "0x10000000 (Unknown)");
        .put(new Long(), "0x20000000 (Negotiate 128)");
        .put(new Long(), "0x40000000 (Negotiate Key Exchange)");
        .put(new Long(), "0x80000000 (Negotiate 56)");
    }
    private static Map ourTargetInfoTypes = new TreeMap();
    static {
        .put(new Integer(1), "Server Name");
        .put(new Integer(2), "Domain Name");
        .put(new Integer(3), "DNS Host Name");
        .put(new Integer(4), "DNS Domain Name");
    }
    
    private int myState;
    private byte[] myResponse;
    private int myPosition
    private byte[] myNonce;
    private boolean myIsNegotiateLocalCall;
    
    protected HTTPNTLMAuthentication () {
         = ;
         = false;
    }
    
    public void setType1State(){
         = ;
    }
    public void setType3State(){
         = ;
    }
    public boolean isInType3State(){
        return  == ;
    }
    
    private void initResponse(int bufferSize){
         = new byte[bufferSize];
         = 0;
    }
    
    private void addByte(byte b){
        [++] = b;
    }
    private void addBytes(byte[] bytes) {
        for (int i = 0; i < bytes.lengthi++) {
            [++] = bytes[i];
        }
    }
    private byte[] convertToShortValue(int num){
        byte[] val = new byte[2];
        val[0] = (byte)(num & 0xff);
        val[1] = (byte)((num >> 8) & 0xff);
        return val;
    }
    
    private String getResponse(){
        byte[] response;
        if (. > ) {
            response = new byte[];
            for (int i = 0; i < i++) {
                response[i] = [i];
            }
        } else {
            response = ;
        }
        
        String base64EncodedResponse = SVNBase64.byteArrayToBase64(response);
        return new String(HTTPAuthentication.getASCIIBytes(base64EncodedResponse));
    }
    
    public void parseChallenge(String challengethrows SVNException {
        if (challenge == null) {
            SVNErrorMessage err = SVNErrorMessage.create(."NTLM HTTP auth: expected challenge");
            SVNErrorManager.error(err);
        }
        byte[] challengeBase64Bytes = HTTPAuthentication.getBytes(challenge);
        byte[] resultBuffer = new byte[challengeBase64Bytes.length];
        int resultLength = SVNBase64.base64ToByteArray(new StringBuffer(new String(challengeBase64Bytes)), resultBuffer);
        
        String proto = new String(resultBuffer, 0, 7);
        byte[] typeBytes = new byte[4];
        for (int i = 0; i < 4; i++) {
            typeBytes[i] = resultBuffer[8 + i];
        }
        long type = toLong(typeBytes); 
        
        if (!.equalsIgnoreCase(proto)) {
            SVNErrorMessage err = SVNErrorMessage.create(."NTLM HTTP auth: incorrect signature ''(0}''"proto);
            SVNErrorManager.error(err);
        } else if (type != 2) {
            SVNErrorMessage err = SVNErrorMessage.create(."NTLM HTTP auth: expected type 2 message instead of ''(0, number, integer}''"new Long(type));
            SVNErrorManager.error(err);
        }
        
         = new byte[8];
        for (int i = 0; i < 8; i++) {
            [i] = resultBuffer[i + 24];
        }
        
        byte[] flagBytes = new byte[4];
        for (int i = 0; i < 4; i++) {
            flagBytes[i] = resultBuffer[i + 20];
        }
        long flags = toLong(flagBytes);
        
        StringBuffer log = new StringBuffer();
        String base64DecodedMessage = new String(resultBuffer, 0, resultLength);
        log.append("NTLM auth message: " + base64DecodedMessage);
        log.append('\n');
        log.append("Length: " + base64DecodedMessage.length());
        log.append('\n');
        log.append("Signature: " + proto);
        log.append('\n');
        log.append("Type: " + type);
        log.append('\n');
        log.append("Flags: " + Long.toString(flags, 16));
        log.append('\n');
        for (Iterator flagsIter = .keySet().iterator(); flagsIter.hasNext();) {
            Long curFlag = (Long)flagsIter.next();
            if ((flags & curFlag.longValue()) != 0) {
                log.append(.get(curFlag));
                log.append('\n');
            }
        }
        
        byte[] targetNameLengthBytes = new byte[2];
        for (int i = 0; i < 2; i++) {
            targetNameLengthBytes[i] = resultBuffer[12 + i];
        }
        int targetNameLength = toInt(targetNameLengthBytes);
        byte[] targetNameAllocatedBytes = new byte[2];
        for (int i = 0; i < 2; i++) {
            targetNameAllocatedBytes[i] = resultBuffer[14 + i];
        }
        int targetNameAllocated = toInt(targetNameAllocatedBytes);
        
        byte[] targetNameOffsetBytes = new byte[4];
        for (int i = 0; i < 4; i++) {
            targetNameOffsetBytes[i] = resultBuffer[16 + i];
        }
        long targetNameOffset = toLong(targetNameOffsetBytes); 
        
        if (targetNameLength > 0) {
            String targetName = new String(resultBuffer, (int)targetNameOffsettargetNameAllocated);
            log.append("Target Name: " + targetName);
            log.append('\n');
        }
        log.append("Challenge: ");
        for (int i = 0; i < .i++) {
            log.append(SVNFormatUtil.getHexNumberFromByte([i]));
        }
        log.append('\n');
        
        //check for local call
        long contextH = -1;
        long contextL = -1;
        boolean containsContext = false;
        if (targetNameOffset != 32 && resultLength >= 40) {
            byte[] contextHBytes = new byte[4];
            byte[] contextLBytes = new byte[4];
            int i = 0;
            for (i = 0; i < 4; i++) {
                contextHBytes[i] = resultBuffer[i + 32];
            }
            for (;i < 8; i++) {
                contextLBytes[i - 4] = resultBuffer[i + 32];
            }
            contextH = toLong(contextHBytes);
            contextL = toLong(contextLBytes);
            if (contextL == 0) {
                containsContext = true;
                log.append("Context: ");
                log.append(Long.toString(contextH, 16) + " " + Long.toString(contextL, 16));
                log.append('\n');
            }
            
            if (contextH != 0 && (flags & ) != 0) {
                 = true;
            } else {
                 = false;
            }
        } else {
             = false;
        }
        
        if ((flags & ) != 0) {
            int tgtInfoSecurityBufferOffset = containsContext ? 40: 32;
            
            byte[] targetInfoLengthBytes = new byte[2];
            for (int i = 0; i < 2; i++) {
                targetInfoLengthBytes[i] = resultBuffer[tgtInfoSecurityBufferOffset + i];
            }
            int targetInfoLength = toInt(targetInfoLengthBytes);
            
            byte[] targetInfoAllocatedBytes = new byte[2];
            for (int i = 0; i < 2; i++) {
                targetInfoAllocatedBytes[i] = resultBuffer[tgtInfoSecurityBufferOffset + 2 + i];
            }
            int targetInfoAllocated = toInt(targetInfoAllocatedBytes);
            
            byte[] targetInfoOffsetBytes = new byte[4];
            for (int i = 0; i < 4; i++) {
                targetInfoOffsetBytes[i] = resultBuffer[tgtInfoSecurityBufferOffset + 4 + i];
            }
            long targetInfoOffset = toLong(targetInfoOffsetBytes);
            
            byte[] targetInfoTypeBytes = new byte[2];
            byte[] subblockLengthBytes = new byte[2];
            int read = 0;
            while (targetInfoLength > 0 && read <= targetInfoAllocated) {
                for (int i = 0; i < 2; i++) {
                    targetInfoTypeBytes[i] = resultBuffer[(int)targetInfoOffset + i];
                }
                read += 2;
                targetInfoOffset += 2;
                int targetInfoType = toInt(targetInfoTypeBytes);
                if (targetInfoType == 0){
                    break;
                }
                for (int i = 0; i < 2; i++) {
                    subblockLengthBytes[i] = resultBuffer[(int)targetInfoOffset + i];
                }
                read += 2;
                targetInfoOffset += 2;
                int subblockLength = toInt(subblockLengthBytes);
                String typeDescription = (String).get(new Integer(targetInfoType));
                if (typeDescription != null) {
                    String info = new String(resultBuffer, (int)targetInfoOffsetsubblockLength);
                    log.append(typeDescription + ": " + info);
                    log.append('\n');
                }
                read += subblockLength;
                targetInfoOffset += subblockLength;
            }
        }
        log.append('\n');
    }
    
    private static int toInt(byte[] num){
        int l = 0;
        for (int i = 0; i < 2 ; i++) {
            int b = num[i] & 0xff;
            b = b << i*8;
            l |=  b;
        }
        return l;
    }
    private long toLong(byte[] num){
        long l = 0;
        for (int i = 0; i < 4 ; i++) {
            long b = num[i] & 0xff;
            b = b << i*8;
            l |=  b;
        }
        return l;
    }
    
    public String authenticate() throws SVNException {
        if ( !=  &&  != ) {
            SVNErrorMessage err = SVNErrorMessage.create(."Unsupported message type in HTTP NTLM authentication");
            SVNErrorManager.error(err);
        }
        
        String login = getUserName();
        String domain = null;
        String username = null;
        int slashInd = login != null ? login.indexOf('\\') : -1; 
        if (slashInd != -1) {
            domain = login.substring(0, slashInd);
            int lastInd = slashInd + 1;
            while (lastInd < login.length() && login.charAt(lastInd) == '\\') {
                lastInd++;
            }
            username = login.substring(lastInd);
        } else {
            domain = "";
            username = login;
        }
        String hostName = null;
        try {
            InetAddress localhost = InetAddress.getLocalHost();
            hostName = localhost.getHostName();
        } catch (UnknownHostException uhe) {
            hostName = "";
        }
        
        if (isUpperCase()) {
            domain = domain.toUpperCase();
            hostName = hostName.toUpperCase();
        }
        
        byte[] protocol = HTTPAuthentication.getBytes();
        byte[] domainBytes = HTTPAuthentication.getBytes(domain);
        byte[] hostNameBytes = HTTPAuthentication.getBytes(hostName);
        byte[] domLen = convertToShortValue(domainBytes.length);
        byte[] hostLen = convertToShortValue(hostNameBytes.length);
        StringBuffer sublog = new StringBuffer();
        sublog.append("Signature: " + );
        sublog.append('\n');
        long flags =  |  |  | ;
        if (domain.length() > 0) {
            flags |= ;
        }
        
        if ( == ) {
            int responseLength = 32 + domainBytes.length + hostNameBytes.length;
            
            initResponse(responseLength);
            //NTLMSSP\0 signature (8 bytes long)
            addBytes(protocol);
            addByte((byte) 0);
            // Type1 - Negotiate (4 bytes long)
            addByte((byte) 1);
            addByte((byte) 0);
            addByte((byte) 0);
            addByte((byte) 0);
            sublog.append("Type: " + 1);
            sublog.append('\n');
            // Flags (4 bytes long): 'Negotiate OEM', 'Request Target', 
            // 'Negotiate NTLM', 'Negotiate Always Sign'
            addByte((byte)(flags & 0xff));
            addByte((byte)((flags >> 8) & 0xff));
            addByte((byte)((flags >> 16) & 0xff));
            addByte((byte)((flags >> 24) & 0xff));
            sublog.append("Flags: " + Long.toString(flags, 16));
            sublog.append('\n');
            for (Iterator flagsIter = .keySet().iterator(); flagsIter.hasNext();) {
                Long curFlag = (Long)flagsIter.next();
                if ((flags & curFlag.longValue()) != 0) {
                    sublog.append(.get(curFlag));
                    sublog.append('\n');
                }
            }
            // Domain name length (2 bytes short)
            addBytes(domLen);
            // Allocated space for the domain name (2 bytes short)
            addBytes(domLen);
            // Domain name offset (4 bytes long)
            byte[] domainOffset = convertToShortValue(hostNameBytes.length + 32);
            addBytes(domainOffset);
            addByte((byte) 0);
            addByte((byte) 0);
            // Host name length (2 bytes short).
            addBytes(hostLen);
            // Allocated space for the host name (2 bytes short)
            addBytes(hostLen);
            // Host name offset (always 32, 4 bytes long).
            byte[] hostOffset = convertToShortValue(32);
            addBytes(hostOffset);
            addByte((byte) 0);
            addByte((byte) 0);
            // Host name 
            addBytes(hostNameBytes);
            if (hostName.length() > 0) {
                sublog.append("Host Name: " + hostName);
                sublog.append('\n');
            }
            // Domain name
            addBytes(domainBytes);
            if (domain.length() > 0) {
                sublog.append("Domain: " + domain);
                sublog.append('\n');
            }
        } else if ( == ) {
            byte[] userBytes = username.getBytes();
            sublog.append("Type: " + 3);
            sublog.append('\n');
            sublog.append("Flags: " + Long.toString(flags, 16));
            sublog.append('\n');
            for (Iterator flagsIter = .keySet().iterator(); flagsIter.hasNext();) {
                Long curFlag = (Long)flagsIter.next();
                if ((flags & curFlag.longValue()) != 0) {
                    sublog.append(.get(curFlag));
                    sublog.append('\n');
                }
            }
            if (!) {
                int responseLength = 64 +  + domainBytes.length + hostNameBytes.length + userBytes.length;
                
                initResponse(responseLength);
    
                addBytes(protocol);
                addByte((byte) 0);
    
                //Type3
                addByte((byte) 3);
                addByte((byte) 0);
                addByte((byte) 0);
                addByte((byte) 0);
    
                byte[] lmResponseLength = convertToShortValue(24); 
                // LM Response Length 
                addBytes(lmResponseLength);
                // LM Response allocated space
                addBytes(lmResponseLength);
    
                // LM Response Offset
                addBytes(convertToShortValue(responseLength - 24));
                addByte((byte) 0);
                addByte((byte) 0);
    
                byte[] ntlmResponseLength = convertToShortValue(0); 
                // NTLM Response Length 
                addBytes(ntlmResponseLength);
                // NTLM Response allocated space
                addBytes(ntlmResponseLength);
    
                byte[] responseLengthShortBytes = convertToShortValue(responseLength); 
                // NTLM Response Offset
                addBytes(responseLengthShortBytes);
                addByte((byte) 0);
                addByte((byte) 0);
    
                // Domain length
                addBytes(domLen);
                // Domain allocated space
                addBytes(domLen);
                
                // Domain Offset
                addBytes(convertToShortValue(64));
                addByte((byte) 0);
                addByte((byte) 0);
    
                byte[] usernameLength = convertToShortValue(userBytes.length); 
                // Username Length 
                addBytes(usernameLength);
                // Username allocated space
                addBytes(usernameLength);
    
                // User offset
                addBytes(convertToShortValue(64 + domainBytes.length));
                addByte((byte) 0);
                addByte((byte) 0);
    
                // Host name length
                addBytes(hostLen);
                // Host name allocated space
                addBytes(hostLen);
    
                // Host offset
                addBytes(convertToShortValue(64 + domainBytes.length + userBytes.length));
    
                for (int i = 0; i < 6; i++) {
                    addByte((byte) 0);
                }
    
                // Message length
                addBytes(responseLengthShortBytes);
                addByte((byte) 0);
                addByte((byte) 0);
    
                // Flags
                addByte((byte)(flags & 0xff));
                addByte((byte)((flags >> 8) & 0xff));
                addByte((byte)((flags >> 16) & 0xff));
                addByte((byte)((flags >> 24) & 0xff));
                addBytes(domainBytes);
                if (domain.length() > 0) {
                    sublog.append("Domain: " + domain);
                    sublog.append('\n');
                }
                addBytes(userBytes);
                if (username.length() > 0) {
                    sublog.append("User Name: " + username);
                    sublog.append('\n');
                }
                addBytes(hostNameBytes);
                if (hostName.length() > 0) {
                    sublog.append("Host Name: " + hostName);
                    sublog.append('\n');
                }
                String password = getPassword();
                byte[] hash = hashPassword(password != null ? password : ""); 
                addBytes(hash);
                sublog.append("Hash: " + new String(hash));
                sublog.append('\n');
                
            } else {
                int responseLength = 64;
                byte[] responseLengthShortBytes = convertToShortValue(responseLength); 
                initResponse(responseLength);
                addBytes(protocol);
                addByte((byte) 0);
                //Type3
                addByte((byte) 3);
                addByte((byte) 0);
                addByte((byte) 0);
                addByte((byte) 0);
                // LM Response Length 
                addByte((byte)0);
                addByte((byte)0);
                // LM Response allocated space
                addByte((byte)0);
                addByte((byte)0);
                // LM Response Offset
                addBytes(responseLengthShortBytes);
                addByte((byte) 0);
                addByte((byte) 0);
                // NTLM Response Length 
                addByte((byte)0);
                addByte((byte)0);
                // NTLM Response allocated space
                addByte((byte)0);
                addByte((byte)0);
                // NTLM Response Offset
                addBytes(responseLengthShortBytes);
                addByte((byte) 0);
                addByte((byte) 0);
                // Domain length
                addByte((byte)0);
                addByte((byte)0);
                // Domain allocated space
                addByte((byte)0);
                addByte((byte)0);
                // Domain Offset
                addBytes(responseLengthShortBytes);
                addByte((byte) 0);
                addByte((byte) 0);
                // Username Length 
                addByte((byte)0);
                addByte((byte)0);
                // Username allocated space
                addByte((byte)0);
                addByte((byte)0);
                // User offset
                addBytes(responseLengthShortBytes);
                addByte((byte) 0);
                addByte((byte) 0);
                // Host name length
                addByte((byte)0);
                addByte((byte)0);
                // Host name allocated space
                addByte((byte)0);
                addByte((byte)0);
                // Host offset
                addBytes(responseLengthShortBytes);
                for (int i = 0; i < 6; i++) {
                    addByte((byte) 0);
                }
                // Message length
                addBytes(responseLengthShortBytes);
                addByte((byte) 0);
                addByte((byte) 0);
                // Flags
                addByte((byte)(flags & 0xff));
                addByte((byte)((flags >> 8) & 0xff));
                addByte((byte)((flags >> 16) & 0xff));
                addByte((byte)((flags >> 24) & 0xff));
            }
            setType1State();
        }
        StringBuffer log = new StringBuffer();
        String message = new String(, 0, );
        log.append("NTLM auth message: " + message);
        log.append('\n');
        log.append("Length: " + message.length());
        log.append('\n');
        log.append(sublog);
        return "NTLM " + getResponse();
    }
    private boolean isUpperCase() {
        String upperCase = System.getProperty(, System.getProperty("true"));
        return Boolean.valueOf(upperCase).booleanValue();
    }
    private byte[] hashPassword(String passwordthrows SVNException {
        byte[] passw = isUpperCase() ? password.toUpperCase().getBytes() : password.getBytes();
        byte[] lmPw1 = new byte[7];
        byte[] lmPw2 = new byte[7];
        int len = passw.length;
        if (len > 7) {
            len = 7;
        }
        int idx;
        for (idx = 0; idx < lenidx++) {
            lmPw1[idx] = passw[idx];
        }
        
        for (; idx < 7; idx++) {
            lmPw1[idx] = (byte) 0;
        }
        len = passw.length;
        if (len > 14) {
            len = 14;
        }
        for (idx = 7; idx < lenidx++) {
            lmPw2[idx - 7] = passw[idx];
        }
        for (; idx < 14; idx++) {
            lmPw2[idx - 7] = (byte) 0;
        }
        byte[] lmHpw1;
        lmHpw1 = encrypt(lmPw1);
        byte[] lmHpw2 = encrypt(lmPw2);
        byte[] lmHpw = new byte[21];
        for (int i = 0; i < lmHpw1.lengthi++) {
            lmHpw[i] = lmHpw1[i];
        }
        for (int i = 0; i < lmHpw2.lengthi++) {
            lmHpw[i + 8] = lmHpw2[i];
        }
        for (int i = 0; i < 5; i++) {
            lmHpw[i + 16] = (byte) 0;
        }
        // Create the responses.
        byte[] lmResp = new byte[24];
        calcResp(lmHpwlmResp);
        return lmResp;
    }
    
    private void calcResp(byte[] keysbyte[] resultsthrows SVNException {
        byte[] keys1 = new byte[7];
        byte[] keys2 = new byte[7];
        byte[] keys3 = new byte[7];
        
        for (int i = 0; i < 7; i++) {
            keys1[i] = keys[i];
        }
        for (int i = 0; i < 7; i++) {
            keys2[i] = keys[i + 7];
        }
        for (int i = 0; i < 7; i++) {
            keys3[i] = keys[i + 14];
        }
        
        byte[] results1 = encrypt(keys1);
        byte[] results2 = encrypt(keys2);
        byte[] results3 = encrypt(keys3);
        for (int i = 0; i < 8; i++) {
            results[i] = results1[i];
        }
        
        for (int i = 0; i < 8; i++) {
            results[i + 8] = results2[i];
        }
        
        for (int i = 0; i < 8; i++) {
            results[i + 16] = results3[i];
        }
    }
    
    private byte[] encrypt(byte[] keybyte[] bytesthrows SVNException {
        Cipher ecipher = getCipher(key);
        try {
            byte[] enc = ecipher.doFinal(bytes);
            return enc;
        } catch (IllegalBlockSizeException e) {
            SVNErrorMessage err = SVNErrorMessage.create(."Invalid block size for DES encryption: {0}"e.getLocalizedMessage());
            SVNErrorManager.error(err);
        } catch (BadPaddingException e) {
            SVNErrorMessage err = SVNErrorMessage.create(."Data not padded correctly for DES encryption: {0}"e.getLocalizedMessage());
            SVNErrorManager.error(err);
        }
        return null;
    }
    
    private Cipher getCipher(byte[] keythrows SVNException {
        try {
            final Cipher ecipher = Cipher.getInstance("DES/ECB/NoPadding");
            key = setupKey(key);
            ecipher.init(.new SecretKeySpec(key"DES"));
            return ecipher;
        } catch (NoSuchAlgorithmException e) {
            SVNErrorMessage err = SVNErrorMessage.create(."DES encryption is not available: {0}"e.getLocalizedMessage());
            SVNErrorManager.error(err);
        } catch (InvalidKeyException e) {
            SVNErrorMessage err = SVNErrorMessage.create(."Invalid key for DES encryption: {0}"e.getLocalizedMessage());
            SVNErrorManager.error(err);
        } catch (NoSuchPaddingException e) {
            SVNErrorMessage err = SVNErrorMessage.create(."NoPadding option for DES is not available: {0}"e.getLocalizedMessage());
            SVNErrorManager.error(err);
        }
        return null;
    }
    
    private byte[] setupKey(byte[] key56) {
        byte[] key = new byte[8];
        key[0] = (byte) ((key56[0] >> 1) & 0xff);
        key[1] = (byte) ((((key56[0] & 0x01) << 6) 
            | (((key56[1] & 0xff) >> 2) & 0xff)) & 0xff);
        key[2] = (byte) ((((key56[1] & 0x03) << 5) 
            | (((key56[2] & 0xff) >> 3) & 0xff)) & 0xff);
        key[3] = (byte) ((((key56[2] & 0x07) << 4) 
            | (((key56[3] & 0xff) >> 4) & 0xff)) & 0xff);
        key[4] = (byte) ((((key56[3] & 0x0f) << 3) 
            | (((key56[4] & 0xff) >> 5) & 0xff)) & 0xff);
        key[5] = (byte) ((((key56[4] & 0x1f) << 2) 
            | (((key56[5] & 0xff) >> 6) & 0xff)) & 0xff);
        key[6] = (byte) ((((key56[5] & 0x3f) << 1) 
            | (((key56[6] & 0xff) >> 7) & 0xff)) & 0xff);
        key[7] = (byte) (key56[6] & 0x7f);
        
        for (int i = 0; i < key.lengthi++) {
            key[i] = (byte) (key[i] << 1);
        }
        return key;
    }
        return "NTLM";
    }
New to GrepCode? Check out our FAQ X