/// <summary> /// create negotiate request packet. client sends this packet to server to negotiate the dialects. /// </summary> /// <param name = "messageId"> /// This field SHOULD be the multiplex ID that is used to associate a response with a request, as specified in /// [CIFS] sections 2.4.2 and 3.1.5. /// </param> /// <param name = "flags"> /// The Flags field contains individual flags, as specified in [CIFS] sections 2.4.2 and 3.1.1. /// </param> /// <param name = "flags2"> /// The Flags2 field contains individual bit flags that, depending on the negotiated SMB dialect, indicate /// various client and server capabilities. /// </param> /// <param name = "dialects"> /// Array of null-terminated ASCII strings that indicate the SMB dialects supported by the client. /// </param> /// <returns>a smb negotiate packet. </returns> private SmbNegotiateRequestPacket CreateNegotiateRequest( ushort messageId, SmbHeader_Flags_Values flags, SmbHeader_Flags2_Values flags2, params string[] dialects) { // update global context using flags2 this.capability.IsSupportsExtendedSecurity = (flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY) == SmbHeader_Flags2_Values.SMB_FLAGS2_EXTENDED_SECURITY; this.capability.IsUnicode = (flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_UNICODE) == SmbHeader_Flags2_Values.SMB_FLAGS2_UNICODE; this.capability.IsKnowEAS = (flags2 & SmbHeader_Flags2_Values.SMB_FLAGS2_KNOWS_EAS) == SmbHeader_Flags2_Values.SMB_FLAGS2_KNOWS_EAS; // initialize the dialects SMB_Dialect[] smbDialects = new SMB_Dialect[dialects.Length]; for (int i = 0; i < smbDialects.Length; i++) { SMB_Dialect dialect = new SMB_Dialect(); // Each string MUST be prefixed with ASCII code 0x02 dialect.BufferFormat = 0x02; dialect.DialectString = dialects[i]; smbDialects[i] = dialect; } return new SmbNegotiateRequestPacket( this.cifsClient.CreateNegotiateRequest(messageId, (SmbFlags)flags, (SmbFlags2)flags2, smbDialects)); }
/// <summary> /// to create a Negotiate request packet. /// </summary> /// <param name="dialects">This is a variable length list of dialect identifiers in order of preference from /// least to most preferred</param> /// <returns>a Negotiate request packet</returns> /// <exception cref="System.NullReferenceException">There is no connection in context. </exception> public SmbNegotiateRequestPacket CreateNegotiateRequest( SMB_Dialect[] dialects) { return this.CreateNegotiateRequest(this.Context.GetMessageId(this.connectionId), this.defaultParameters.Flag, this.defaultParameters.Flag2, dialects); }
/// <summary> /// Set up connection with server. /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order /// </summary> /// <param name="server">server name of ip address</param> /// <param name="client">client name of ip address</param> /// <param name="domain">user's domain</param> /// <param name="userName">user's name</param> /// <param name="password">user's password</param> /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param> /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception> public override void Connect( string server, string client, string domain, string userName, string password, TimeSpan timeout, SecurityPackageType securityPackage = SecurityPackageType.Ntlm, bool useServerToken = false) { this.cifsClient.Connect(server, client); SmbPacket request, response; uint status; // Negotiate: SMB_Dialect dialectLM21 = new SMB_Dialect(); dialectLM21.BufferFormat = dialectBufferFormat; dialectLM21.DialectString = dialectLanMan21; SMB_Dialect dialectNTLM = new SMB_Dialect(); dialectNTLM.BufferFormat = dialectBufferFormat; dialectNTLM.DialectString = dialectNtLanMan; request = this.cifsClient.CreateNegotiateRequest(new SMB_Dialect[] { dialectLM21, dialectNTLM }); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); status = (response as SmbNegotiateResponsePacket).SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Negotiate Failed. ErrorCode: " + status); } // Session setup: CifsUserAccount userAccount = new CifsUserAccount(domain, userName, password); request = this.cifsClient.CreateSessionSetupRequest(userAccount, nativeOS, nativeLanMan); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); SmbSessionSetupAndxResponsePacket sessionSetupResponse = response as SmbSessionSetupAndxResponsePacket; status = sessionSetupResponse.SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Session Setup Failed. ErrorCode: " + status); } this.uid = sessionSetupResponse.SmbHeader.Uid; // Tree connect: string ipcAddress = "\\\\" + server + '\\' + ipcConnectString; request = this.cifsClient.CreateTreeConnectAndxRequest(this.uid, TreeConnectAndxFlags.NONE, ipcAddress, treeConnectService, null, null); this.cifsClient.SendPacket(request); response = this.cifsClient.ExpectPacket(timeout); SmbTreeConnectAndxResponsePacket treeConnectResponse = response as SmbTreeConnectAndxResponsePacket; status = treeConnectResponse.SmbHeader.Status; if (status != 0) { throw new ProtocolViolationException("Tree Connect Failed. ErrorCode: " + status); } this.treeId = treeConnectResponse.SmbHeader.Tid; }
/// <summary> /// to create a Negotiate request packet. /// </summary> /// <param name="messageId">This field SHOULD be the multiplex ID that is used to associate a response with a /// request.</param> /// <param name="flags">An 8-bit field of 1-bit flags describing various features in effect for the /// message</param> /// <param name="flags2">A 16-bit field of 1-bit flags that represent various features in effect for the /// message. Unspecified bits are reserved and MUST be zero.</param> /// <param name="dialects">This is a variable length list of dialect identifiers in order of preference from /// least to most preferred</param> /// <returns>a Negotiate request packet</returns> public SmbNegotiateRequestPacket CreateNegotiateRequest( ushort messageId, SmbFlags flags, SmbFlags2 flags2, SMB_Dialect[] dialects) { if (dialects == null) { dialects = new SMB_Dialect[0]; } SmbNegotiateRequestPacket packet = new SmbNegotiateRequestPacket(); packet.SmbHeader = CifsMessageUtils.CreateSmbHeader(SmbCommand.SMB_COM_NEGOTIATE, messageId, 0, 0, flags, flags2); SMB_COM_NEGOTIATE_Request_SMB_Parameters smbParameters = new SMB_COM_NEGOTIATE_Request_SMB_Parameters(); smbParameters.WordCount = 0; SMB_COM_NEGOTIATE_Request_SMB_Data smbData = new SMB_COM_NEGOTIATE_Request_SMB_Data(); List<byte> list = new List<byte>(); foreach (SMB_Dialect dialect in dialects) { list.Add(dialect.BufferFormat); list.AddRange(CifsMessageUtils.ToSmbStringBytes(dialect.DialectString, false)); } smbData.Dialects = list.ToArray(); smbData.ByteCount = (ushort)(smbData.Dialects.Length); packet.SmbParameters = smbParameters; packet.SmbData = smbData; return packet; }