jdk/src/share/classes/com/sun/security/ntlm/Client.java
changeset 25396 5e73c95f95db
parent 23010 6dadb192ad81
equal deleted inserted replaced
25395:4c004dfa3340 25396:5e73c95f95db
    44  */
    44  */
    45 public final class Client extends NTLM {
    45 public final class Client extends NTLM {
    46     final private String hostname;
    46     final private String hostname;
    47     final private String username;
    47     final private String username;
    48 
    48 
    49     private String domain;    // might be updated by Type 2 msg
    49     private String domain;
    50     private byte[] pw1, pw2;
    50     private byte[] pw1, pw2;
    51 
    51 
    52     /**
    52     /**
    53      * Creates an NTLM Client instance.
    53      * Creates an NTLM Client instance.
    54      * @param version the NTLM version to use, which can be:
    54      * @param version the NTLM version to use, which can be:
    80             throw new NTLMException(NTLMException.PROTOCOL,
    80             throw new NTLMException(NTLMException.PROTOCOL,
    81                     "username/password cannot be null");
    81                     "username/password cannot be null");
    82         }
    82         }
    83         this.hostname = hostname;
    83         this.hostname = hostname;
    84         this.username = username;
    84         this.username = username;
    85         this.domain = domain;
    85         this.domain = domain == null ? "" : domain;
    86         this.pw1 = getP1(password);
    86         this.pw1 = getP1(password);
    87         this.pw2 = getP2(password);
    87         this.pw2 = getP2(password);
    88         debug("NTLM Client: (h,u,t,version(v)) = (%s,%s,%s,%s(%s))\n",
    88         debug("NTLM Client: (h,u,t,version(v)) = (%s,%s,%s,%s(%s))\n",
    89                     hostname, username, domain, version, v.toString());
    89                     hostname, username, domain, version, v.toString());
    90     }
    90     }
    93      * Generates the Type 1 message
    93      * Generates the Type 1 message
    94      * @return the message generated
    94      * @return the message generated
    95      */
    95      */
    96     public byte[] type1() {
    96     public byte[] type1() {
    97         Writer p = new Writer(1, 32);
    97         Writer p = new Writer(1, 32);
    98         int flags = 0x8203;
    98         // Negotiate always sign, Negotiate NTLM,
    99         if (hostname != null) {
    99         // Request Target, Negotiate OEM, Negotiate unicode
   100             flags |= 0x2000;
   100         int flags = 0x8207;
   101         }
       
   102         if (domain != null) {
       
   103             flags |= 0x1000;
       
   104         }
       
   105         if (v != Version.NTLM) {
   101         if (v != Version.NTLM) {
   106             flags |= 0x80000;
   102             flags |= 0x80000;
   107         }
   103         }
   108         p.writeInt(12, flags);
   104         p.writeInt(12, flags);
   109         p.writeSecurityBuffer(24, hostname, false);
       
   110         p.writeSecurityBuffer(16, domain, false);
       
   111         debug("NTLM Client: Type 1 created\n");
   105         debug("NTLM Client: Type 1 created\n");
   112         debug(p.getBytes());
   106         debug(p.getBytes());
   113         return p.getBytes();
   107         return p.getBytes();
   114     }
   108     }
   115 
   109 
   131         debug(type2);
   125         debug(type2);
   132         Reader r = new Reader(type2);
   126         Reader r = new Reader(type2);
   133         byte[] challenge = r.readBytes(24, 8);
   127         byte[] challenge = r.readBytes(24, 8);
   134         int inputFlags = r.readInt(20);
   128         int inputFlags = r.readInt(20);
   135         boolean unicode = (inputFlags & 1) == 1;
   129         boolean unicode = (inputFlags & 1) == 1;
   136         String domainFromServer = r.readSecurityBuffer(12, unicode);
   130 
   137         if (domainFromServer != null) {
   131         // IE uses domainFromServer to generate an alist if server has not
   138             domain = domainFromServer;
   132         // provided one. Firefox/WebKit do not. Neither do we.
   139         }
   133         //String domainFromServer = r.readSecurityBuffer(12, unicode);
   140         if (domain == null) {
       
   141             domain = "";
       
   142         }
       
   143 
   134 
   144         int flags = 0x88200 | (inputFlags & 3);
   135         int flags = 0x88200 | (inputFlags & 3);
   145         Writer p = new Writer(3, 64);
   136         Writer p = new Writer(3, 64);
   146         byte[] lm = null, ntlm = null;
   137         byte[] lm = null, ntlm = null;
   147 
   138 
   161         } else {
   152         } else {
   162             byte[] nthash = calcNTHash(pw2);
   153             byte[] nthash = calcNTHash(pw2);
   163             if (writeLM) lm = calcV2(nthash,
   154             if (writeLM) lm = calcV2(nthash,
   164                     username.toUpperCase(Locale.US)+domain, nonce, challenge);
   155                     username.toUpperCase(Locale.US)+domain, nonce, challenge);
   165             if (writeNTLM) {
   156             if (writeNTLM) {
   166                 byte[] alist = type2.length > 48 ?
   157                 // Some client create a alist even if server does not send
       
   158                 // one: (i16)2 (i16)len target_in_unicode (i16)0 (i16) 0
       
   159                 byte[] alist = ((inputFlags & 0x800000) != 0) ?
   167                     r.readSecurityBuffer(40) : new byte[0];
   160                     r.readSecurityBuffer(40) : new byte[0];
   168                 byte[] blob = new byte[32+alist.length];
   161                 byte[] blob = new byte[32+alist.length];
   169                 System.arraycopy(new byte[]{1,1,0,0,0,0,0,0}, 0, blob, 0, 8);
   162                 System.arraycopy(new byte[]{1,1,0,0,0,0,0,0}, 0, blob, 0, 8);
   170                 // TS
   163                 // TS
   171                 byte[] time = BigInteger.valueOf(new Date().getTime())
   164                 byte[] time = BigInteger.valueOf(new Date().getTime())