1 17 package org.alfresco.filesys.server.auth.passthru; 18 19 import java.io.IOException ; 20 21 import org.alfresco.filesys.netbios.NetBIOSSession; 22 import org.alfresco.filesys.netbios.RFCNetBIOSProtocol; 23 import org.alfresco.filesys.smb.NetworkSession; 24 import org.alfresco.filesys.smb.PacketType; 25 import org.alfresco.filesys.smb.SMBException; 26 import org.alfresco.filesys.smb.SMBStatus; 27 import org.alfresco.filesys.util.DataPacker; 28 29 34 public class SMBPacket 35 { 36 37 39 public static final int SIGNATURE = RFCNetBIOSProtocol.HEADER_LEN; 40 public static final int COMMAND = 4 + RFCNetBIOSProtocol.HEADER_LEN; 41 public static final int ERRORCODE = 5 + RFCNetBIOSProtocol.HEADER_LEN; 42 public static final int ERRORCLASS = 5 + RFCNetBIOSProtocol.HEADER_LEN; 43 public static final int ERROR = 7 + RFCNetBIOSProtocol.HEADER_LEN; 44 public static final int FLAGS = 9 + RFCNetBIOSProtocol.HEADER_LEN; 45 public static final int FLAGS2 = 10 + RFCNetBIOSProtocol.HEADER_LEN; 46 public static final int PIDHIGH = 12 + RFCNetBIOSProtocol.HEADER_LEN; 47 public static final int SID = 18 + RFCNetBIOSProtocol.HEADER_LEN; 48 public static final int SEQNO = 20 + RFCNetBIOSProtocol.HEADER_LEN; 49 public static final int TID = 24 + RFCNetBIOSProtocol.HEADER_LEN; 50 public static final int PID = 26 + RFCNetBIOSProtocol.HEADER_LEN; 51 public static final int UID = 28 + RFCNetBIOSProtocol.HEADER_LEN; 52 public static final int MID = 30 + RFCNetBIOSProtocol.HEADER_LEN; 53 public static final int WORDCNT = 32 + RFCNetBIOSProtocol.HEADER_LEN; 54 public static final int ANDXCOMMAND = 33 + RFCNetBIOSProtocol.HEADER_LEN; 55 public static final int ANDXRESERVED = 34 + RFCNetBIOSProtocol.HEADER_LEN; 56 public static final int PARAMWORDS = 33 + RFCNetBIOSProtocol.HEADER_LEN; 57 58 60 public static final int TRANS_HEADERLEN = 66 + RFCNetBIOSProtocol.HEADER_LEN; 61 62 64 public static final int MIN_RXLEN = 32; 65 66 68 public static final int DEFAULT_BUFSIZE = 4096; 69 70 72 public static final int FLG_SUBDIALECT = 0x01; 73 public static final int FLG_CASELESS = 0x08; 74 public static final int FLG_CANONICAL = 0x10; 75 public static final int FLG_OPLOCK = 0x20; 76 public static final int FLG_NOTIFY = 0x40; 77 public static final int FLG_RESPONSE = 0x80; 78 79 81 public static final int FLG2_LONGFILENAMES = 0x0001; 82 public static final int FLG2_EXTENDEDATTRIB = 0x0002; 83 public static final int FLG2_EXTENDEDSECURITY = 0x0800; 84 public static final int FLG2_READIFEXE = 0x2000; 85 public static final int FLG2_LONGERRORCODE = 0x4000; 86 public static final int FLG2_UNICODE = 0x8000; 87 88 90 public static final int SEC_USER = 0x0001; 91 public static final int SEC_ENCRYPT = 0x0002; 92 93 95 public static final int RAW_READ = 0x0001; 96 public static final int RAW_WRITE = 0x0002; 97 98 100 private byte[] m_smbbuf; 101 102 104 private int m_pkttype; 105 106 108 protected int m_pos; 109 protected int m_endpos; 110 111 113 protected long m_lastTxTime; 114 115 118 public SMBPacket() 119 { 120 m_smbbuf = new byte[DEFAULT_BUFSIZE]; 121 InitializeBuffer(); 122 } 123 124 129 public SMBPacket(byte[] buf) 130 { 131 m_smbbuf = buf; 132 } 133 134 139 public SMBPacket(int siz) 140 { 141 m_smbbuf = new byte[siz]; 142 InitializeBuffer(); 143 } 144 145 150 public final void checkForError() throws SMBException 151 { 152 153 155 if (isValidResponse() == false) 156 { 157 158 160 if (isLongErrorCode()) 161 throw new SMBException(SMBStatus.NTErr, getLongErrorCode()); 162 else 163 throw new SMBException(getErrorClass(), getErrorCode()); 164 } 165 } 166 167 170 public final void clearBytes() 171 { 172 int offset = getByteOffset() - 2; 173 DataPacker.putIntelShort(0, m_smbbuf, offset); 174 } 175 176 183 public final boolean equalsError(int errClass, int errCode) 184 { 185 if (getErrorClass() == errClass && getErrorCode() == errCode) 186 return true; 187 return false; 188 } 189 190 199 protected final synchronized void ExchangeLowLevelSMB(NetworkSession sess, SMBPacket rxPkt, boolean throwerr) 200 throws java.io.IOException , SMBException 201 { 202 203 205 if (getMultiplexId() == 0) 206 setMultiplexId(1); 207 208 210 sess.Send(m_smbbuf, getLength()); 211 212 214 if (sess.Receive(rxPkt.getBuffer(), 0) >= MIN_RXLEN) 215 { 216 217 219 if (rxPkt.getCommand() == m_pkttype) 220 { 221 222 224 if (throwerr == true) 225 checkForError(); 226 227 229 return; 230 } 231 } 232 233 235 throw new java.io.IOException ("Invalid SMB Receive Packet"); 236 } 237 238 246 public synchronized final void ExchangeSMB(AuthenticateSession sess, SMBPacket rxPkt) throws SMBException, 247 IOException 248 { 249 250 252 ExchangeSMB(sess, rxPkt, false); 253 } 254 255 264 public synchronized final void ExchangeSMB(AuthenticateSession sess, SMBPacket rxPkt, boolean throwerr) 265 throws SMBException, IOException 266 { 267 268 270 setProcessId(sess.getProcessId()); 271 setUserId(sess.getUserId()); 272 273 if (getMultiplexId() == 0) 274 setMultiplexId(1); 275 276 278 NetworkSession netSess = sess.getSession(); 279 280 282 netSess.Send(m_smbbuf, getLength()); 283 284 287 boolean rxValid = false; 288 289 while (rxValid == false) 290 { 291 292 294 if (netSess.Receive(rxPkt.getBuffer(), RFCNetBIOSProtocol.TMO) >= MIN_RXLEN) 295 { 296 297 299 if (rxPkt.getCommand() == m_pkttype) 300 { 301 302 304 if (throwerr == true) 305 checkForError(); 306 307 309 return; 310 } 311 } 312 } 313 314 316 throw new java.io.IOException ("Invalid SMB Receive Packet"); 317 } 318 319 324 public final int getAndXCommand() 325 { 326 return (int) (m_smbbuf[ANDXCOMMAND] & 0xFF); 327 } 328 329 334 public final byte[] getBuffer() 335 { 336 return m_smbbuf; 337 } 338 339 344 public final int getBufferLength() 345 { 346 return m_smbbuf.length - RFCNetBIOSProtocol.HEADER_LEN; 347 } 348 349 354 public final int getAvailableLength() 355 { 356 return m_smbbuf.length - DataPacker.longwordAlign(getByteOffset()); 357 } 358 359 364 public final int getByteCount() 365 { 366 367 369 int pos = PARAMWORDS + (2 * getParameterCount()); 370 return (int) DataPacker.getIntelShort(m_smbbuf, pos); 371 } 372 373 378 public final int getByteOffset() 379 { 380 381 383 int pCnt = getParameterCount(); 384 int pos = WORDCNT + (2 * pCnt) + 3; 385 return pos; 386 } 387 388 393 public final int getCommand() 394 { 395 return (int) (m_smbbuf[COMMAND] & 0xFF); 396 } 397 398 403 public final boolean hasLongErrorCode() 404 { 405 if ((getFlags2() & FLG2_LONGERRORCODE) == 0) 406 return false; 407 return true; 408 } 409 410 415 public final int isType() 416 { 417 return m_pkttype; 418 } 419 420 425 public final boolean isUnicode() 426 { 427 return (getFlags2() & FLG2_UNICODE) != 0 ? true : false; 428 } 429 430 435 public final boolean isCaseless() 436 { 437 return (getFlags() & FLG_CASELESS) != 0 ? true : false; 438 } 439 440 445 public final boolean isLongFileNames() 446 { 447 return (getFlags2() & FLG2_LONGFILENAMES) != 0 ? true : false; 448 } 449 450 455 public final boolean isLongErrorCode() 456 { 457 return (getFlags2() & FLG2_LONGERRORCODE) != 0 ? true : false; 458 } 459 460 465 public final int getErrorClass() 466 { 467 return (int) m_smbbuf[ERRORCLASS] & 0xFF; 468 } 469 470 475 public final int getErrorCode() 476 { 477 return (int) m_smbbuf[ERROR] & 0xFF; 478 } 479 480 485 public final int getFlags() 486 { 487 return (int) m_smbbuf[FLAGS] & 0xFF; 488 } 489 490 495 public final int getFlags2() 496 { 497 return (int) DataPacker.getIntelShort(m_smbbuf, FLAGS2); 498 } 499 500 505 public final int getLength() 506 { 507 return (getByteOffset() + getByteCount()) - SIGNATURE; 508 } 509 510 515 public final int getLongErrorCode() 516 { 517 return DataPacker.getIntelInt(m_smbbuf, ERRORCODE); 518 } 519 520 525 public final int getMultiplexId() 526 { 527 return DataPacker.getIntelShort(m_smbbuf, MID); 528 } 529 530 537 public final int getParameter(int idx) throws java.lang.IndexOutOfBoundsException 538 { 539 540 542 if (idx > getParameterCount()) 543 throw new java.lang.IndexOutOfBoundsException (); 544 545 547 int pos = WORDCNT + (2 * idx) + 1; 548 return (int) (DataPacker.getIntelShort(m_smbbuf, pos) & 0xFFFF); 549 } 550 551 557 public final int getParameterLong(int idx) 558 { 559 int pos = WORDCNT + (2 * idx) + 1; 560 return DataPacker.getIntelInt(m_smbbuf, pos); 561 } 562 563 568 public final int getParameterCount() 569 { 570 return (int) m_smbbuf[WORDCNT]; 571 } 572 573 578 public final int getProcessId() 579 { 580 return DataPacker.getIntelShort(m_smbbuf, PID); 581 } 582 583 588 public final int getTreeId() 589 { 590 return DataPacker.getIntelShort(m_smbbuf, TID); 591 } 592 593 598 public final int getUserId() 599 { 600 return DataPacker.getIntelShort(m_smbbuf, UID); 601 } 602 603 608 public final long getLastPacketSendTime() 609 { 610 return m_lastTxTime; 611 } 612 613 616 private final void InitializeBuffer() 617 { 618 619 621 m_smbbuf[SIGNATURE] = (byte) 0xFF; 622 m_smbbuf[SIGNATURE + 1] = (byte) 'S'; 623 m_smbbuf[SIGNATURE + 2] = (byte) 'M'; 624 m_smbbuf[SIGNATURE + 3] = (byte) 'B'; 625 } 626 627 632 public final boolean isResponse() 633 { 634 int resp = getFlags(); 635 if ((resp & FLG_RESPONSE) != 0) 636 return true; 637 return false; 638 } 639 640 645 public final boolean isValidResponse() 646 { 647 648 650 if (isResponse() && getCommand() == m_pkttype) 651 { 652 653 655 if ((getFlags2() & FLG2_LONGERRORCODE) == 0) 656 { 657 if (getErrorCode() == SMBStatus.Success) 658 return true; 659 } 660 else if (getLongErrorCode() == SMBStatus.NTSuccess) 661 return true; 662 } 663 return false; 664 } 665 666 671 public final void packByte(byte val) 672 { 673 m_smbbuf[m_pos++] = val; 674 } 675 676 681 public final void packByte(int val) 682 { 683 m_smbbuf[m_pos++] = (byte) val; 684 } 685 686 692 public final void packBytes(byte[] byts, int len) 693 { 694 System.arraycopy(byts, 0, m_smbbuf, m_pos, len); 695 m_pos += len; 696 } 697 698 704 public final void packString(String str, boolean uni) 705 { 706 707 709 if (uni) 710 { 711 712 714 m_pos = DataPacker.wordAlign(m_pos); 715 DataPacker.putUnicodeString(str, m_smbbuf, m_pos, true); 716 m_pos += (str.length() * 2) + 2; 717 } 718 else 719 { 720 721 723 DataPacker.putString(str, m_smbbuf, m_pos, true); 724 m_pos += str.length() + 1; 725 } 726 } 727 728 733 public final void packWord(int val) 734 { 735 DataPacker.putIntelShort(val, m_smbbuf, m_pos); 736 m_pos += 2; 737 } 738 739 744 public final void packInt(int val) 745 { 746 DataPacker.putIntelInt(val, m_smbbuf, m_pos); 747 m_pos += 4; 748 } 749 750 755 public final void packLong(long val) 756 { 757 DataPacker.putIntelLong(val, m_smbbuf, m_pos); 758 m_pos += 8; 759 } 760 761 766 public final int getPosition() 767 { 768 return m_pos; 769 } 770 771 776 public final void setPosition(int pos) 777 { 778 m_pos = pos; 779 } 780 781 786 public final int unpackByte() 787 { 788 return (int) m_smbbuf[m_pos++]; 789 } 790 791 797 public final byte[] unpackBytes(int len) 798 { 799 if (len <= 0) 800 return null; 801 802 byte[] buf = new byte[len]; 803 System.arraycopy(m_smbbuf, m_pos, buf, 0, len); 804 m_pos += len; 805 return buf; 806 } 807 808 813 public final int unpackWord() 814 { 815 int val = DataPacker.getIntelShort(m_smbbuf, m_pos); 816 m_pos += 2; 817 return val; 818 } 819 820 825 public final int unpackInt() 826 { 827 int val = DataPacker.getIntelInt(m_smbbuf, m_pos); 828 m_pos += 4; 829 return val; 830 } 831 832 837 public final long unpackLong() 838 { 839 long val = DataPacker.getIntelLong(m_smbbuf, m_pos); 840 m_pos += 8; 841 return val; 842 } 843 844 850 public final String unpackString(boolean uni) 851 { 852 853 855 String ret = null; 856 857 if (uni) 858 { 859 860 862 m_pos = DataPacker.wordAlign(m_pos); 863 ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, 255); 864 if (ret != null) 865 m_pos += (ret.length() * 2) + 2; 866 } 867 else 868 { 869 870 872 ret = DataPacker.getString(m_smbbuf, m_pos, 255); 873 if (ret != null) 874 m_pos += ret.length() + 1; 875 } 876 877 879 return ret; 880 } 881 882 889 public final String unpackString(int len, boolean uni) 890 { 891 892 894 String ret = null; 895 896 if (uni) 897 { 898 899 901 m_pos = DataPacker.wordAlign(m_pos); 902 ret = DataPacker.getUnicodeString(m_smbbuf, m_pos, len); 903 if (ret != null) 904 m_pos += (ret.length() * 2); 905 } 906 else 907 { 908 909 911 ret = DataPacker.getString(m_smbbuf, m_pos, len); 912 if (ret != null) 913 m_pos += ret.length(); 914 } 915 916 918 return ret; 919 } 920 921 926 public final boolean hasMoreData() 927 { 928 if (m_pos < m_endpos) 929 return true; 930 return false; 931 } 932 933 939 private final void ReceiveSMB(NetBIOSSession sess) throws java.io.IOException 940 { 941 942 if (sess.Receive(m_smbbuf, RFCNetBIOSProtocol.TMO) >= MIN_RXLEN) 943 return; 944 945 947 throw new java.io.IOException ("Short NetBIOS receive"); 948 } 949 950 957 protected final void ReceiveSMB(AuthenticateSession sess) throws java.io.IOException , SMBException 958 { 959 960 962 ReceiveSMB(sess, true); 963 } 964 965 973 protected final void ReceiveSMB(AuthenticateSession sess, boolean throwErr) throws java.io.IOException , 974 SMBException 975 { 976 977 979 NetworkSession netSess = sess.getSession(); 980 981 984 boolean rxValid = false; 985 986 while (rxValid == false) 987 { 988 989 991 if (netSess.Receive(getBuffer(), RFCNetBIOSProtocol.TMO) >= MIN_RXLEN) 992 { 993 994 996 if (getCommand() == m_pkttype) 997 { 998 999 1001 if (throwErr == true) 1002 checkForError(); 1003 1004 1006 return; 1007 } 1008 } 1009 else 1010 { 1011 1012 1014 throw new java.io.IOException ("Short NetBIOS receive"); 1015 } 1016 } 1017 } 1018 1019 1025 protected final void SendSMB(AuthenticateSession sess) throws java.io.IOException 1026 { 1027 1028 1030 m_lastTxTime = System.currentTimeMillis(); 1031 1032 1034 sess.getSession().Send(m_smbbuf, getLength()); 1035 } 1036 1037 1042 public final void setAndXCommand(int cmd) 1043 { 1044 1045 1047 m_smbbuf[ANDXCOMMAND] = (byte) cmd; 1048 m_smbbuf[ANDXRESERVED] = (byte) 0; 1049 1050 1052 if (cmd == PacketType.NoChainedCommand) 1053 setParameter(1, 0); 1054 } 1055 1056 1061 public final void setByteCount(int cnt) 1062 { 1063 int offset = getByteOffset() - 2; 1064 DataPacker.putIntelShort(cnt, m_smbbuf, offset); 1065 } 1066 1067 1070 1071 public final void setByteCount() 1072 { 1073 int offset = getByteOffset() - 2; 1074 int len = m_pos - getByteOffset(); 1075 DataPacker.putIntelShort(len, m_smbbuf, offset); 1076 } 1077 1078 1083 public final void setBytes(byte[] byts) 1084 { 1085 int offset = getByteOffset() - 2; 1086 DataPacker.putIntelShort(byts.length, m_smbbuf, offset); 1087 1088 offset += 2; 1089 1090 for (int idx = 0; idx < byts.length; m_smbbuf[offset + idx] = byts[idx++]) 1091 ; 1092 } 1093 1094 1099 public final void setCommand(int cmd) 1100 { 1101 m_pkttype = cmd; 1102 m_smbbuf[COMMAND] = (byte) cmd; 1103 } 1104 1105 1110 public final void setErrorClass(int cl) 1111 { 1112 m_smbbuf[ERRORCLASS] = (byte) (cl & 0xFF); 1113 } 1114 1115 1120 public final void setErrorCode(int sts) 1121 { 1122 m_smbbuf[ERROR] = (byte) (sts & 0xFF); 1123 } 1124 1125 1130 public final void setFlags(int flg) 1131 { 1132 m_smbbuf[FLAGS] = (byte) flg; 1133 } 1134 1135 1140 public final void setFlags2(int flg) 1141 { 1142 DataPacker.putIntelShort(flg, m_smbbuf, FLAGS2); 1143 } 1144 1145 1150 public final void setMultiplexId(int mid) 1151 { 1152 DataPacker.putIntelShort(mid, m_smbbuf, MID); 1153 } 1154 1155 1161 public final void setParameter(int idx, int val) 1162 { 1163 int pos = WORDCNT + (2 * idx) + 1; 1164 DataPacker.putIntelShort(val, m_smbbuf, pos); 1165 } 1166 1167 1173 1174 public final void setParameterLong(int idx, int val) 1175 { 1176 int pos = WORDCNT + (2 * idx) + 1; 1177 DataPacker.putIntelInt(val, m_smbbuf, pos); 1178 } 1179 1180 1185 public final void setParameterCount(int cnt) 1186 { 1187 m_smbbuf[WORDCNT] = (byte) cnt; 1188 } 1189 1190 1195 public final void setProcessId(int pid) 1196 { 1197 DataPacker.putIntelShort(pid, m_smbbuf, PID); 1198 } 1199 1200 1205 public final void setSeqNo(int seq) 1206 { 1207 DataPacker.putIntelShort(seq, m_smbbuf, SEQNO); 1208 } 1209 1210 1215 public final void setSID(int sid) 1216 { 1217 DataPacker.putIntelShort(sid, m_smbbuf, SID); 1218 } 1219 1220 1225 public final void setTreeId(int tid) 1226 { 1227 DataPacker.putIntelShort(tid, m_smbbuf, TID); 1228 } 1229 1230 1235 public final void setUserId(int uid) 1236 { 1237 DataPacker.putIntelShort(uid, m_smbbuf, UID); 1238 } 1239 1240 1243 public final void alignBytePointer() 1244 { 1245 m_pos = DataPacker.longwordAlign(m_pos); 1246 } 1247 1248 1251 public final void resetBytePointer() 1252 { 1253 m_pos = getByteOffset(); 1254 m_endpos = m_pos + getByteCount(); 1255 } 1256 1257 1261 public final void resetBytePointerAlign() 1262 { 1263 m_pos = DataPacker.longwordAlign(getByteOffset()); 1264 m_endpos = m_pos + getByteCount(); 1265 } 1266 1267 1270 public final void resetParameterPointer() 1271 { 1272 m_pos = PARAMWORDS; 1273 } 1274 1275 1281 public final void setBytePointer(int off, int len) 1282 { 1283 m_pos = off; 1284 m_endpos = m_pos + len; 1285 } 1286 1287 1292 public final void skipBytes(int cnt) 1293 { 1294 m_pos += cnt; 1295 } 1296 1297 1302 protected final String getFlagsAsString() 1303 { 1304 1305 1307 int flags = getFlags(); 1308 if (flags == 0) 1309 return "<None>"; 1310 1311 StringBuffer str = new StringBuffer (); 1312 if ((flags & FLG_SUBDIALECT) != 0) 1313 str.append("SubDialect,"); 1314 1315 if ((flags & FLG_CASELESS) != 0) 1316 str.append("Caseless,"); 1317 1318 if ((flags & FLG_CANONICAL) != 0) 1319 str.append("Canonical,"); 1320 1321 if ((flags & FLG_OPLOCK) != 0) 1322 str.append("Oplock,"); 1323 1324 if ((flags & FLG_NOTIFY) != 0) 1325 str.append("Notify,"); 1326 1327 if ((flags & FLG_RESPONSE) != 0) 1328 str.append("Response,"); 1329 1330 str.setLength(str.length() - 1); 1331 1332 return str.toString(); 1333 } 1334 1335 1340 protected final String getFlags2AsString() 1341 { 1342 1343 1345 int flags2 = getFlags2(); 1346 1347 if (flags2 == 0) 1348 return "<None>"; 1349 1350 StringBuffer str = new StringBuffer (); 1351 1352 if ((flags2 & FLG2_LONGFILENAMES) != 0) 1353 str.append("LongFilenames,"); 1354 1355 if ((flags2 & FLG2_EXTENDEDATTRIB) != 0) 1356 str.append("ExtAttributes,"); 1357 1358 if ((flags2 & FLG2_READIFEXE) != 0) 1359 str.append("ReadIfEXE,"); 1360 1361 if ((flags2 & FLG2_LONGERRORCODE) != 0) 1362 str.append("LongErrorCode,"); 1363 1364 if ((flags2 & FLG2_UNICODE) != 0) 1365 str.append("Unicode,"); 1366 1367 str.setLength(str.length() - 1); 1368 1369 return str.toString(); 1370 } 1371} | Popular Tags |