private void ConnectToShare(
            Smb2FunctionalClient client,
            Guid clientGuid,
            out uint treeId)
        {
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            // Negotiate
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed.");

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb21, response);
            });

            // SMB2 SESSION SETUP
            client.SessionSetup(
                testConfig.DefaultSecurityPackage,
                testConfig.SutComputerName,
                testConfig.AccountCredential,
                testConfig.UseServerGssToken);

            // SMB2 Tree Connect
            client.TreeConnect(
                Smb2Utility.GetUncPath(testConfig.SutComputerName, testConfig.BasicFileShare),
                out treeId);
        }
        /// <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="serverName">Name of file server to access</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,
            string serverName,
            bool isDirectory,
            LeaseStateValues requestedLeaseState,
            AccessMask accessMask)
        {
            BaseTestSite.Log.Add(LogEntryKind.Debug, "AfterFailover: Attempt to access same file/directory to trigger LeaseBreakNotification 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,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            });
            #endregion

            #region SESSION_SETUP
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                serverName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            uint treeId;
            status = client.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            Smb2CreateContextResponse[] serverCreateContexts;
            FILEID fileId;
            status = client.Create(
                treeId, // To break lease on directory, create a new child item
                isDirectory ? testDirectory + @"\child.txt" : fileName,
                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,
                shareAccess: ShareAccess_Values.NONE,
                checker: (header, response) => { });
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "AfterFailover: Finish triggering a LeaseBreakNotification from a separate client.");
        }
        private void PrepareFileForTrimming(out uint treeId, out FILEID fileId)
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_FILE_LEVEL_TRIM);
            #endregion

            string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            string fileName     = GetTestFileName(uncSharePath);
            string contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);

            smb2Functionalclient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            uint status = smb2Functionalclient.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            });

            status = smb2Functionalclient.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            status = smb2Functionalclient.TreeConnect(uncSharePath, out treeId);

            Smb2CreateContextResponse[] serverCreateContexts;
            status = smb2Functionalclient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);

            status = smb2Functionalclient.Write(treeId, fileId, contentWrite);

            status = smb2Functionalclient.Close(treeId, fileId);

            status = smb2Functionalclient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);
        }
        /// <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);
        }
