private bool GetRemoteNetworkInterfaceInformation(IPAddress ip) { try { using (var client = new SMBDClient(DetectionInfo.ConnectionTimeout)) { client.Connect(ip, IPAddress.Parse(DetectionInfo.DriverNonRdmaNICIPAddress)); client.Smb2Negotiate(new DialectRevision[] { DialectRevision.Smb30, DialectRevision.Smb302, DialectRevision.Smb311 }); client.Smb2SessionSetup(DetectionInfo.Authentication, DetectionInfo.DomainName, DetectionInfo.SUTName, DetectionInfo.UserName, DetectionInfo.Password); uint treeId; string ipcPath = Smb2Utility.GetIPCPath(DetectionInfo.SUTName); client.Smb2TreeConnect(ipcPath, out treeId); byte[] input; byte[] output; client.IoCtl(treeId, CtlCode_Values.FSCTL_QUERY_NETWORK_INTERFACE_INFO, FILEID.Invalid, IOCTL_Request_Flags_Values.SMB2_0_IOCTL_IS_FSCTL, out input, out output); var networkInterfaces = Smb2Utility.UnmarshalNetworkInterfaceInfoResponse(output); var remoteInterfaces = ParseRemoteNetworkInterfaceInformation(networkInterfaces); FilterNetworkInterfaces(remoteInterfaces); return(true); } } catch (Exception ex) { DetectorUtil.WriteLog(String.Format("GetRemoteNetworkInterfaceInformation failed for {0}: {1}.", ip.ToString(), ex.ToString())); return(false); } }
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 } }
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\"."); }
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); }
/// <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); }