changeset 25396 | 5e73c95f95db |
parent 23010 | 6dadb192ad81 |
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()) |