Ejemplo n.º 5
0
        private void ConnectToShare(
            Smb2FunctionalClient client,
            Guid clientGuid,
            out uint treeId)
        {
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.CAShareServerName, TestConfig.CAShareServerIP);

            // Negotiate
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
                clientGuid: clientGuid,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual <NtStatus>(
                    NtStatus.STATUS_SUCCESS,
                    (NtStatus)header.Status,
                    "Negotiate should be successfully");

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, response);
            }
                );

            // SMB2 SESSION SETUP
            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.CAShareServerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            // SMB2 Tree Connect
            client.TreeConnect(
                Smb2Utility.GetUncPath(TestConfig.CAShareServerName, TestConfig.CAShareName),
                out treeId,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual <NtStatus>(
                    NtStatus.STATUS_SUCCESS,
                    (NtStatus)header.Status,
                    "TreeConnect should be successfully");

                // Check IsCA
                BaseTestSite.Assert.IsTrue(
                    response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY),
                    "Share should support capabilities of SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY ");
            });
        }
        private void NewTestFile(Smb2FunctionalClient client, string fileName, string content, out uint treeId, out FILEID fileId)
        {
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP);
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "NEGOTIATE should succeed.");

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            });

            client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.ShareServerName,
                //TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            //string uncSharePath = Smb2Utility.GetUncPath(TestConfig.HvrsSutComputerName, TestConfig.ShareName);
            client.TreeConnect(TestConfig.SharePath, out treeId);
            //string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            //client.TreeConnect(uncSharePath, out treeId);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client writes to the file.");
            Smb2CreateContextResponse[] serverCreateContexts;
            client.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);

            client.Write(treeId, fileId, content);

            // Flush written content to backend storage to avoid cache.
            client.Flush(treeId, fileId);
        }
        private void ConnectToShare(Smb2FunctionalClient smbClient, Guid clientGuid, out uint treeId)
        {
            smbClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ShareServerName, TestConfig.ShareServerIP);
            smbClient.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES,
                clientGuid: clientGuid,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual <NtStatus>(
                    NtStatus.STATUS_SUCCESS,
                    (NtStatus)header.Status,
                    "Negotiate should be successfully");
                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
                TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, response);
            });

            smbClient.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.ShareServerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            smbClient.TreeConnect(
                TestConfig.SharePath,
                out treeId,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreEqual <NtStatus>(
                    NtStatus.STATUS_SUCCESS,
                    (NtStatus)header.Status,
                    "TreeConnect should be successfully");
            }

                // TODO: Check IsCA
                );
        }
        /// <summary>
        /// Reconnect to share on clustered file server after failover happens, include NEGOTIATE, SESSION_SETUP, TREE_CONNECT
        /// </summary>
        /// <param name="server">Name of clustered file server</param>
        /// <param name="fsType">Type of clustered file server</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 ReconnectServerAfterFailover(string server, FileServerType fsType, out uint treeId, bool enableEncryptionPerShare = false)
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "AfterFailover: Connect share {0} on server {1} with following steps.", uncSharePath, server);
            if (fsType == FileServerType.ScaleOutFileServer)
            {
                // For scale-out file server case, retrieve and use another access IP for connection
                IPAddress oldAccessIp = currentAccessIp;
                currentAccessIp = null;

                foreach (var ip in accessIpList)
                {
                    if (!ip.Equals(oldAccessIp))
                    {
                        currentAccessIp = ip;
                        break;
                    }
                }
            }
            else if (fsType == FileServerType.GeneralFileServer)
            {
                currentAccessIp = null;
                DoUntilSucceed(() =>
                {
                    foreach (IPAddress ipAddress in accessIpList)
                    {
                        Smb2FunctionalClient pingClient = new Smb2FunctionalClient(TestConfig.FailoverTimeout, TestConfig, BaseTestSite);

                        try
                        {
                            pingClient.ConnectToServerOverTCP(ipAddress);
                            pingClient.Disconnect();
                            pingClient = null;

                            currentAccessIp = ipAddress;
                            return(true);
                        }
                        catch
                        {
                        }
                    }
                    return(false);
                }, TestConfig.FailoverTimeout, "Retry to ping to server until succeed within timeout span");
            }
            BaseTestSite.Assert.AreNotEqual(
                null,
                currentAccessIp,
                "Access IP to the file server should not be empty");
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Got IP {0} to access the file server",
                currentAccessIp.ToString());

            DoUntilSucceed(() => clientAfterFailover.ConnectToServer(TestConfig.UnderlyingTransport, server, currentAccessIp), TestConfig.FailoverTimeout,
                           "Retry to connect to server until succeed within timeout span");

            #region Negotiate
            Capabilities_Values clientCapabilitiesAfterFailover = 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 = clientAfterFailover.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilitiesAfterFailover,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            });
            #endregion

            #region SESSION_SETUP
            status = clientAfterFailover.ReconnectSessionSetup(
                clientBeforeFailover,
                TestConfig.DefaultSecurityPackage,
                server,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Global encryption disabled");
            #endregion

            #region TREE_CONNECT to share
            uint innerTreeId = 0;
            //Retry TreeConnect until succeed within timeout span
            status = DoUntilSucceed(
                () => clientAfterFailover.TreeConnect(uncSharePath, out innerTreeId, (header, response) => { }),
                TestConfig.FailoverTimeout,
                "Retry TreeConnect until succeed within timeout span");
            BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "TreeConnect to {0} should succeed, actual status is {1}", uncSharePath, Smb2Status.GetStatusCode(status));
            treeId = innerTreeId;

            clientAfterFailover.SetTreeEncryption(innerTreeId, enableEncryptionPerShare);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Per share encryption for TreeId=0x{0:x} : {1}", treeId, enableEncryptionPerShare);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "AfterFailover: Finish connecting to share {0} on server {1}", uncSharePath, server);
        }
        /// <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 DirecotryLeasing(
            DialectRevision[] requestDialect,
            DialectRevision expectedDialect,
            LeaseStateValues leaseState,
            LeaseBreakAckType leaseBreakAckType = LeaseBreakAckType.None)
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING);
            TestConfig.CheckCreateContext(CreateContextTypeValue.SMB2_CREATE_REQUEST_LEASE_V2);
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                @"Start to create a directory on share \\{0}\{1} with lease state {2}",
                TestConfig.SutComputerName, TestConfig.BasicFileShare, leaseState);

            string testDirectory = CreateTestDirectory(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            #region Negotiate
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start the client by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT");
            Capabilities_Values capabilities = 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;
            status = client.Negotiate(
                requestDialect,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: capabilities,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(expectedDialect, response);
                if (expectedDialect >= DialectRevision.Smb30)
                {
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING, response);
                }
            });
            #endregion

            #region SESSION_SETUP
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            uint   treeId;
            status = client.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Client sends CREATE request for the directory with the LeaseState set to {0} in SMB2_CREATE_REQUEST_LEASE_V2.", leaseState);
            status = client.Create(
                treeId,
                testDirectory,
                CreateOptions_Values.FILE_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_LEASE,
                new Smb2CreateContextRequest[]
            {
                new Smb2CreateRequestLeaseV2
                {
                    LeaseKey   = Guid.NewGuid(),
                    LeaseState = leaseState
                }
            },
                checker: (Packet_Header header, CREATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                if (expectedDialect == DialectRevision.Smb2002 || expectedDialect == DialectRevision.Smb21)
                {
                    BaseTestSite.Assert.AreEqual(
                        OplockLevel_Values.OPLOCK_LEVEL_NONE,
                        response.OplockLevel,
                        "The expected oplock level is OPLOCK_LEVEL_NONE.");
                }
            });

            #endregion

            if (expectedDialect >= DialectRevision.Smb30)
            {
                // Break the lease with creating another file in the directory
                sutProtocolController.CreateFile(Path.Combine(Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare), testDirectory), CurrentTestCaseName, string.Empty);

                // Wait until LEASE_BREAK_Notification is received
                BaseTestSite.Assert.IsTrue(
                    // Wait 5 seconds for notification arrival
                    notificationReceived.WaitOne(SMB2TestConfig.WAIT_TIMEOUT_IN_MILLISECONDS),
                    "LeaseBreakNotification should be raised.");

                if (receivedLeaseBreakNotify.Flags == LEASE_BREAK_Notification_Packet_Flags_Values.SMB2_NOTIFY_BREAK_LEASE_FLAG_ACK_REQUIRED)
                {
                    BaseTestSite.Log.Add(
                        LogEntryKind.Debug,
                        "Server requires an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY");

                    #region LEASE_BREAK_ACK
                    switch (leaseBreakAckType)
                    {
                    case LeaseBreakAckType.None:
                        status = client.LeaseBreakAcknowledgment(treeId, receivedLeaseBreakNotify.LeaseKey, receivedLeaseBreakNotify.NewLeaseState);
                        break;

                    case LeaseBreakAckType.InvalidLeaseState:
                        LeaseStateValues newLeaseState = LeaseStateValues.SMB2_LEASE_WRITE_CACHING;
                        BaseTestSite.Log.Add(
                            LogEntryKind.Comment,
                            "Client attempts to send LEASE_BREAK_ACK with an invalid LeaseState {0} on this LEASE_BREAK_NOTIFY", newLeaseState);
                        status = client.LeaseBreakAcknowledgment(
                            treeId,
                            receivedLeaseBreakNotify.LeaseKey,
                            newLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK with invalid LeaseState is not expected to SUCCESS, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_REQUEST_NOT_ACCEPTED,
                                header.Status,
                                RequirementCategory.STATUS_REQUEST_NOT_ACCEPTED.Id,
                                RequirementCategory.STATUS_REQUEST_NOT_ACCEPTED.Description);
                        });
                        break;

                    case LeaseBreakAckType.InvalidLeaseKey:
                        Guid invalidLeaseKey = Guid.NewGuid();
                        BaseTestSite.Log.Add(
                            LogEntryKind.Debug,
                            "Client attempts to send LEASE_BREAK_ACK with an invalid LeaseKey {0} on this LEASE_BREAK_NOTIFY", invalidLeaseKey);
                        status = client.LeaseBreakAcknowledgment(
                            treeId,
                            invalidLeaseKey,
                            receivedLeaseBreakNotify.NewLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK with invalid LeaseKey is not expected to SUCCESS, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                                header.Status,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                        });
                        break;

                    case LeaseBreakAckType.InvalidClientGuid:
                        BaseTestSite.Log.Add(LogEntryKind.Debug, "Initialize a new different client to attempts to send LEASE_BREAK_ACK");
                        Smb2FunctionalClient newClient = new Smb2FunctionalClient(TestConfig.Timeout, TestConfig, BaseTestSite);

                        newClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

                        #region Negotiate
                        status = newClient.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 = newClient.SessionSetup(
                            TestConfig.DefaultSecurityPackage,
                            TestConfig.SutComputerName,
                            TestConfig.AccountCredential,
                            TestConfig.UseServerGssToken);
                        #endregion

                        #region TREE_CONNECT to share
                        uint newTreeId;
                        status = newClient.TreeConnect(uncSharePath, out newTreeId);
                        #endregion

                        status = newClient.LeaseBreakAcknowledgment(
                            newTreeId,
                            receivedLeaseBreakNotify.LeaseKey,
                            receivedLeaseBreakNotify.NewLeaseState,
                            checker: (header, response) =>
                        {
                            BaseTestSite.Assert.AreNotEqual(
                                Smb2Status.STATUS_SUCCESS,
                                header.Status,
                                "LEASE_BREAK_ACK is not expected to SUCCESS when the open is closed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                            BaseTestSite.CaptureRequirementIfAreEqual(
                                Smb2Status.STATUS_OBJECT_NAME_NOT_FOUND,
                                header.Status,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Id,
                                RequirementCategory.STATUS_OBJECT_NAME_NOT_FOUND.Description);
                        });

                        status = newClient.TreeDisconnect(newTreeId);

                        status = newClient.LogOff();

                        BaseTestSite.Log.Add(
                            LogEntryKind.Comment,
                            "Initialize a new different client to attempts to send LEASE_BREAK_ACK");
                        break;

                    default:
                        throw new InvalidOperationException("Unexpected LeaseBreakAckType " + leaseBreakAckType);
                    }

                    #endregion
                }
                else
                {
                    BaseTestSite.Log.Add(
                        LogEntryKind.Debug,
                        "Server does not require an LEASE_BREAK_ACK on this LEASE_BREAK_NOTIFY");
                }
            }

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: TREE_DISCONNECT; LOG_OFF");
            #region TREE_DISCONNECT
            status = client.TreeDisconnect(treeId);
            #endregion

            #region LOGOFF
            status = client.LogOff();
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.Comment,
                @"Complete creating a directory on share \\{0}\{1} with lease state {2}",
                TestConfig.SutComputerName, TestConfig.BasicFileShare, leaseState);
        }
        private void ReadFromAlternativeChannel(
            DialectRevision[] requestDialect,
            DialectRevision expectedDialect,
            IPAddress serverIp,
            IPAddress clientIp,
            uint lengthRead,
            uint treeId,
            FILEID fileId,
            out string contentRead)
        {
            contentRead = "";
            alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp);

            #region Negotiate
            status = alternativeChannelClient.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,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(expectedDialect, response);
                if (Smb2Utility.IsSmb3xFamily(expectedDialect))
                {
                    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,
                checker: (header, response) => { });
            #endregion

            if (expectedDialect == DialectRevision.Smb2002 || expectedDialect == DialectRevision.Smb21)
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_REQUEST_NOT_ACCEPTED,
                    status,
                    "SessionSetup is expected to fail with STATUS_REQUEST_NOT_ACCEPTED.");
                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Dialect " + expectedDialect + " is not supported for multiple channel and fail as expected with STATUS_REQUEST_NOT_ACCEPTED.");
            }
            else
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    status,
                    "SessionSetup should succeed");

                #region READ
                status = alternativeChannelClient.Read(treeId, fileId, 0, lengthRead, out contentRead);
                #endregion

                #region CLOSE file
                status = alternativeChannelClient.Close(treeId, fileId);
                #endregion

                #region TREE_DISCONNECT
                status = alternativeChannelClient.TreeDisconnect(treeId);
                #endregion

                #region LOGOFF
                status = alternativeChannelClient.LogOff();
                #endregion
            }

            alternativeChannelClient.Disconnect();
        }
        private void WriteFromMainChannel(
            DialectRevision[] requestDialect,
            DialectRevision expectedDialect,
            IPAddress serverIp,
            IPAddress clientIp,
            string contentWrite,
            bool isNicRedundantOnServer,
            out uint treeId,
            out FILEID fileId)
        {
            mainChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp);

            #region Negotiate
            mainChannelClient.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,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));
                TestConfig.CheckNegotiateDialect(expectedDialect, response);
                if (Smb2Utility.IsSmb3xFamily(expectedDialect))
                {
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response);
                }
            });
            #endregion

            #region SESSION_SETUP
            mainChannelClient.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region Retrieve 2nd IP on server for alternative channel if there is
            if (TestConfig.UnderlyingTransport == Smb2TransportType.Tcp &&
                isNicRedundantOnServer &&
                TestConfig.IsIoCtlCodeSupported(CtlCode_Values.FSCTL_QUERY_NETWORK_INTERFACE_INFO))
            {
                #region TREE_CONNECT to IPC$
                string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName);
                mainChannelClient.TreeConnect(ipcPath, out treeId);
                #endregion

                #region IOCTL FSCTL_QUERY_NETWORK_INTERFACE_INFO
                NETWORK_INTERFACE_INFO_Response[] networkInfoResponses;
                string interfaceAddress;
                bool   secondAddressQueried = false;
                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
            string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.BasicFileShare);
            mainChannelClient.TreeConnect(uncSharePath, out treeId);
            #endregion

            #region CREATE
            Smb2CreateContextResponse[] serverCreateContexts;
            mainChannelClient.Create(
                treeId,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE | CreateOptions_Values.FILE_DELETE_ON_CLOSE,
                out fileId,
                out serverCreateContexts);
            #endregion

            if (Smb2Utility.IsSmb3xFamily(expectedDialect))
            {
                #region WRITE
                mainChannelClient.Write(treeId, fileId, contentWrite);
                #endregion
            }
        }
