Session.java 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  1. /*
  2. * Copyright (C) 2006-2010 Alfresco Software Limited.
  3. *
  4. * This file is part of Alfresco
  5. *
  6. * Alfresco is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU Lesser General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Alfresco is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. package org.alfresco.jlan.client;
  20. import java.io.*;
  21. import java.security.*;
  22. import org.alfresco.jlan.debug.Debug;
  23. import org.alfresco.jlan.netbios.NetworkSession;
  24. import org.alfresco.jlan.netbios.RFCNetBIOSProtocol;
  25. import org.alfresco.jlan.smb.Capability;
  26. import org.alfresco.jlan.smb.Dialect;
  27. import org.alfresco.jlan.smb.PCShare;
  28. import org.alfresco.jlan.smb.PacketType;
  29. import org.alfresco.jlan.smb.SMBException;
  30. import org.alfresco.jlan.smb.SMBStatus;
  31. import org.alfresco.jlan.util.DataPacker;
  32. /**
  33. * SMB Session Class
  34. *
  35. * <p>Base class for sessions connected to remote disk, print, named pipe and administration named pipe shares.
  36. *
  37. * @author gkspencer
  38. */
  39. public class Session {
  40. // Session security mode
  41. public static final int SecurityModeUser = 1;
  42. public static final int SecurityModeShare = 2;
  43. // Tree identifier that indicates that the disk session has been closed
  44. protected final static int Closed = -1;
  45. // Debug flags
  46. public final static int DBGPacketType = 0x0001;
  47. public final static int DBGDumpPacket = 0x0002;
  48. public final static int DBGHexDump = 0x0004;
  49. public final static int DBGSigning = 0x0008;
  50. // Default SMB packet size to allocate
  51. public static final int DEFAULT_BUFSIZE = 4096;
  52. // Multiplex id to indicate the session is not in a transaction
  53. public static final int NO_TRANSACTION = -1;
  54. // SMB dialect id and string for this session
  55. private int m_dialect;
  56. private String m_diaStr;
  57. // Network session
  58. private NetworkSession m_netSession;
  59. // SMB packet for protocol exhanges
  60. protected SMBPacket m_pkt;
  61. // Default packet flags
  62. private int m_defFlags = SMBPacket.FLG_CASELESS;
  63. private int m_defFlags2 = SMBPacket.FLG2_LONGFILENAMES;
  64. // Server connection details
  65. private PCShare m_remoteShr;
  66. // Domain name
  67. private String m_domain;
  68. // Remote operating system and LAN manager type
  69. private String m_srvOS;
  70. private String m_srvLM;
  71. // Security mode (user or share)
  72. private int m_secMode;
  73. // Challenge encryption key
  74. private byte[] m_encryptKey;
  75. // SMB session information
  76. private int m_sessIdx;
  77. private int m_userId;
  78. private int m_processId;
  79. // Tree identifier for this connection
  80. protected int m_treeid;
  81. // Device type that this session is connected to
  82. private int m_devtype;
  83. // Maximum transmit buffer size allowed
  84. private int m_maxPktSize;
  85. // Session capabilities
  86. private int m_sessCaps;
  87. // Maximum virtual circuits allowed on this session, and maximum multiplxed read/writes
  88. private int m_maxVCs;
  89. private int m_maxMPX;
  90. // Indicate if the session was created as a guest rather than using the supplied username/password
  91. private boolean m_guest;
  92. // SMB signing support
  93. //
  94. // Session key, packet sequence number and MD5 digest
  95. private byte[] m_sessionKey;
  96. private int m_seqNo;
  97. private MessageDigest m_md5;
  98. private long m_lastTxSig;
  99. // Multiplex id of an active transaction
  100. //
  101. // A transaction may span multiple requests/responses, when signing is enabled the sequence number is not
  102. // incremented for a transaction that spans multiple packets
  103. //
  104. // -1 indicates that there is no currently active transaction
  105. private int m_transMID = NO_TRANSACTION;
  106. // Global session id
  107. private static int m_sessionIdx = 1;
  108. // Multiplex id
  109. private static int m_multiplexId = 1;
  110. // Debug support
  111. private static int m_debug = 0;
  112. /**
  113. * Construct an SMB session
  114. *
  115. * @param shr Remote server details.
  116. * @param dialect SMB dialect for this session.
  117. * @param pkt SMB packet
  118. */
  119. protected Session(PCShare shr, int dialect, SMBPacket pkt) {
  120. // Set the SMB dialect for this session
  121. m_dialect = dialect;
  122. // Save the remote share details
  123. m_remoteShr = shr;
  124. // Allocate a unique session index
  125. m_sessIdx = getNextSessionId();
  126. // Allocate an SMB protocol packet
  127. m_pkt = pkt;
  128. if ( pkt == null)
  129. m_pkt = new SMBPacket(DEFAULT_BUFSIZE);
  130. }
  131. /**
  132. * Allocate an SMB packet for this session. The preferred packet size is specified, if a smaller
  133. * buffer size has been negotiated a smaller SMB packet will be returned.
  134. *
  135. * @param pref Preferred SMB packet size
  136. * @return Allocated SMB packet
  137. */
  138. protected final SMBPacket allocatePacket(int pref) {
  139. // Check if the preferred size is larger than the maximum allowed packet
  140. // size for this session.
  141. if ( pref > m_maxPktSize)
  142. return new SMBPacket(m_maxPktSize + RFCNetBIOSProtocol.HEADER_LEN);
  143. // Return the preferred SMB packet size
  144. return new SMBPacket(pref + RFCNetBIOSProtocol.HEADER_LEN);
  145. }
  146. /**
  147. * Determine if the session supports raw mode read/writes
  148. *
  149. * @return true if this session supports raw mode, else false
  150. */
  151. public final boolean supportsRawMode() {
  152. return (m_sessCaps & Capability.RawMode) != 0 ? true : false;
  153. }
  154. /**
  155. * Determine if the session supports Unicode
  156. *
  157. * @return boolean
  158. */
  159. public final boolean supportsUnicode() {
  160. return (m_sessCaps & Capability.Unicode) != 0 ? true : false;
  161. }
  162. /**
  163. * Determine if the session supports large files (ie. 64 bit file offsets)
  164. *
  165. * @return boolean
  166. */
  167. public final boolean supportsLargeFiles() {
  168. return (m_sessCaps & Capability.LargeFiles) != 0 ? true : false;
  169. }
  170. /**
  171. * Determine if the session supports NT specific SMBs
  172. *
  173. * @return boolean
  174. */
  175. public final boolean supportsNTSmbs() {
  176. return (m_sessCaps & Capability.NTSMBs) != 0 ? true : false;
  177. }
  178. /**
  179. * Determine if the session supports RPC API requests
  180. *
  181. * @return boolean
  182. */
  183. public final boolean supportsRPCAPIs() {
  184. return (m_sessCaps & Capability.RemoteAPIs) != 0 ? true : false;
  185. }
  186. /**
  187. * Determine if the session supports NT status codes
  188. *
  189. * @return boolean
  190. */
  191. public final boolean supportsNTStatusCodes() {
  192. return (m_sessCaps & Capability.NTStatus) != 0 ? true : false;
  193. }
  194. /**
  195. * Determine if the session supports level 2 oplocks
  196. *
  197. * @return boolean
  198. */
  199. public final boolean supportsLevel2Oplocks() {
  200. return (m_sessCaps & Capability.Level2Oplocks) != 0 ? true : false;
  201. }
  202. /**
  203. * Determine if the session supports lock and read
  204. *
  205. * @return boolean
  206. */
  207. public final boolean supportsLockAndRead() {
  208. return (m_sessCaps & Capability.LockAndRead) != 0 ? true : false;
  209. }
  210. /**
  211. * Determine if the session supports NT find
  212. *
  213. * @return boolean
  214. */
  215. public final boolean supportsNTFind() {
  216. return (m_sessCaps & Capability.NTFind) != 0 ? true : false;
  217. }
  218. /**
  219. * Close this connection with the remote server.
  220. *
  221. * @exception java.io.IOException If an I/O error occurs.
  222. * @exception SMBException If an SMB level error occurs
  223. */
  224. public void CloseSession()
  225. throws java.io.IOException, SMBException {
  226. // If the NetBIOS session is valid then hangup the session
  227. if ( isActive()) {
  228. // Close the network session
  229. m_netSession.Close();
  230. // Clear the session
  231. m_netSession = null;
  232. }
  233. }
  234. /**
  235. * Return the default flags settings for this session
  236. *
  237. * @return int
  238. */
  239. public final int getDefaultFlags() {
  240. return m_defFlags;
  241. }
  242. /**
  243. * Return the default flags2 settings for this session
  244. *
  245. * @return int
  246. */
  247. public final int getDefaultFlags2() {
  248. return m_defFlags2;
  249. }
  250. /**
  251. * Get the device type that this session is connected to.
  252. *
  253. * @return Device type for this session.
  254. */
  255. public final int getDeviceType() {
  256. return m_devtype;
  257. }
  258. /**
  259. * Get the SMB dialect property
  260. *
  261. * @return SMB dialect that this session has negotiated.
  262. */
  263. public final int getDialect() {
  264. return m_dialect;
  265. }
  266. /**
  267. * Get the SMB dialect string
  268. *
  269. * @return SMB dialect string for this session.
  270. */
  271. public final String getDialectString() {
  272. return m_diaStr;
  273. }
  274. /**
  275. * Get the servers primary domain name
  276. *
  277. * @return Servers primary domain name, if known, else null.
  278. */
  279. public final String getDomain() {
  280. return m_domain;
  281. }
  282. /**
  283. * Determine if there is a challenge encryption key
  284. *
  285. * @return boolean
  286. */
  287. public final boolean hasEncryptionKey() {
  288. return m_encryptKey != null ? true : false;
  289. }
  290. /**
  291. * Return the cahllenge encryption key
  292. *
  293. * @return byte[]
  294. */
  295. public final byte[] getEncryptionKey() {
  296. return m_encryptKey;
  297. }
  298. /**
  299. * Get the servers LAN manager type
  300. *
  301. * @return Servers LAN manager type, if known, else null.
  302. */
  303. public final String getLANManagerType() {
  304. return m_srvLM;
  305. }
  306. /**
  307. * Get the maximum number of multiplxed requests that are allowed
  308. *
  309. * @return int
  310. */
  311. public final int getMaximumMultiplexedRequests() {
  312. return m_maxMPX;
  313. }
  314. /**
  315. * Get the maximum packet size allowed for this session
  316. *
  317. * @return Maximum packet size, in bytes.
  318. */
  319. public final int getMaximumPacketSize() {
  320. return m_maxPktSize;
  321. }
  322. /**
  323. * Get the maximum virtual circuits allowed on this session
  324. *
  325. * @return int
  326. */
  327. public final int getMaximumVirtualCircuits() {
  328. return m_maxVCs;
  329. }
  330. /**
  331. * Get the next multiplex id to uniquely identify a transaction
  332. *
  333. * @return Unique multiplex id for a transaction
  334. */
  335. public final synchronized int getNextMultiplexId() {
  336. return m_multiplexId++;
  337. }
  338. /**
  339. * Get the next session id
  340. *
  341. * @return int
  342. */
  343. protected final synchronized int getNextSessionId() {
  344. return m_sessionIdx++;
  345. }
  346. /**
  347. * Get the servers operating system type
  348. *
  349. * @return Servers operating system, if known, else null.
  350. */
  351. public final String getOperatingSystem() {
  352. return m_srvOS;
  353. }
  354. /**
  355. * Get the remote share password string
  356. *
  357. * @return Remote share password string
  358. */
  359. public final String getPassword() {
  360. return m_remoteShr.getPassword();
  361. }
  362. /**
  363. * Get the remote share details for this session
  364. *
  365. * @return PCShare information for this session
  366. */
  367. public final PCShare getPCShare() {
  368. return m_remoteShr;
  369. }
  370. /**
  371. * Return the security mode of the session (user or share)
  372. *
  373. * @return int
  374. */
  375. public final int getSecurityMode() {
  376. return m_secMode;
  377. }
  378. /**
  379. * Get the remote server name
  380. *
  381. * @return Remote server name
  382. */
  383. public final String getServer() {
  384. return m_remoteShr.getNodeName();
  385. }
  386. /**
  387. * Access the associated network session
  388. *
  389. * @return NetworkSession that the SMB session is using
  390. */
  391. public final NetworkSession getSession() {
  392. return m_netSession;
  393. }
  394. /**
  395. * Return the session capability flags.
  396. *
  397. * @return int
  398. */
  399. public final int getCapabilities() {
  400. return m_sessCaps;
  401. }
  402. /**
  403. * Get the process id for this session
  404. *
  405. * @return int
  406. */
  407. public final int getProcessId() {
  408. return m_processId;
  409. }
  410. /**
  411. * Get the session identifier property
  412. *
  413. * @return Session identifier
  414. */
  415. public final int getSessionId() {
  416. return m_sessIdx;
  417. }
  418. /**
  419. * Get the remote share name
  420. *
  421. * @return Remote share name string
  422. */
  423. public final String getShareName() {
  424. return m_remoteShr.getShareName();
  425. }
  426. /**
  427. * Get the connected tree identifier.
  428. *
  429. * @return Tree identifier.
  430. */
  431. public final int getTreeId() {
  432. return m_treeid;
  433. }
  434. /**
  435. * Return the assigned use id for this SMB session
  436. *
  437. * @return Assigned user id
  438. */
  439. public final int getUserId() {
  440. return m_userId;
  441. }
  442. /**
  443. * Get the remote share user name string
  444. *
  445. * @return Remote share user name string
  446. */
  447. public final String getUserName() {
  448. return m_remoteShr.getUserName();
  449. }
  450. /**
  451. * Check if there is data available in the network receive buffer
  452. *
  453. * @return boolean
  454. * @exception IOException
  455. */
  456. public final boolean hasDataAvailable()
  457. throws IOException {
  458. return m_netSession.hasData();
  459. }
  460. /**
  461. * Determine if the specified debugging option is enabled
  462. *
  463. * @param opt Debug option bit mask
  464. * @return true if the debug option is enabled, else false
  465. */
  466. public static boolean hasDebugOption(int opt) {
  467. if ( m_debug == 0)
  468. return false;
  469. if ( (m_debug & opt) != 0)
  470. return true;
  471. return false;
  472. }
  473. /**
  474. * Check if SMB signing is enabled on this session
  475. *
  476. * @return boolean
  477. */
  478. public final boolean hasSMBSigning() {
  479. return m_sessionKey != null;
  480. }
  481. /**
  482. * Determine if the session is valid, ie. still open.
  483. *
  484. * @return true if the session is still active, else false.
  485. */
  486. public final boolean isActive() {
  487. return (m_netSession == null) ? false : true;
  488. }
  489. /**
  490. * Determine if SMB session debugging is enabled
  491. *
  492. * @return true if debugging is enabled, else false.
  493. */
  494. public static boolean hasDebug() {
  495. return m_debug != 0 ? true : false;
  496. }
  497. /**
  498. * Determine if the session has been created as a guest logon
  499. *
  500. * @return boolean
  501. */
  502. public final boolean isGuest() {
  503. return m_guest;
  504. }
  505. /**
  506. * Determine if the Unicode flag is enabled
  507. *
  508. * @return boolean
  509. */
  510. public final boolean isUnicode() {
  511. return (m_defFlags2 & SMBPacket.FLG2_UNICODE) != 0 ? true : false;
  512. }
  513. /**
  514. * Send a single echo request to the server
  515. *
  516. * @throws java.io.IOException
  517. * @throws SMBException
  518. */
  519. public final void pingServer()
  520. throws java.io.IOException, SMBException {
  521. // Send a single echo request to the server
  522. pingServer(1);
  523. }
  524. /**
  525. * Send an echo request to the server
  526. *
  527. * @param cnt Number of packets to echo from the remote server
  528. * @exception java.io.IOException If an I/O error occurs
  529. * @exception SMBException SMB error occurred
  530. */
  531. public final void pingServer(int cnt)
  532. throws java.io.IOException, SMBException {
  533. // Build a server ping SMB packet
  534. m_pkt.setCommand(PacketType.Echo);
  535. m_pkt.setFlags(0);
  536. m_pkt.setTreeId(getTreeId());
  537. m_pkt.setUserId(getUserId());
  538. m_pkt.setProcessId(getProcessId());
  539. m_pkt.setMultiplexId(1);
  540. // Set the parameter words
  541. m_pkt.setParameterCount(1);
  542. m_pkt.setParameter(0, cnt); // number of packets that the server should return
  543. String echoStr = "ECHO";
  544. m_pkt.setBytes(echoStr.getBytes());
  545. // Send the echo request
  546. m_pkt.SendSMB(this);
  547. // Receive the reply packets, if any
  548. while (cnt > 0) {
  549. // Receive a reply packet
  550. m_pkt.ReceiveSMB(this);
  551. // Decrement the reply counter
  552. cnt--;
  553. }
  554. }
  555. /**
  556. * Enable/disable SMB session debugging
  557. *
  558. * @param dbg Bit mask of debug options to enable, or zero to disable
  559. */
  560. public static void setDebug(int dbg) {
  561. m_debug = dbg;
  562. }
  563. /**
  564. * Set the default SMB packet flags for this session
  565. *
  566. * @param flg int
  567. */
  568. protected final void setDefaultFlags(int flg) {
  569. m_defFlags = flg;
  570. }
  571. /**
  572. * Set the SMB packet default flags2 for this session
  573. *
  574. * @param flg2 int
  575. */
  576. protected final void setDefaultFlags2(int flg2) {
  577. m_defFlags2 = flg2;
  578. }
  579. /**
  580. * Set the device type for this session.
  581. *
  582. * @param dev Device type for this session.
  583. */
  584. protected final void setDeviceType(int dev) {
  585. m_devtype = dev;
  586. }
  587. /**
  588. * Set the dialect for this session
  589. *
  590. * @param dia SMB dialect that this session is using.
  591. */
  592. protected final void setDialect(int dia) {
  593. m_dialect = dia;
  594. }
  595. /**
  596. * Set the dialect string for this session
  597. *
  598. * @param dia SMB dialect string
  599. */
  600. protected final void setDialectString(String dia) {
  601. m_diaStr = dia;
  602. }
  603. /**
  604. * Set the remote servers primary domain name
  605. *
  606. * @param dom Servers primary domain name.
  607. */
  608. protected final void setDomain(String dom) {
  609. m_domain = dom;
  610. }
  611. /**
  612. * Set the encryption key
  613. *
  614. * @param key byte[]
  615. */
  616. public final void setEncryptionKey(byte[] key) {
  617. // Set the challenge response encryption key
  618. m_encryptKey = key;
  619. }
  620. /**
  621. * Set the guest status for the session
  622. *
  623. * @param sts boolean
  624. */
  625. protected final void setGuest(boolean sts) {
  626. m_guest = sts;
  627. }
  628. /**
  629. * Set the remote servers LAN manager type
  630. *
  631. * @param lm Servers LAN manager type string.
  632. */
  633. protected final void setLANManagerType(String lm) {
  634. m_srvLM = lm;
  635. }
  636. /**
  637. * Set the maximum number of multiplexed requests allowed
  638. *
  639. * @param maxMulti int
  640. */
  641. protected final void setMaximumMultiplexedRequests(int maxMulti) {
  642. m_maxMPX = maxMulti;
  643. }
  644. /**
  645. * Set the maximum packet size allowed on this session
  646. *
  647. * @param siz Maximum allowed packet size.
  648. */
  649. protected final void setMaximumPacketSize(int siz) {
  650. m_maxPktSize = siz;
  651. }
  652. /**
  653. * Set the maximum number of virtual circuits allowed on this session
  654. *
  655. * @param maxVC int
  656. */
  657. protected final void setMaximumVirtualCircuits(int maxVC) {
  658. m_maxVCs = maxVC;
  659. }
  660. /**
  661. * Set the remote servers operating system type
  662. *
  663. * @param os Servers operating system type string.
  664. */
  665. protected final void setOperatingSystem(String os) {
  666. m_srvOS = os;
  667. }
  668. /**
  669. * Set the remote share password
  670. *
  671. * @param pwd Remtoe share password string.
  672. */
  673. protected final void setPassword(String pwd) {
  674. m_remoteShr.setPassword(pwd);
  675. }
  676. /**
  677. * Set the session security mode (user or share)
  678. *
  679. * @param secMode int
  680. */
  681. public final void setSecurityMode(int secMode) {
  682. m_secMode = secMode;
  683. }
  684. /**
  685. * Set the remote server name
  686. *
  687. * @param srv Server name string
  688. */
  689. protected final void setServer(String srv) {
  690. m_remoteShr.setNodeName(srv);
  691. }
  692. /**
  693. * Set the network session that this SMB session is associated with
  694. *
  695. * @param netSess Network session that this SMB session is to be associated with.
  696. */
  697. protected final void setSession(NetworkSession netSess) {
  698. m_netSession = netSess;
  699. }
  700. /**
  701. * Set the session capability flags
  702. *
  703. * @param caps Capability flags.
  704. */
  705. protected final void setCapabilities(int caps) {
  706. m_sessCaps = caps;
  707. }
  708. /**
  709. * Set the remote share name
  710. *
  711. * @param shr Remote share name string
  712. */
  713. protected final void setShareName(String shr) {
  714. m_remoteShr.setShareName(shr);
  715. }
  716. /**
  717. * Set the process id for this session
  718. *
  719. * @param id
  720. */
  721. public final void setProcessId(int id) {
  722. m_processId = id;
  723. }
  724. /**
  725. * Set the connected tree identifier for this session.
  726. *
  727. * @param id Tree identifier for this session.
  728. */
  729. protected final void setTreeId(int id) {
  730. m_treeid = id;
  731. }
  732. /**
  733. * Set the user identifier for this session
  734. *
  735. * @param uid User identifier
  736. */
  737. protected final void setUserId(int uid) {
  738. m_userId = uid;
  739. }
  740. /**
  741. * Set the remote share user name
  742. *
  743. * @param user Remote share user name string
  744. */
  745. protected final void setUserName(String user) {
  746. m_remoteShr.setUserName(user);
  747. }
  748. /**
  749. * Process an asynchronous packet
  750. *
  751. * @param pkt SMBPacket
  752. */
  753. protected void processAsynchResponse(SMBPacket pkt) {
  754. // Default is to ignore the packet
  755. //
  756. // This method is overridden by SMB dialects that can generate asynchronous responses
  757. if ( Debug.EnableInfo && hasDebug())
  758. Debug.println("++ Asynchronous response received, command = 0x" + pkt.getCommand());
  759. }
  760. /**
  761. * Enable SMB signing for this session
  762. *
  763. * @param sessKey byte[]
  764. * @exception NoSuchAlgorithmException If the MD5 message digest is not available
  765. */
  766. protected final void enableSMBSigning(byte[] sessKey)
  767. throws NoSuchAlgorithmException {
  768. // Save the session key
  769. m_sessionKey = sessKey;
  770. // Set the starting sequence number
  771. m_seqNo = 0;
  772. // Allocate the MD5 message digest for calculating the SMB signatures
  773. m_md5 = MessageDigest.getInstance("MD5");
  774. }
  775. /**
  776. * Disable SMB signing for this session
  777. */
  778. protected final void disableSMBSigning() {
  779. // Clear the session key and message digest to disable signing
  780. m_sessionKey = null;
  781. m_md5 = null;
  782. }
  783. /**
  784. * Add an SMB signature to an outgoing SMB request
  785. *
  786. * @param pkt SMBPacket
  787. */
  788. protected final void signTxPacket(SMBPacket pkt) {
  789. // Replace the signature with the sequence number
  790. int seqNo = m_seqNo;
  791. pkt.setSignature(seqNo);
  792. // Clear the status code area
  793. pkt.setLongErrorCode(0);
  794. // Update the sequence number if not in a transaction
  795. if ( hasActiveTransaction() == false)
  796. m_seqNo++;
  797. // Calculate the signature value
  798. m_md5.update(m_sessionKey);
  799. m_md5.update(pkt.getBuffer(), 4, pkt.getLength());
  800. byte[] sigByts = m_md5.digest();
  801. m_lastTxSig = DataPacker.getIntelLong(sigByts, 0);
  802. // Set the SMB signature for the request
  803. pkt.setSignature(m_lastTxSig);
  804. // DEBUG
  805. if ( Debug.EnableInfo && hasDebugOption(DBGSigning)) {
  806. Debug.println("Sign request " + PacketType.getCommandName(pkt.getCommand()) + ", seq=" + seqNo + ", signature = 0x"
  807. + Long.toHexString(m_lastTxSig));
  808. Debug.println("Send length = " + pkt.getLength());
  809. }
  810. }
  811. /**
  812. * Verify the SMB signature on an incoming SMB response
  813. *
  814. * @param pkt SMBPacket
  815. * @exception SMBException If the received packet SMB signature is not valid
  816. */
  817. protected final void verifyRxPacket(SMBPacket pkt)
  818. throws SMBException {
  819. // Get the signature value
  820. long rxSig = pkt.getSignature();
  821. // Update the sequence number if not in a transaction
  822. int seqNo = m_seqNo;
  823. if ( hasActiveTransaction() == false) {
  824. m_seqNo++;
  825. }
  826. else {
  827. // Check if the response is valid
  828. if ( pkt.isValidResponse())
  829. seqNo = m_seqNo + 1;
  830. else {
  831. // DEBUG
  832. if ( Debug.EnableInfo && hasDebugOption(DBGSigning))
  833. Debug.println("Transaction error returned, signature NOT checked");
  834. // Do not check the signature
  835. return;
  836. }
  837. }
  838. // Replace the signature with the sequence number
  839. pkt.setSignature(seqNo);
  840. // Calculate the signature value
  841. m_md5.update(m_sessionKey);
  842. m_md5.update(pkt.getBuffer(), 4, pkt.getLength());
  843. byte[] sigByts = m_md5.digest();
  844. long calcSig = DataPacker.getIntelLong(sigByts, 0);
  845. // DEBUG
  846. if ( Debug.EnableInfo && hasDebugOption(DBGSigning)) {
  847. Debug.println("Verify sign " + PacketType.getCommandName(pkt.getCommand()) + ", seq=" + seqNo + ", signature = 0x"
  848. + Long.toHexString(rxSig) + ", calc=" + Long.toHexString(calcSig));
  849. Debug.println("Received length = " + pkt.getLength());
  850. if ( calcSig != rxSig)
  851. Debug.println("#### SMB signature mismatch ####");
  852. }
  853. // Check if the signature is valid
  854. if ( calcSig != rxSig) {
  855. // Check if the received signature is the same as the one sent in the request, if so it
  856. // looks like
  857. // signing is not enabled
  858. if ( rxSig == m_lastTxSig) {
  859. // Disable signing
  860. disableSMBSigning();
  861. // DEBUG
  862. if ( Debug.EnableInfo && hasDebugOption(DBGSigning))
  863. Debug.println("Received signature equals sent, disabling signing");
  864. }
  865. else {
  866. // Bad signature received
  867. throw new SMBException(SMBStatus.JLANErr, SMBStatus.JLANInvalidSMBSignature);
  868. }
  869. }
  870. }
  871. /**
  872. * Set the multiplex id of an active transaction
  873. *
  874. * @param mid int
  875. */
  876. public final void setTransactionMID(int mid) {
  877. m_transMID = mid;
  878. // Bump the sequence number at the end of a transaction
  879. if ( mid == NO_TRANSACTION)
  880. m_seqNo += 2;
  881. }
  882. /**
  883. * Determine if there is an active transaction
  884. *
  885. * @return boolean
  886. */
  887. public final boolean hasActiveTransaction() {
  888. return m_transMID != -1 ? true : false;
  889. }
  890. /**
  891. * Get the SMB signing sequence number
  892. *
  893. * @return int
  894. */
  895. public final int getSMBSequence() {
  896. return m_seqNo;
  897. }
  898. /**
  899. * Set the SMB signing sequence number
  900. *
  901. * @param seq int
  902. */
  903. public final void setSMBSequence(int seq) {
  904. m_seqNo = seq;
  905. }
  906. /**
  907. * Output the session details as a string
  908. *
  909. * @return Session details string
  910. */
  911. public String toString() {
  912. StringBuffer str = new StringBuffer();
  913. str.append("[\\\\");
  914. str.append(getServer());
  915. str.append("\\");
  916. str.append(getShareName());
  917. str.append(":");
  918. str.append(Dialect.DialectTypeString(m_dialect));
  919. str.append(",UserId=");
  920. str.append(getUserId());
  921. str.append("]");
  922. return str.toString();
  923. }
  924. }