001: /* jcifs smb client library in Java
002: * Copyright (C) 2002 "Michael B. Allen" <jcifs at samba dot org>
003: * "Eric Glass" <jcifs at samba dot org>
004: *
005: * This library is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU Lesser General Public
007: * License as published by the Free Software Foundation; either
008: * version 2.1 of the License, or (at your option) any later version.
009: *
010: * This library is distributed in the hope that it will be useful,
011: * but WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * Lesser General Public License for more details.
014: *
015: * You should have received a copy of the GNU Lesser General Public
016: * License along with this library; if not, write to the Free Software
017: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
018: */
019:
020: package jcifs.ntlmssp;
021:
022: import java.io.IOException;
023:
024: import java.net.UnknownHostException;
025:
026: import jcifs.netbios.NbtAddress;
027:
028: import jcifs.Config;
029:
030: /**
031: * Represents an NTLMSSP Type-1 message.
032: */
033: public class Type1Message extends NtlmMessage {
034:
035: private static final int DEFAULT_FLAGS;
036:
037: private static final String DEFAULT_DOMAIN;
038:
039: private static final String DEFAULT_WORKSTATION;
040:
041: private String suppliedDomain;
042:
043: private String suppliedWorkstation;
044:
045: static {
046: DEFAULT_FLAGS = NTLMSSP_NEGOTIATE_NTLM
047: | (Config.getBoolean("jcifs.smb.client.useUnicode",
048: true) ? NTLMSSP_NEGOTIATE_UNICODE
049: : NTLMSSP_NEGOTIATE_OEM);
050: DEFAULT_DOMAIN = Config.getProperty("jcifs.smb.client.domain",
051: null);
052: String defaultWorkstation = null;
053: try {
054: defaultWorkstation = NbtAddress.getLocalHost()
055: .getHostName();
056: } catch (UnknownHostException ex) {
057: }
058: DEFAULT_WORKSTATION = defaultWorkstation;
059: }
060:
061: /**
062: * Creates a Type-1 message using default values from the current
063: * environment.
064: */
065: public Type1Message() {
066: this (getDefaultFlags(), getDefaultDomain(),
067: getDefaultWorkstation());
068: }
069:
070: /**
071: * Creates a Type-1 message with the specified parameters.
072: *
073: * @param flags The flags to apply to this message.
074: * @param suppliedDomain The supplied authentication domain.
075: * @param suppliedWorkstation The supplied workstation name.
076: */
077: public Type1Message(int flags, String suppliedDomain,
078: String suppliedWorkstation) {
079: setFlags(flags);
080: setSuppliedDomain(suppliedDomain);
081: setSuppliedWorkstation(suppliedWorkstation);
082: }
083:
084: /**
085: * Creates a Type-1 message using the given raw Type-1 material.
086: *
087: * @param material The raw Type-1 material used to construct this message.
088: * @throws IOException If an error occurs while parsing the material.
089: */
090: public Type1Message(byte[] material) throws IOException {
091: parse(material);
092: }
093:
094: /**
095: * Returns the supplied authentication domain.
096: *
097: * @return A <code>String</code> containing the supplied domain.
098: */
099: public String getSuppliedDomain() {
100: return suppliedDomain;
101: }
102:
103: /**
104: * Sets the supplied authentication domain for this message.
105: *
106: * @param suppliedDomain The supplied domain for this message.
107: */
108: public void setSuppliedDomain(String suppliedDomain) {
109: this .suppliedDomain = suppliedDomain;
110: }
111:
112: /**
113: * Returns the supplied workstation name.
114: *
115: * @return A <code>String</code> containing the supplied workstation name.
116: */
117: public String getSuppliedWorkstation() {
118: return suppliedWorkstation;
119: }
120:
121: /**
122: * Sets the supplied workstation name for this message.
123: *
124: * @param suppliedWorkstation The supplied workstation for this message.
125: */
126: public void setSuppliedWorkstation(String suppliedWorkstation) {
127: this .suppliedWorkstation = suppliedWorkstation;
128: }
129:
130: public byte[] toByteArray() {
131: try {
132: String suppliedDomain = getSuppliedDomain();
133: String suppliedWorkstation = getSuppliedWorkstation();
134: int flags = getFlags();
135: boolean hostInfo = false;
136: byte[] domain = new byte[0];
137: if (suppliedDomain != null && suppliedDomain.length() != 0) {
138: hostInfo = true;
139: flags |= NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED;
140: domain = suppliedDomain.toUpperCase().getBytes(
141: getOEMEncoding());
142: } else {
143: flags &= (NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED ^ 0xffffffff);
144: }
145: byte[] workstation = new byte[0];
146: if (suppliedWorkstation != null
147: && suppliedWorkstation.length() != 0) {
148: hostInfo = true;
149: flags |= NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED;
150: workstation = suppliedWorkstation.toUpperCase()
151: .getBytes(getOEMEncoding());
152: } else {
153: flags &= (NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED ^ 0xffffffff);
154: }
155: byte[] type1 = new byte[hostInfo ? (32 + domain.length + workstation.length)
156: : 16];
157: System.arraycopy(NTLMSSP_SIGNATURE, 0, type1, 0, 8);
158: writeULong(type1, 8, 1);
159: writeULong(type1, 12, flags);
160: if (hostInfo) {
161: writeSecurityBuffer(type1, 16, 32, domain);
162: writeSecurityBuffer(type1, 24, 32 + domain.length,
163: workstation);
164: }
165: return type1;
166: } catch (IOException ex) {
167: throw new IllegalStateException(ex.getMessage());
168: }
169: }
170:
171: public String toString() {
172: String suppliedDomain = getSuppliedDomain();
173: String suppliedWorkstation = getSuppliedWorkstation();
174: int flags = getFlags();
175: StringBuffer buffer = new StringBuffer();
176: if (suppliedDomain != null) {
177: buffer.append("suppliedDomain: ").append(suppliedDomain);
178: }
179: if (suppliedWorkstation != null) {
180: if (buffer.length() > 0)
181: buffer.append("; ");
182: buffer.append("suppliedWorkstation: ").append(
183: suppliedWorkstation);
184: }
185: if (flags != 0) {
186: if (buffer.length() > 0)
187: buffer.append("; ");
188: buffer.append("flags: ");
189: buffer.append("0x");
190: buffer.append(Integer.toHexString((flags >> 28) & 0x0f));
191: buffer.append(Integer.toHexString((flags >> 24) & 0x0f));
192: buffer.append(Integer.toHexString((flags >> 20) & 0x0f));
193: buffer.append(Integer.toHexString((flags >> 16) & 0x0f));
194: buffer.append(Integer.toHexString((flags >> 12) & 0x0f));
195: buffer.append(Integer.toHexString((flags >> 8) & 0x0f));
196: buffer.append(Integer.toHexString((flags >> 4) & 0x0f));
197: buffer.append(Integer.toHexString(flags & 0x0f));
198: }
199: return buffer.toString();
200: }
201:
202: /**
203: * Returns the default flags for a generic Type-1 message in the
204: * current environment.
205: *
206: * @return An <code>int</code> containing the default flags.
207: */
208: public static int getDefaultFlags() {
209: return DEFAULT_FLAGS;
210: }
211:
212: /**
213: * Returns the default domain from the current environment.
214: *
215: * @return A <code>String</code> containing the default domain.
216: */
217: public static String getDefaultDomain() {
218: return DEFAULT_DOMAIN;
219: }
220:
221: /**
222: * Returns the default workstation from the current environment.
223: *
224: * @return A <code>String</code> containing the default workstation.
225: */
226: public static String getDefaultWorkstation() {
227: return DEFAULT_WORKSTATION;
228: }
229:
230: private void parse(byte[] material) throws IOException {
231: for (int i = 0; i < 8; i++) {
232: if (material[i] != NTLMSSP_SIGNATURE[i]) {
233: throw new IOException("Not an NTLMSSP message.");
234: }
235: }
236: if (readULong(material, 8) != 1) {
237: throw new IOException("Not a Type 1 message.");
238: }
239: int flags = readULong(material, 12);
240: String suppliedDomain = null;
241: if ((flags & NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED) != 0) {
242: byte[] domain = readSecurityBuffer(material, 16);
243: suppliedDomain = new String(domain, getOEMEncoding());
244: }
245: String suppliedWorkstation = null;
246: if ((flags & NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED) != 0) {
247: byte[] workstation = readSecurityBuffer(material, 24);
248: suppliedWorkstation = new String(workstation,
249: getOEMEncoding());
250: }
251: setFlags(flags);
252: setSuppliedDomain(suppliedDomain);
253: setSuppliedWorkstation(suppliedWorkstation);
254: }
255:
256: }
|