Ejemplo n.º 13
0
        public void ValidateNegotiateInfo_Negative_SMB311()
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb311);
            // Server will terminate connection if Validate Negotiate Info Request is not signed.
            TestConfig.CheckSigning();
            #endregion

            Smb2FunctionalClient testClient = new Smb2FunctionalClient(testConfig.Timeout, testConfig, this.Site);
            testClient.ConnectToServer(testConfig.UnderlyingTransport, testConfig.SutComputerName, testConfig.SutIPAddress);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE;  SESSION_SETUP; TREE_CONNECT");

            Guid clientGuid = Guid.NewGuid();
            DialectRevision[]   requestDialects    = Smb2Utility.GetDialects(DialectRevision.Smb311);
            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_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;
            NEGOTIATE_Response? negotiateResponse  = null;
            status = client.Negotiate(
                requestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                clientSecurityMode,
                clientCapabilities,
                clientGuid,
                (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb311, response);

                negotiateResponse = response;
            });

            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint   treeId;
            string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName);
            status = client.TreeConnect(ipcPath, out treeId);

            VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq = new VALIDATE_NEGOTIATE_INFO_Request();
            validateNegotiateInfoReq.Guid         = clientGuid;
            validateNegotiateInfoReq.Capabilities = clientCapabilities;
            validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NONE;
            validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
            validateNegotiateInfoReq.Dialects     = requestDialects;

            byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq);
            byte[] outputBuffer;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Attempt to validate negotiate info with info Guid: {0}, Capabilities: {1}, SecurityMode: {2}, DialectCount: {3}, Dialects: {4}",
                validateNegotiateInfoReq.Guid, validateNegotiateInfoReq.Capabilities, validateNegotiateInfoReq.SecurityMode, validateNegotiateInfoReq.DialectCount, Smb2Utility.GetArrayString(validateNegotiateInfoReq.Dialects));

            try
            {
                BaseTestSite.Log.Add(
                    LogEntryKind.TestStep,
                    "Attempt to send a request with an SMB2 header with a Command value equal to SMB2 IOCTL, and a CtlCode of FSCTL_VALIDATE_NEGOTIATE_INFO.");

                client.ValidateNegotiateInfo(
                    treeId,
                    inputBuffer,
                    out outputBuffer
                    );
            }
            catch
            {
            }

            BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when Connection.Dialect is \"3.1.1\".");
        }
