/// <summary> /// Connects to the tree /// </summary> /// <param name = "password">password</param> /// <returns>true if ok, false if bad password</returns> private bool DoTreeConnect(string password) { if (Debug.DebugOn) Debug.WriteLine(Debug.Info, "SMB_COM_TREE_CONNECT_ANDX"); SetupSmbMessage(fMsg, SmbMessage.SMB_COM_TREE_CONNECT_ANDX); fMsg.setTID(0); /* UCHAR WordCount; Count of parameter words = 4 0: UCHAR AndXCommand; Secondary (X) command; 0xFF = none 1: UCHAR AndXReserved; Reserved (must be 0) 2: USHORT AndXOffset; Offset to next command WordCount 4: USHORT Flags; Additional information bit 0 set = disconnect Tid 6: USHORT PasswordLength; Length of Password[] USHORT ByteCount; Count of data bytes; min = 3 UCHAR Password[]; Password STRING Path[]; Server name and share name STRING Service[]; Service name */ fMsg.setWordCount(4); //AndXCommand fMsg.setByteParameterAt(0, 0xFF); // AndXReserved fMsg.setByteParameterAt(1, 0); // AndXOffset fMsg.setShortParameterAt(2, 0); // Flags fMsg.setShortParameterAt(4, 0); byte[] challenge_response = null; if ((fSecurityMode & SM_ENCRYPT_PASSWORDS) != 0) challenge_response = CifsLogin.GetNtAuthData(password, fEncryptionKey); else challenge_response = Util.Util.GetZtStringBytes(password); //Debug.WriteLine("password="******"A:"; break; case Share.IPC: dev = "IPC"; break; case Share.PRINTER: dev = "LPT1:"; break; default: dev = "A:"; break; } pos += data.SetZtAsciiStringAt(pos, dev); data.Size = pos; fMsg.setContent(data); fMsg.SendAndRecieve(fNBTSession, fMsg); int errorclass = fMsg.getErrorClass(); if (errorclass != CifsIoException.SUCCESS) { int errorcode = fMsg.getErrorCode(); if ((errorclass == CifsIoException.ERROR_SRV && errorcode == CifsIoException.SRV_BAD_PASSWORD) || (errorclass == CifsIoException.ERROR_DOS && errorcode == CifsIoException.DOS_NO_ACCESS)) return false; throw new CifsIoException(errorclass, errorcode); } fUID = fMsg.getUID(); fTID = fMsg.getTID(); return true; }
/// <summary> /// Set up the session /// </summary> /// <returns>true if ok, false if bad password</returns> private bool DoSessionSetup() { if (Debug.DebugOn) Debug.WriteLine(Debug.Info, "SMB_COM_SESSION_SETUP_ANDX"); byte[] case_sensitive_passwd = null; byte[] case_insensitive_passwd = null; string string_passwd = fShare.Login.Password; SetupSmbMessage(fMsg, SmbMessage.SMB_COM_SESSION_SETUP_ANDX); if (Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer) { Debug.WriteLine(Debug.Buffer, "New SMB Msg:"); Debug.WriteLine(Debug.Buffer, fMsg.getMessageBuffer(), 0, fMsg.getMessageSize()); } if ((fSecurityMode & SM_ENCRYPT_PASSWORDS) != 0) { case_sensitive_passwd = CifsLogin.GetNtAuthData(string_passwd, fEncryptionKey); case_insensitive_passwd = CifsLogin.GetLmAuthData(string_passwd, fEncryptionKey); } else { case_sensitive_passwd = CifsLogin.GetPasswordBytesUnicode(string_passwd); case_insensitive_passwd = CifsLogin.GetPasswordBytesAscii(string_passwd); } /* UCHAR WordCount; Count of parameter words = 13 0: UCHAR AndXCommand; Secondary (X) command; 0xFF = none 1: UCHAR AndXReserved; Reserved (must be 0) 2: USHORT AndXOffset; Offset to next command WordCount 4: USHORT MaxBufferSize; Client's maximum buffer size 6: USHORT MaxMpxCount; Actual maximum multiplexed pending requests 8: USHORT VcNumber; 0 = first (only), nonzero=additional VC number 10:ULONG SessionKey; Session key (valid iff VcNumber != 0) 14:USHORT CaseInsensitivePasswordLength; Account password size, ANSI 16:USHORT CaseSensitivePasswordLength; Account password size, Unicode 18:ULONG Reserved; must be 0 22:ULONG Capabilities; Client capabilities USHORT ByteCount; Count of data bytes; min = 0 UCHAR CaseInsensitivePassword[]; Account Password, ANSI UCHAR CaseSensitivePassword[]; Account Password, Unicode STRING AccountName[]; Account Name, Unicode STRING PrimaryDomain[]; Client's primary domain, Unicode STRING NativeOS[]; Client's native operating system, Unicode STRING NativeLanMan[]; Client's native LAN Manager type, Unicode */ fMsg.setWordCount(13); // AndXCommand fMsg.setByteParameterAt(0, 0xFF); // AndXReserved fMsg.setByteParameterAt(1, 0); // AndXOffset fMsg.setShortParameterAt(2, 0); // MaxBufferSize fMsg.setShortParameterAt(4, CIFS_MAX_BUFFER_SIZE); // MaxMpxCount fMsg.setShortParameterAt(6, 1); // VcNumber fMsg.setShortParameterAt(8, 0); // SessionKey fMsg.setIntParameterAt(10, 0); // CaseInsensitivePasswordLength fMsg.setShortParameterAt(14, case_insensitive_passwd.Length); // CaseSensitivePasswordLength fMsg.setShortParameterAt(16, case_sensitive_passwd.Length); // Reserved fMsg.setIntParameterAt(18, 0); // Capabilities fMsg.setIntParameterAt(22, CAP_UNICODE | CAP_NT_SMBS); var data = new MarshalBuffer(200); int pos = 0; Debug.WriteLine(Debug.Buffer, "Before Ins Pass:"******"After Ins Pass:"******"After Sens Pass:"******"After Acct Name:"); Debug.WriteLine(Debug.Buffer, data.GetBytes(), 0, data.Size); // Primary domain //string pdomain = Environment.GetEnvironmentVariable("CIFSDOMAIN"); // Can this be done better? string pdomain = "?"; // testing -- This works, but the above breaks... why? pos += data.SetZtAsciiStringAt(pos, pdomain); // Native OS pos += data.SetZtAsciiStringAt(pos, ".NET CIFS Client"); data.Size = pos; Debug.WriteLine(Debug.Buffer, "Final data:"); Debug.WriteLine(Debug.Buffer, data.GetBytes(), 0, data.Size); fMsg.setContent(data); if (Debug.DebugOn && Debug.DebugLevel >= Debug.Buffer) { Debug.WriteLine(Debug.Buffer, "Msg to send"); Debug.WriteLine(Debug.Buffer, fMsg.getMessageBuffer(), 0, fMsg.getMessageSize()); } fMsg.SendAndRecieve(fNBTSession, fMsg); if (!fMsg.isResponse()) throw new CifsIoException("PE3"); int errorclass = fMsg.getErrorClass(); if (errorclass != CifsIoException.SUCCESS) { int errorcode = fMsg.getErrorCode(); if ((errorclass == CifsIoException.ERROR_SRV && errorcode == CifsIoException.SRV_BAD_PASSWORD) || (errorclass == CifsIoException.ERROR_DOS && errorcode == CifsIoException.DOS_NO_ACCESS)) return false; throw new CifsIoException(errorclass, errorcode); } fUID = fMsg.getUID(); /* if(Debug.debugOn && Debug.debugLevel >= Debug.INFO) Debug.WriteLine("UID = " + fMsg.getUID()); */ if (fMsg.getWordCount() != 3) return true; /* UCHAR WordCount; Count of parameter words = 3 0: UCHAR AndXCommand; Secondary (X) command; 0xFF = none 1: UCHAR AndXReserved; Reserved (must be 0) 2: USHORT AndXOffset; Offset to next command WordCount 4: USHORT Action; Request mode: bit0 = logged in as GUEST 6: USHORT SecurityBlobLength length of Security Blob that follows in a later field 8: USHORT ByteCount; Count of data bytes UCHAR SecurityBlob[] SecurityBlob of length specified in field SecurityBlobLength STRING NativeOS[]; Server's native operating system STRING NativeLanMan[]; Server's native LAN Manager type STRING PrimaryDomain[]; Server's primary domain */ byte action = fMsg.getByteParameterAt(4); if ((action & 0x01) != 0) fLoggedAsGuest = true; int byte_count = fMsg.getContentSize(); int off = fMsg.getContentOffset(); int max_off = off + byte_count; /* // Skip security blob off += fMsg.getShortParameterAt(6); */ if (off >= max_off) return true; // Read Native OS fServerOS = fMsg.GetZtAsciiStringAt(off, max_off - off); off += fServerOS.Length + 1; if (off >= max_off) return true; // Read NativeLanMan fServerLanMan = fMsg.GetZtAsciiStringAt(off, max_off - off); off += fServerLanMan.Length + 1; if (off >= max_off) return true; // Read Primary Domain fServerPrimaryDomain = fNBTSession.WorkgroupName; return true; }
/// <summary> /// Receives SMB_COM_TRANSACTION /// </summary> /// <param name = "param">param parameters</param> /// <param name = "data">data buffer</param> internal void receiveTransaction(MarshalBuffer param, MarshalBuffer data) { if (Debug.DebugOn) Debug.WriteLine(Debug.Info, "Receive SMB_COM_TRANSACTION"); fMsg.receive(fNBTSession); int errorclass = fMsg.getErrorClass(); if (errorclass != CifsIoException.SUCCESS) throw new CifsIoException(errorclass, fMsg.getErrorCode()); /* UCHAR WordCount; Count of data bytes; value = 10 + SetupCount 0:USHORT TotalParameterCount; Total parameter bytes being sent 2:USHORT TotalDataCount; Total data bytes being sent 4:USHORT Reserved; 6:USHORT ParameterCount; Parameter bytes sent this buffer 8:USHORT ParameterOffset; Offset (from header start) to Parameters 10:USHORT ParameterDisplacement; Displacement of these Parameter bytes 12:USHORT DataCount; Data bytes sent this buffer 14:USHORT DataOffset; Offset (from header start) to data 16:USHORT DataDisplacement; Displacement of these data bytes 18:UCHAR SetupCount; Count of setup words 19:UCHAR Reserved2; Reserved (pad above to word) 20:USHORT Setup[SetupWordCount]; Setup words (# = SetupWordCount) USHORT ByteCount; Count of data bytes UCHAR Pad[]; Pad to SHORT or LONG UCHAR Parameters[ParameterCount]; Parameter bytes (# = ParameterCount) UCHAR Pad1[]; Pad to SHORT or LONG UCHAR Data[DataCount]; Data bytes (# = DataCount) */ int lparam = 0; int ldata = 0; // TotalParameterCount int tot_lparam = fMsg.getShortParameterAt(0); int tot_ldata = fMsg.getShortParameterAt(2); // alloca buffer param.Capacity = tot_lparam; data.Capacity = tot_ldata; while (true) { int rcv_lparam = fMsg.getShortParameterAt(6); int rcv_ldata = fMsg.getShortParameterAt(12); if (rcv_lparam + lparam > tot_lparam || rcv_ldata + ldata > tot_ldata) throw new SystemException("Invalid Data"); if (rcv_lparam > 0) { int off_param = fMsg.getShortParameterAt(8); int dsp_param = fMsg.getShortParameterAt(10); param.SetBytesAt(dsp_param, fMsg, off_param, rcv_lparam); } if (rcv_ldata > 0) { int off_data = fMsg.getShortParameterAt(14); int dsp_data = fMsg.getShortParameterAt(16); data.SetBytesAt(dsp_data, fMsg, off_data, rcv_ldata); } lparam += rcv_lparam; ldata += rcv_ldata; // get Total (they can shrink!) tot_lparam = fMsg.getShortParameterAt(0); tot_ldata = fMsg.getShortParameterAt(2); if (tot_lparam <= lparam && tot_ldata <= ldata) break; fMsg.receive(fNBTSession); errorclass = fMsg.getErrorClass(); if (errorclass != CifsIoException.SUCCESS) throw new CifsIoException(errorclass, fMsg.getErrorCode()); } // while loop param.Size = lparam; data.Size = ldata; }