123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409 |
- /*
- * Copyright (C) 2006-2010 Alfresco Software Limited.
- *
- * This file is part of Alfresco
- *
- * Alfresco is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * Alfresco is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
- */
- package org.alfresco.jlan.client;
- import java.io.*;
- import org.alfresco.jlan.debug.Debug;
- import org.alfresco.jlan.netbios.NetworkSession;
- import org.alfresco.jlan.smb.Capability;
- import org.alfresco.jlan.smb.Dialect;
- import org.alfresco.jlan.smb.NTTime;
- import org.alfresco.jlan.smb.PCShare;
- import org.alfresco.jlan.smb.PacketType;
- import org.alfresco.jlan.smb.SMBDate;
- import org.alfresco.jlan.smb.SMBException;
- import org.alfresco.jlan.util.DataPacker;
- import org.alfresco.jlan.util.HexDump;
- /**
- * Authenticate Session Class
- *
- * <p>
- * Used for passthru authentication mechanisms.
- *
- * @author gkspencer
- */
- public class AuthenticateSession extends Session {
- /**
- * Class constructor
- *
- * @param shr PCShare
- * @param sess NetworkSession
- * @param dialect int
- * @param pkt SMBPacket
- */
- protected AuthenticateSession(PCShare shr, NetworkSession sess, int dialect, SMBPacket pkt) {
- super(shr, dialect, pkt);
- // Save the session and packet
- setSession(sess);
- // Extract the details from the negotiate response packet
- processNegotiateResponse();
- }
- /**
- * Perform a session setup to create a session on the remote server validating the user.
- *
- * @param userName String
- * @param ascPwd ASCII password hash
- * @param uniPwd Unicode password hash
- * @param vc Virtual circuit number
- */
- public final void doSessionSetup(String userName, byte[] ascPwd, byte[] uniPwd, int vc)
- throws IOException, SMBException {
- // Create a session setup packet
- SMBPacket pkt = new SMBPacket();
- pkt.setCommand(PacketType.SessionSetupAndX);
- // Check if the negotiated SMB dialect is NT LM 1.2 or an earlier dialect
- if ( getDialect() == Dialect.NT) {
- // NT LM 1.2 SMB dialect
- pkt.setParameterCount(13);
- pkt.setAndXCommand(0xFF); // no secondary command
- pkt.setParameter(1, 0); // offset to next command
- pkt.setParameter(2, SessionFactory.DefaultPacketSize());
- pkt.setParameter(3, getMaximumMultiplexedRequests());
- pkt.setParameter(4, vc); // virtual circuit number
- pkt.setParameterLong(5, 0); // session key
- // Set the share password length(s)
- pkt.setParameter(7, ascPwd != null ? ascPwd.length : 0); // ANSI password length
- pkt.setParameter(8, uniPwd != null ? uniPwd.length : 0); // Unicode password length
- pkt.setParameter(9, 0); // reserved, must be zero
- pkt.setParameter(10, 0); // reserved, must be zero
- // Send the client capabilities
- int caps = Capability.LargeFiles + Capability.Unicode + Capability.NTSMBs + Capability.NTStatus
- + Capability.RemoteAPIs;
- pkt.setParameterLong(11, caps);
- // Store the encrypted passwords
- //
- // Store the ASCII password hash, if specified
- int pos = pkt.getByteOffset();
- pkt.setPosition(pos);
- if ( ascPwd != null)
- pkt.packBytes(ascPwd, ascPwd.length);
- // Store the Unicode password hash, if specified
- if ( uniPwd != null)
- pkt.packBytes(uniPwd, uniPwd.length);
- // Pack the account/client details
- pkt.packString(userName, false);
- // Check if the share has a domain, if not then use the default domain string
- if ( getPCShare().hasDomain())
- pkt.packString(getPCShare().getDomain(), false);
- else
- pkt.packString(SessionFactory.getDefaultDomain(), false);
- pkt.packString("Java VM", false);
- pkt.packString("JLAN", false);
- // Set the packet length
- pkt.setByteCount(pkt.getPosition() - pos);
- }
- else {
- // Earlier SMB dialect
- pkt.setUserId(1);
- pkt.setParameterCount(10);
- pkt.setAndXCommand(0xFF); // no secondary command
- pkt.setParameter(1, 0); // offset to next command
- pkt.setParameter(2, SessionFactory.DefaultPacketSize());
- pkt.setParameter(3, 2); // max multiplexed pending requests
- pkt.setParameter(4, 0); // getSessionId ());
- pkt.setParameter(5, 0);
- pkt.setParameter(6, 0);
- pkt.setParameter(7, ascPwd != null ? ascPwd.length : 0);
- pkt.setParameter(8, 0);
- pkt.setParameter(9, 0);
- // Put the password into the SMB packet
- byte[] buf = pkt.getBuffer();
- int pos = pkt.getByteOffset();
- if ( ascPwd != null) {
- for (int i = 0; i < ascPwd.length; i++)
- buf[pos++] = ascPwd[i];
- }
- // Build the account/client details
- StringBuffer clbuf = new StringBuffer();
- clbuf.append(getPCShare().getUserName());
- clbuf.append((char) 0x00);
- // Check if the share has a domain, if not then use the unknown domain string
- if ( getPCShare().hasDomain())
- clbuf.append(getPCShare().getDomain());
- else
- clbuf.append(SessionFactory.getDefaultDomain());
- clbuf.append((char) 0x00);
- clbuf.append("Java VM");
- clbuf.append((char) 0x00);
- clbuf.append("JLAN");
- clbuf.append((char) 0x00);
- // Copy the remaining data to the SMB packet
- byte[] byts = clbuf.toString().getBytes();
- for (int i = 0; i < byts.length; i++)
- buf[pos++] = byts[i];
- int pwdLen = ascPwd != null ? ascPwd.length : 0;
- pkt.setByteCount(pwdLen + byts.length);
- }
- // Exchange an SMB session setup packet with the remote file server
- pkt.ExchangeSMB(this, pkt, true);
- // Save the session user id
- setUserId(pkt.getUserId());
- // Check if the session was created as a guest
- if ( pkt.getParameterCount() >= 3) {
- // Set the guest status for the session
- setGuest(pkt.getParameter(2) != 0 ? true : false);
- }
- // The response packet should also have the server OS, LAN Manager type
- // and primary domain name.
- if ( pkt.getByteCount() > 0) {
- // Get the packet buffer and byte offset
- byte[] buf = pkt.getBuffer();
- int offset = pkt.getByteOffset();
- int maxlen = offset + pkt.getByteCount();
- // Get the server OS
- String srvOS = DataPacker.getString(buf, offset, maxlen);
- setOperatingSystem(srvOS);
- offset += srvOS.length() + 1;
- maxlen -= srvOS.length() + 1;
- // Get the LAN Manager type
- String lanman = DataPacker.getString(buf, offset, maxlen);
- setLANManagerType(lanman);
- // Check if we have the primary domain for this session
- if ( getDomain() == null || getDomain().length() == 0) {
- // Get the domain name string
- offset += lanman.length() + 1;
- maxlen += lanman.length() + 1;
- String dom = DataPacker.getString(buf, offset, maxlen);
- setDomain(dom);
- }
- }
- // Check for a core protocol session, set the maximum packet size
- if ( getDialect() == Dialect.Core || getDialect() == Dialect.CorePlus) {
- // Set the maximum packet size to be used on this session
- setMaximumPacketSize(pkt.getParameter(2));
- }
- }
- /**
- * Process the negotiate response SMB packet
- *
- */
- private void processNegotiateResponse() {
- // Set the security mode flags
- int keyLen = 0;
- boolean unicodeStr = false;
- int encAlgorithm = PasswordEncryptor.LANMAN;
- int defFlags2 = 0;
- if ( getDialect() == Dialect.NT) {
- // Read the returned negotiate parameters, for NT dialect the parameters are not aligned
- m_pkt.resetParameterPointer();
- m_pkt.skipBytes(2); // skip the dialect index
- setSecurityMode(m_pkt.unpackByte());
- // Set the maximum virtual circuits and multiplxed requests allowed by the server
- setMaximumMultiplexedRequests(m_pkt.unpackWord());
- setMaximumVirtualCircuits(m_pkt.unpackWord());
- // Set the maximum buffer size
- setMaximumPacketSize(m_pkt.unpackInt());
- // Skip the maximum raw buffer size and session key
- m_pkt.skipBytes(8);
- // Set the server capabailities
- setCapabilities(m_pkt.unpackInt());
- // Get the server system time and timezone
- SMBDate srvTime = NTTime.toSMBDate(m_pkt.unpackLong());
- int tzone = m_pkt.unpackWord();
- // Get the encryption key length
- keyLen = m_pkt.unpackByte();
- // Indicate that strings are UniCode
- unicodeStr = true;
- // Use NTLMv1 password encryption
- encAlgorithm = PasswordEncryptor.NTLM1;
- // Set the default flags for subsequent SMB requests
- defFlags2 = SMBPacket.FLG2_LONGFILENAMES + SMBPacket.FLG2_UNICODE + SMBPacket.FLG2_LONGERRORCODE;
- }
- else if ( getDialect() > Dialect.CorePlus) {
- // Set the security mode and encrypted password mode
- int secMode = m_pkt.getParameter(1);
- setSecurityMode((secMode & 0x01) != 0 ? Session.SecurityModeUser : Session.SecurityModeShare);
- if ( m_pkt.getParameterCount() >= 11)
- keyLen = m_pkt.getParameter(11) & 0xFF; // should always be 8
- // Set the maximum virtual circuits and multiplxed requests allowed by the server
- setMaximumMultiplexedRequests(m_pkt.getParameter(3));
- setMaximumVirtualCircuits(m_pkt.getParameter(4));
- // Check if Unicode strings are being used
- if ( m_pkt.isUnicode())
- unicodeStr = true;
- // Set the default flags for subsequent SMB requests
- defFlags2 = SMBPacket.FLG2_LONGFILENAMES;
- }
- // Set the default packet flags for this session
- setDefaultFlags2(defFlags2);
- // Get the server details from the negotiate SMB packet
- if ( m_pkt.getByteCount() > 0) {
- // Get the returned byte area length and offset
- int bytsiz = m_pkt.getByteCount();
- int bytpos = m_pkt.getByteOffset();
- byte[] buf = m_pkt.getBuffer();
- // Extract the challenge response key, if specified
- if ( keyLen > 0) {
- // Allocate a buffer for the challenge response key
- byte[] encryptKey = new byte[keyLen];
- // Copy the challenge response key
- for (int keyIdx = 0; keyIdx < keyLen; keyIdx++)
- encryptKey[keyIdx] = buf[bytpos++];
- // Set the sessions encryption key
- setEncryptionKey(encryptKey);
- // DEBUG
- if ( Debug.EnableInfo && Session.hasDebugOption(Session.DBGDumpPacket)) {
- Debug.print("** Encryption Key: ");
- Debug.print(HexDump.hexString(encryptKey));
- Debug.println(", length = " + keyLen);
- }
- }
- // Extract the domain name
- String dom;
- if ( unicodeStr == false)
- dom = DataPacker.getString(buf, bytpos, bytsiz);
- else
- dom = DataPacker.getUnicodeString(buf, bytpos, bytsiz / 2);
- setDomain(dom);
- // DEBUG
- if ( Debug.EnableInfo && Session.hasDebugOption(Session.DBGDumpPacket))
- Debug.println("** Server domain : " + getDomain() + ".");
- }
- }
- }
|