Ejemplo n.º 14
0
        private void TestValidateNegotiateInfo(Smb2FunctionalClient client, ValidateNegotiateInfoRequestType requestType, DialectRevision[] invalidDialects = null)
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO);
            TestConfig.CheckDialectIOCTLCompatibility(CtlCode_Values.FSCTL_VALIDATE_NEGOTIATE_INFO);
            // Server will terminate connection if Validate Negotiate Info Request is not signed.
            TestConfig.CheckSigning();
            #endregion

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Start a client by sending the following requests: NEGOTIATE;  SESSION_SETUP; TREE_CONNECT");

            Guid clientGuid = Guid.NewGuid();
            DialectRevision[]   requestDialects    = TestConfig.RequestDialects;
            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_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES;
            SecurityMode_Values clientSecurityMode = SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED;
            NEGOTIATE_Response? negotiateResponse  = null;
            status = client.Negotiate(
                requestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                clientSecurityMode,
                clientCapabilities,
                clientGuid,
                (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);

                negotiateResponse = response;
            });


            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint   treeId;
            string ipcPath = Smb2Utility.GetIPCPath(TestConfig.SutComputerName);
            status = client.TreeConnect(ipcPath, out treeId);

            VALIDATE_NEGOTIATE_INFO_Request validateNegotiateInfoReq;
            switch (requestType)
            {
            case ValidateNegotiateInfoRequestType.None:
            case ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse:
                validateNegotiateInfoReq.Guid         = clientGuid;
                validateNegotiateInfoReq.Capabilities = clientCapabilities;
                validateNegotiateInfoReq.SecurityMode = clientSecurityMode;
                validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
                validateNegotiateInfoReq.Dialects     = requestDialects;
                break;

            case ValidateNegotiateInfoRequestType.InvalidDialects:
                validateNegotiateInfoReq.Guid         = clientGuid;
                validateNegotiateInfoReq.Capabilities = clientCapabilities;
                validateNegotiateInfoReq.SecurityMode = clientSecurityMode;
                validateNegotiateInfoReq.DialectCount = (ushort)invalidDialects.Length;
                validateNegotiateInfoReq.Dialects     = invalidDialects;
                break;

            case ValidateNegotiateInfoRequestType.InvalidGuid:
                validateNegotiateInfoReq.Guid         = Guid.NewGuid();
                validateNegotiateInfoReq.Capabilities = clientCapabilities;
                validateNegotiateInfoReq.SecurityMode = clientSecurityMode;
                validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
                validateNegotiateInfoReq.Dialects     = requestDialects;
                break;

            case ValidateNegotiateInfoRequestType.InvalidSecurityMode:
                validateNegotiateInfoReq.Guid         = clientGuid;
                validateNegotiateInfoReq.Capabilities = clientCapabilities;
                validateNegotiateInfoReq.SecurityMode = SecurityMode_Values.NONE;
                validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
                validateNegotiateInfoReq.Dialects     = requestDialects;
                break;

            case ValidateNegotiateInfoRequestType.InvalidCapabilities:
                validateNegotiateInfoReq.Guid         = clientGuid;
                validateNegotiateInfoReq.Capabilities = Capabilities_Values.NONE;
                validateNegotiateInfoReq.SecurityMode = clientSecurityMode;
                validateNegotiateInfoReq.DialectCount = (ushort)requestDialects.Length;
                validateNegotiateInfoReq.Dialects     = requestDialects;
                break;

            default:
                throw new InvalidOperationException("Unexpected ValidateNegotiateInfo request type " + requestType);
            }

            byte[] inputBuffer = TypeMarshal.ToBytes <VALIDATE_NEGOTIATE_INFO_Request>(validateNegotiateInfoReq);
            byte[] outputBuffer;
            VALIDATE_NEGOTIATE_INFO_Response validateNegotiateInfoResp;
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Attempt to validate negotiate info with info Guid: {0}, Capabilities: {1}, SecurityMode: {2}, DialectCount: {3}, Dialects: {4}",
                validateNegotiateInfoReq.Guid, validateNegotiateInfoReq.Capabilities, validateNegotiateInfoReq.SecurityMode, validateNegotiateInfoReq.DialectCount, Smb2Utility.GetArrayString(validateNegotiateInfoReq.Dialects));

            if (requestType == ValidateNegotiateInfoRequestType.None)
            {
                status = client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, checker: (header, response) => { });

                BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status,
                                             "ValidateNegotiateInfo should succeed ");

                validateNegotiateInfoResp = TypeMarshal.ToStruct <VALIDATE_NEGOTIATE_INFO_Response>(outputBuffer);
                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Capabilities returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Capabilities);
                BaseTestSite.Assert.AreEqual(
                    (Capabilities_Values)negotiateResponse.Value.Capabilities,
                    validateNegotiateInfoResp.Capabilities,
                    "Capabilities returned in ValidateNegotiateInfo response should be equal to server capabilities in original Negotiate response");

                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Guid returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Guid);
                BaseTestSite.Assert.AreEqual(
                    negotiateResponse.Value.ServerGuid,
                    validateNegotiateInfoResp.Guid,
                    "ServerGuid returned in ValidateNegotiateInfo response should be equal to server ServerGuid in original Negotiate response");

                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "SecurityMode returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.SecurityMode);
                BaseTestSite.Assert.AreEqual(
                    (SecurityMode_Values)negotiateResponse.Value.SecurityMode,
                    validateNegotiateInfoResp.SecurityMode,
                    "SecurityMode returned in ValidateNegotiateInfo response should be equal to server SecurityMode in original Negotiate response");

                BaseTestSite.Log.Add(
                    LogEntryKind.Debug,
                    "Dialect returned in ValidateNegotiateInfo response: {0}", validateNegotiateInfoResp.Dialect);
                BaseTestSite.Assert.AreEqual(
                    negotiateResponse.Value.DialectRevision,
                    validateNegotiateInfoResp.Dialect,
                    "DialectRevision returned in ValidateNegotiateInfo response should be equal to server DialectRevision in original Negotiate response");

                client.TreeDisconnect(treeId);
                client.LogOff();
                return;
            }

            uint maxOutputResponse = (requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse) ? (uint)0: 64 * 1024;

            try
            {
                client.ValidateNegotiateInfo(treeId, inputBuffer, out outputBuffer, maxOutputResponse, (header, response) => { });

                client.TreeDisconnect(treeId);
                client.LogOff();
                return;
            }
            catch
            {
            }

            string errCondition = requestType == ValidateNegotiateInfoRequestType.InvalidMaxOutputResponse ?
                                  "MaxOutputResponse in the request is less than the size of a VALIDATE_NEGOTIATE_INFO Response" : "there's invalid info in the request";

            BaseTestSite.Assert.IsTrue(client.Smb2Client.IsServerDisconnected, "Transport connection should be terminated when {0}", errCondition);
        }
        public void MultipleChannel_SecondChannelSessionSetupFailAtFirstTime()
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb311);
            TestConfig.CheckCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL);
            #endregion

            string contentWrite;
            string contentRead;
            uint   treeId;
            FILEID fileId;

            contentWrite = Smb2Utility.CreateRandomString(TestConfig.WriteBufferLengthInKb);

            BaseTestSite.Assert.IsTrue(
                clientIps.Count > 0,
                "Client should have at least one IP address");
            BaseTestSite.Assert.IsTrue(
                serverIps.Count > 0,
                "Server should have more than one IP address");

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Start to write content to file from main channel with client {0} and server {1}", clientIps[0].ToString(), serverIps[0].ToString());
            WriteFromMainChannel(
                serverIps[0],
                clientIps[0],
                contentWrite,
                false,
                out treeId,
                out fileId);

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Set up alternative channel with client {0} and server {1}", clientIps[0].ToString(), serverIps[0].ToString());

            alternativeChannelClient.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIps[1], clientIps[1]);
            alternativeChannelClient.Negotiate(
                TestConfig.RequestDialects,
                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,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb311, response);
                if (Smb2Utility.IsSmb3xFamily(DialectRevision.Smb311))
                {
                    TestConfig.CheckNegotiateCapabilities(NEGOTIATE_Response_Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL, response);
                }
            });

            status = alternativeChannelClient.AlternativeChannelSessionSetup(
                mainChannelClient,
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken,
                checker: (header, response) => { },
                invalidToken: true);

            BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_INVALID_PARAMETER, status,
                                         "The first SessionSetup from alternative channel should return STATUS_INVALID_PARAMETER since the token in buffer field is set to an invalid value.");

            status = alternativeChannelClient.AlternativeChannelSessionSetup(
                mainChannelClient,
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken,
                checker: (header, response) => { });
            BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "The second SessionSetup from alternative channel should succeed");

            contentRead = "";
            status      = alternativeChannelClient.Read(treeId, fileId, 0, (uint)contentWrite.Length, out contentRead);

            // Read should succeed.
            // If Read response returns STATUS_ACCESS_DEINIED, it means signingkey used by server is wrong, and so that the PreauthIntegrityHashValue (which is used to generate the signingkey) calculated by server is wrong.
            // It is very possible that server uses the first failed session setup request/response (alternative channel) to calculate PreauthIntegrityHashValue, which is wrong.
            BaseTestSite.Assert.AreEqual(Smb2Status.STATUS_SUCCESS, status, "Read from the alternative channel should succeed");

            alternativeChannelClient.Close(treeId, fileId);
            alternativeChannelClient.TreeDisconnect(treeId);
            alternativeChannelClient.LogOff();

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Verify the contents read from alternative channel are the same as the one written by main channel.");
            BaseTestSite.Assert.IsTrue(
                contentWrite.Equals(contentRead),
                "Content read should be identical to content written.");
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Connect share on file server
        /// </summary>
        /// <param name="serverIp">Server IP address used for connection</param>
        /// <param name="clientIp">Client IP address used for connection</param>
        /// <param name="client">Client object to initialize the connection</param>
        /// <param name="treeId">Out param tree id connected</param>
        /// <param name="enableEncryptionPerShare">True indicates encryption enabled per share, otherwise disabled</param>
        private void ConnectShare(IPAddress serverIp, IPAddress clientIp, Smb2FunctionalClient client, out uint treeId, bool enableEncryptionPerShare = false)
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Connect to share {0} with following steps.", uncSharePath);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Connect to server via Nic with Ip {0}", clientIp.ToString());
            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, serverIp, clientIp);

            #region Negotiate
            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_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES | Capabilities_Values.GLOBAL_CAP_ENCRYPTION;
            status = client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilities,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "CREATE should succeed.");

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            });
            #endregion

            #region SESSION_SETUP
            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Global encryption disabled");
            #endregion

            #region TREE_CONNECT to share
            status = client.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");
                }
            });

            client.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 connecting to share {0}", uncSharePath);
        }
        /// <summary>
        /// Connect to share on general clustered file server before failover happens, include NEGOTIATE, SESSION_SETUP, TREE_CONNECT
        /// </summary>
        /// <param name="server">Name of clustered file server</param>
        /// <param name="fsType">Type of clustered file server</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 ConnectGeneralFileServerBeforeFailover(string server, out uint treeId, bool enableEncryptionPerShare = false)
        {
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "BeforeFailover: Connect share {0} on server {1} with following steps.", uncSharePath, server);
            GetGeneralFileServerClusterOwner(server);

            clientBeforeFailover.ConnectToServer(TestConfig.UnderlyingTransport, server, currentAccessIp);

            #region Negotiate
            Capabilities_Values clientCapabilitiesBeforeFAilover = 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 = clientBeforeFailover.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilitiesBeforeFAilover,
                clientGuid: clientGuid,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            }
                );
            #endregion

            #region SESSION_SETUP
            status = clientBeforeFailover.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                server,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Global encryption disabled");
            #endregion

            #region TREE_CONNECT to share
            status = clientBeforeFailover.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");
                }

                BaseTestSite.Assert.IsTrue(response.Capabilities.HasFlag(Share_Capabilities_Values.SHARE_CAP_CONTINUOUS_AVAILABILITY),
                                           "CA Share should have SHARE_CAP_CONTINUOUS_AVAILABILITY bit set for Capabilities in TreeConnect response.");
            });

            clientBeforeFailover.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,
                "BeforeFailover: Finish connecting to share {0} on server {1}", uncSharePath, server);
        }
