public void Negotiate_SMB311_ContextID_NetName() { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send NEGOTIATE request with SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context."); DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "SMB2_ENCRYPTION_CAPABILITIES context and SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, encryptionAlgs, addNetNameContextId: true, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "[MS-SMB2] section 2.2.3.1.3: The SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context is specified in an SMB2 NEGOTIATE request to indicate the server name the client connects to. The server MUST ignore this context. " ); } ); }
public TestConfigBase(ITestSite site) { Site = site; WriteBufferLengthInKb = DEFAULT_WRITE_BUFFER_SIZE_IN_KB; string activeTDIsProperty = GetProperty("ActiveTDIs", false); if (!string.IsNullOrEmpty(activeTDIsProperty)) { ActiveTDIs = new List <string>(activeTDIsProperty.Split(';')); } else { ActiveTDIs = new List <string>(); } MaxSmbVersionSupported = ParsePropertyToEnum <DialectRevision>(GetProperty("MaxSmbVersionSupported"), "MaxSmbVersionSupported"); MaxSmbVersionClientSupported = ParsePropertyToEnum <DialectRevision>(GetProperty("MaxSmbVersionClientSupported"), "MaxSmbVersionClientSupported"); SupportedEncryptionAlgorithmList = ParsePropertyToList <EncryptionAlgorithm>("SupportedEncryptionAlgorithms"); SupportedCompressionAlgorithmList = ParsePropertyToList <CompressionAlgorithm>("SupportedCompressionAlgorithms"); }
protected byte[] SendAndRecieveSmb2Ap(FileServer fileServer, byte[] gssApiToken) { BaseTestSite.Log.Add(LogEntryKind.Comment, "SMB2 AP Exchange."); Smb2FunctionalTestClient smb2Client = new Smb2FunctionalTestClient(KerberosConstValue.TIMEOUT_FOR_SMB2AP); smb2Client.ConnectToServerOverTCP(System.Net.IPAddress.Parse(fileServer.IPAddress)); DialectRevision smb2Dialect = (DialectRevision)Enum.Parse(typeof(DialectRevision), fileServer.Smb2Dialect); DialectRevision selectedDialect; uint status = smb2Client.Negotiate( new DialectRevision[] { smb2Dialect }, SecurityMode_Values.NONE, Capabilities_Values.GLOBAL_CAP_DFS, Guid.NewGuid(), out selectedDialect); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Negotiate failed with error."); byte[] repToken; status = smb2Client.SessionSetup( SESSION_SETUP_Request_SecurityMode_Values.NONE, SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS, SecurityPackageType.Kerberos, fileServer.FQDN, gssApiToken, out repToken); if (status == Smb2Status.STATUS_SUCCESS) { status = smb2Client.LogOff(); BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Logoff failed with error."); } smb2Client.Disconnect(); return(repToken); }
public uint Smb2Negotiate(DialectRevision[] requestDialects, out DialectRevision selectedDialect) { uint status; NEGOTIATE_Response negotiateResponse; clientGuid = Guid.NewGuid(); status = this.Negotiate( 1, 1, Packet_Header_Flags_Values.NONE, this.messageId, requestDialects, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, CAPABILITIES, clientGuid, out selectedDialect, out this.gssToken, out packetHeader, out negotiateResponse ); this.Smb2MaxReadSize = negotiateResponse.MaxReadSize; this.Smb2MaxWriteSize = negotiateResponse.MaxWriteSize; CalculateSmb2AvailableCredits(1, packetHeader.CreditRequestResponse); return(status); }
private void NegotiateWithSpecificDialect(DialectRevision clientMaxDialectSupported) { DialectRevision serverMaxDialectSupported = TestConfig.MaxSmbVersionSupported; DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(clientMaxDialectSupported); if (clientMaxDialectSupported > TestConfig.MaxSmbVersionClientSupported) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured MaxSmbVersionClientSupported {0} is lower than {1}.", TestConfig.MaxSmbVersionClientSupported, clientMaxDialectSupported); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "Send Negotiate request with maximum dialect: {0}.", clientMaxDialectSupported); client.Negotiate( Packet_Header_Flags_Values.NONE, negotiateDialects, checker: (Packet_Header header, NEGOTIATE_Response response) => { DialectRevision expectedDialect = clientMaxDialectSupported < serverMaxDialectSupported ? clientMaxDialectSupported : serverMaxDialectSupported; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Check negotiate response contains expected dialect."); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.AreEqual(expectedDialect, response.DialectRevision, "Selected dialect should be {0}", expectedDialect); }); }
public bool CheckSmbDialect() { DetectorUtil.WriteLog("Check the supported SMB dialects of SUT..."); bool result = false; var dialects = new DialectRevision[] { DialectRevision.Smb30, DialectRevision.Smb302, DialectRevision.Smb311 }; var ipList = GetIPAdressOfSut(); // try all reachable SUT IP address foreach (var ip in ipList) { var supportedDialects = TryNegotiateDialects(ip, dialects); if (supportedDialects.Length > 0) { DetectionInfo.SupportedSmbDialects = supportedDialects; DetectorUtil.WriteLog(String.Format("SMB dialects supported by SUT: {0}", String.Join(",", supportedDialects))); result = true; break; } } if (result) { DetectorUtil.WriteLog("Finished", false, LogStyle.StepPassed); return(true); } else { DetectorUtil.WriteLog("Failed", false, LogStyle.StepFailed); return(false); } }
/// <summary> /// This method will send ComNegotiate request before sending a Negotiate request to simulate windows client behaviour. /// If ComNegotiate failed, the Negotiate request will still be sent. /// </summary> public uint MultiProtocolNegotiate( Smb2Client client, ushort creditCharge, ushort creditRequest, Packet_Header_Flags_Values flags, ulong messageId, DialectRevision[] dialects, SecurityMode_Values securityMode, Capabilities_Values capabilities, Guid clientGuid, out DialectRevision selectedDialect, out byte[] gssToken, out Packet_Header responseHeader, out NEGOTIATE_Response responsePayload) { uint status = client.MultiProtocolNegotiate( new string[] { "SMB 2.002", "SMB 2.???" }, out selectedDialect, out gssToken, out responseHeader, out responsePayload); if (responseHeader.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("ComNegotiate", responseHeader.Status); } PreauthIntegrityHashID[] preauthHashAlgs = null; EncryptionAlgorithm[] encryptionAlgs = null; // For back compatibility, if dialects contains SMB 3.11, preauthentication integrity context should be present. if (Array.IndexOf(dialects, DialectRevision.Smb311) >= 0) { preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; } status = client.Negotiate( creditCharge, creditRequest, flags, messageId, dialects, securityMode, capabilities, clientGuid, out selectedDialect, out gssToken, out responseHeader, out responsePayload, 0, preauthHashAlgs, encryptionAlgs); return(status); }
private void NegotiateWithNegotiateContexts( DialectRevision clientMaxDialectSupported, PreauthIntegrityHashID[] preauthHashAlgs, EncryptionAlgorithm[] encryptionAlgs = null, ResponseChecker <NEGOTIATE_Response> checker = null) { // ensure clientMaxDialectSupported higher than 3.11 if (clientMaxDialectSupported < DialectRevision.Smb311) { clientMaxDialectSupported = DialectRevision.Smb311; } DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(clientMaxDialectSupported); if (clientMaxDialectSupported > TestConfig.MaxSmbVersionClientSupported) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured MaxSmbVersionClientSupported {0} is lower than {1}.", TestConfig.MaxSmbVersionClientSupported, clientMaxDialectSupported); } status = client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, negotiateDialects, preauthHashAlgs: preauthHashAlgs, encryptionAlgs: encryptionAlgs, checker: checker); }
public TestConfigBase(ITestSite site) { Site = site; WriteBufferLengthInKb = DEFAULT_WRITE_BUFFER_SIZE_IN_KB; string activeTDIsProperty = GetProperty("ActiveTDIs", false); if (!string.IsNullOrEmpty(activeTDIsProperty)) { ActiveTDIs = new List <string>(activeTDIsProperty.Split(';')); } else { ActiveTDIs = new List <string>(); } MaxSmbVersionSupported = ParsePropertyToEnum <DialectRevision>(GetProperty("MaxSmbVersionSupported"), "MaxSmbVersionSupported"); MaxSmbVersionClientSupported = ParsePropertyToEnum <DialectRevision>(GetProperty("MaxSmbVersionClientSupported"), "MaxSmbVersionClientSupported"); SupportedEncryptionAlgorithmList = ParsePropertyToList <EncryptionAlgorithm>("SupportedEncryptionAlgorithms"); SupportedCompressionAlgorithmList = ParsePropertyToList <CompressionAlgorithm>("SupportedCompressionAlgorithms"); SendSignedRequest = Boolean.Parse(GetProperty("SendSignedRequest")); if (!SendSignedRequest && MaxSmbVersionSupported == DialectRevision.Smb311) { Site.Assume.Fail("The config \"SendSignedRequest\" should not be false if \"MaxSmbVersionSupported\" is \"Smb311\"."); } }
public void ComNegotiateRequest(Sequence <string> dialects) { Packet_Header responseHeader = new Packet_Header(); DialectRevision selectedDialect = DialectRevision.Smb2Unknown; NEGOTIATE_Response responsePayload = new NEGOTIATE_Response(); byte[] smb2ClientGssToken; ModelSmb2Status status = ModelSmb2Status.STATUS_SUCCESS; try { status = (ModelSmb2Status)smb2Client.MultiProtocolNegotiate(dialects.ToArray(), out selectedDialect, out smb2ClientGssToken, out responseHeader, out responsePayload); if (status != ModelSmb2Status.STATUS_SUCCESS) { selectedDialect = DialectRevision.Smb2Unknown; } this.NegotiateResponse(status, selectedDialect); if (selectedDialect == DialectRevision.Smb2Wildcard) { messageId = 1; } } catch { } }
public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportsEncryptionType clientSupportsEncryptionType) { Condition.IsTrue(state == ModelState.Initialized); Condition.IsNull(request); negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, config.MaxSmbVersionSupported); Connection_ClientCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION = (clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) ? true : false; if (ModelUtility.IsSmb3xFamily(negotiateDialect) && clientSupportsEncryptionType == ClientSupportsEncryptionType.ClientSupportsEncryption) { ModelHelper.Log(LogType.Requirement, "3.3.5.4: The Capabilities field MUST be set to a combination of zero or more of the following bit values, as specified in section 2.2.4:"); ModelHelper.Log(LogType.Requirement, "\tSMB2_GLOBAL_CAP_ENCRYPTION if Connection.Dialect belongs to the SMB 3.x dialect family, the server supports encryption, " + "and SMB2_GLOBAL_CAP_ENCRYPTION is set in the Capabilities field of the request."); // Encrpytion Model only applies to server that supports encryption. ModelHelper.Log(LogType.TestInfo, "Connection.Dialect is {0}, the server supports encryption and SMB2_GLOBAL_CAP_ENCRYPTION is set. " + "So SMB2_GLOBAL_CAP_ENCRYPTION bit is set in Capabilities field.", negotiateDialect); Connection_ServerCapabilities_SMB2_GLOBAL_CAP_ENCRYPTION = true; } state = ModelState.Connected; }
public static void SetupConnection() { Condition.IsTrue(State == ModelState.Initialized); Request = null; ModelHelper.Log( LogType.Requirement, "3.3.5.1: Connection.CommandSequenceWindow is set to a sequence window, as specified in section 3.3.1.1, with a starting receive sequence of 0 and a window size of 1"); MessageId = 0; ModelHelper.Log( LogType.TestInfo, "Connection.CommandSequenceWindow to receive sequence of 0."); ModelHelper.Log( LogType.Requirement, "Connection.NegotiateDialect is set to 0xFFFF"); NegotiateDialect = DialectRevision.Smb2Unknown; ModelHelper.Log( LogType.TestInfo, "Connection.NegotiateDialect is set to {0}", NegotiateDialect); State = ModelState.Connected; }
public void BVT_Negotiate_SMB311_Preauthentication_Encryption_GCM() { DialectRevision clientMaxDialectSupported = DialectRevision.Smb311; PreauthIntegrityHashID[] preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; EncryptionAlgorithm[] encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; if (TestConfig.MaxSmbVersionSupported < DialectRevision.Smb311) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured server max dialect is lower than 3.11."); } BaseTestSite.Log.Add( LogEntryKind.TestStep, "Send Negotiate request with dialect SMB 3.11, SMB2_PREAUTH_INTEGRITY_CAPABILITIES context and " + "SMB2_ENCRYPTION_CAPABILITIES context with AES-128-GCM preferred."); NegotiateWithNegotiateContexts( clientMaxDialectSupported, preauthHashAlgs, encryptionAlgs, checker: (Packet_Header header, NEGOTIATE_Response response) => { CheckNegotiateResponse(header, response, clientMaxDialectSupported, encryptionAlgs); } ); }
public ModelReplayChannel(DialectRevision Connection_NegotiateDialect, ReplayModelShareType Connection_Session_TreeConnect_Share_IsCA, bool Connection_ClientCapabilities_SupportPersistent) { this.Connection_NegotiateDialect = Connection_NegotiateDialect; this.Connection_Session_TreeConnect_Share_IsCA = Connection_Session_TreeConnect_Share_IsCA; this.Connection_ClientCapabilities_SupportPersistent = Connection_ClientCapabilities_SupportPersistent; }
public ModelConnection(DialectRevision dialect) { this.ConnectionState = ModelState.Initialized; this.NegotiateDialect = dialect; this.Session = null; this.Request = null; this.ConstrainedConnection = false; }
public static void PrepareOpen(ModelDialectRevision clientMaxDialect, DurableHandle durableHandle) { Condition.IsTrue(State == ModelState.Initialized); Connection_Dialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, Config.MaxSmbVersionSupported); State = ModelState.Connected; Open = new ModelOpen(durableHandle == DurableHandle.DurableHandle? true : false); }
/// <summary> /// Check whether actual dialect is bigger than expected dialect or not. /// </summary> /// <param name="expectedMinimalDialect">Expected minimal dialect.</param> /// <param name="response">Negotiate response header.</param> public void CheckNegotiateDialect(DialectRevision expectedMinimalDialect, NEGOTIATE_Response response) { if (response.DialectRevision < expectedMinimalDialect) { Site.Assert.Inconclusive( "This test case is not applicable due to that actual dialect {0} is less than expected minimal dialect {1}", (DialectRevision)response.DialectRevision, (DialectRevision)expectedMinimalDialect); } }
private void CheckNegotiateResponse( Packet_Header header, NEGOTIATE_Response response, DialectRevision clientMaxDialectSupported, EncryptionAlgorithm[] encryptionAlgs) { DialectRevision expectedDialect = clientMaxDialectSupported < TestConfig.MaxSmbVersionSupported ? clientMaxDialectSupported : TestConfig.MaxSmbVersionSupported; BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.AreEqual(expectedDialect, response.DialectRevision, "Selected dialect should be {0}", expectedDialect); if (expectedDialect >= DialectRevision.Smb311) { BaseTestSite.Assert.AreEqual( PreauthIntegrityHashID.SHA_512, client.SelectedPreauthIntegrityHashID, "[MS-SMB2] 3.3.5.4 The server MUST set Connection.PreauthIntegrityHashId to one of the hash algorithms " + "in the client's SMB2_PREAUTH_INTEGRITY_CAPABILITIES HashAlgorithms array."); if (encryptionAlgs != null) { BaseTestSite.Assert.IsTrue( TestConfig.SupportedEncryptionAlgorithmList.Contains(client.SelectedCipherID), "[MS-SMB2] 3.3.5.4 The server MUST set Connection.CipherId to one of the ciphers in the client's " + "SMB2_ENCRYPTION_CAPABILITIES Ciphers array in an implementation-specific manner."); } else { BaseTestSite.Assert.AreEqual( EncryptionAlgorithm.ENCRYPTION_NONE, client.SelectedCipherID, "[MS-SMB2] if client doesn't present SMB2_ENCRYPTION_CAPABILITIES context in negotiate request, " + "server should not present this context in negotiate response."); } } else { // If server supported dialect version is lower than 3.11, server should ignore the negotiate contexts. BaseTestSite.Assert.AreEqual( PreauthIntegrityHashID.HashAlgorithm_NONE, client.SelectedPreauthIntegrityHashID, "[MS-SMB2] The server must ignore the SMB2_PREAUTH_INTEGRITY_CAPABILITIES context if Connection.Dialect is less than 3.11. "); BaseTestSite.Assert.AreEqual( EncryptionAlgorithm.ENCRYPTION_NONE, client.SelectedCipherID, "[MS-SMB2] The server must ignore the SMB2_ENCRYPTION_CAPABILITIES context if Connection.Dialect is less than 3.11. "); } CheckServerCapabilities(response); }
public void CheckDialect(DialectRevision dialect) { if (MaxSmbVersionSupported < dialect) { Site.Assert.Inconclusive("Test case is applicable in servers that implement dialect {0}.", dialect); } if (MaxSmbVersionClientSupported < dialect) { Site.Assert.Inconclusive("Test case is applicable when the ptf property value of MaxSmbVersionClientSupported is larger than or equal to {0}.", dialect); } }
public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ClientSupportDirectoryLeasingType clientSupportDirectoryLeasingType) { Condition.IsTrue(state == ModelState.Initialized); // Current leasing only supports to test leasing on the file. So limit the exploration. Condition.IsTrue(clientSupportDirectoryLeasingType == ClientSupportDirectoryLeasingType.ClientNotSupportDirectoryLeasing); request = null; negotiateDialect = DialectRevision.Smb2Unknown; smb2Lease = null; negotiateDialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, config.MaxSmbVersionSupported); state = ModelState.Connected; }
private static void ComNegotiateHandleSmb2002InResponse(DialectRevision dialectRevision) { ModelHelper.Log( LogType.Requirement, "3.3.5.3.2: DialectRevision MUST be set to 0x0202.<218>"); //<218> Section 3.3.5.3.2: A Windows Vista RTM–based server sets DialectRevision to 6 Condition.IsTrue(dialectRevision == DialectRevision.Smb2002); ModelHelper.Log( LogType.Requirement, "3.3.5.3.2: Connection.Dialect MUST be set to \"2.002\", Connection.NegotiateDialect MUST be set to 0x0202, and the response is sent to the client"); NegotiateDialect = DialectRevision.Smb2002; }
public static void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ModelShareFlag shareFlag, ModelShareType shareType) { Condition.IsTrue(State == ModelState.Initialized); Open = null; Request = null; Connection_Dialect = DialectRevision.Smb2Unknown; Connection_Dialect = ModelHelper.DetermineNegotiateDialect(maxSmbVersionClientSupported, Config.MaxSmbVersionSupported); Share_ForceLevel2Oplock = shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK; Share_Type_Include_STYPE_CLUSTER_SOFS = shareType == ModelShareType.STYPE_CLUSTER_SOFS; State = ModelState.Connected; }
private bool CheckSMBDReadWriteRDMAV1Invalidate() { var dialectSupportingInvalidate = new DialectRevision[] { DialectRevision.Smb302, DialectRevision.Smb311 }; var dialects = dialectSupportingInvalidate.Intersect(DetectionInfo.SupportedSmbDialects); if (dialects.Count() == 0) { return(false); } bool result = CheckSMBDReadWrite(DetectionInfo.SupportedSmbDialects, Channel_Values.CHANNEL_RDMA_V1_INVALIDATE); return(result); }
/// <summary> /// Establish SMB2 connection over RDMA and open file /// 1. Connect to server over RDMA /// 2. SMBD Negotiation over RDMA /// 3. Establish SMB2 session and open file with specific dialect /// </summary> /// <param name="fileName">File name to open</param> /// <param name="negotiatedDialect">Optional to set the SMB2 dialect used for SMB2 connection</param> protected virtual void EstablishConnectionAndOpenFile(string fileName, DialectRevision negotiatedDialect = DialectRevision.Smb30) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "Establish SMB2 connection over RDMA and open file " + fileName); // Connect to server over RDMA NtStatus status = smbdAdapter.ConnectToServerOverRDMA(); BaseTestSite.Assert.AreEqual <NtStatus>(NtStatus.STATUS_SUCCESS, status, "Status of SMBD connection is {0}", status); // SMBD Negotiate status = smbdAdapter.SmbdNegotiate(); BaseTestSite.Assert.AreEqual <NtStatus>(NtStatus.STATUS_SUCCESS, status, "Status of SMBD negotiate is {0}", status); status = smbdAdapter.Smb2EstablishSessionAndOpenFile(fileName, negotiatedDialect); BaseTestSite.Assert.AreEqual <NtStatus>(NtStatus.STATUS_SUCCESS, status, "Status of SMB2 establish session and open file is {0}", status); }
public static void ReadConfigReturn(EncryptionConfig c) { Condition.IsTrue(state == ModelState.Uninitialized); Condition.IsNotNull(c); negotiateDialect = DialectRevision.Smb2Unknown; // Force SE to expand Config.MaxSmbVersionServerSupported Condition.IsTrue(c.MaxSmbVersionSupported == ModelDialectRevision.Smb2002 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb21 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb30 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb302); config = c; request = null; state = ModelState.Initialized; }
public static void ReadConfigReturn(CreditMgmtConfig c) { Condition.IsTrue(state == ModelState.Uninitialized); Condition.IsNotNull(c); Condition.IsTrue( c.MaxSmbVersionSupported == ModelDialectRevision.Smb2002 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb21 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb30 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb302); negotiateDialect = DialectRevision.Smb2Unknown; config = c; request = null; state = ModelState.Initialized; acceptingCondition = false; }
public static void ReadConfigReturn(SigningConfig c) { Condition.IsTrue(State == ModelState.Uninitialized); Condition.IsNotNull(c); NegotiateDialect = DialectRevision.Smb2Unknown; Condition.IsTrue(c.MaxSmbVersionSupported == ModelDialectRevision.Smb2002 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb21 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb30 || c.MaxSmbVersionSupported == ModelDialectRevision.Smb302); Config = c; Request = null; State = ModelState.Initialized; }
/// <summary> /// Convert dialect from DialectRevision to ModelDialectRevision. /// </summary> /// <param name="dialect">DialectRevision</param> /// <returns>ModelDialectRevision</returns> public static ModelDialectRevision GetModelDialectRevision(DialectRevision dialect) { ModelDialectRevision revision = (ModelDialectRevision)(uint)dialect; if (Enum.IsDefined(typeof(ModelDialectRevision), revision)) { return revision; } else if (dialect > DialectRevision.Smb302 && dialect != DialectRevision.Smb2Unknown) { return ModelDialectRevision.Smb302; // Model cases only test Dialect lower than 3.11 } else { throw new ArgumentException("Unexpected dialect"); } }
/// <summary> /// Convert dialect from DialectRevision to ModelDialectRevision. /// </summary> /// <param name="dialect">DialectRevision</param> /// <returns>ModelDialectRevision</returns> public static ModelDialectRevision GetModelDialectRevision(DialectRevision dialect) { ModelDialectRevision revision = (ModelDialectRevision)(uint)dialect; if (Enum.IsDefined(typeof(ModelDialectRevision), revision)) { return(revision); } else if (dialect > DialectRevision.Smb302 && dialect != DialectRevision.Smb2Unknown) { return(ModelDialectRevision.Smb302); // Model cases only test Dialect lower than 3.11 } else { throw new ArgumentException("Unexpected dialect"); } }
protected override uint Negotiate(ushort creditCharge, ushort creditRequest, ulong messageId, Guid clientGuid, out DialectRevision selectedDialect, out byte[] gssToken, out Packet_Header responseHeader, out NEGOTIATE_Response responsePayload) { return(client.Negotiate( creditCharge, creditRequest, Packet_Header_Flags_Values.NONE, messageId, new DialectRevision[] { this.dialect }, SecurityMode_Values.NONE, Capabilities_Values.NONE, clientGuid, out selectedDialect, out gssToken, out responseHeader, out responsePayload)); }
public bool CheckHigherDialect(DialectRevision MaxSupported, DialectRevision ComTarget) { if (MaxSupported == DialectRevision.Smb2Wildcard || MaxSupported == DialectRevision.Smb2Unknown) { return(false); } else { if (MaxSupported.GetHashCode() < ComTarget.GetHashCode()) { return(false); } else { return(true); } } }
/// <summary> /// Establish main channel, which includes NEGOTIATE, SESSION_SETUP and TREE_CONNECT /// </summary> /// <param name="requestDialect">Dialects in request</param> /// <param name="serverIp">Ip address on server side</param> /// <param name="clientIp">Ip address on client side</param> /// <param name="treeId">Out param for tree Id that connected</param> /// <param name="enableEncryptionPerShare">Set true if enable encryption on share, otherwise set false</param> private void EstablishMainChannel( DialectRevision[] requestDialect, IPAddress serverIp, IPAddress clientIp, out uint treeId, bool enableEncryptionPerShare = false) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Establish main channel to connect share {0} with following steps.", uncSharePath); mainChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp); #region Negotiate Capabilities_Values mainChannelClientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES | Capabilities_Values.GLOBAL_CAP_ENCRYPTION; status = mainChannelClient.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientGuid: clientGuid, capabilityValue: mainChannelClientCapabilities, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed."); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response); } ); #endregion #region SESSION_SETUP status = mainChannelClient.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); BaseTestSite.Log.Add( LogEntryKind.Debug, "Global encryption disabled"); #endregion #region Retrieve 2nd IP on server for alternative channel if there is #region TREE_CONNECT to IPC$ string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName); status = mainChannelClient.TreeConnect(ipcPath, out treeId); #endregion if (TestConfig.UnderlyingTransport == Smb2TransportType.Tcp) { #region IOCTL FSCTL_QUERY_NETWORK_INTERFACE_INFO NETWORK_INTERFACE_INFO_Response[] networkInfoResponses; string interfaceAddress; bool secondAddressQueried = false; status = mainChannelClient.QueryNetworkInterfaceInfo(treeId, out networkInfoResponses); foreach (NETWORK_INTERFACE_INFO_Response netInfoResp in networkInfoResponses) { interfaceAddress = netInfoResp.AddressStorage.Address; if (interfaceAddress != null) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Get NETWORK_INTERFACE_INFO: " + interfaceAddress); if (interfaceAddress == serverIps[1].ToString()) { secondAddressQueried = true; BaseTestSite.Log.Add( LogEntryKind.Debug, "Address queried by IOCTL request with FSCTL_QUERY_NETWORK_INTERFACE_INFO matches server second address {0}", serverIps[1].ToString()); break; } } } BaseTestSite.Assert.IsTrue( secondAddressQueried, "Second address {0} should be queried by IOCTL request with FSCTL_QUERY_NETWORK_INTERFACE_INFO", serverIps[1].ToString()); #endregion } #endregion #region TREE_CONNECT to share status = mainChannelClient.TreeConnect( uncSharePath, out treeId, (Packet_Header header, TREE_CONNECT_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "TreeConnect should succeed."); if (enableEncryptionPerShare) { BaseTestSite.Assert.AreEqual( ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA, ShareFlags_Values.SHAREFLAG_ENCRYPT_DATA & response.ShareFlags, "Server should set SMB2_SHAREFLAG_ENCRYPT_DATA for ShareFlags field in TREE_CONNECT response"); } }); mainChannelClient.SetTreeEncryption(treeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "Finish establishing main channel to connect share {0}", uncSharePath); }
private void AppInstanceVersionTest( ulong? firstClientAppInstanceVersionHigh, ulong? firstClientAppInstanceVersionLow, DialectRevision firstClientDialect, ulong? secondClientAppInstanceVersionHigh, ulong? secondClientAppInstanceVersionLow, DialectRevision secondClientDialect, uint expectedReopenStatus, uint expectedInitialOpenStatusAfterReopen, bool logoff = true ) { string content = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb); #region Client1 connects to Server BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client1 connects to the file server by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); uint treeIdForInitialOpen; FILEID fileIdForInitialOpen; Guid appInstanceId = Guid.NewGuid(); SendCreateRequestWithSpecificAppInstanceversion( clientForInitialOpen, appInstanceId, firstClientAppInstanceVersionHigh, firstClientAppInstanceVersionLow, firstClientDialect, Smb2Status.STATUS_SUCCESS, out treeIdForInitialOpen, out fileIdForInitialOpen ); #endregion #region Client2 connects to Server BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client2 connects to file server by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT with dialect {0}.", secondClientDialect); uint treeIdForReOpen; FILEID fileIdForReOpen; SendCreateRequestWithSpecificAppInstanceversion( clientForReOpen, appInstanceId, secondClientAppInstanceVersionHigh, secondClientAppInstanceVersionLow, secondClientDialect, expectedReopenStatus, out treeIdForReOpen, out fileIdForReOpen ); #endregion #region Client1 reconnects to Server BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client1 sends another WRITE request."); clientForInitialOpen.Write( treeIdForInitialOpen, fileIdForInitialOpen, content, checker: (header, response) => { BaseTestSite.Assert.AreEqual( expectedInitialOpenStatusAfterReopen, header.Status, (expectedInitialOpenStatusAfterReopen == Smb2Status.STATUS_SUCCESS ? "The initial open is not closed. Write should succeed. Actually server returns with {0}." : "The initial open is closed. Write should not succeed. Actually server returns with {0}."), Smb2Status.GetStatusCode(header.Status)); }); #endregion #region Disconnect Client1 or Client2 to Server according to the expectedReopenStatus and expectedInitialOpenStatusAfterReopen if (expectedReopenStatus == Smb2Status.STATUS_SUCCESS) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client2 by sending CLOSE requests."); clientForReOpen.Close(treeIdForReOpen, fileIdForReOpen); } BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client2 by sending TREE_DISCONNECT request."); clientForReOpen.TreeDisconnect(treeIdForReOpen); if (logoff) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client1 by sending the following requests: LOG_OFF; DISCONNECT"); Logoff(clientForReOpen); } if (expectedInitialOpenStatusAfterReopen == Smb2Status.STATUS_SUCCESS) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client2 by sending CLOSE requests."); clientForInitialOpen.Close(treeIdForInitialOpen, fileIdForInitialOpen); } BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client2 by sending TREE_DISCONNECT request."); clientForInitialOpen.TreeDisconnect(treeIdForInitialOpen); if (logoff) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Tear down the client2 by sending the following requests: LOG_OFF; DISCONNECT"); Logoff(clientForInitialOpen); } #endregion }
public bool CheckHigherDialect(DialectRevision MaxSupported, DialectRevision ComTarget) { if (MaxSupported == DialectRevision.Smb2Wildcard || MaxSupported == DialectRevision.Smb2Unknown) return false; else { if (MaxSupported.GetHashCode() < ComTarget.GetHashCode()) return false; else return true; } }
public ModelReplayChannel(DialectRevision Connection_NegotiateDialect) { this.Connection_NegotiateDialect = Connection_NegotiateDialect; }
/// <summary> /// Common method used to connect to target server, including the following message sequences: /// 1. Negotiate /// 2. Session Setup /// 3. Tree Connect /// </summary> /// <param name="smb2Dialect"></param> /// <param name="client"></param> /// <param name="clientGuid"></param> /// <param name="account"></param> /// <param name="connectShareType"></param> /// <param name="treeId"></param> /// <param name="clientBeforeDisconnection"></param> protected virtual void Connect(DialectRevision smb2Dialect, Smb2FunctionalClient client, Guid clientGuid, AccountCredential account, ConnectShareType connectShareType, out uint treeId, Smb2FunctionalClient clientBeforeDisconnection) { DialectRevision[] requestDialect = Smb2Utility.GetDialects(smb2Dialect); Capabilities_Values clientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES; SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED; IPAddress targetIPAddress = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerIP : testConfig.SutIPAddress; string targetServer = (connectShareType == ConnectShareType.CAShare) ? testConfig.CAShareServerName : testConfig.SutComputerName; client.ConnectToServer(TestConfig.UnderlyingTransport, targetServer, targetIPAddress); BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends NEGOTIATE request.", clientGuid); client.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientSecurityMode, clientCapabilities, clientGuid); if (null != clientBeforeDisconnection) { BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request to reconnect to the previous session.", clientGuid); client.ReconnectSessionSetup( clientBeforeDisconnection, testConfig.DefaultSecurityPackage, targetServer, account, testConfig.UseServerGssToken); } else { BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends SESSION_SETUP request.", clientGuid); client.SessionSetup( testConfig.DefaultSecurityPackage, targetServer, account, testConfig.UseServerGssToken); } BaseTestSite.Log.Add(LogEntryKind.TestStep, "The client with clientGuid {0} sends TREE_CONNECT request.", clientGuid); client.TreeConnect( durableHandleUncSharePath, out treeId, checker: (header, response) => { BaseTestSite.Log.Add( LogEntryKind.Debug, "Capabilities in TREE_CONNECT response: {0}", response.Capabilities); BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should be successful", header.Command); if (connectShareType == ConnectShareType.CAShare) { BaseTestSite.Assert.AreEqual( Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY, Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities, "The share should have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability"); } if (connectShareType == ConnectShareType.BasicShare) { BaseTestSite.Assert.AreNotEqual( Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY, Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY & response.Capabilities, "The share should not have SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY capability"); } }); }
private void InternalConnectShare(string domain, string userName, string password, string shareName, TimeSpan timeout, SecurityPackageType securityPackage, bool useServerToken) { uint status; DialectRevision selectedDialect; Packet_Header header; byte[] serverGssToken; Array allDialects = Enum.GetValues(typeof(DialectRevision)); DialectRevision[] validDialects = new DialectRevision[allDialects.Length - 2]; int index = 0; foreach (var dialect in allDialects) { if ((DialectRevision)dialect != DialectRevision.Smb2Unknown && (DialectRevision)dialect != DialectRevision.Smb2Wildcard) { validDialects[index++] = (DialectRevision)dialect; } } PreauthIntegrityHashID[] preauthIntegrityHashIDArray = null; EncryptionAlgorithm[] encryptionAlgorithmArray = null; if (validDialects.Contains(DialectRevision.Smb311)) { preauthIntegrityHashIDArray = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; encryptionAlgorithmArray = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; } // Negotiate: NEGOTIATE_Response negotiateResponse; CheckStatusCode( client.Negotiate( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, // Will negotiate highest dialect server supports validDialects, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_ENCRYPTION | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_LARGE_MTU, clientGuid, out selectedDialect, out serverGssToken, out header, out negotiateResponse, preauthHashAlgs: preauthIntegrityHashIDArray, encryptionAlgs: encryptionAlgorithmArray)); negotiatedDialect = selectedDialect; serverCapabilities = (Capabilities_Values)negotiateResponse.Capabilities; // 3.2.5.2: If the SecurityMode field in the SMB2 header of the response has the SMB2_NEGOTIATE_SIGNING_REQUIRED bit set, // the client MUST set Connection.RequireSigning to TRUE. // 3.2.5.3.1: If the global setting RequireMessageSigning is set to TRUE or // Connection.RequireSigning is set to TRUE then Session.SigningRequired MUST be set to TRUE bool session_SigningRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); if (session_SigningRequired) { // 3.2.4.1.1: If the client signs the request, it MUST set the SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header. headerFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED; } // Session setup: SESSION_SETUP_Response sessionSetupResponse; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( securityPackage, new AccountCredential(domain, userName, password), Smb2Utility.GetCifsServicePrincipalName(serverPrincipleName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); if (securityPackage == SecurityPackageType.Negotiate) sspiClientGss.Initialize(serverGssToken); else sspiClientGss.Initialize(null); do { status = client.SessionSetup( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, sessionId, SESSION_SETUP_Request_Flags.NONE, SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS, 0, sspiClientGss.Token, out sessionId, out serverGssToken, out header, out sessionSetupResponse); CheckStatusCode(status); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && serverGssToken != null && serverGssToken.Length > 0) { sspiClientGss.Initialize(serverGssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); // 3.2.4.1.1 If Connection.Dialect is "3.1.1" and the message being sent is a TREE_CONNECT Request and the session identified by SessionId has Session.EncryptData equal to FALSE bool treeconnect_SigningRequired = session_SigningRequired || (selectedDialect >= DialectRevision.Smb311); client.GenerateCryptoKeys(sessionId, sspiClientGss.SessionKey, treeconnect_SigningRequired, false); this.sessionId = header.SessionId; // Session Key will be used in the MS-LSA SDK, see LsaClient.cs Line 179 SessionKey // Insert the session key to the global context Smb2ClientSession smb2CliSession = new Smb2ClientSession(); smb2CliSession.SessionKey = client.GetSessionKeyForAuthenticatedContext(sessionId); Smb2ClientConnection smb2CliConn = new Smb2ClientConnection(); smb2CliConn.SessionTable = new Dictionary<ulong, Smb2ClientSession>(); smb2CliConn.SessionTable.Add(sessionId, smb2CliSession); context.ConnectionTable = new Dictionary<string, Smb2ClientConnection>(); context.ConnectionTable.Add("Smb2ClientConnection", smb2CliConn); // Tree connect: TREE_CONNECT_Response treeConnectResponse; status = client.TreeConnect( 1, 1, treeconnect_SigningRequired? headerFlags| Packet_Header_Flags_Values.FLAGS_SIGNED:headerFlags, messageId++, sessionId, "\\\\" + serverPrincipleName + "\\" + shareName, out treeId, out header, out treeConnectResponse); this.treeId = header.TreeId; // For the messages followed by TREE_CONNECT, set them as signed/not signed following the normal proces client.EnableSessionSigningAndEncryption(sessionId, session_SigningRequired, false); }
public static void PrepareOpen( ModelDialectRevision clientMaxDialect, PersistentBitType persistentBit, CAShareType connectToCAShare, ModelHandleType modelHandleType, OplockLeaseType oplockLeaseType) { Condition.IsNull(Request); Condition.IsNull(Open); // CAShare, Persistent Handle , Durable Handle v2 and Lease V2 are only applied for SMB 3.x family. Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), connectToCAShare == CAShareType.NonCAShare); Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), persistentBit == PersistentBitType.PersistentBitNotSet); Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), modelHandleType == ModelHandleType.DurableHandleV1); // Case will go to non-accpeting state if clientMaxDialect > Config.MaxSmbVersionSupported. NegotiateDialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, Config.MaxSmbVersionSupported); // Restrict the params combination Combination.Pairwise(clientMaxDialect, persistentBit, connectToCAShare, modelHandleType, oplockLeaseType); Share_IsCA = (connectToCAShare == CAShareType.CAShare); Open = new HandleModelOpen(); Open.IsConnectionExisted = true; Open.IsSessionExisted = true; if (oplockLeaseType == OplockLeaseType.LeaseV1) { Open.IsLeaseExisted = true; Open.LeaseVersion = 1; } else if (oplockLeaseType == OplockLeaseType.LeaseV2) { Open.IsLeaseExisted = true; Open.LeaseVersion = 2; } else if (oplockLeaseType == OplockLeaseType.BatchOplock) { Open.IsBatchOplockExisted = true; } if (modelHandleType == ModelHandleType.DurableHandleV1) { if (!Open.IsBatchOplockExisted && !Open.IsLeaseExisted) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.6: If the RequestedOplockLevel field in the create request is not set to SMB2_OPLOCK_LEVEL_BATCH and " + "the create request does not include an SMB2_CREATE_REQUEST_LEASE create context with a LeaseState field that " + "includes the SMB2_LEASE_HANDLE_CACHING bit value, " + "the server MUST ignore this create context and skip this section."); ModelHelper.Log(LogType.TestInfo, "This section is skipped."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return; } ModelHelper.Log(LogType.Requirement, "3.3.5.9.6: In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE. "); ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is set to TRUE."); Open.IsDurable = true; } else if (modelHandleType == ModelHandleType.DurableHandleV2 || modelHandleType == ModelHandleType.PersistentHandle) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.10: This section applies only to servers that implement the SMB 3.x dialect family. "); if (!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported)) { ModelHelper.Log(LogType.TestInfo, "The server implements the dialect {0}.", Config.MaxSmbVersionSupported); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return; } if (modelHandleType != ModelHandleType.PersistentHandle && !Open.IsBatchOplockExisted && !Open.IsLeaseExisted) { ModelHelper.Log(LogType.Requirement, "If the SMB2_DHANDLE_FLAG_PERSISTENT bit is not set in the Flags field of this create context, " + "if RequestedOplockLevel in the create request is not set to SMB2_OPLOCK_LEVEL_BATCH, " + "and if the create request does not include a SMB2_CREATE_REQUEST_LEASE or " + "SMB2_CREATE_REQUEST_LEASE_V2 create context with a LeaseState field that includes SMB2_LEASE_HANDLE_CACHING, " + "the server MUST ignore this create context and skip this section."); ModelHelper.Log(LogType.TestInfo, "This section is skipped."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return; } if (ModelUtility.IsSmb3xFamily(NegotiateDialect) && persistentBit == PersistentBitType.PersistentBitSet && Config.IsPersistentHandleSupported) { ModelHelper.Log(LogType.Requirement, "3.3.5.4: The Capabilities field MUST be set to a combination of zero or more of the following bit values, as specified in section 2.2.4:"); ModelHelper.Log(LogType.Requirement, "\tSMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " + "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So SMB2_DHANDLE_FLAG_PERSISTENT bit is set in Connection.ServerCapabilities."); ServerCapabilities_PersistentBitSet = true; } if (modelHandleType == ModelHandleType.PersistentHandle && !(Share_IsCA && ServerCapabilities_PersistentBitSet)) { // TDI: if client asks for a persistent handle to a non CA share or // Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_PERSISTENT_HANDLES // The persistent handle is not granted. ModelHelper.Log( LogType.TestInfo, "Share is not a CA share or Connection.ServerCapabilities does not include SMB2_GLOBAL_CAP_PERSISTENT_HANDLES."); ModelHelper.Log(LogType.TestTag, TestTag.Compatibility); return; } ModelHelper.Log(LogType.Requirement, "In the \"Successful Open Initialization\" phase, the server MUST set Open.IsDurable to TRUE. "); ModelHelper.Log(LogType.TestInfo, "Open.IsDurable is set to TRUE."); Open.IsDurable = true; if (modelHandleType == ModelHandleType.PersistentHandle && Share_IsCA && ServerCapabilities_PersistentBitSet) { ModelHelper.Log(LogType.Requirement, "3.3.5.9.10: If the SMB2_DHANDLE_FLAG_PERSISTENT bit is set in the Flags field of the request, " + "TreeConnect.Share.IsCA is TRUE, " + "and Connection.ServerCapabilities includes SMB2_GLOBAL_CAP_PERSISTENT_HANDLES, " + "the server MUST set Open.IsPersistent to TRUE."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So Open.IsPersistent is set to TRUE."); Open.IsPersistent = true; } } }
public static void OpenRequest( ModelDialectRevision clientMaxDialect, PersistentBitType persistentBit, CAShareType connectToCAShare, OplockLeaseType oplockLeaseType, DurableV1RequestContext durableV1RequestContext, DurableV2RequestContext durableV2RequestContext, DurableV1ReconnectContext durableV1ReconnectContext, DurableV2ReconnectContext durableV2ReconnectContext) { Condition.IsNull(Request); Condition.IsNull(Open); // CAShare, Persistent Handle and Durable Handle V2 are only applied for SMB 3.x family. Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), connectToCAShare == CAShareType.NonCAShare); Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), persistentBit == PersistentBitType.PersistentBitNotSet); Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), durableV2RequestContext == DurableV2RequestContext.DurableV2RequestContextNotExist); Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), durableV2ReconnectContext == DurableV2ReconnectContext.DurableV2ReconnectContextNotExist); Condition.IfThen(!ModelUtility.IsSmb3xFamily(Config.MaxSmbVersionSupported), oplockLeaseType != OplockLeaseType.LeaseV2); // If leasing is not supported, do not test LeaseV1 or LeaseV2. Condition.IfThen(!Config.IsLeasingSupported, oplockLeaseType != OplockLeaseType.LeaseV1 && oplockLeaseType != OplockLeaseType.LeaseV2); Combination.Pairwise( clientMaxDialect, persistentBit, connectToCAShare, oplockLeaseType, durableV1RequestContext, durableV2RequestContext, durableV1ReconnectContext, durableV2ReconnectContext); NegotiateDialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, Config.MaxSmbVersionSupported); Share_IsCA = (connectToCAShare == CAShareType.CAShare); if (ModelUtility.IsSmb3xFamily(NegotiateDialect) && persistentBit == PersistentBitType.PersistentBitSet && Config.IsPersistentHandleSupported) { ModelHelper.Log(LogType.Requirement, "3.3.5.4: The Capabilities field MUST be set to a combination of zero or more of the following bit values, as specified in section 2.2.4:"); ModelHelper.Log(LogType.Requirement, "\tSMB2_GLOBAL_CAP_PERSISTENT_HANDLES if Connection.Dialect belongs to the SMB 3.x dialect family, " + "SMB2_GLOBAL_CAP_PERSISTENT_HANDLES is set in the Capabilities field of the request, and the server supports persistent handles."); ModelHelper.Log(LogType.TestInfo, "All the above conditions are met. So SMB2_DHANDLE_FLAG_PERSISTENT bit is set in Connection.ServerCapabilities."); ServerCapabilities_PersistentBitSet = true; } Request = new ModelOpenFileRequest( durableV1RequestContext, durableV2RequestContext, durableV1ReconnectContext, durableV2ReconnectContext, oplockLeaseType, false, false, false); }
public DetectResult CheckCreateContexts_HandleV1BatchOplock(string sharename, DialectRevision smb2Dialect, ref DetectionInfo info) { logWriter.AddLog(LogLevel.Information, "===== Detecting create context HandleV1 with Batch oplock ====="); using (Smb2Client client = new Smb2Client(new TimeSpan(0, 0, defaultTimeoutInSeconds))) { ulong messageId; ulong sessionId; uint treeId; ConnectToShare(sharename, info, client, out messageId, out sessionId, out treeId); Packet_Header header; #region Create FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts = null; string fileName = "DurableHandleV1BatchOplock_" + Guid.NewGuid() + ".txt"; CREATE_Response createResponse; logWriter.AddLog(LogLevel.Information, "Client opens file with a durable handle v1 and batch oplock"); uint status = client.Create( 1, 1, info.smb2Info.IsRequireMessageSigning ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE, messageId++, sessionId, treeId, fileName, AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE | AccessMask.DELETE, ShareAccess_Values.NONE, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, CreateDisposition_Values.FILE_OPEN_IF, File_Attributes.NONE, ImpersonationLevel_Values.Impersonation, SecurityFlags_Values.NONE, RequestedOplockLevel_Values.OPLOCK_LEVEL_BATCH, new Smb2CreateContextRequest[] { new Smb2CreateDurableHandleRequest { DurableRequest = Guid.Empty, }, }, out fileId, out serverCreateContexts, out header, out createResponse, 0); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("Create durable handle v1 with batch oplock", header.Status); return DetectResult.UnSupported; } #endregion if (serverCreateContexts != null) { foreach (Smb2CreateContextResponse ctx in serverCreateContexts) { if (ctx is Smb2CreateDurableHandleResponse) { logWriter.AddLog(LogLevel.Information, "Create context HandleV1 with Batch oplock is supported"); return DetectResult.Supported; } } } logWriter.AddLog(LogLevel.Information, "The returned Create response doesn't contain handle v1 context. So Create context HandleV1 with Batch oplock is not supported"); return DetectResult.UnSupported; } }
private bool DetectAP(DomainInfo domain, Server ap, KerberosDetector detector) { logWriter.AddLog(string.Format("===== Detect Application Server in Domain {0} =====", domain.Name), LogLevel.Normal); string hostname = ap.FQDN; IPAddress ip = IPAddress.Loopback; try { var hostentry = Dns.GetHostEntry(hostname); ip = hostentry.AddressList[0]; ap.IPv4 = ip.ToString(); string computerName = hostentry.HostName; string machineName = computerName.Split('.')[0]; ap.FQDN = ServerHelper.GetAccountAttribute(machineName, "Computers", "dNSHostName", domain.Name, domain.Admin, domain.AdminPassword); ap.IsWindows = detector.FetchPlatformInfo(computerName); } catch { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } if (ap.FQDN == null) { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } string[] tempArray = ap.FQDN.Split('.'); ap.ComputerName = tempArray[0]; try { ap.NetBIOS = ServerHelper.GetAccountAttribute(ap.ComputerName, "Computers", "sAMAccountName", domain.Name, domain.Admin, domain.AdminPassword);//DC01$: NetBIOS name ap.DefaultServiceName = "host/" + ap.FQDN.ToLower(); ap.ServiceSalt = domain.Name.ToUpper() + "host" + ap.FQDN.ToLower(); ap.smb2Service.SMB2ServiceName = "cifs/" + ap.FQDN.ToLower(); } catch { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } try { if (detectionInfo.HasSmbServer) { //get smb dialect Smb2Client clientForInitialOpen = new Smb2Client(new TimeSpan(0, 0, 15)); byte[] gssToken; Packet_Header header; try { clientForInitialOpen.ConnectOverTCP(ip); NEGOTIATE_Response negotiateResp; DialectRevision connection_Dialect = DialectRevision.Smb2Unknown; DialectRevision[] requestDialect = new DialectRevision[] { DialectRevision.Smb2002, DialectRevision.Smb21, DialectRevision.Smb30, DialectRevision.Smb302 }; ulong messageId = 0; uint status = clientForInitialOpen.Negotiate( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, requestDialect, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU, Guid.NewGuid(), out connection_Dialect, out gssToken, out header, out negotiateResp); if (header.Status != Smb2Status.STATUS_SUCCESS) { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } else { ap.smb2Service.SMB2Dialect = connection_Dialect.ToString(); } } catch { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } //detect smb share string[] shareList = ServerHelper.EnumShares(ap.IPv4, domain.Admin, domain.Name, domain.AdminPassword); if (shareList.Length > 0) { //only get the first one as default value //can ptftool support add more choices? for (int i = 0; i < shareList.Length; i++) { if (shareList[i].Substring(shareList[i].Length - 1, 1) != "$") { ap.smb2Service.DACShare = shareList[i]; ap.smb2Service.CBACShare = shareList[i]; break; } } } else { ap.smb2Service.DACShare = string.Empty; ap.smb2Service.CBACShare = string.Empty; } } if (detectionInfo.HasHttpServer) { //detect http server ap.httpService.HttpServiceName = "http/" + ap.FQDN.ToLower(); try { HttpWebRequest request = (HttpWebRequest)WebRequest.Create("http://" + ap.FQDN); request.Credentials = new NetworkCredential(domain.Admin + "@" + domain.Name, domain.AdminPassword); WebResponse response = request.GetResponse(); ap.httpService.Uri = response.ResponseUri.OriginalString; } catch { ap.httpService.Uri = string.Empty; } } } catch { logWriter.AddLog("Failed", LogLevel.Normal, false, LogStyle.StepFailed); logWriter.AddLineToLog(LogLevel.Advanced); return false; } logWriter.AddLog("Success", LogLevel.Normal, false, LogStyle.StepPassed); logWriter.AddLineToLog(LogLevel.Advanced); return true; }
protected virtual uint Negotiate( ushort creditCharge, ushort creditRequest, ulong messageId, Guid clientGuid, out DialectRevision selectedDialect, out byte[] gssToken, out Packet_Header responseHeader, out NEGOTIATE_Response responsePayload) { uint status = client.Negotiate( creditCharge, creditRequest, Packet_Header_Flags_Values.NONE, messageId, new DialectRevision[] { DialectRevision.Smb2002 }, SecurityMode_Values.NONE, Capabilities_Values.NONE, clientGuid, out selectedDialect, out gssToken, out responseHeader, out responsePayload); negotiatedDialect = selectedDialect; serverCapabilities = (Capabilities_Values)responsePayload.Capabilities; return status; }
private void CheckNegotiateResponse( Packet_Header header, NEGOTIATE_Response response, DialectRevision clientMaxDialectSupported, EncryptionAlgorithm[] encryptionAlgs) { DialectRevision expectedDialect = clientMaxDialectSupported < TestConfig.MaxSmbVersionSupported ? clientMaxDialectSupported : TestConfig.MaxSmbVersionSupported; BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed, actually server returns {1}.", header.Command, Smb2Status.GetStatusCode(header.Status)); BaseTestSite.Assert.AreEqual(expectedDialect, response.DialectRevision, "Selected dialect should be {0}", expectedDialect); if (expectedDialect >= DialectRevision.Smb311) { BaseTestSite.Assert.AreEqual( PreauthIntegrityHashID.SHA_512, client.SelectedPreauthIntegrityHashID, "[MS-SMB2] 3.3.5.4 The server MUST set Connection.PreauthIntegrityHashId to one of the hash algorithms " + "in the client's SMB2_PREAUTH_INTEGRITY_CAPABILITIES HashAlgorithms array. "); if (encryptionAlgs != null) { EncryptionAlgorithm expectedEnAlg = EncryptionAlgorithm.ENCRYPTION_NONE; foreach (var alg in encryptionAlgs) { if (TestConfig.SupportedEncryptionAlgorithmList.Contains(alg)) { expectedEnAlg = alg; break; } } BaseTestSite.Assert.AreEqual( expectedEnAlg, client.SelectedCipherID, "[MS-SMB2] 3.3.5.4 The server MUST set Connection.CipherId to one of the ciphers in the client's " + "SMB2_ENCRYPTION_CAPABILITIES Ciphers array in an implementation-specific manner."); } else { BaseTestSite.Assert.AreEqual( EncryptionAlgorithm.ENCRYPTION_NONE, client.SelectedCipherID, "[MS-SMB2] if client doesn't present SMB2_ENCRYPTION_CAPABILITIES context in negotiate request, " + "server should not present this context in negotiate response."); } } else { // If server supported dialect version is lower than 3.11, server should ignore the negotiate contexts. BaseTestSite.Assert.AreEqual( PreauthIntegrityHashID.HashAlgorithm_NONE, client.SelectedPreauthIntegrityHashID, "[MS-SMB2] The server must ignore the SMB2_PREAUTH_INTEGRITY_CAPABILITIES context if Connection.Dialect is less than 3.11. "); BaseTestSite.Assert.AreEqual( EncryptionAlgorithm.ENCRYPTION_NONE, client.SelectedCipherID, "[MS-SMB2] The server must ignore the SMB2_ENCRYPTION_CAPABILITIES context if Connection.Dialect is less than 3.11. "); } }
private void NegotiateWithNegotiateContexts( DialectRevision clientMaxDialectSupported, PreauthIntegrityHashID[] preauthHashAlgs, EncryptionAlgorithm[] encryptionAlgs = null, ResponseChecker<NEGOTIATE_Response> checker = null) { // ensure clientMaxDialectSupported higher than 3.11 if (clientMaxDialectSupported < DialectRevision.Smb311) clientMaxDialectSupported = DialectRevision.Smb311; DialectRevision[] negotiateDialects = Smb2Utility.GetDialects(clientMaxDialectSupported); if (clientMaxDialectSupported > TestConfig.MaxSmbVersionClientSupported) { BaseTestSite.Assert.Inconclusive("Stop to run this test case because the configured MaxSmbVersionClientSupported {0} is lower than {1}.", TestConfig.MaxSmbVersionClientSupported, clientMaxDialectSupported); } status = client.NegotiateWithContexts( Packet_Header_Flags_Values.NONE, negotiateDialects, preauthHashAlgs: preauthHashAlgs, encryptionAlgs: encryptionAlgs, checker: checker); }
/// <summary> /// This method will send ComNegotiate request before sending a Negotiate request to simulate windows client behaviour. /// If ComNegotiate failed, the Negotiate request will still be sent. /// </summary> public uint MultiProtocolNegotiate( Smb2Client client, ushort creditCharge, ushort creditRequest, Packet_Header_Flags_Values flags, ulong messageId, DialectRevision[] dialects, SecurityMode_Values securityMode, Capabilities_Values capabilities, Guid clientGuid, out DialectRevision selectedDialect, out byte[] gssToken, out Packet_Header responseHeader, out NEGOTIATE_Response responsePayload) { uint status = client.MultiProtocolNegotiate( new string[] { "SMB 2.002", "SMB 2.???" }, out selectedDialect, out gssToken, out responseHeader, out responsePayload); if (responseHeader.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("ComNegotiate", responseHeader.Status); } // If server only supports Smb2002, no further SMB2 negotiate needed if (selectedDialect == DialectRevision.Smb2002) { return status; } PreauthIntegrityHashID[] preauthHashAlgs = null; EncryptionAlgorithm[] encryptionAlgs = null; // For back compatibility, if dialects contains SMB 3.11, preauthentication integrity context should be present. if (Array.IndexOf(dialects, DialectRevision.Smb311) >= 0) { preauthHashAlgs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; encryptionAlgs = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; } status = client.Negotiate( creditCharge, creditRequest, flags, messageId, dialects, securityMode, capabilities, clientGuid, out selectedDialect, out gssToken, out responseHeader, out responsePayload, 0, preauthHashAlgs, encryptionAlgs); return status; }
public static void SetupConnection(ModelDialectRevision clientMaxDialect) { Condition.IsTrue(state == ModelState.Initialized); Condition.IsNull(request); negotiateDialect = ModelHelper.DetermineNegotiateDialect(clientMaxDialect, config.MaxSmbVersionSupported); if ((negotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(negotiateDialect)) && config.IsMultiCreditSupportedOnServer) { ModelHelper.Log( LogType.Requirement, "3.3.5.4: If the common dialect is SMB 2.1 or 3.x dialect family and the underlying connection is either TCP port 445 or RDMA," + "Connection.SupportsMultiCredit MUST be set to TRUE; otherwise, it MUST be set to FALSE."); ModelHelper.Log( LogType.TestInfo, "Common dialect is {0} and server implementation {1} multicredit", negotiateDialect, config.IsMultiCreditSupportedOnServer ? "supports" : "does not support"); isMultiCreditSupported = true; ModelHelper.Log( LogType.TestInfo, "Connection.SupportsMultiCredit is set to TRUE"); } else { isMultiCreditSupported = false; ModelHelper.Log( LogType.TestInfo, "Connection.SupportsMultiCredit is set to FALSE"); } state = ModelState.Connected; }
/// <summary> /// Establish alternative channel, which includes NEGOTIATE, SESSION_SETUP /// </summary> /// <param name="requestDialect">Dialects in request</param> /// <param name="serverIp">Ip address on server side</param> /// <param name="clientIp">Ip address on client side</param> /// <param name="treeId">Tree id that is used to set encryption</param> /// <param name="enableEncryptionPerShare">Set true if enable encryption on share, otherwise set false</param> private void EstablishAlternativeChannel( DialectRevision[] requestDialect, IPAddress serverIp, IPAddress clientIp, uint treeId, bool enableEncryptionPerShare = false) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Establish alternative channel to connect share {0}", uncSharePath); alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp); #region Negotiate Capabilities_Values alternativeChannelClientCapabilities = Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES | Capabilities_Values.GLOBAL_CAP_ENCRYPTION; status = alternativeChannelClient.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, clientGuid: clientGuid, capabilityValue: alternativeChannelClientCapabilities, checker: (Packet_Header header, NEGOTIATE_Response response) => { BaseTestSite.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "CREATE should succeed."); TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response); TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response); } ); #endregion #region SESSION_SETUP status = alternativeChannelClient.AlternativeChannelSessionSetup( mainChannelClient, TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion alternativeChannelClient.SetTreeEncryption(treeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare); BaseTestSite.Log.Add( LogEntryKind.Debug, "Establish alternative channel to connect share {0}", uncSharePath); }
public Smb2TransportAdapter(DialectRevision[] dialects) { this.requestDialects = dialects; }
public void SetupConnection(ModelDialectRevision maxSmbVersionClientSupported, ModelShareFlag shareFlag, ModelShareType shareType) { IPAddress ip; if (shareType == ModelShareType.STYPE_CLUSTER_SOFS) { server = testConfig.ScaleOutFileServerName; ip = Dns.GetHostEntry(server).AddressList[0]; if (shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK) { uncSharePath = Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.ShareWithForceLevel2AndSOFS); } else { uncSharePath = Smb2Utility.GetUncPath(testConfig.ScaleOutFileServerName, testConfig.ShareWithoutForceLevel2WithSOFS); } } else { server = testConfig.SutComputerName; ip = testConfig.SutIPAddress; if (shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK) { uncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.ShareWithForceLevel2WithoutSOFS); } else { uncSharePath = Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.ShareWithoutForceLevel2OrSOFS); } } testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.Smb2Client.OplockBreakNotificationReceived += new Action<Packet_Header, OPLOCK_BREAK_Notification_Packet>(OnOplockBreakNotificationReceived); testClient.ConnectToServer(testConfig.UnderlyingTransport, server, ip, testConfig.ClientNic1IPAddress); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(maxSmbVersionClientSupported)); NEGOTIATE_Response? negotiateResponse = null; testClient.Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); negotiateResponse = response; }); negotiatedDialect = negotiateResponse.Value.DialectRevision; testClient.SessionSetup( testConfig.DefaultSecurityPackage, server, testConfig.AccountCredential, testConfig.UseServerGssToken); testClient.TreeConnect( uncSharePath, out treeId, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); Site.Assert.AreEqual( shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK, response.ShareFlags.HasFlag(ShareFlags_Values.SHAREFLAG_FORCE_LEVELII_OPLOCK), "SHAREFLAG_FORCE_LEVELII_OPLOCK is{0}expected to be set", shareFlag == ModelShareFlag.SMB2_SHAREFLAG_FORCE_LEVELII_OPLOCK ? " " : " not "); if (ModelUtility.IsSmb3xFamily(negotiateResponse.Value.DialectRevision)) { Site.Assert.AreEqual( shareType == ModelShareType.STYPE_CLUSTER_SOFS, response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_SCALEOUT), "SHARE_CAP_SCALEOUT is{0}expected to be set", shareType == ModelShareType.STYPE_CLUSTER_SOFS ? " " : " not "); } }); }
/// <summary> /// Initialize all fields to the default values. /// </summary> private void Initialize() { Flags = testConfig.SendSignedRequest ? Packet_Header_Flags_Values.FLAGS_SIGNED : Packet_Header_Flags_Values.NONE; Dialect = DialectRevision.Smb2Unknown; MessageId = 0; GrantedCredit = 0; SessionKey = null; ServerGssToken = null; unchecked { TreeId = (uint)-1; } SessionId = 0; ParentDirectory = null; File = null; FileId = FILEID.Zero; IsDirectory = false; Locks = null; LockSequence = 0; LeaseState = LeaseStateValues.SMB2_LEASE_NONE; CreateContexts = null; OperationMessageId = 0; Client = new Smb2Client(Timeout); Client.DisableVerifySignature = this.testConfig.DisableVerifySignature; }
/// <summary> /// Attempt to trigger LeaseBreakNotification from a separate client /// </summary> /// <param name="client">Client to trigger LeaseBreakNotification</param> /// <param name="requestDialect">Negotiate dialects</param> /// <param name="isDirectory">True value indicating to open a directory, false for a file</param> /// <param name="requestedLeaseState">LeaseState when open the directory or file</param> /// <param name="accessMask">AccessMask when open the directory or file</param> private void TriggerBreakFromClient( Smb2FunctionalClient client, DialectRevision[] requestDialect, bool isDirectory, LeaseStateValues requestedLeaseState, AccessMask accessMask) { BaseTestSite.Log.Add( LogEntryKind.Debug, "Trigger a lease break notification by accessing same file/directory from a separate client with LeaseState {0} and AccessMask {1}", requestedLeaseState, accessMask); #region Negotiate status = client.Negotiate( requestDialect, TestConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES); #endregion #region SESSION_SETUP status = client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); #endregion #region TREE_CONNECT to share uint treeId; status = client.TreeConnect(uncSharePath, out treeId); #endregion #region CREATE FILEID fileId; Smb2CreateContextResponse[] serverCreateContexts; status = client.Create( treeId, isDirectory ? testDirectory : fileName, isDirectory ? CreateOptions_Values.FILE_DIRECTORY_FILE : CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE, new Smb2CreateContextRequest[] { new Smb2CreateRequestLeaseV2 { LeaseKey = Guid.NewGuid(), LeaseState = requestedLeaseState } }, accessMask: accessMask); #endregion BaseTestSite.Log.Add( LogEntryKind.Debug, "Finish triggering lease break notification"); }
private void SendCreateRequestWithSpecificAppInstanceversion( Smb2FunctionalClient client, Guid appInstanceId, ulong? appInstanceVersionHigh, ulong? appInstanceVersionLow, DialectRevision dialect, uint expectedCreateResponseStatus, out uint treeId, out FILEID fileId ) { #region Client connects to Server BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client connects to the file server by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT"); client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress, TestConfig.ClientNic1IPAddress); client.Negotiate(Smb2Utility.GetDialects(dialect), TestConfig.IsSMB1NegotiateEnabled); client.SessionSetup( TestConfig.DefaultSecurityPackage, TestConfig.SutComputerName, TestConfig.AccountCredential, TestConfig.UseServerGssToken); client.TreeConnect(uncSharePath, out treeId); Smb2CreateContextResponse[] serverCreateContexts; Smb2CreateAppInstanceVersion appInstanceVersion = new Smb2CreateAppInstanceVersion(); Smb2CreateContextRequest[] clientCreateContexts; if (appInstanceVersionHigh.HasValue && appInstanceVersionLow.HasValue) { appInstanceVersion.AppInstanceVersionHigh = appInstanceVersionHigh.Value; appInstanceVersion.AppInstanceVersionLow = appInstanceVersionLow.Value; clientCreateContexts = new Smb2CreateContextRequest[] { new Smb2CreateAppInstanceId { AppInstanceId = appInstanceId }, appInstanceVersion }; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request with AppInstanceVersionHigh = {0}, AppInstanceVersionLow = {1}.", appInstanceVersion.AppInstanceVersionHigh, appInstanceVersion.AppInstanceVersionLow); } else { clientCreateContexts = new Smb2CreateContextRequest[] { new Smb2CreateAppInstanceId { AppInstanceId = appInstanceId } }; BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends CREATE request without AppInstanceVersion."); } client.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts, RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, clientCreateContexts, shareAccess: ShareAccess_Values.NONE, checker: (header, response) => { BaseTestSite.Assert.AreEqual( expectedCreateResponseStatus, header.Status, (expectedCreateResponseStatus == Smb2Status.STATUS_SUCCESS ? "The open will be closed. Create should succeed. Actually server returns with {0}." : "The open cannot be closed. Create should not succeed. Actually server returns with {0}."), Smb2Status.GetStatusCode(header.Status)); }); #endregion }
public void SetupConnection(ModelDialectRevision clientMaxDialect) { testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site); testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress); testClient.RequestSent += new Action<Packet_Header>(PrintSequenceWindow); DialectRevision[] dialects = Smb2Utility.GetDialects(ModelUtility.GetDialectRevision(clientMaxDialect)); uint status; NEGOTIATE_Response? negotiateResponse = null; status = testClient.Negotiate( dialects, testConfig.IsSMB1NegotiateEnabled, capabilityValue: Capabilities_Values.GLOBAL_CAP_LARGE_MTU, checker: (header, response) => { Site.Assert.AreEqual( Smb2Status.STATUS_SUCCESS, header.Status, "{0} should succeed", header.Command); // The server MUST grant the client at least 1 credit when responding to SMB2 NEGOTIATE. Site.Assert.IsTrue( header.CreditRequestResponse >= 1, "The server MUST grant the client at least 1 credit when responding to SMB2 NEGOTIATE"); negotiateResponse = response; }); Site.Log.Add( LogEntryKind.Debug, "The maximum size, in bytes, of Length in READ/WRITE that server will accept on the connection is {0}", testClient.MaxBufferSize); Site.Assert.AreEqual( ModelUtility.GetDialectRevision(clientMaxDialect), negotiateResponse.Value.DialectRevision, "DialectRevision {0} is expected", ModelUtility.GetDialectRevision(clientMaxDialect)); negotiateDialect = negotiateResponse.Value.DialectRevision; if ((negotiateDialect == DialectRevision.Smb21 || ModelUtility.IsSmb3xFamily(negotiateDialect)) // In case server does not support multicredit even implement Smb21 or Smb30 && testConfig.IsMultiCreditSupported) { isMultiCreditSupportedOnConnection = true; } else { isMultiCreditSupportedOnConnection = false; } status = testClient.SessionSetup( testConfig.DefaultSecurityPackage, testConfig.SutComputerName, testConfig.AccountCredential, testConfig.UseServerGssToken); status = testClient.TreeConnect( uncSharePath, out treeId); Smb2CreateContextResponse[] serverCreateContexts; fileName = Guid.NewGuid().ToString(); status = testClient.Create( treeId, fileName, CreateOptions_Values.FILE_NON_DIRECTORY_FILE, out fileId, out serverCreateContexts); }