KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > server > auth > passthru > AuthenticateSession


1 /*
2  * Copyright (C) 2006 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.filesys.server.auth.passthru;
18
19 import java.io.IOException JavaDoc;
20
21 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol;
22 import org.alfresco.filesys.server.auth.PasswordEncryptor;
23 import org.alfresco.filesys.server.auth.ntlm.NTLM;
24 import org.alfresco.filesys.server.auth.ntlm.Type1NTLMMessage;
25 import org.alfresco.filesys.server.auth.ntlm.Type2NTLMMessage;
26 import org.alfresco.filesys.server.auth.ntlm.Type3NTLMMessage;
27 import org.alfresco.filesys.smb.Capability;
28 import org.alfresco.filesys.smb.Dialect;
29 import org.alfresco.filesys.smb.NTTime;
30 import org.alfresco.filesys.smb.NetworkSession;
31 import org.alfresco.filesys.smb.PCShare;
32 import org.alfresco.filesys.smb.PacketType;
33 import org.alfresco.filesys.smb.SMBDate;
34 import org.alfresco.filesys.smb.SMBException;
35 import org.alfresco.filesys.smb.SMBStatus;
36 import org.alfresco.filesys.util.DataPacker;
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39
40 /**
41  * Authenticate Session Class
42  * <p>
43  * Used for passthru authentication mechanisms.
44  */