Ejemplo n.º 18
0
        public void FileServerFailover_BlockCreateFromDifferentClient()
        {
            uncSharePath = Smb2Utility.GetUncPath(TestConfig.ClusteredFileServerName, TestConfig.ClusteredFileShare);

            #region From one client open a file and request persistent handle before failover
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "From one client open a file and request persistent handle before failover");

            FILEID fileIdBeforeFailover;
            uint   treeIdBeforeFailover;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: Connect to general file server {0}.", TestConfig.ClusteredFileServerName);
            ConnectGeneralFileServerBeforeFailover(TestConfig.ClusteredFileServerName, out treeIdBeforeFailover);

            #region CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "BeforeFailover: CREATE a durable open with flag DHANDLE_FLAG_PERSISTENT.");
            Smb2CreateContextResponse[] serverCreateContexts;
            createGuid = Guid.NewGuid();
            status     = clientBeforeFailover.Create(
                treeIdBeforeFailover,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdBeforeFailover,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                new Smb2CreateContextRequest[] {
                new Smb2CreateDurableHandleRequestV2
                {
                    CreateGuid = createGuid,
                    Flags      = CREATE_DURABLE_HANDLE_REQUEST_V2_Flags.DHANDLE_FLAG_PERSISTENT,
                    Timeout    = 3600000,
                },
            });
            #endregion
            #endregion

            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "Disable owner node to simulate failover");
            FailoverServer(currentAccessIp, TestConfig.ClusteredFileServerName, FileServerType.GeneralFileServer);

            #region From a different client try to open the same file after failover
            BaseTestSite.Log.Add(
                LogEntryKind.TestStep,
                "AfterFailover: From a different client try to open the same file");
            DoUntilSucceed(() => clientAfterFailover.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.ClusteredFileServerName, currentAccessIp), TestConfig.FailoverTimeout,
                           "Retry to connect to server until succeed within timeout span");

            #region Connect to the same share of the same general file server
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Connect to the same share of the same general file server.");

            #region Negotiate
            Capabilities_Values clientCapabilitiesAfterFailover = 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;
            status = clientAfterFailover.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                capabilityValue: clientCapabilitiesAfterFailover,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                TestConfig.CheckNegotiateDialect(DialectRevision.Smb21, response);
            });
            #endregion

            #region SESSION_SETUP
            status = clientAfterFailover.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.ClusteredFileServerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);
            #endregion

            #region TREE_CONNECT to share
            uint treeIdAfterFailover = 0;
            //Retry TreeConnect until succeed within timeout span
            status = DoUntilSucceed(
                () => clientAfterFailover.TreeConnect(uncSharePath, out treeIdAfterFailover, (header, response) => { }),
                TestConfig.FailoverTimeout,
                "Retry TreeConnect until succeed within timeout span");
            BaseTestSite.Assert.AreEqual(
                Smb2Status.STATUS_SUCCESS,
                status,
                "TreeConnect to {0} should succeed, actual status is {1}", uncSharePath, Smb2Status.GetStatusCode(status));
            #endregion
            #endregion

            #region CREATE to open the same file
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "AfterFailover: Send CREATE request using incompatible share access with previous CREATE and this should result violation");
            FILEID fileIdAfterFailover;
            status = clientAfterFailover.Create(
                treeIdAfterFailover,
                fileName,
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileIdAfterFailover,
                out serverCreateContexts,
                RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                null,
                // Incompatible share access with previous CREATE request and will result violation
                shareAccess: ShareAccess_Values.FILE_SHARE_WRITE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_DELETE,
                checker: (header, response) =>
            {
                BaseTestSite.Assert.AreNotEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "From a different client try to open the same file after failover should not success");
            });
            #endregion
            #endregion
        }
