History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/security/ntlm/Server.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/security/ntlm/Server.java+205−0
@@ -0,0 +1,205 @@
1/*
2 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.security.ntlm;
27
28import java.util.Arrays;
29import java.util.Locale;
30
31/**
32 * The NTLM server, not multi-thread enabled.<p>
33 * Example:
34 * <pre>
35 * Server server = new Server(null, "REALM") {
36 * public char[] getPassword(String ntdomain, String username) {
37 * switch (username) {
38 * case "dummy": return "t0pSeCr3t".toCharArray();
39 * case "guest": return "".toCharArray();
40 * default: return null;
41 * }
42 * }
43 * };
44 * // Receive client request as type1
45 * byte[] type2 = server.type2(type1, nonce);
46 * // Send type2 to client and receive type3
47 * verify(type3, nonce);
48 * </pre>
49 */
50public abstract class Server extends NTLM {
51 final private String domain;
52 final private boolean allVersion;
53 /**
54 * Creates a Server instance.
55 * @param version the NTLM version to use, which can be:
56 * <ul>
57 * <li>NTLM: Original NTLM v1
58 * <li>NTLM2: NTLM v1 with Client Challenge
59 * <li>NTLMv2: NTLM v2
60 * </ul>
61 * If null, all versions will be supported. Please note that unless NTLM2
62 * is selected, authentication succeeds if one of LM (or LMv2) or
63 * NTLM (or NTLMv2) is verified.
64 * @param domain the domain, must not be null
65 * @throws NullPointerException if {@code domain} is null.
66 */
67 public Server(String version, String domain) throws NTLMException {
68 super(version);
69 if (domain == null) {
70 throw new NullPointerException("domain cannot be null");
71 }
72 this.allVersion = (version == null);
73 this.domain = domain;
74 debug("NTLM Server: (t,version) = (%s,%s)\n", domain, version);
75 }
76
77 /**
78 * Generates the Type 2 message
79 * @param type1 the Type1 message received, must not be null
80 * @param nonce the random 8-byte array to be used in message generation,
81 * must not be null
82 * @return the message generated
83 * @throws NullPointerException if type1 or nonce is null
84 * @throws NTLMException if the incoming message is invalid
85 */
86 public byte[] type2(byte[] type1, byte[] nonce) {
87 if (nonce == null) {
88 throw new NullPointerException("nonce cannot be null");
89 }
90 debug("NTLM Server: Type 1 received\n");
91 if (type1 != null) debug(type1);
92 Writer p = new Writer(2, 32);
93 int flags = 0x80205;
94 p.writeSecurityBuffer(12, domain, true);
95 p.writeInt(20, flags);
96 p.writeBytes(24, nonce);
97 debug("NTLM Server: Type 2 created\n");
98 debug(p.getBytes());
99 return p.getBytes();
100 }
101
102 /**
103 * Verifies the Type3 message received from client and returns
104 * various negotiated information.
105 * @param type3 the incoming Type3 message from client, must not be null
106 * @param nonce the same nonce provided in {@link #type2}, must not be null
107 * @return username and hostname of the client in a byte array
108 * @throws NullPointerException if {@code type3} or {@code nonce} is null
109 * @throws NTLMException if the incoming message is invalid
110 */
111 public String[] verify(byte[] type3, byte[] nonce)
112 throws NTLMException {
113 if (type3 == null || nonce == null) {
114 throw new NullPointerException("type1 or nonce cannot be null");
115 }
116 debug("NTLM Server: Type 3 received\n");
117 if (type3 != null) debug(type3);
118 Reader r = new Reader(type3);
119 String username = r.readSecurityBuffer(36, true);
120 String hostname = r.readSecurityBuffer(44, true);
121 String incomingDomain = r.readSecurityBuffer(28, true);
122 /*if (incomingDomain != null && !incomingDomain.equals(domain)) {
123 throw new NTLMException(NTLMException.DOMAIN_UNMATCH,
124 "Wrong domain: " + incomingDomain +
125 " vs " + domain); // Needed?
126 }*/
127 boolean verified = false;
128 char[] password = getPassword(domain, username);
129 if (password == null) {
130 throw new NTLMException(NTLMException.USER_UNKNOWN,
131 "Unknown user");
132 }
133 byte[] incomingLM = r.readSecurityBuffer(12);
134 byte[] incomingNTLM = r.readSecurityBuffer(20);
135
136 if (!verified && (allVersion || v == Version.NTLM)) {
137 if (incomingLM.length > 0) {
138 byte[] pw1 = getP1(password);
139 byte[] lmhash = calcLMHash(pw1);
140 byte[] lmresponse = calcResponse (lmhash, nonce);
141 if (Arrays.equals(lmresponse, incomingLM)) {
142 verified = true;
143 }
144 }
145 if (incomingNTLM.length > 0) {
146 byte[] pw2 = getP2(password);
147 byte[] nthash = calcNTHash(pw2);
148 byte[] ntresponse = calcResponse (nthash, nonce);
149 if (Arrays.equals(ntresponse, incomingNTLM)) {
150 verified = true;
151 }
152 }
153 debug("NTLM Server: verify using NTLM: " + verified + "\n");
154 }
155 if (!verified && (allVersion || v == Version.NTLM2)) {
156 byte[] pw2 = getP2(password);
157 byte[] nthash = calcNTHash(pw2);
158 byte[] clientNonce = Arrays.copyOf(incomingLM, 8);
159 byte[] ntlmresponse = ntlm2NTLM(nthash, clientNonce, nonce);
160 if (Arrays.equals(incomingNTLM, ntlmresponse)) {
161 verified = true;
162 }
163 debug("NTLM Server: verify using NTLM2: " + verified + "\n");
164 }
165 if (!verified && (allVersion || v == Version.NTLMv2)) {
166 byte[] pw2 = getP2(password);
167 byte[] nthash = calcNTHash(pw2);
168 if (incomingLM.length > 0) {
169 byte[] clientNonce = Arrays.copyOfRange(
170 incomingLM, 16, incomingLM.length);
171 byte[] lmresponse = calcV2(nthash,
172 username.toUpperCase(Locale.US)+incomingDomain,
173 clientNonce, nonce);
174 if (Arrays.equals(lmresponse, incomingLM)) {
175 verified = true;
176 }
177 }
178 if (incomingNTLM.length > 0) {
179 byte[] clientBlob = Arrays.copyOfRange(
180 incomingNTLM, 16, incomingNTLM.length);
181 byte[] ntlmresponse = calcV2(nthash,
182 username.toUpperCase(Locale.US)+incomingDomain,
183 clientBlob, nonce);
184 if (Arrays.equals(ntlmresponse, incomingNTLM)) {
185 verified = true;
186 }
187 }
188 debug("NTLM Server: verify using NTLMv2: " + verified + "\n");
189 }
190 if (!verified) {
191 throw new NTLMException(NTLMException.AUTH_FAILED,
192 "None of LM and NTLM verified");
193 }
194 return new String[] {username, hostname};
195 }
196
197 /**
198 * Retrieves the password for a given user. This method should be
199 * overridden in a concrete class.
200 * @param domain can be null
201 * @param username must not be null
202 * @return the password for the user, or null if unknown
203 */
204 public abstract char[] getPassword(String domain, String username);
205}