45 public class AuthenticateSession
46 {
47
48     // Debug logging
49

50     private static final Log logger = LogFactory.getLog("org.alfresco.smb.protocol.auth");
51
52     // Default packet size
53

54     private static final int DefaultPacketSize = 1024;
55
56     // Session security mode
57

58     public static final int SecurityModeUser = 1;
59     public static final int SecurityModeShare = 2;
60
61     // Tree identifier that indicates that the disk session has been closed
62

63     protected final static int Closed = -1;
64
65     // Default SMB packet size to allocate
66

67     public static final int DEFAULT_BUFSIZE = 4096;
68
69     // SMB dialect id and string for this session
70

71     private int m_dialect;
72     private String JavaDoc m_diaStr;
73
74     // Network session
75

76     private NetworkSession m_netSession;
77
78     // SMB packet for protocol exhanges
79

80     protected SMBPacket m_pkt;
81
82     // Default packet flags
83

84     private int m_defFlags = SMBPacket.FLG_CASELESS;
85     private int m_defFlags2 = SMBPacket.FLG2_LONGFILENAMES;
86
87     // Server connection details
88

89     private PCShare m_remoteShr;
90
91     // Domain name
92

93     private String JavaDoc m_domain;
94
95     // Remote operating system and LAN manager type
96

97     private String JavaDoc m_srvOS;
98     private String JavaDoc m_srvLM;
99
100     // Security mode (user or share)
101

102     private int m_secMode;
103
104     // Challenge encryption key
105

106     private byte[] m_encryptKey;
107
108     // SMB session information
109

110     private int m_sessIdx;
111     private int m_userId;
112     private int m_processId;
113
114     // Tree identifier for this connection
115

116     protected int m_treeid;
117
118     // Device type that this session is connected to
119

120     private int m_devtype;
121
122     // Maximum transmit buffer size allowed
123

124     private int m_maxPktSize;
125
126     // Session capabilities
127

128     private int m_sessCaps;
129
130     // Maximum virtual circuits allowed on this session, and maximum multiplxed read/writes
131

132     private int m_maxVCs;
133     private int m_maxMPX;
134
135     // Indicate if the session was created as a guest rather than using the supplied
136
// username/password
137

138     private boolean m_guest;
139
140     // Flag to indicate extended security exchange is being used
141

142     private boolean m_extendedSec;
143     
144     // Server GUID, if using extended security
145

146     private byte[] m_serverGUID;
147     
148     // Type 2 security blob from the server
149

150     private Type2NTLMMessage m_type2Msg;
151     
152     // Global session id
153

154     private static int m_sessionIdx = 1;
155
156     // Multiplex id
157

158     private static int m_multiplexId = 1;
159
160     /**
161      * Class constructor
162      *
163      * @param shr PCShare
164      * @param sess NetworkSession
165      * @param dialect int
166      * @param pkt SMBPacket
167      * @exception IOException If a network error occurs
168      * @eception SMBException If a CIFS error occurs
169      */

170     protected AuthenticateSession(PCShare shr, NetworkSession sess, int dialect, SMBPacket pkt) throws IOException JavaDoc, SMBException
171     {
172
173         // Set the SMB dialect for this session
174

175         m_dialect = dialect;
176
177         // Save the remote share details
178

179         m_remoteShr = shr;
180
181         // Allocate a unique session index
182

183         m_sessIdx = getNextSessionId();
184
185         // Allocate an SMB protocol packet
186

187         m_pkt = pkt;
188         if (pkt == null)
189             m_pkt = new SMBPacket(DEFAULT_BUFSIZE);
190
191         // Save the session and packet
192

193         setSession(sess);
194
195         // Extract the details from the negotiate response packet
196

197         processNegotiateResponse();
198     }
199
200     /**
201      * Allocate an SMB packet for this session. The preferred packet size is specified, if a smaller
202      * buffer size has been negotiated a smaller SMB packet will be returned.
203      *
204      * @param pref Preferred SMB packet size
205      * @return Allocated SMB packet
206      */

207     protected final SMBPacket allocatePacket(int pref)
208     {
209
210         // Check if the preferred size is larger than the maximum allowed packet
211
// size for this session.
212

213         if (pref > m_maxPktSize)
214             return new SMBPacket(m_maxPktSize + RFCNetBIOSProtocol.HEADER_LEN);
215
216         // Return the preferred SMB packet size
217

218         return new SMBPacket(pref + RFCNetBIOSProtocol.HEADER_LEN);
219     }
220
221     /**
222      * Determine if the session supports extended security
223      *
224      * @return true if this session supports extended security, else false
225      */

226     public final boolean supportsExtendedSecurity()
227     {
228         return (m_sessCaps & Capability.ExtendedSecurity) != 0 ? true : false;
229     }
230     
231     /**
232      * Determine if the session supports raw mode read/writes
233      *
234      * @return true if this session supports raw mode, else false
235      */

236     public final boolean supportsRawMode()
237     {
238         return (m_sessCaps & Capability.RawMode) != 0 ? true : false;
239     }
240
241     /**
242      * Determine if the session supports Unicode
243      *
244      * @return boolean
245      */

246     public final boolean supportsUnicode()
247     {
248         return (m_sessCaps & Capability.Unicode) != 0 ? true : false;
249     }
250
251     /**
252      * Determine if the session supports large files (ie. 64 bit file offsets)
253      *
254      * @return boolean
255      */

256     public final boolean supportsLargeFiles()
257     {
258         return (m_sessCaps & Capability.LargeFiles) != 0 ? true : false;
259     }
260
261     /**
262      * Determine if the session supports NT specific SMBs
263      *
264      * @return boolean
265      */

266     public final boolean supportsNTSmbs()
267     {
268         return (m_sessCaps & Capability.NTSMBs) != 0 ? true : false;
269     }
270
271     /**
272      * Determine if the session supports RPC API requests
273      *
274      * @return boolean
275      */

276     public final boolean supportsRPCAPIs()
277     {
278         return (m_sessCaps & Capability.RemoteAPIs) != 0 ? true : false;
279     }
280
281     /**
282      * Determine if the session supports NT status codes
283      *
284      * @return boolean
285      */

286     public final boolean supportsNTStatusCodes()
287     {
288         return (m_sessCaps & Capability.NTStatus) != 0 ? true : false;
289     }
290
291     /**
292      * Determine if the session supports level 2 oplocks
293      *
294      * @return boolean
295      */

296     public final boolean supportsLevel2Oplocks()
297     {
298         return (m_sessCaps & Capability.Level2Oplocks) != 0 ? true : false;
299     }
300
301     /**
302      * Determine if the session supports lock and read
303      *
304      * @return boolean
305      */

306     public final boolean supportsLockAndRead()
307     {
308         return (m_sessCaps & Capability.LockAndRead) != 0 ? true : false;
309     }
310
311     /**
312      * Determine if the session supports NT find
313      *
314      * @return boolean
315      */

316     public final boolean supportsNTFind()
317     {
318         return (m_sessCaps & Capability.NTFind) != 0 ? true : false;
319     }
320
321     /**
322      * Close this connection with the remote server.
323      *
324      * @exception java.io.IOException If an I/O error occurs.
325      * @exception SMBException If an SMB level error occurs
326      */

327     public void CloseSession() throws java.io.IOException JavaDoc, SMBException
328     {
329
330         // If the session is valid then hangup the session
331

332         if (isActive())
333         {
334
335             // Close the network session
336

337             m_netSession.Close();
338
339             // Clear the session
340

341             m_netSession = null;
342         }
343     }
344
345     /**
346      * Return the default flags settings for this session
347      *
348      * @return int
349      */

350     public final int getDefaultFlags()
351     {
352         return m_defFlags;
353     }
354
355     /**
356      * Return the default flags2 settings for this session
357      *
358      * @return int
359      */

360     public final int getDefaultFlags2()
361     {
362         return m_defFlags2;
363     }
364
365     /**
366      * Get the device type that this session is connected to.
367      *
368      * @return Device type for this session.
369      */

370     public final int getDeviceType()
371     {
372         return m_devtype;
373     }
374
375     /**
376      * Get the SMB dialect property
377      *
378      * @return SMB dialect that this session has negotiated.
379      */

380     public final int getDialect()
381     {
382         return m_dialect;
383     }
384
385     /**
386      * Get the SMB dialect string
387      *
388      * @return SMB dialect string for this session.
389      */

390     public final String JavaDoc getDialectString()
391     {
392         return m_diaStr;
393     }
394
395     /**
396      * Get the servers primary domain name
397      *
398      * @return Servers primary domain name, if knwon, else null.
399      */

400     public final String JavaDoc getDomain()
401     {
402         return m_domain;
403     }
404
405     /**
406      * Determine if there is a challenge encryption key
407      *
408      * @return boolean
409      */

410     public final boolean hasEncryptionKey()
411     {
412         return m_encryptKey != null ? true : false;
413     }
414
415     /**
416      * Return the cahllenge encryption key
417      *
418      * @return byte[]
419      */

420     public final byte[] getEncryptionKey()
421     {
422         return m_encryptKey;
423     }
424
425     /**
426      * Get the servers LAN manager type
427      *
428      * @return Servers LAN manager type, if known, else null.
429      */

430     public final String JavaDoc getLANManagerType()
431     {
432         return m_srvLM;
433     }
434
435     /**
436      * Get the maximum number of multiplxed requests that are allowed
437      *
438      * @return int
439      */

440     public final int getMaximumMultiplexedRequests()
441     {
442         return m_maxMPX;
443     }
444
445     /**
446      * Get the maximum packet size allowed for this session
447      *
448      * @return Maximum packet size, in bytes.
449      */

450     public final int getMaximumPacketSize()
451     {
452         return m_maxPktSize;
453     }
454
455     /**
456      * Get the maximum virtual circuits allowed on this session
457      *
458      * @return int
459      */

460     public final int getMaximumVirtualCircuits()
461     {
462         return m_maxVCs;
463     }
464
465     /**
466      * Get the next multiplex id to uniquely identify a transaction
467      *
468      * @return Unique multiplex id for a transaction
469      */

470     public final synchronized int getNextMultiplexId()
471     {
472         return m_multiplexId++;
473     }
474
475     /**
476      * Get the next session id
477      *
478      * @return int
479      */

480     protected final synchronized int getNextSessionId()
481     {
482         return m_sessionIdx++;
483     }
484
485     /**
486      * Get the servers operating system type
487      *
488      * @return Servers operating system, if known, else null.
489      */

490     public final String JavaDoc getOperatingSystem()
491     {
492         return m_srvOS;
493     }
494
495     /**
496      * Get the remote share password string
497      *
498      * @return Remote share password string
499      */

500     public final String JavaDoc getPassword()
501     {
502         return m_remoteShr.getPassword();
503     }
504
505     /**
506      * Get the remote share details for this session
507      *
508      * @return PCShare information for this session
509      */

510     public final PCShare getPCShare()
511     {
512         return m_remoteShr;
513     }
514
515     /**
516      * Return the security mode of the session (user or share)
517      *
518      * @return int
519      */

520     public final int getSecurityMode()
521     {
522         return m_secMode;
523     }
524
525     /**
526      * Get the remote server name
527      *
528      * @return Remote server name
529      */

530     public final String JavaDoc getServer()
531     {
532         return m_remoteShr.getNodeName();
533     }
534
535     /**
536      * Access the associated network session
537      *
538      * @return NetworkSession that the SMB session is using
539      */

540     public final NetworkSession getSession()
541     {
542         return m_netSession;
543     }
544
545     /**
546      * Determine if the session has an associated type2 NTLM security blob
547      *
548      * @return boolean
549      */

550     public final boolean hasType2NTLMMessage()
551     {
552         return m_type2Msg != null ? true : false;
553     }
554     
555     /**
556      * Return the type2 NTLM security blob that was received from the authentication server
557      *
558      * @return Type2NTLMMessage
559      */

560     public final Type2NTLMMessage getType2NTLMMessage()
561     {
562         return m_type2Msg;
563     }
564     
565     /**
566      * Return the session capability flags.
567      *
568      * @return int
569      */

570     public final int getCapabilities()
571     {
572         return m_sessCaps;
573     }
574
575     /**
576      * Get the process id for this session
577      *
578      * @return int
579      */

580     public final int getProcessId()
581     {
582         return m_processId;
583     }
584
585     /**
586      * Get the session identifier property
587      *
588      * @return Session identifier
589      */

590     public final int getSessionId()
591     {
592         return m_sessIdx;
593     }
594
595     /**
596      * Get the remote share name
597      *
598      * @return Remote share name string
599      */

600     public final String JavaDoc getShareName()
601     {
602         return m_remoteShr.getShareName();
603     }
604
605     /**
606      * Get the connected tree identifier.
607      *
608      * @return Tree identifier.
609      */

610     public final int getTreeId()
611     {
612         return m_treeid;
613     }
614
615     /**
616      * Return the assigned use id for this SMB session
617      *
618      * @return Assigned user id
619      */

620     public final int getUserId()
621     {
622         return m_userId;
623     }
624
625     /**
626      * Get the remote share user name string
627      *
628      * @return Remote share user name string
629      */

630     public final String JavaDoc getUserName()
631     {
632         return m_remoteShr.getUserName();
633     }
634
635     /**
636      * Check if there is data available in the network receive buffer
637      *
638      * @return boolean
639      * @exception IOException
640      */

641     public final boolean hasDataAvailable() throws IOException JavaDoc
642     {
643         return m_netSession.hasData();
644     }
645
646     /**
647      * Determine if the session is valid, ie. still open.
648      *
649      * @return true if the session is still active, else false.
650      */

651     public final boolean isActive()
652     {
653         return (m_netSession == null) ? false : true;
654     }
655
656     /**
657      * Determine if the session has been created as a guest logon
658      *
659      * @return boolean
660      */

661     public final boolean isGuest()
662     {
663         return m_guest;
664     }
665
666     /**
667      * Determine if the Unicode flag is enabled
668      *
669      * @return boolean
670      */

671     public final boolean isUnicode()
672     {
673         return (m_defFlags2 & SMBPacket.FLG2_UNICODE) != 0 ? true : false;
674     }
675
676     /**
677      * Determine if extended security exchanges are being used
678      *
679      * @return boolean
680      */

681     public final boolean isUsingExtendedSecurity()
682     {
683         return m_extendedSec;
684     }
685     
686     /**
687      * Send a single echo request to the server
688      *
689      * @throws java.io.IOException
690      * @throws SMBException
691      */

692     public final void pingServer() throws java.io.IOException JavaDoc, SMBException
693     {
694
695         // Send a single echo request to the server
696

697         pingServer(1);
698     }
699
700     /**
701      * Send an echo request to the server
702      *
703      * @param cnt Number of packets to echo from the remote server
704      * @exception java.io.IOException If an I/O error occurs
705      * @exception SMBException SMB error occurred
706      */

707     public final void pingServer(int cnt) throws java.io.IOException JavaDoc, SMBException
708     {
709
710         // Build a server ping SMB packet
711

712         m_pkt.setCommand(PacketType.Echo);
713         m_pkt.setFlags(0);
714         m_pkt.setTreeId(getTreeId());
715         m_pkt.setUserId(getUserId());
716         m_pkt.setProcessId(getProcessId());
717         m_pkt.setMultiplexId(1);
718
719         // Set the parameter words
720

721         m_pkt.setParameterCount(1);
722         m_pkt.setParameter(0, cnt); // number of packets that the server should return
723
String JavaDoc echoStr = "ECHO";
724         m_pkt.setBytes(echoStr.getBytes());
725
726         // Send the echo request
727

728         m_pkt.SendSMB(this);
729
730         // Receive the reply packets, if any
731

732         while (cnt > 0)
733         {
734
735             // Receive a reply packet
736

737             m_pkt.ReceiveSMB(this);
738
739             // Decrement the reply counter
740

741             cnt--;
742         }
743     }
744
745     /**
746      * Set the default SMB packet flags for this session
747      *
748      * @param flg int
749      */

750     protected final void setDefaultFlags(int flg)
751     {
752         m_defFlags = flg;
753     }
754
755     /**
756      * Set the SMB packet default flags2 for this session
757      *
758      * @param flg2 int
759      */

760     protected final void setDefaultFlags2(int flg2)
761     {
762         m_defFlags2 = flg2;
763     }
764
765     /**
766      * Set the device type for this session.
767      *
768      * @param dev Device type for this session.
769      */

770     protected final void setDeviceType(int dev)
771     {
772         m_devtype = dev;
773     }
774
775     /**
776      * Set the dialect for this session
777      *
778      * @param dia SMB dialect that this session is using.
779      */

780     protected final void setDialect(int dia)
781     {
782         m_dialect = dia;
783     }
784
785     /**
786      * Set the dialect string for this session
787      *
788      * @param dia SMB dialect string
789      */

790     protected final void setDialectString(String JavaDoc dia)
791     {
792         m_diaStr = dia;
793     }
794
795     /**
796      * Set the remote servers primary domain name
797      *
798      * @param dom Servers primary domain name.
799      */

800     protected final void setDomain(String JavaDoc dom)
801     {
802         m_domain = dom;
803     }
804
805     /**
806      * Set the encryption key
807      *
808      * @param key byte[]
809      */

810     public final void setEncryptionKey(byte[] key)
811     {
812
813         // Set the challenge response encryption key
814

815         m_encryptKey = key;
816     }
817
818     /**
819      * Set the guest status for the session
820      *
821      * @param sts boolean
822      */

823     protected final void setGuest(boolean sts)
824     {
825         m_guest = sts;
826     }
827
828     /**
829      * Set the remote servers LAN manager type
830      *
831      * @param lm Servers LAN manager type string.
832      */

833     protected final void setLANManagerType(String JavaDoc lm)
834     {
835         m_srvLM = lm;
836     }
837
838     /**
839      * Set the maximum number of multiplexed requests allowed
840      *
841      * @param maxMulti int
842      */

843     protected final void setMaximumMultiplexedRequests(int maxMulti)
844     {
845         m_maxMPX = maxMulti;
846     }
847
848     /**
849      * Set the maximum packet size allowed on this session
850      *
851      * @param siz Maximum allowed packet size.
852      */

853     protected final void setMaximumPacketSize(int siz)
854     {
855         m_maxPktSize = siz;
856     }
857
858     /**
859      * Set the maximum number of virtual circuits allowed on this session
860      *
861      * @param maxVC int
862      */

863     protected final void setMaximumVirtualCircuits(int maxVC)
864     {
865         m_maxVCs = maxVC;
866     }
867
868     /**
869      * Set the remote servers operating system type
870      *
871      * @param os Servers operating system type string.
872      */

873     protected final void setOperatingSystem(String JavaDoc os)
874     {
875         m_srvOS = os;
876     }
877
878     /**
879      * Set the remote share password
880      *
881      * @param pwd Remtoe share password string.
882      */

883     protected final void setPassword(String JavaDoc pwd)
884     {
885         m_remoteShr.setPassword(pwd);
886     }
887
888     /**
889      * Set the session security mode (user or share)
890      *
891      * @param secMode int
892      */

893     public final void setSecurityMode(int secMode)
894     {
895         m_secMode = secMode;
896     }
897
898     /**
899      * Set the remote server name
900      *
901      * @param srv Server name string
902      */

903     protected final void setServer(String JavaDoc srv)
904     {
905         m_remoteShr.setNodeName(srv);
906     }
907
908     /**
909      * Set the network session that this SMB session is associated with
910      *
911      * @param netSess Network session that this SMB session is to be associated with.
912      */

913     protected final void setSession(NetworkSession netSess)
914     {
915         m_netSession = netSess;
916     }
917
918     /**
919      * Set the session capability flags
920      *
921      * @param flg Capability flags.
922      */

923     protected final void setCapabilities(int caps)
924     {
925         m_sessCaps = caps;
926     }
927
928     /**
929      * Set the remote share name
930      *
931      * @param shr Remote share name string
932      */

933     protected final void setShareName(String JavaDoc shr)
934     {
935         m_remoteShr.setShareName(shr);
936     }
937
938     /**
939      * Set the process id for this session
940      *
941      * @param id
942      */

943     protected final void setProcessId(int id)
944     {
945         m_processId = id;
946     }
947
948     /**
949      * Set the connected tree identifier for this session.
950      *
951      * @param id Tree identifier for this session.
952      */

953     protected final void setTreeId(int id)
954     {
955         m_treeid = id;
956     }
957
958     /**
959      * Set the user identifier for this session
960      *
961      * @param uid User identifier
962      */

963     protected final void setUserId(int uid)
964     {
965         m_userId = uid;
966     }
967
968     /**
969      * Set the remote share user name
970      *
971      * @param user Remote share user name string
972      */

973     protected final void setUserName(String JavaDoc user)
974     {
975         m_remoteShr.setUserName(user);
976     }
977
978     /**
979      * Output the session details as a string
980      *
981      * @return Session details string
982      */

983     public String JavaDoc toString()
984     {
985         StringBuffer JavaDoc str = new StringBuffer JavaDoc();
986
987         str.append("[\\\\");
988         str.append(getServer());
989         str.append("\\");
990         str.append(getShareName());
991         str.append(":");
992         str.append(Dialect.DialectTypeString(m_dialect));
993         str.append(",UserId=");
994         str.append(getUserId());
995         str.append("]");
996
997         return str.toString();
998     }
999
1000    /**
1001     * Perform a session setup to create a session on the remote server validating the user.
1002     *
1003     * @param userName String
1004     * @param ascPwd ASCII password hash
1005     * @param uniPwd Unicode password hash
1006     * @exception IOException If a network error occurs
1007     * @exception SMBException If a CIFS error occurs
1008     */

1009    public final void doSessionSetup(String JavaDoc userName, byte[] ascPwd, byte[] uniPwd) throws IOException JavaDoc, SMBException
1010    {
1011        doSessionSetup(null, userName, null, ascPwd, uniPwd);
1012    }
1013    
1014    /**
1015     * Perform a session using the type3 NTLM response received from the client
1016     *
1017     * @param type3 Type3NTLMMessage
1018     * @exception IOException If a network error occurs
1019     * @exception SMBException If a CIFS error occurs
1020     */

1021    public final void doSessionSetup(Type3NTLMMessage type3Msg) throws IOException JavaDoc, SMBException
1022    {
1023        doSessionSetup(type3Msg.getDomain(), type3Msg.getUserName(), type3Msg.getWorkstation(),
1024                type3Msg.getLMHash(), type3Msg.getNTLMHash());
1025    }
1026    
1027    /**
1028     * Perform a session setup to create a session on the remote server validating the user.
1029     *
1030     * @param domain String
1031     * @param userName String
1032     * @param wksName String
1033     * @param ascPwd ASCII password hash
1034     * @param uniPwd Unicode password hash
1035     * @exception IOException If a network error occurs
1036     * @exception SMBException If a CIFS error occurs
1037     */

1038    public final void doSessionSetup(String JavaDoc domain, String JavaDoc userName, String JavaDoc wksName,
1039            byte[] ascPwd, byte[] uniPwd) throws IOException JavaDoc, SMBException
1040    {
1041        // Check if we are using extended security
1042

1043        if ( isUsingExtendedSecurity())
1044        {
1045            // Run the second phase of the extended security session setup
1046

1047            doExtendedSessionSetupPhase2(domain, userName, wksName, ascPwd, uniPwd);
1048            return;
1049        }
1050        
1051        // Create a session setup packet
1052

1053        SMBPacket pkt = new SMBPacket();
1054
1055        pkt.setCommand(PacketType.SessionSetupAndX);
1056
1057        // Check if the negotiated SMB dialect is NT LM 1.2 or an earlier dialect
1058

1059        if (getDialect() == Dialect.NT)
1060        {
1061
1062            // NT LM 1.2 SMB dialect
1063

1064            pkt.setParameterCount(13);
1065            pkt.setAndXCommand(0xFF); // no secondary command
1066
pkt.setParameter(1, 0); // offset to next command
1067
pkt.setParameter(2, DefaultPacketSize);
1068            pkt.setParameter(3, 1);
1069            pkt.setParameter(4, 0); // virtual circuit number
1070
pkt.setParameterLong(5, 0); // session key
1071

1072            // Set the share password length(s)
1073

1074            pkt.setParameter(7, ascPwd != null ? ascPwd.length : 0); // ANSI password length
1075
pkt.setParameter(8, uniPwd != null ? uniPwd.length : 0); // Unicode password length
1076

1077            pkt.setParameter(9, 0); // reserved, must be zero
1078
pkt.setParameter(10, 0); // reserved, must be zero
1079

1080            // Send the client capabilities
1081

1082            int caps = Capability.LargeFiles + Capability.Unicode + Capability.NTSMBs + Capability.NTStatus
1083                    + Capability.RemoteAPIs;
1084            
1085            // Set the client capabilities
1086

1087            pkt.setParameterLong(11, caps);
1088
1089            // Get the offset to the session setup request byte data
1090

1091            int pos = pkt.getByteOffset();
1092            pkt.setPosition(pos);
1093
1094            // Store the ASCII password hash, if specified
1095

1096            if (ascPwd != null)
1097                pkt.packBytes(ascPwd, ascPwd.length);
1098
1099            // Store the Unicode password hash, if specified
1100

1101            if (uniPwd != null)
1102                pkt.packBytes(uniPwd, uniPwd.length);
1103
1104            // Pack the account/client details
1105

1106            pkt.packString(userName, false);
1107
1108            // Check if the share has a domain, if not then use the default domain string
1109

1110            if (getPCShare().hasDomain())
1111                pkt.packString(getPCShare().getDomain(), false);
1112            else
1113                pkt.packString("?", false);
1114
1115            pkt.packString("Java VM", false);
1116            pkt.packString("JLAN", false);
1117            
1118            // Set the packet length
1119

1120            pkt.setByteCount(pkt.getPosition() - pos);
1121        }
1122        else
1123        {
1124
1125            // Earlier SMB dialect
1126

1127            pkt.setUserId(1);
1128
1129            pkt.setParameterCount(10);
1130            pkt.setAndXCommand(0xFF);
1131            pkt.setParameter(1, 0);
1132            pkt.setParameter(2, DefaultPacketSize);
1133            pkt.setParameter(3, 1);
1134            pkt.setParameter(4, 0);
1135            pkt.setParameter(5, 0);
1136            pkt.setParameter(6, 0);
1137            pkt.setParameter(7, ascPwd != null ? ascPwd.length : 0);
1138            pkt.setParameter(8, 0);
1139            pkt.setParameter(9, 0);
1140
1141            // Put the password into the SMB packet
1142

1143            byte[] buf = pkt.getBuffer();
1144            int pos = pkt.getByteOffset();
1145
1146            if (ascPwd != null)
1147            {
1148                for (int i = 0; i < ascPwd.length; i++)
1149                    buf[pos++] = ascPwd[i];
1150            }
1151
1152            // Build the account/client details
1153

1154            StringBuffer JavaDoc clbuf = new StringBuffer JavaDoc();
1155
1156            clbuf.append(getPCShare().getUserName());
1157            clbuf.append((char) 0x00);
1158
1159            // Check if the share has a domain, if not then use the unknown domain string
1160

1161            if (getPCShare().hasDomain())
1162                clbuf.append(getPCShare().getDomain());
1163            else
1164                clbuf.append("?");
1165            clbuf.append((char) 0x00);
1166
1167            clbuf.append("Java VM");
1168            clbuf.append((char) 0x00);
1169
1170            clbuf.append("JLAN");
1171            clbuf.append((char) 0x00);
1172
1173            // Copy the remaining data to the SMB packet
1174

1175            byte[] byts = clbuf.toString().getBytes();
1176            for (int i = 0; i < byts.length; i++)
1177                buf[pos++] = byts[i];
1178
1179            int pwdLen = ascPwd != null ? ascPwd.length : 0;
1180            pkt.setByteCount(pwdLen + byts.length);
1181        }
1182
1183        // Exchange an SMB session setup packet with the remote file server
1184

1185        pkt.ExchangeSMB(this, pkt, true);
1186
1187        // Save the session user id
1188

1189        setUserId(pkt.getUserId());
1190
1191        // Check if the session was created as a guest
1192

1193        if (pkt.getParameterCount() >= 3)
1194        {
1195
1196            // Set the guest status for the session
1197

1198            setGuest(pkt.getParameter(2) != 0 ? true : false);
1199        }
1200
1201        // The response packet should also have the server OS, LAN Manager type
1202
// and primary domain name.
1203

1204        if (pkt.getByteCount() > 0)
1205        {
1206
1207            // Get the packet buffer and byte offset
1208

1209            byte[] buf = pkt.getBuffer();
1210            int offset = pkt.getByteOffset();
1211            int maxlen = offset + pkt.getByteCount();
1212
1213            // Get the server OS
1214

1215            String JavaDoc srvOS = DataPacker.getString(buf, offset, maxlen);
1216            setOperatingSystem(srvOS);
1217
1218            offset += srvOS.length() + 1;
1219            maxlen -= srvOS.length() + 1;
1220
1221            // Get the LAN Manager type
1222

1223            String JavaDoc lanman = DataPacker.getString(buf, offset, maxlen);
1224            setLANManagerType(lanman);
1225
1226            // Check if we have the primary domain for this session
1227

1228            if (getDomain() == null || getDomain().length() == 0)
1229            {
1230
1231                // Get the domain name string
1232

1233                offset += lanman.length() + 1;
1234                maxlen += lanman.length() + 1;
1235
1236                String JavaDoc dom = DataPacker.getString(buf, offset, maxlen);
1237                setDomain(dom);
1238            }
1239        }
1240
1241        // Check for a core protocol session, set the maximum packet size
1242

1243        if (getDialect() == Dialect.Core || getDialect() == Dialect.CorePlus)
1244        {
1245
1246            // Set the maximum packet size to be used on this session
1247

1248            setMaximumPacketSize(pkt.getParameter(2));
1249        }
1250    }
1251
1252    /**
1253     * Process the negotiate response SMB packet
1254     *
1255     * @exception IOException If a network error occurs
1256     * @eception SMBException If a CIFS error occurs
1257     */

1258    private void processNegotiateResponse() throws IOException JavaDoc, SMBException
1259    {
1260
1261        // Set the security mode flags
1262

1263        int keyLen = 0;
1264        boolean unicodeStr = false;
1265        int encAlgorithm = PasswordEncryptor.LANMAN;
1266        int defFlags2 = 0;
1267
1268        if (getDialect() == Dialect.NT)
1269        {
1270
1271            // Read the returned negotiate parameters, for NT dialect the parameters are not aligned
1272

1273            m_pkt.resetParameterPointer();
1274            m_pkt.skipBytes(2); // skip the dialect index
1275

1276            setSecurityMode(m_pkt.unpackByte());
1277
1278            // Set the maximum virtual circuits and multiplxed requests allowed by the server
1279

1280            setMaximumMultiplexedRequests(m_pkt.unpackWord());
1281            setMaximumVirtualCircuits(m_pkt.unpackWord());
1282
1283            // Set the maximum buffer size
1284

1285            setMaximumPacketSize(m_pkt.unpackInt());
1286
1287            // Skip the maximum raw buffer size and session key
1288

1289            m_pkt.skipBytes(8);
1290
1291            // Set the server capabailities
1292

1293            setCapabilities(m_pkt.unpackInt());
1294            
1295            // Check if extended security is enabled
1296

1297            if ( supportsExtendedSecurity())
1298                m_extendedSec = true;
1299
1300            // Get the server system time and timezone
1301

1302            SMBDate srvTime = NTTime.toSMBDate(m_pkt.unpackLong());
1303            int tzone = m_pkt.unpackWord();
1304
1305            // Get the encryption key length
1306

1307            keyLen = m_pkt.unpackByte();
1308
1309            // Indicate that strings are UniCode
1310

1311            unicodeStr = true;
1312
1313            // Use NTLMv1 password encryption
1314

1315            encAlgorithm = PasswordEncryptor.NTLM1;
1316
1317            // Set the default flags for subsequent SMB requests
1318

1319            defFlags2 = SMBPacket.FLG2_LONGFILENAMES + SMBPacket.FLG2_UNICODE + SMBPacket.FLG2_LONGERRORCODE;
1320            
1321            if ( isUsingExtendedSecurity())
1322                defFlags2 += SMBPacket.FLG2_EXTENDEDSECURITY;
1323        }
1324        else if (getDialect() > Dialect.CorePlus)
1325        {
1326
1327            // Set the security mode and encrypted password mode
1328

1329            int secMode = m_pkt.getParameter(1);
1330            setSecurityMode((secMode & 0x01) != 0 ? SecurityModeUser : SecurityModeShare);
1331
1332            if (m_pkt.getParameterCount() >= 11)
1333                keyLen = m_pkt.getParameter(11) & 0xFF; // should always be 8
1334

1335            // Set the maximum virtual circuits and multiplxed requests allowed by the server
1336

1337            setMaximumMultiplexedRequests(m_pkt.getParameter(3));
1338            setMaximumVirtualCircuits(m_pkt.getParameter(4));
1339
1340            // Check if Unicode strings are being used
1341

1342            if (m_pkt.isUnicode())
1343                unicodeStr = true;
1344
1345            // Set the default flags for subsequent SMB requests
1346

1347            defFlags2 = SMBPacket.FLG2_LONGFILENAMES;
1348        }
1349
1350        // Set the default packet flags for this session
1351

1352        setDefaultFlags2(defFlags2);
1353
1354        // Get the server details from the negotiate SMB packet
1355

1356        if (m_pkt.getByteCount() > 0)
1357        {
1358
1359            // Get the returned byte area length and offset
1360

1361            int bytsiz = m_pkt.getByteCount();
1362            int bytpos = m_pkt.getByteOffset();
1363            byte[] buf = m_pkt.getBuffer();
1364
1365            // Original format response
1366

1367            if ( isUsingExtendedSecurity() == false)
1368            {
1369                // Extract the challenge response key, if specified
1370

1371                if (keyLen > 0)
1372                {
1373    
1374                    // Allocate a buffer for the challenge response key
1375

1376                    byte[] encryptKey = new byte[keyLen];
1377    
1378                    // Copy the challenge response key
1379

1380                    for (int keyIdx = 0; keyIdx < keyLen; keyIdx++)
1381                        encryptKey[keyIdx] = buf[bytpos++];
1382    
1383                    // Set the sessions encryption key
1384

1385                    setEncryptionKey(encryptKey);
1386                }
1387    
1388                // Extract the domain name
1389

1390                String JavaDoc dom;
1391    
1392                if (unicodeStr == false)
1393                    dom = DataPacker.getString(buf, bytpos, bytsiz);
1394                else
1395                    dom = DataPacker.getUnicodeString(buf, bytpos, bytsiz / 2);
1396                setDomain(dom);
1397            }
1398            else
1399            {
1400                // Extract the server GUID
1401

1402                m_serverGUID = new byte[16];
1403                System.arraycopy(buf, bytpos, m_serverGUID, 0, 16);
1404                
1405                // Run the first phase of the extended security session setup to get the challenge
1406
// from the server
1407

1408                doExtendedSessionSetupPhase1();
1409            }
1410        }
1411    }
1412    
1413    /**
1414     * Send the first stage of the extended security session setup
1415     *
1416     * @exception IOException If a network error occurs
1417     * @eception SMBException If a CIFS error occurs
1418     */

1419    private final void doExtendedSessionSetupPhase1() throws IOException JavaDoc, SMBException
1420    {
1421        // Create a session setup packet
1422

1423        SMBPacket pkt = new SMBPacket();
1424
1425        pkt.setCommand(PacketType.SessionSetupAndX);
1426        
1427        pkt.setFlags(getDefaultFlags());
1428        pkt.setFlags2(getDefaultFlags2());
1429
1430        // Build the extended session setup phase 1 request
1431

1432        pkt.setParameterCount(12);
1433        pkt.setAndXCommand(0xFF); // no secondary command
1434
pkt.setParameter(1, 0); // offset to next command
1435
pkt.setParameter(2, DefaultPacketSize);
1436        pkt.setParameter(3, 1);
1437        pkt.setParameter(4, 0); // virtual circuit number
1438
pkt.setParameterLong(5, 0); // session key
1439

1440        // Clear the security blob length and reserved area
1441

1442        pkt.setParameter(7, 0); // security blob length
1443
pkt.setParameterLong(8, 0); // reserved
1444

1445        // Send the client capabilities
1446

1447        int caps = Capability.LargeFiles + Capability.Unicode + Capability.NTSMBs + Capability.NTStatus
1448                + Capability.RemoteAPIs + Capability.ExtendedSecurity;
1449        
1450        // Set the client capabilities
1451

1452        pkt.setParameterLong(10, caps);
1453
1454        // Get the offset to the session setup request byte data
1455

1456        int pos = pkt.getByteOffset();
1457        pkt.setPosition(pos);
1458
1459        // Create a type 1 NTLM message using the session setup request buffer
1460

1461        Type1NTLMMessage type1Msg = new Type1NTLMMessage(pkt.getBuffer(), pos, 0);
1462
1463        int type1Flags = getPCShare().getExtendedSecurityFlags();
1464        if ( type1Flags == 0)
1465            type1Flags = NTLM.FlagNegotiateUnicode + NTLM.FlagNegotiateNTLM + NTLM.FlagRequestTarget;
1466        
1467        type1Msg.buildType1(type1Flags, null, null);
1468        
1469        // Update the request buffer position
1470

1471        pkt.setPosition(pos + type1Msg.getLength());
1472
1473        // Set the security blob length
1474

1475        pkt.setParameter(7, type1Msg.getLength());
1476        
1477        // Pack the OS details
1478

1479        pkt.packString("Java VM", true);
1480        pkt.packString("JLAN", true);
1481
1482        pkt.packString("", true);
1483            
1484        // Set the packet length
1485

1486        pkt.setByteCount(pkt.getPosition() - pos);
1487
1488        // Exchange an SMB session setup packet with the remote file server
1489

1490        pkt.ExchangeSMB(this, pkt, false);
1491
1492        // Check the error status, should be a warning status to indicate more processing required
1493

1494        if ( pkt.isLongErrorCode() == false || pkt.getLongErrorCode() != SMBStatus.NTMoreProcessingRequired)
1495            pkt.checkForError();
1496        
1497        // Save the session user id
1498

1499        setUserId(pkt.getUserId());
1500
1501        // The response packet should also have the type 2 security blob
1502

1503        int type2Len = pkt.getParameter(3);
1504        if (pkt.getByteCount() > 0)
1505        {
1506
1507            // Get the packet buffer and byte offset
1508

1509            byte[] buf = pkt.getBuffer();
1510            int offset = pkt.getByteOffset();
1511            int maxlen = offset + pkt.getByteCount();
1512
1513            // Take a copy of the type 2 security blob
1514

1515            m_type2Msg = new Type2NTLMMessage();
1516            m_type2Msg.copyFrom(buf, offset, type2Len);
1517            
1518            // Get the encryption key from the security blob
1519

1520            m_encryptKey = m_type2Msg.getChallenge();
1521            
1522            // Update the byte area offset and align
1523

1524            offset = DataPacker.wordAlign(offset + type2Len);
1525            maxlen -= type2Len;
1526            
1527            // Get the server OS
1528

1529            String JavaDoc srvOS = DataPacker.getString(buf, offset, maxlen);
1530            setOperatingSystem(srvOS);
1531
1532            offset += srvOS.length() + 1;
1533            maxlen -= srvOS.length() + 1;
1534
1535            // Get the LAN Manager type
1536

1537            String JavaDoc lanman = DataPacker.getString(buf, offset, maxlen);
1538            setLANManagerType(lanman);
1539        }
1540    }
1541    
1542   /**
1543    * Send the second stage of the extended security session setup
1544    *
1545    * @param domain String
1546    * @param userName String
1547    * @param wksName String
1548    * @param lmPwd byte[]
1549    * @param ntlmPwd byte[]
1550    * @exception IOException If a network error occurs
1551    * @eception SMBException If a CIFS error occurs
1552    */

1553   private final void doExtendedSessionSetupPhase2(String JavaDoc domain, String JavaDoc userName, String JavaDoc wksName,
1554           byte[] lmPwd, byte[] ntlmPwd) throws IOException JavaDoc, SMBException
1555   {
1556       // Check if the domain name has been specified, if not then use the domain name from the
1557
// original connection details or the servers domain name
1558

1559       if ( domain == null)
1560       {
1561           if ( getPCShare().hasDomain() && getPCShare().getDomain().length() > 0)
1562               domain = getPCShare().getDomain();
1563           else
1564               domain = m_type2Msg.getTarget();
1565       }
1566       
1567       // Create a session setup packet
1568

1569       SMBPacket pkt = new SMBPacket();
1570
1571       pkt.setCommand(PacketType.SessionSetupAndX);
1572       
1573       pkt.setFlags(getDefaultFlags());
1574       pkt.setFlags2(getDefaultFlags2());
1575       
1576       pkt.setUserId(getUserId());
1577
1578       // Build the extended session setup phase 2 request
1579

1580       pkt.setParameterCount(12);
1581       pkt.setAndXCommand(0xFF); // no secondary command
1582
pkt.setParameter(1, 0); // offset to next command
1583
pkt.setParameter(2, DefaultPacketSize);
1584       pkt.setParameter(3, 1);
1585       pkt.setParameter(4, 0); // virtual circuit number
1586
pkt.setParameterLong(5, 0); // session key
1587

1588       // Clear the security blob length and reserved area
1589

1590       pkt.setParameter(7, 0); // security blob length
1591
pkt.setParameterLong(8, 0); // reserved
1592

1593       // Send the client capabilities
1594

1595       int caps = Capability.LargeFiles + Capability.Unicode + Capability.NTSMBs + Capability.NTStatus
1596               + Capability.RemoteAPIs + Capability.ExtendedSecurity;
1597       
1598       // Set the client capabilities
1599

1600       pkt.setParameterLong(10, caps);
1601
1602       // Get the offset to the session setup request byte data
1603

1604       int pos = pkt.getByteOffset();
1605       pkt.setPosition(pos);
1606
1607       // Create a type 3 NTLM message using the session setup request buffer
1608

1609       Type3NTLMMessage type3Msg = new Type3NTLMMessage(pkt.getBuffer(), pos, 0, true);
1610       
1611       type3Msg.buildType3(lmPwd, ntlmPwd, domain, userName, wksName != null ? wksName : "", null, m_type2Msg.getFlags());
1612       
1613       // Update the request buffer position
1614

1615       pkt.setPosition(pos + type3Msg.getLength());
1616
1617       // Set the security blob length
1618

1619       pkt.setParameter(7, type3Msg.getLength());
1620       
1621       // Pack the OS details
1622

1623       pkt.packString("Java VM", true);
1624       pkt.packString("JLAN", true);
1625
1626       pkt.packString("", true);
1627           
1628       // Set the packet length
1629

1630       pkt.setByteCount(pkt.getPosition() - pos);
1631
1632       // Exchange an SMB session setup packet with the remote file server
1633

1634       pkt.ExchangeSMB(this, pkt, true);
1635       
1636       // Set the guest status for the session
1637

1638       setGuest(pkt.getParameter(2) != 0 ? true : false);
1639   }
1640}
1641
Popular Tags