Ejemplo n.º 19
0
        public void BVT_SetGetIntegrityInfo()
        {
            #region Check Applicability
            TestConfig.CheckDialect(DialectRevision.Smb30);
            TestConfig.CheckIOCTL(CtlCode_Values.FSCTL_SET_INTEGRITY_INFORMATION, CtlCode_Values.FSCTL_GET_INTEGRITY_INFORMATION);
            #endregion

            client.ConnectToServer(TestConfig.UnderlyingTransport, TestConfig.SutComputerName, TestConfig.SutIPAddress);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client creates a file by sending the following requests: NEGOTIATE; SESSION_SETUP; TREE_CONNECT; CREATE");
            status = client.Negotiate(
                TestConfig.RequestDialects,
                TestConfig.IsSMB1NegotiateEnabled,
                checker: (Packet_Header header, NEGOTIATE_Response response) =>
            {
                BaseTestSite.Assert.AreEqual(
                    Smb2Status.STATUS_SUCCESS,
                    header.Status,
                    "Negotiation should succeed, actually server returns {0}.", Smb2Status.GetStatusCode(header.Status));

                TestConfig.CheckNegotiateDialect(DialectRevision.Smb30, response);
            });

            status = client.SessionSetup(
                TestConfig.DefaultSecurityPackage,
                TestConfig.SutComputerName,
                TestConfig.AccountCredential,
                TestConfig.UseServerGssToken);

            uint   treeId;
            string uncSharePath = Smb2Utility.GetUncPath(TestConfig.SutComputerName, TestConfig.FileShareSupportingIntegrityInfo);
            status = client.TreeConnect(uncSharePath, out treeId);

            FILEID fileId;
            Smb2CreateContextResponse[] serverCreateContexts;
            status = client.Create(
                treeId,
                GetTestFileName(uncSharePath),
                CreateOptions_Values.FILE_NON_DIRECTORY_FILE,
                out fileId,
                out serverCreateContexts);

            FSCTL_GET_INTEGRITY_INFO_OUTPUT getIntegrityInfo;
            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_GET_INTEGRITY_INFORMATION.");
            status = client.GetIntegrityInfo(treeId, fileId, out getIntegrityInfo);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Integrity info returned in FSCTL_GET_INTEGRITY_INFO request: ChecksumAlgorithm {0}, Flags {1}, ChecksumChunkSizeInBytes {2}, ClusterSizeInBytes {3}",
                getIntegrityInfo.ChecksumAlgorithm, getIntegrityInfo.Flags, getIntegrityInfo.ChecksumChunkSizeInBytes, getIntegrityInfo.ClusterSizeInBytes);

            FSCTL_SET_INTEGRIY_INFO_INPUT setIntegrityInfo;
            setIntegrityInfo.ChecksumAlgorithm = FSCTL_SET_INTEGRITY_INFO_INPUT_CHECKSUMALGORITHM.CHECKSUM_TYPE_CRC64;
            setIntegrityInfo.Flags             = FSCTL_SET_INTEGRITY_INFO_INPUT_FLAGS.FSCTL_INTEGRITY_FLAG_CHECKSUM_ENFORCEMENT_OFF;
            setIntegrityInfo.Reserved          = FSCTL_SET_INTEGRITY_INFO_INPUT_RESERVED.V1;
            byte[] buffer = TypeMarshal.ToBytes <FSCTL_SET_INTEGRIY_INFO_INPUT>(setIntegrityInfo);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Attempt to set integrity info with ChecksumAlgrithm {0}, Flags {1}",
                setIntegrityInfo.ChecksumAlgorithm, setIntegrityInfo.Flags);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_SET_INTEGRITY_INFORMATION after changed the value of the following fields in FSCTL_SET_INTEGRIY_INFO_INPUT: ChecksumAlgorithm, Flags, Reserved.");
            status = client.SetIntegrityInfo(treeId, fileId, buffer);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Client sends IOCTL request with FSCTL_GET_INTEGRITY_INFORMATION.");
            status = client.GetIntegrityInfo(treeId, fileId, out getIntegrityInfo);

            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Current ChecksumAlgorithm is " + getIntegrityInfo.ChecksumAlgorithm);
            BaseTestSite.Assert.AreEqual(
                (ushort)setIntegrityInfo.ChecksumAlgorithm,
                (ushort)getIntegrityInfo.ChecksumAlgorithm,
                "ChecksumAlgorithm field after set should be {0}, actual value is {1}", setIntegrityInfo.ChecksumAlgorithm, getIntegrityInfo.ChecksumAlgorithm);
            BaseTestSite.Log.Add(
                LogEntryKind.Debug,
                "Current Flags is " + getIntegrityInfo.Flags);
            BaseTestSite.Assert.AreEqual(
                (uint)setIntegrityInfo.Flags,
                (uint)getIntegrityInfo.Flags,
                "Flags field after set should be {0}, actual value is {1}", setIntegrityInfo.Flags, getIntegrityInfo.Flags);

            BaseTestSite.Log.Add(LogEntryKind.TestStep, "Tear down the client by sending the following requests: CLOSE; TREE_DISCONNECT; LOG_OFF.");
            status = client.Close(treeId, fileId);
            status = client.TreeDisconnect(treeId);
            status = client.LogOff();
        }