SMBPacket.java 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545
  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 org.alfresco.jlan.debug.Debug;
  22. import org.alfresco.jlan.netbios.NetworkSession;
  23. import org.alfresco.jlan.netbios.RFCNetBIOSProtocol;
  24. import org.alfresco.jlan.smb.PacketType;
  25. import org.alfresco.jlan.smb.SMBErrorText;
  26. import org.alfresco.jlan.smb.SMBException;
  27. import org.alfresco.jlan.smb.SMBStatus;
  28. import org.alfresco.jlan.util.DataPacker;
  29. import org.alfresco.jlan.util.HexDump;
  30. /**
  31. * SMB packet type class
  32. *
  33. * <p>Contains the details of an SMB/CIFS request or response. The SMB packet class has methods for packing
  34. * and unpacking the various fields of the SMB header and requests.
  35. *
  36. * <p>Contains SMB/CIFS constants for SMB packet field offsets and header flag values.
  37. *
  38. * @author gkspencer
  39. */
  40. public class SMBPacket {
  41. // SMB packet offsets, assuming an RFC NetBIOS transport
  42. public static final int SMBHEADER = RFCNetBIOSProtocol.HEADER_LEN;
  43. public static final int COMMAND = 4 + RFCNetBIOSProtocol.HEADER_LEN;
  44. public static final int ERRORCODE = 5 + RFCNetBIOSProtocol.HEADER_LEN;
  45. public static final int ERRORCLASS = 5 + RFCNetBIOSProtocol.HEADER_LEN;
  46. public static final int ERROR = 7 + RFCNetBIOSProtocol.HEADER_LEN;
  47. public static final int FLAGS = 9 + RFCNetBIOSProtocol.HEADER_LEN;
  48. public static final int FLAGS2 = 10 + RFCNetBIOSProtocol.HEADER_LEN;
  49. public static final int PIDHIGH = 12 + RFCNetBIOSProtocol.HEADER_LEN;
  50. public static final int SIGNATURE = 14 + RFCNetBIOSProtocol.HEADER_LEN;
  51. public static final int SID = 18 + RFCNetBIOSProtocol.HEADER_LEN;
  52. public static final int SEQNO = 20 + RFCNetBIOSProtocol.HEADER_LEN;
  53. public static final int TID = 24 + RFCNetBIOSProtocol.HEADER_LEN;
  54. public static final int PID = 26 + RFCNetBIOSProtocol.HEADER_LEN;
  55. public static final int UID = 28 + RFCNetBIOSProtocol.HEADER_LEN;
  56. public static final int MID = 30 + RFCNetBIOSProtocol.HEADER_LEN;
  57. public static final int WORDCNT = 32 + RFCNetBIOSProtocol.HEADER_LEN;
  58. public static final int ANDXCOMMAND = 33 + RFCNetBIOSProtocol.HEADER_LEN;
  59. public static final int ANDXRESERVED = 34 + RFCNetBIOSProtocol.HEADER_LEN;
  60. public static final int PARAMWORDS = 33 + RFCNetBIOSProtocol.HEADER_LEN;
  61. // SMB packet header length for a transaction type request
  62. public static final int TRANS_HEADERLEN = 66 + RFCNetBIOSProtocol.HEADER_LEN;
  63. // Minimum receive length for a valid SMB packet
  64. public static final int MIN_RXLEN = 32;
  65. // Default buffer size to allocate for SMB packets
  66. public static final int DEFAULT_BUFSIZE = 4096;
  67. // Flag bits
  68. public static final int FLG_SUBDIALECT = 0x01;
  69. public static final int FLG_CASELESS = 0x08;
  70. public static final int FLG_CANONICAL = 0x10;
  71. public static final int FLG_OPLOCK = 0x20;
  72. public static final int FLG_NOTIFY = 0x40;
  73. public static final int FLG_RESPONSE = 0x80;
  74. // Flag2 bits
  75. public static final int FLG2_LONGFILENAMES = 0x0001;
  76. public static final int FLG2_EXTENDEDATTRIB = 0x0002;
  77. public static final int FLG2_SECURITYSIG = 0x0004;
  78. public static final int FLG2_EXTENDEDSETUP = 0x0800;
  79. public static final int FLG2_READIFEXE = 0x2000;
  80. public static final int FLG2_LONGERRORCODE = 0x4000;
  81. public static final int FLG2_UNICODE = 0x8000;
  82. // Security mode bits
  83. public static final int SEC_USER = 0x0001;
  84. public static final int SEC_ENCRYPT = 0x0002;
  85. // Raw mode bits
  86. public static final int RAW_READ = 0x0001;
  87. public static final int RAW_WRITE = 0x0002;
  88. // SMB packet buffer
  89. private byte[] m_smbbuf;
  90. // Packet type
  91. private int m_pkttype;
  92. // Current byte area pack/unpack position
  93. protected int m_pos;
  94. protected int m_endpos;
  95. // Time of last packet send
  96. protected long m_lastTxTime;
  97. /**
  98. * Default constructor
  99. */
  100. public SMBPacket() {
  101. m_smbbuf = new byte[DEFAULT_BUFSIZE];
  102. InitializeBuffer();
  103. }
  104. /**
  105. * Construct an SMB packet using the specified packet buffer.
  106. *
  107. * @param buf SMB packet buffer.
  108. */
  109. public SMBPacket(byte[] buf) {
  110. m_smbbuf = buf;
  111. }
  112. /**
  113. * Construct an SMB packet of the specified size.
  114. *
  115. * @param siz Size of SMB packet buffer to allocate.
  116. */
  117. public SMBPacket(int siz) {
  118. m_smbbuf = new byte[siz];
  119. InitializeBuffer();
  120. }
  121. /**
  122. * Check if a received SMB is valid, if not then throw an exception
  123. *
  124. * @exception SMBException
  125. */
  126. public final void checkForError()
  127. throws SMBException {
  128. // Check if a valid SMB response has been received
  129. if ( isValidResponse() == false) {
  130. // Check for NT error codes
  131. if ( isLongErrorCode())
  132. throw new SMBException(SMBStatus.NTErr, getLongErrorCode());
  133. else
  134. throw new SMBException(getErrorClass(), getErrorCode());
  135. }
  136. }
  137. /**
  138. * Clear the data byte count
  139. */
  140. public final void clearBytes() {
  141. int offset = getByteOffset() - 2;
  142. DataPacker.putIntelShort(0, m_smbbuf, offset);
  143. }
  144. /**
  145. * Dump the SMB packet to the debug stream
  146. */
  147. public void DumpPacket() {
  148. // Dump the command type
  149. int pCount = getParameterCount();
  150. Debug.println("** SMB Packet Type: " + PacketType.getCommandName(getCommand()) + (isResponse() ? " [Response]" : ""));
  151. // Dump flags/secondary flags
  152. if ( Debug.EnableInfo && Session.hasDebugOption(Session.DBGDumpPacket)) {
  153. // Dump the packet length
  154. Debug.println("** SMB Packet Dump");
  155. Debug.println("Packet Length : " + getLength());
  156. Debug.println("Byte Offset: " + getByteOffset() + ", Byte Count: " + getByteCount());
  157. // Dump the flags
  158. Debug.println("Flags: " + getFlagsAsString());
  159. Debug.println("Flags2: " + getFlags2AsString());
  160. // Dump the security signature is signing is enabled
  161. if ( hasSecuritySignature())
  162. Debug.println("Signature: " + Long.toHexString(getSignature()));
  163. // Dump various ids
  164. Debug.print("TID=" + getTreeId());
  165. Debug.print(", PID=" + getProcessId());
  166. Debug.print(", UID=" + getUserId());
  167. Debug.println(", MID=" + getMultiplexId());
  168. // Dump parameter words/count
  169. Debug.println("Parameter Words: " + pCount);
  170. if ( pCount > 0) {
  171. StringBuffer str = new StringBuffer(128);
  172. int colCnt = (pCount + 3) & 0xFFFC;
  173. int curCol = 1;
  174. for (int i = 0; i < colCnt; i++) {
  175. // Check if there is a parameter to output
  176. if ( i < pCount) {
  177. str.append("P");
  178. str.append(Integer.toString(i + 1));
  179. if ( i < 9)
  180. str.append(" ");
  181. str.append("=");
  182. str.append(Integer.toString(getParameter(i)));
  183. str.append("/0x");
  184. str.append(Integer.toHexString(getParameter(i)));
  185. }
  186. // Pad the column
  187. while (str.length() < (curCol * 20))
  188. str.append(" ");
  189. if ( curCol == 4) {
  190. curCol = 1;
  191. Debug.println(str.toString());
  192. str.setLength(0);
  193. }
  194. else
  195. curCol++;
  196. }
  197. }
  198. // Response packet fields
  199. if ( isResponse()) {
  200. // Dump the error code
  201. if ( isLongErrorCode())
  202. Debug.println("Long error: 0x" + Integer.toHexString(getLongErrorCode()));
  203. else {
  204. Debug.print("Error text: ");
  205. Debug.println(SMBErrorText.ErrorString(getErrorClass(), getErrorCode()));
  206. }
  207. }
  208. }
  209. // Dump the raw data
  210. if ( Debug.EnableInfo && Session.hasDebugOption(Session.DBGHexDump)) {
  211. Debug.println("********** Raw SMB Data Dump **********");
  212. HexDump.Dump(m_smbbuf, getLength(), 4);
  213. }
  214. Debug.println("");
  215. }
  216. /**
  217. * Check if the error class/code match the specified error/class
  218. *
  219. * @param errClass int
  220. * @param errCode int
  221. * @return boolean
  222. */
  223. public final boolean equalsError(int errClass, int errCode) {
  224. if ( getErrorClass() == errClass && getErrorCode() == errCode)
  225. return true;
  226. return false;
  227. }
  228. /**
  229. * Send the SMB packet and receive the response packet
  230. *
  231. * @param sess Network session to send/receive the packet over.
  232. * @param rxPkt SMB packet to receive the response into.
  233. * @param throwerr If true then throw an I/O error if an invalid response is received.
  234. * @exception java.io.IOException If a network error occurs.
  235. * @exception SMBException If an SMB level error occurs
  236. */
  237. protected final synchronized void ExchangeLowLevelSMB(NetworkSession sess, SMBPacket rxPkt, boolean throwerr)
  238. throws java.io.IOException, SMBException {
  239. // Set multiplex id
  240. if ( getMultiplexId() == 0)
  241. setMultiplexId(1);
  242. // DEBUG
  243. if ( Session.hasDebug())
  244. DumpPacket();
  245. // Send the SMB request
  246. sess.Send(m_smbbuf, getLength());
  247. // Receive a response
  248. if ( sess.Receive(rxPkt.getBuffer()) >= MIN_RXLEN) {
  249. // Check if the response is for the current request
  250. if ( rxPkt.getCommand() == m_pkttype) {
  251. // DEBUG
  252. if ( Session.hasDebug())
  253. rxPkt.DumpPacket();
  254. // Check if a valid SMB response has been received
  255. if ( throwerr == true)
  256. checkForError();
  257. // Valid packet received, return to caller
  258. return;
  259. }
  260. }
  261. // Invalid receive packet
  262. throw new java.io.IOException("Invalid SMB Receive Packet");
  263. }
  264. /**
  265. * Send/receive an SMB protocol packet to the remote server.
  266. *
  267. * @param sess SMB session to send/receive data on.
  268. * @param rxPkt SMB packet to receive the response into.
  269. * @exception java.io.IOException If an I/O error occurs.
  270. * @exception SMBException If an SMB level error occurs.
  271. */
  272. public synchronized final void ExchangeSMB(Session sess, SMBPacket rxPkt)
  273. throws SMBException, IOException {
  274. // Call the main SMB exhchange method
  275. ExchangeSMB(sess, rxPkt, false);
  276. }
  277. /**
  278. * Send the SMB packet and receive the response packet
  279. *
  280. * @param sess SMB session to send/receive the packet over.
  281. * @param rxPkt SMB packet to receive the response into.
  282. * @param throwerr If true then throw an I/O error if an invalid response is received.
  283. * @exception java.io.IOException If an I/O error occurs.
  284. * @exception SMBException If an SMB level error occurs.
  285. */
  286. public synchronized final void ExchangeSMB(Session sess, SMBPacket rxPkt, boolean throwerr)
  287. throws SMBException, IOException {
  288. // Set the process id, user id and multiplex id
  289. setProcessId(sess.getProcessId());
  290. setUserId(sess.getUserId());
  291. if ( getMultiplexId() == 0)
  292. setMultiplexId(1);
  293. // DEBUG
  294. if ( Session.hasDebug())
  295. DumpPacket();
  296. // Get the network session
  297. NetworkSession netSess = sess.getSession();
  298. // Check if SMB signing is enabled, if so then set the SMB signature for the request
  299. if ( sess.hasSMBSigning())
  300. sess.signTxPacket(this);
  301. // Send the SMB request
  302. netSess.Send(m_smbbuf, getLength());
  303. // Receive the response, other asynchronous responses may be received before the response
  304. // for this request
  305. boolean rxValid = false;
  306. while (rxValid == false) {
  307. // Receive a response
  308. if ( netSess.Receive(rxPkt.getBuffer()) >= MIN_RXLEN) {
  309. // Check if the response is for the current request
  310. if ( rxPkt.getCommand() == m_pkttype) {
  311. // Check if SMB signing is enabled and received packet signatures should be
  312. // checked
  313. if ( sess.hasSMBSigning() && SessionFactory.isReceivedSMBSigningEnabled())
  314. sess.verifyRxPacket(this);
  315. // DEBUG
  316. if ( Session.hasDebug())
  317. rxPkt.DumpPacket();
  318. // Check if a valid SMB response has been received, done before checking SMB
  319. // signatures
  320. if ( throwerr == true)
  321. checkForError();
  322. // Valid packet received, return to caller
  323. return;
  324. }
  325. // Asynchronous response received, pass the packet to the session for processing
  326. sess.processAsynchResponse(rxPkt);
  327. }
  328. }
  329. // Invalid receive packet
  330. throw new java.io.IOException("Invalid SMB Receive Packet");
  331. }
  332. /**
  333. * Get the secondary command code
  334. *
  335. * @return Secondary command code
  336. */
  337. public final int getAndXCommand() {
  338. return (int) (m_smbbuf[ANDXCOMMAND] & 0xFF);
  339. }
  340. /**
  341. * Return the byte array used for the SMB packet
  342. *
  343. * @return Byte array used for the SMB packet.
  344. */
  345. public final byte[] getBuffer() {
  346. return m_smbbuf;
  347. }
  348. /**
  349. * Return the total buffer size available to the SMB request
  350. *
  351. * @return Total SMB buffer length available.
  352. */
  353. public final int getBufferLength() {
  354. return m_smbbuf.length - RFCNetBIOSProtocol.HEADER_LEN;
  355. }
  356. /**
  357. * Return the available buffer space for data bytes
  358. *
  359. * @return int
  360. */
  361. public final int getAvailableLength() {
  362. return m_smbbuf.length - DataPacker.longwordAlign(getByteOffset());
  363. }
  364. /**
  365. * Get the data byte count for the SMB packet
  366. *
  367. * @return Data byte count
  368. */
  369. public final int getByteCount() {
  370. // Calculate the offset of the byte count
  371. int pos = PARAMWORDS + (2 * getParameterCount());
  372. return (int) DataPacker.getIntelShort(m_smbbuf, pos);
  373. }
  374. /**
  375. * Get the data byte area offset within the SMB packet
  376. *
  377. * @return Data byte offset within the SMB packet.
  378. */
  379. public final int getByteOffset() {
  380. // Calculate the offset of the byte buffer
  381. int pCnt = getParameterCount();
  382. int pos = WORDCNT + (2 * pCnt) + 3;
  383. return pos;
  384. }
  385. /**
  386. * Get the SMB command
  387. *
  388. * @return SMB command code.
  389. */
  390. public final int getCommand() {
  391. return (int) (m_smbbuf[COMMAND] & 0xFF);
  392. }
  393. /**
  394. * Determine if normal or long error codes have been returned
  395. *
  396. * @return boolean
  397. */
  398. public final boolean hasLongErrorCode() {
  399. if ( (getFlags2() & FLG2_LONGERRORCODE) == 0)
  400. return false;
  401. return true;
  402. }
  403. /**
  404. * Determine if security signatures are being used
  405. *
  406. * @return boolean
  407. */
  408. public final boolean hasSecuritySignature() {
  409. if ( (getFlags2() & FLG2_SECURITYSIG) == 0)
  410. return false;
  411. return true;
  412. }
  413. /**
  414. * Determine if extended session setup is being used
  415. *
  416. * @return boolean
  417. */
  418. public final boolean hasExtendedSetup() {
  419. if ( (getFlags2() & FLG2_EXTENDEDSETUP) == 0)
  420. return false;
  421. return true;
  422. }
  423. /**
  424. * Return the saved packet type
  425. *
  426. * @return int
  427. */
  428. public final int isType() {
  429. return m_pkttype;
  430. }
  431. /**
  432. * Check if the packet contains ASCII or Unicode strings
  433. *
  434. * @return boolean
  435. */
  436. public final boolean isUnicode() {
  437. return (getFlags2() & FLG2_UNICODE) != 0 ? true : false;
  438. }
  439. /**
  440. * Check if the packet is using caseless filenames
  441. *
  442. * @return boolean
  443. */
  444. public final boolean isCaseless() {
  445. return (getFlags() & FLG_CASELESS) != 0 ? true : false;
  446. }
  447. /**
  448. * Check if long file names are being used
  449. *
  450. * @return boolean
  451. */
  452. public final boolean isLongFileNames() {
  453. return (getFlags2() & FLG2_LONGFILENAMES) != 0 ? true : false;
  454. }
  455. /**
  456. * Check if long error codes are being used
  457. *
  458. * @return boolean
  459. */
  460. public final boolean isLongErrorCode() {
  461. return (getFlags2() & FLG2_LONGERRORCODE) != 0 ? true : false;
  462. }
  463. /**
  464. * Get the SMB error class
  465. *
  466. * @return SMB error class.
  467. */
  468. public final int getErrorClass() {
  469. return (int) m_smbbuf[ERRORCLASS] & 0xFF;
  470. }
  471. /**
  472. * Get the SMB error code
  473. *
  474. * @return SMB error code.
  475. */
  476. public final int getErrorCode() {
  477. return (int) m_smbbuf[ERROR] & 0xFF;
  478. }
  479. /**
  480. * Get the SMB flags value.
  481. *
  482. * @return SMB flags value.
  483. */
  484. public final int getFlags() {
  485. return (int) m_smbbuf[FLAGS] & 0xFF;
  486. }
  487. /**
  488. * Get the SMB flags2 value.
  489. *
  490. * @return SMB flags2 value.
  491. */
  492. public final int getFlags2() {
  493. return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2);
  494. }
  495. /**
  496. * Calculate the total used packet length.
  497. *
  498. * @return Total used packet length.
  499. */
  500. public final int getLength() {
  501. return (getByteOffset() + getByteCount()) - RFCNetBIOSProtocol.HEADER_LEN;
  502. }
  503. /**
  504. * Get the long SMB error code
  505. *
  506. * @return Long SMB error code.
  507. */
  508. public final int getLongErrorCode() {
  509. return DataPacker.getIntelInt(m_smbbuf, ERRORCODE);
  510. }
  511. /**
  512. * Get the multiplex identifier.
  513. *
  514. * @return Multiplex identifier.
  515. */
  516. public final int getMultiplexId() {
  517. return DataPacker.getIntelShort(m_smbbuf, MID);
  518. }
  519. /**
  520. * Get a parameter word from the SMB packet.
  521. *
  522. * @param idx Parameter index (zero based).
  523. * @return Parameter word value.
  524. * @exception java.lang.IndexOutOfBoundsException If the parameter index is out of range.
  525. */
  526. public final int getParameter(int idx)
  527. throws java.lang.IndexOutOfBoundsException {
  528. // Range check the parameter index
  529. if ( idx > getParameterCount())
  530. throw new java.lang.IndexOutOfBoundsException();
  531. // Calculate the parameter word offset
  532. int pos = WORDCNT + (2 * idx) + 1;
  533. return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF);
  534. }
  535. /**
  536. * Get the specified parameter words, as an int value.
  537. *
  538. * @param idx Parameter index (zero based).
  539. * @return int
  540. */
  541. public final int getParameterLong(int idx) {
  542. int pos = WORDCNT + (2 * idx) + 1;
  543. return DataPacker.getIntelInt(m_smbbuf, pos);
  544. }
  545. /**
  546. * Get the parameter count
  547. *
  548. * @return Parameter word count.
  549. */
  550. public final int getParameterCount() {
  551. return (int) m_smbbuf[WORDCNT];
  552. }
  553. /**
  554. * Get the process indentifier (PID)
  555. *
  556. * @return Process identifier value.
  557. */
  558. public final int getProcessId() {
  559. return DataPacker.getIntelShort(m_smbbuf, PID);
  560. }
  561. /**
  562. * Get the SMB signing value, as a long value
  563. *
  564. * @return long
  565. */
  566. public final long getSignature() {
  567. return DataPacker.getIntelLong(m_smbbuf, SIGNATURE);
  568. }
  569. /**
  570. * Get the tree identifier (TID)
  571. *
  572. * @return Tree identifier (TID)
  573. */
  574. public final int getTreeId() {
  575. return DataPacker.getIntelShort(m_smbbuf, TID);
  576. }
  577. /**
  578. * Get the user identifier (UID)
  579. *
  580. * @return User identifier (UID)
  581. */
  582. public final int getUserId() {
  583. return DataPacker.getIntelShort(m_smbbuf, UID);
  584. }
  585. /**
  586. * Return the last sent packet time
  587. *
  588. * @return long
  589. */
  590. public final long getLastPacketSendTime() {
  591. return m_lastTxTime;
  592. }
  593. /**
  594. * Initialize the SMB packet buffer.
  595. */
  596. private final void InitializeBuffer() {
  597. // Set the packet signature
  598. m_smbbuf[SMBHEADER] = (byte) 0xFF;
  599. m_smbbuf[SMBHEADER + 1] = (byte) 'S';
  600. m_smbbuf[SMBHEADER + 2] = (byte) 'M';
  601. m_smbbuf[SMBHEADER + 3] = (byte) 'B';
  602. }
  603. /**
  604. * Determine if this packet is an SMB response, or command packet
  605. *
  606. * @return true if this SMB packet is a response, else false
  607. */
  608. public final boolean isResponse() {
  609. int resp = getFlags();
  610. if ( (resp & FLG_RESPONSE) != 0)
  611. return true;
  612. return false;
  613. }
  614. /**
  615. * Check if this is an SMB request packet
  616. *
  617. * @return boolean
  618. */
  619. public final boolean isRequest() {
  620. return ( getFlags() & FLG_RESPONSE) == 0 ? true : false;
  621. }
  622. /**
  623. * Check if the response packet is valid, ie. type and flags
  624. *
  625. * @return true if the SMB packet is a response packet and the response is valid, else false.
  626. */
  627. public final boolean isValidResponse() {
  628. // Check if this is a response packet, and the correct type of packet
  629. if ( isResponse() && getCommand() == m_pkttype) {
  630. // Check if standard error codes or NT 32-bit error codes are being used
  631. if ( (getFlags2() & FLG2_LONGERRORCODE) == 0) {
  632. if ( getErrorCode() == SMBStatus.Success)
  633. return true;
  634. }
  635. else if ( getLongErrorCode() == SMBStatus.NTSuccess)
  636. return true;
  637. }
  638. return false;
  639. }
  640. /**
  641. * Pack a byte (8 bit) value into the byte area
  642. *
  643. * @param val byte
  644. */
  645. public final void packByte(byte val) {
  646. m_smbbuf[m_pos++] = val;
  647. }
  648. /**
  649. * Pack a byte (8 bit) value into the byte area
  650. *
  651. * @param val int
  652. */
  653. public final void packByte(int val) {
  654. m_smbbuf[m_pos++] = (byte) val;
  655. }
  656. /**
  657. * Pack the specified bytes into the byte area
  658. *
  659. * @param byts byte[]
  660. * @param len int
  661. */
  662. public final void packBytes(byte[] byts, int len) {
  663. System.arraycopy(byts, 0, m_smbbuf, m_pos, len);
  664. m_pos += len;
  665. }
  666. /**
  667. * Pack a string using either ASCII or Unicode into the byte area
  668. *
  669. * @param str String
  670. * @param uni boolean
  671. */
  672. public final void packString(String str, boolean uni) {
  673. // Check for Unicode or ASCII
  674. if ( uni) {
  675. // Word align the buffer position, pack the Unicode string
  676. m_pos = DataPacker.wordAlign(m_pos);
  677. DataPacker.putUnicodeString(str, m_smbbuf, m_pos, true);
  678. m_pos += (str.length() * 2) + 2;
  679. }
  680. else {
  681. // Pack the ASCII string
  682. DataPacker.putString(str, m_smbbuf, m_pos, true);
  683. m_pos += str.length() + 1;
  684. }
  685. }
  686. /**
  687. * Pack a word (16 bit) value into the byte area
  688. *
  689. * @param val int
  690. */
  691. public final void packWord(int val) {
  692. DataPacker.putIntelShort(val, m_smbbuf, m_pos);
  693. m_pos += 2;
  694. }
  695. /**
  696. * Pack a 32 bit integer value into the byte area
  697. *
  698. * @param val int
  699. */
  700. public final void packInt(int val) {
  701. DataPacker.putIntelInt(val, m_smbbuf, m_pos);
  702. m_pos += 4;
  703. }
  704. /**
  705. * Pack a long integer (64 bit) value into the byte area
  706. *
  707. * @param val long
  708. */
  709. public final void packLong(long val) {
  710. DataPacker.putIntelLong(val, m_smbbuf, m_pos);
  711. m_pos += 8;
  712. }
  713. /**
  714. * Return the current byte area buffer position
  715. *
  716. * @return int
  717. */
  718. public final int getPosition() {
  719. return m_pos;
  720. }
  721. /**
  722. * Set the byte area buffer position
  723. *
  724. * @param pos int
  725. */
  726. public final void setPosition(int pos) {
  727. m_pos = pos;
  728. }
  729. /**
  730. * Unpack a byte value from the byte area
  731. *
  732. * @return int
  733. */
  734. public final int unpackByte() {
  735. return (int) m_smbbuf[m_pos++];
  736. }
  737. /**
  738. * Unpack a block of bytes from the byte area
  739. *
  740. * @param len int
  741. * @return byte[]
  742. */
  743. public final byte[] unpackBytes(int len) {
  744. if ( len <= 0)
  745. return null;
  746. byte[] buf = new byte[len];
  747. System.arraycopy(m_smbbuf, m_pos, buf, 0, len);
  748. m_pos += len;
  749. return buf;
  750. }
  751. /**
  752. * Unpack a word (16 bit) value from the byte area
  753. *
  754. * @return int
  755. */
  756. public final int unpackWord() {
  757. int val = DataPacker.getIntelShort(m_smbbuf, m_pos);
  758. m_pos += 2;
  759. return val;
  760. }
  761. /**
  762. * Unpack an integer (32 bit) value from the byte/parameter area
  763. *
  764. * @return int
  765. */
  766. public final int unpackInt() {
  767. int val = DataPacker.getIntelInt(m_smbbuf, m_pos);
  768. m_pos += 4;
  769. return val;
  770. }
  771. /**
  772. * Unpack a long integer (64 bit) value from the byte area
  773. *
  774. * @return long
  775. */
  776. public final long unpackLong() {
  777. long val = DataPacker.getIntelLong(m_smbbuf, m_pos);
  778. m_pos += 8;
  779. return val;
  780. }
  781. /**
  782. * Unpack a string from the byte area
  783. *
  784. * @param uni boolean
  785. * @return String
  786. */
  787. public final String unpackString(boolean uni) {
  788. // Check for Unicode or ASCII
  789. String ret = null;
  790. if ( uni) {
  791. // Word align the current buffer position
  792. m_pos = DataPacker.wordAlign(m_pos);
  793. ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, 255);
  794. if ( ret != null)
  795. m_pos += (ret.length() * 2) + 2;
  796. }
  797. else {
  798. // Unpack the ASCII string
  799. ret = DataPacker.getString(m_smbbuf, m_pos, 255);
  800. if ( ret != null)
  801. m_pos += ret.length() + 1;
  802. }
  803. // Return the string
  804. return ret;
  805. }
  806. /**
  807. * Unpack a string from the byte area
  808. *
  809. * @param len int
  810. * @param uni boolean
  811. * @return String
  812. */
  813. public final String unpackString(int len, boolean uni) {
  814. // Check for Unicode or ASCII
  815. String ret = null;
  816. if ( uni) {
  817. // Word align the current buffer position
  818. m_pos = DataPacker.wordAlign(m_pos);
  819. ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, len);
  820. if ( ret != null)
  821. m_pos += (ret.length() * 2);
  822. }
  823. else {
  824. // Unpack the ASCII string
  825. ret = DataPacker.getString(m_smbbuf, m_pos, len);
  826. if ( ret != null)
  827. m_pos += ret.length();
  828. }
  829. // Return the string
  830. return ret;
  831. }
  832. /**
  833. * Check if there is more data in the byte area
  834. *
  835. * @return boolean
  836. */
  837. public final boolean hasMoreData() {
  838. if ( m_pos < m_endpos)
  839. return true;
  840. return false;
  841. }
  842. /**
  843. * Receive an SMB packet on the spceified SMB session.
  844. *
  845. * @param sess SMB session to receive the packet on.
  846. * @exception java.io.IOException If a network error occurs
  847. * @exception SMBException If an SMB level error occurs
  848. */
  849. protected final void ReceiveSMB(Session sess)
  850. throws java.io.IOException, SMBException {
  851. // Call the main receive method
  852. ReceiveSMB(sess, true);
  853. }
  854. /**
  855. * Receive an SMB packet on the spceified SMB session.
  856. *
  857. * @param sess SMB session to receive the packet on.
  858. * @param throwErr Flag to indicate if an error is thrown if an error response is received
  859. * @exception java.io.IOException If a network error occurs
  860. * @exception SMBException If an SMB level error occurs
  861. */
  862. protected final void ReceiveSMB(Session sess, boolean throwErr)
  863. throws java.io.IOException, SMBException {
  864. // Get the network session
  865. NetworkSession netSess = sess.getSession();
  866. // Receive the response, other asynchronous responses may be received before the response
  867. // for this request
  868. boolean rxValid = false;
  869. while (rxValid == false) {
  870. // Receive a response
  871. if ( netSess.Receive(getBuffer()) >= MIN_RXLEN) {
  872. // Check if the response is for the current request
  873. if ( getCommand() == m_pkttype) {
  874. // DEBUG
  875. if ( Session.hasDebug())
  876. DumpPacket();
  877. // Check if SMB signing is enabled and received packet signatures should be
  878. // checked
  879. if ( sess.hasSMBSigning() && SessionFactory.isReceivedSMBSigningEnabled())
  880. sess.verifyRxPacket(this);
  881. // Check if a valid SMB response has been received
  882. if ( throwErr == true)
  883. checkForError();
  884. // Valid packet received, return to caller
  885. return;
  886. }
  887. // Asynchronous response received, pass the packet to the session for processing
  888. sess.processAsynchResponse(this);
  889. }
  890. else {
  891. // Not enough data received for an SMB header
  892. throw new java.io.IOException("Short NetBIOS receive");
  893. }
  894. }
  895. }
  896. /**
  897. * Receive an asynchronous SMB response from the server
  898. *
  899. * @param sess Session
  900. * @param waitTime Receive timeout in milliseconds, or zero for no timeout
  901. * @throws java.io.IOException
  902. * @throws SMBException
  903. */
  904. protected final void ReceiveAsynchSMB(Session sess, int waitTime)
  905. throws java.io.IOException, SMBException {
  906. // Get the network session
  907. NetworkSession netSess = sess.getSession();
  908. netSess.setTimeout(waitTime);
  909. // Receive, or wait for, a response
  910. if ( netSess.Receive(getBuffer()) >= MIN_RXLEN) {
  911. // Asynchronous response received, pass the packet to the session for processing
  912. sess.processAsynchResponse(this);
  913. }
  914. else {
  915. // Not enough data received for an SMB header
  916. throw new java.io.IOException("Short NetBIOS receive");
  917. }
  918. }
  919. /**
  920. * Send the SMB packet on the specified SMB session.
  921. *
  922. * @param sess SMB session to send this packet over.
  923. * @exception java.io.IOException If an I/O error occurs.
  924. */
  925. protected final void SendSMB(Session sess)
  926. throws java.io.IOException {
  927. // DEBUG
  928. if ( Session.hasDebug())
  929. DumpPacket();
  930. // Update the last send time
  931. m_lastTxTime = System.currentTimeMillis();
  932. // Check if SMB signing is enabled, if so then set the SMB signature for the request
  933. if ( sess.hasSMBSigning())
  934. sess.signTxPacket(this);
  935. // Send the SMB request
  936. sess.getSession().Send(m_smbbuf, getLength());
  937. }
  938. /**
  939. * Set the secondary SMB command
  940. *
  941. * @param cmd Secondary SMB command code.
  942. */
  943. public final void setAndXCommand(int cmd) {
  944. // Set the chained command packet type
  945. m_smbbuf[ANDXCOMMAND] = (byte) cmd;
  946. m_smbbuf[ANDXRESERVED] = (byte) 0;
  947. // If the AndX command is disabled clear the offset to the chained packet
  948. if ( cmd == PacketType.NoChainedCommand)
  949. setParameter(1, 0);
  950. }
  951. /**
  952. * Set the data byte count for this SMB packet
  953. *
  954. * @param cnt Data byte count.
  955. */
  956. public final void setByteCount(int cnt) {
  957. int offset = getByteOffset() - 2;
  958. DataPacker.putIntelShort(cnt, m_smbbuf, offset);
  959. }
  960. /**
  961. * Set the data byte count for this SMB packet
  962. */
  963. public final void setByteCount() {
  964. int offset = getByteOffset() - 2;
  965. int len = m_pos - getByteOffset();
  966. DataPacker.putIntelShort(len, m_smbbuf, offset);
  967. }
  968. /**
  969. * Set the data byte area in the SMB packet
  970. *
  971. * @param byts Byte array containing the data to be copied to the SMB packet.
  972. */
  973. public final void setBytes(byte[] byts) {
  974. int offset = getByteOffset() - 2;
  975. DataPacker.putIntelShort(byts.length, m_smbbuf, offset);
  976. offset += 2;
  977. for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++])
  978. ;
  979. }
  980. /**
  981. * Set the SMB command
  982. *
  983. * @param cmd SMB command code
  984. */
  985. public final void setCommand(int cmd) {
  986. m_pkttype = cmd;
  987. m_smbbuf[COMMAND] = (byte) cmd;
  988. }
  989. /**
  990. * Set the SMB error class.
  991. *
  992. * @param cl SMB error class.
  993. */
  994. public final void setErrorClass(int cl) {
  995. m_smbbuf[ERRORCLASS] = (byte) (cl & 0xFF);
  996. }
  997. /**
  998. * Set the SMB error code
  999. *
  1000. * @param sts SMB error code.
  1001. */
  1002. public final void setErrorCode(int sts) {
  1003. m_smbbuf[ERROR] = (byte) (sts & 0xFF);
  1004. }
  1005. /**
  1006. * Set a long error code (NT status code)
  1007. *
  1008. * @param lsts int
  1009. */
  1010. public final void setLongErrorCode(int lsts) {
  1011. DataPacker.putIntelInt(lsts, m_smbbuf, ERRORCODE);
  1012. }
  1013. /**
  1014. * Set the SMB flags value.
  1015. *
  1016. * @param flg SMB flags value.
  1017. */
  1018. public final void setFlags(int flg) {
  1019. m_smbbuf[FLAGS] = (byte) flg;
  1020. }
  1021. /**
  1022. * Set the SMB flags2 value.
  1023. *
  1024. * @param flg SMB flags2 value.
  1025. */
  1026. public final void setFlags2(int flg) {
  1027. DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2);
  1028. }
  1029. /**
  1030. * Set the multiplex identifier.
  1031. *
  1032. * @param mid Multiplex identifier
  1033. */
  1034. public final void setMultiplexId(int mid) {
  1035. DataPacker.putIntelShort(mid, m_smbbuf, MID);
  1036. }
  1037. /**
  1038. * Set the specified parameter word.
  1039. *
  1040. * @param idx Parameter index (zero based).
  1041. * @param val Parameter value.
  1042. */
  1043. public final void setParameter(int idx, int val) {
  1044. int pos = WORDCNT + (2 * idx) + 1;
  1045. DataPacker.putIntelShort(val, m_smbbuf, pos);
  1046. }
  1047. /**
  1048. * Set the specified parameter words.
  1049. *
  1050. * @param idx Parameter index (zero based).
  1051. * @param val Parameter value.
  1052. */
  1053. public final void setParameterLong(int idx, int val) {
  1054. int pos = WORDCNT + (2 * idx) + 1;
  1055. DataPacker.putIntelInt(val, m_smbbuf, pos);
  1056. }
  1057. /**
  1058. * Set the parameter count
  1059. *
  1060. * @param cnt Parameter word count.
  1061. */
  1062. public final void setParameterCount(int cnt) {
  1063. m_smbbuf[WORDCNT] = (byte) cnt;
  1064. }
  1065. /**
  1066. * Set the process identifier value (PID).
  1067. *
  1068. * @param pid Process identifier value.
  1069. */
  1070. public final void setProcessId(int pid) {
  1071. DataPacker.putIntelShort(pid, m_smbbuf, PID);
  1072. }
  1073. /**
  1074. * Set the packet sequence number, for connectionless commands.
  1075. *
  1076. * @param seq Sequence number.
  1077. */
  1078. public final void setSeqNo(int seq) {
  1079. DataPacker.putIntelShort(seq, m_smbbuf, SEQNO);
  1080. }
  1081. /**
  1082. * Set the session id.
  1083. *
  1084. * @param sid Session id.
  1085. */
  1086. public final void setSID(int sid) {
  1087. DataPacker.putIntelShort(sid, m_smbbuf, SID);
  1088. }
  1089. /**
  1090. * Set the SMB signing signature
  1091. *
  1092. * @param ival int
  1093. */
  1094. public final void setSignature(int ival) {
  1095. DataPacker.putIntelInt(ival, m_smbbuf, SIGNATURE);
  1096. DataPacker.putZeros(m_smbbuf, SIGNATURE + 4, 4);
  1097. }
  1098. /**
  1099. * Set the SMB signing signature
  1100. *
  1101. * @param lval long
  1102. */
  1103. public final void setSignature(long lval) {
  1104. DataPacker.putIntelLong(lval, m_smbbuf, SIGNATURE);
  1105. }
  1106. /**
  1107. * Set the SMB signing signature
  1108. *
  1109. * @param byts byte[]
  1110. * @param offset int
  1111. */
  1112. public final void setSignature(byte[] byts, int offset) {
  1113. System.arraycopy(byts, offset, m_smbbuf, SIGNATURE, 8);
  1114. }
  1115. /**
  1116. * Set the tree identifier (TID)
  1117. *
  1118. * @param tid Tree identifier value.
  1119. */
  1120. public final void setTreeId(int tid) {
  1121. DataPacker.putIntelShort(tid, m_smbbuf, TID);
  1122. }
  1123. /**
  1124. * Set the user identifier (UID)
  1125. *
  1126. * @param uid User identifier value.
  1127. */
  1128. public final void setUserId(int uid) {
  1129. DataPacker.putIntelShort(uid, m_smbbuf, UID);
  1130. }
  1131. /**
  1132. * Align the byte area pointer on an int (32bit) boundary
  1133. */
  1134. public final void alignBytePointer() {
  1135. m_pos = DataPacker.longwordAlign(m_pos);
  1136. }
  1137. /**
  1138. * Reset the byte/parameter pointer area for packing/unpacking data items from the packet
  1139. */
  1140. public final void resetBytePointer() {
  1141. m_pos = getByteOffset();
  1142. m_endpos = m_pos + getByteCount();
  1143. }
  1144. /**
  1145. * Reset the byte/parameter pointer area for packing/unpacking data items from the packet, and
  1146. * align the buffer on an int (32bit) boundary
  1147. */
  1148. public final void resetBytePointerAlign() {
  1149. m_pos = DataPacker.longwordAlign(getByteOffset());
  1150. m_endpos = m_pos + getByteCount();
  1151. }
  1152. /**
  1153. * Reset the byte/parameter pointer area for packing/unpacking paramaters from the packet
  1154. */
  1155. public final void resetParameterPointer() {
  1156. m_pos = PARAMWORDS;
  1157. }
  1158. /**
  1159. * Set the unpack pointer to the specified offset, for AndX processing
  1160. *
  1161. * @param off int
  1162. * @param len int
  1163. */
  1164. public final void setBytePointer(int off, int len) {
  1165. m_pos = off;
  1166. m_endpos = m_pos + len;
  1167. }
  1168. /**
  1169. * Skip a number of bytes in the parameter/byte area
  1170. *
  1171. * @param cnt int
  1172. */
  1173. public final void skipBytes(int cnt) {
  1174. m_pos += cnt;
  1175. }
  1176. /**
  1177. * Return the flags value as a string
  1178. *
  1179. * @return String
  1180. */
  1181. protected final String getFlagsAsString() {
  1182. // Get the flags value
  1183. int flags = getFlags();
  1184. if ( flags == 0)
  1185. return "<None>";
  1186. StringBuffer str = new StringBuffer();
  1187. if ( (flags & FLG_SUBDIALECT) != 0)
  1188. str.append("SubDialect,");
  1189. if ( (flags & FLG_CASELESS) != 0)
  1190. str.append("Caseless,");
  1191. if ( (flags & FLG_CANONICAL) != 0)
  1192. str.append("Canonical,");
  1193. if ( (flags & FLG_OPLOCK) != 0)
  1194. str.append("Oplock,");
  1195. if ( (flags & FLG_NOTIFY) != 0)
  1196. str.append("Notify,");
  1197. if ( (flags & FLG_RESPONSE) != 0)
  1198. str.append("Response,");
  1199. str.setLength(str.length() - 1);
  1200. return str.toString();
  1201. }
  1202. /**
  1203. * Return the flags2 value as a string
  1204. *
  1205. * @return String
  1206. */
  1207. protected final String getFlags2AsString() {
  1208. // Get the flags2 value
  1209. int flags2 = getFlags2();
  1210. if ( flags2 == 0)
  1211. return "<None>";
  1212. StringBuffer str = new StringBuffer();
  1213. if ( (flags2 & FLG2_LONGFILENAMES) != 0)
  1214. str.append("LongFilenames,");
  1215. if ( (flags2 & FLG2_EXTENDEDATTRIB) != 0)
  1216. str.append("ExtAttributes,");
  1217. if ( (flags2 & FLG2_SECURITYSIG) != 0)
  1218. str.append("SecuritySignatures,");
  1219. if ( (flags2 & FLG2_EXTENDEDSETUP) != 0)
  1220. str.append("ExtendedSetup,");
  1221. if ( (flags2 & FLG2_READIFEXE) != 0)
  1222. str.append("ReadIfEXE,");
  1223. if ( (flags2 & FLG2_LONGERRORCODE) != 0)
  1224. str.append("LongErrorCode,");
  1225. if ( (flags2 & FLG2_UNICODE) != 0)
  1226. str.append("Unicode,");
  1227. str.setLength(str.length() - 1);
  1228. return str.toString();
  1229. }
  1230. }