Beispiel #1
0
        /// <summary>
        /// Set up connection with server.
        /// Including 5 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect 5. Create an open on the vhd file
        /// </summary>
        /// <param name="serverName">server name</param>
        /// <param name="serverIP">server IP address</param>
        /// <param name="domain">user's domain</param>
        /// <param name="userName">user's name</param>
        /// <param name="password">user's password</param>
        /// <param name="securityPackage">The security package</param>
        /// <param name="useServerToken">Whether to use token from server</param>
        /// <param name="shareName">Name of the share when TreeConnect</param>
        /// <param name="vhdName">Name of the vhd file</param>
        /// <returns>Status of the create operation</returns>
        public uint ConnectToVHD(
            string serverName,
            IPAddress serverIP,
            string domain,
            string userName,
            string password,
            SecurityPackageType securityPackage,
            bool useServerToken,
            string shareName,
            string vhdName)
        {
            transport = new Smb2ClientTransport();
            transport.ConnectShare(serverName, serverIP, domain, userName, password, shareName, securityPackage, useServerToken);
            uint status;

            Smb2CreateContextResponse[] serverContexts;
            CREATE_Response             response;

            transport.Create(
                vhdName,
                // The desired access is set the same as Windows client's behavior
                FsFileDesiredAccess.GENERIC_READ | FsFileDesiredAccess.GENERIC_WRITE | FsFileDesiredAccess.DELETE,
                ShareAccess_Values.FILE_SHARE_DELETE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE,
                FsImpersonationLevel.Impersonation,
                FsFileAttribute.NONE,
                FsCreateDisposition.FILE_OPEN_IF,
                FsCreateOption.NONE,
                null,
                out status,
                out serverContexts,
                out response);
            return(status);
        }
 /// <summary>
 /// Set up connection with server.
 /// Including 5 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect 5. Create an open on the vhd file
 /// </summary>
 /// <param name="serverName">server name</param>
 /// <param name="serverIP">server IP address</param> 
 /// <param name="domain">user's domain</param>
 /// <param name="userName">user's name</param>
 /// <param name="password">user's password</param>
 /// <param name="securityPackage">The security package</param>
 /// <param name="useServerToken">Whether to use token from server</param>
 /// <param name="shareName">Name of the share when TreeConnect</param>
 /// <param name="vhdName">Name of the vhd file</param>
 /// <returns>Status of the create operation</returns>
 public uint ConnectToVHD(
     string serverName,
     IPAddress serverIP,
     string domain,
     string userName,
     string password,
     SecurityPackageType securityPackage,
     bool useServerToken,
     string shareName,
     string vhdName)
 {
     transport = new Smb2ClientTransport();
     transport.ConnectShare(serverName, serverIP, domain, userName, password, shareName, securityPackage, useServerToken);
     uint status;
     Smb2CreateContextResponse[] serverContexts;
     CREATE_Response response;
     transport.Create(
         vhdName,
         // The desired access is set the same as Windows client's behavior
         FsFileDesiredAccess.GENERIC_READ | FsFileDesiredAccess.GENERIC_WRITE | FsFileDesiredAccess.DELETE,
         ShareAccess_Values.FILE_SHARE_DELETE | ShareAccess_Values.FILE_SHARE_READ | ShareAccess_Values.FILE_SHARE_WRITE,
         FsImpersonationLevel.Impersonation,
         FsFileAttribute.NONE,
         FsCreateDisposition.FILE_OPEN_IF,
         FsCreateOption.NONE,
         null,
         out status,
         out serverContexts,
         out response);
     return status;
 }
        public DtlsClientSecurityContext(
            SecurityPackageType packageType,
            CertificateCredential clientCredential,
            string serverPrincipal,
            ClientSecurityContextAttribute contextAttributes,
            SecurityTargetDataRepresentation targetDataRep)
        {
            if (clientCredential == null)
            {
                clientCredential = new CertificateCredential(null);
            }
            this.packageType               = packageType;
            this.serverPrincipalName       = serverPrincipal;
            this.securityContextAttributes = contextAttributes;
            this.targetDataRepresentaion   = targetDataRep;

            SspiUtility.DtlsAcquireCredentialsHandle(
                packageType,
                clientCredential,
                serverPrincipal,
                NativeMethods.SECPKG_CRED_OUTBOUND,
                out this.credentialHandle);

            bStreamSizes     = false;
            hasMoreFragments = false;
        }
        private uint SessionSetup(
            Packet_Header_Flags_Values headerFlags,
            SESSION_SETUP_Request_Flags sessionSetupFlags,
            SESSION_SETUP_Request_SecurityMode_Values securityMode,
            SESSION_SETUP_Request_Capabilities_Values capabilities,
            ulong previousSessionId,
            SecurityPackageType securityPackageType,
            string serverName,
            byte[] token,
            out byte[] serverGssToken,
            ushort creditRequest = 64)
        {
            Packet_Header          header;
            SESSION_SETUP_Response sessionSetupResponse;

            uint status;

            status = client.SessionSetup(
                1,
                creditRequest,
                headerFlags,
                messageId++,
                sessionId,
                sessionSetupFlags,
                securityMode,
                capabilities,
                previousSessionId,
                token,
                out sessionId,
                out serverGssToken,
                out header,
                out sessionSetupResponse);

            return(status);
        }
 /// <summary>
 /// Set up connection with server.
 /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order
 /// </summary>
 /// <param name="server">server name of ip address</param>
 /// <param name="client">client name of ip address</param>
 /// <param name="domain">user's domain</param>
 /// <param name="userName">user's name</param>
 /// <param name="password">user's password</param>
 /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param>
 /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception>
 public abstract void Connect(
     string server,
     string client,
     string domain,
     string userName,
     string password,
     TimeSpan timeout,
     SecurityPackageType securityPackage,
     bool useServerToken);
Beispiel #6
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="packageType">Specifies the name of the security package with which these credentials will be used
 /// </param>
 /// <param name="serverCredential">The credential of server, if null, use default user account.</param>
 /// <param name="serverPrincipal">Server principal name</param>
 /// <param name="contextAttributes">Bit flags that specify the attributes required by the server to establish
 /// the context</param>
 /// <param name="targetDataRep">The data representation, such as byte ordering, on the target. This parameter
 /// can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.</param>
 public SspiServerSecurityContext(
     SecurityPackageType packageType,
     CertificateCredential serverCredential,
     string serverPrincipal,
     ServerSecurityContextAttribute contextAttributes,
     SecurityTargetDataRepresentation targetDataRep)
 {
     this.packageType               = packageType;
     this.serverPrincipalName       = serverPrincipal;
     this.securityContextAttributes = contextAttributes;
     this.targetDataRepresentaion   = targetDataRep;
     this.AcquireCredentialsHandle(serverCredential);
 }
        /// <summary>
        /// Set up connection with server.
        /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order
        /// </summary>
        /// <param name="server">server name</param>
        /// <param name="client">client name</param>
        /// <param name="domain">user's domain</param>
        /// <param name="userName">user's name</param>
        /// <param name="password">user's password</param>
        /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param>
        /// <exception cref="InvalidOperationException">Fail to set up connection with server</exception>
        public override void Connect(
            string server,
            string client,
            string domain,
            string userName,
            string password,
            TimeSpan timeout,
            SecurityPackageType securityPackage,
            bool useServerToken)
        {
            this.internalTimeout = timeout;

            ConnectShare(server, 445, IpVersion.Any, domain, userName, password, IPC_SHARE, securityPackage, useServerToken);
        }
        public DtlsServerSecurityContext(
            SecurityPackageType packageType,
            CertificateCredential serverCredential,
            string serverPrincipal,
            ServerSecurityContextAttribute contextAttributes,
            SecurityTargetDataRepresentation targetDataRep)
        {
            this.packageType               = packageType;
            this.serverPrincipalName       = serverPrincipal;
            this.securityContextAttributes = contextAttributes;
            this.targetDataRepresentaion   = targetDataRep;

            this.Context = new Sspi.DtlsServerSecurityContext(packageType, serverCredential, serverPrincipal, contextAttributes, targetDataRep);
        }
        /// <summary>
        /// Constructor with client credential, principal of server, ContextAttributes and TargetDataRep.
        /// </summary>
        /// <param name="packageType">Specifies the name of the security package with which these credentials will be used
        /// </param>
        /// <param name="clientCredential">Client account credential, if null, use default user account</param>
        /// <param name="serverPrincipal">Server principal name</param>
        /// <param name="contextAttributes">Context attributes</param>
        /// <param name="targetDataRep">The data representation, such as byte ordering, on the target.
        /// This parameter can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.</param>
        public SspiClientSecurityContext(
            SecurityPackageType packageType,
            AccountCredential clientCredential,
            string serverPrincipal,
            ClientSecurityContextAttribute contextAttributes,
            SecurityTargetDataRepresentation targetDataRep)
        {
            this.packageType               = packageType;
            this.serverPrincipalName       = serverPrincipal;
            this.securityContextAttributes = contextAttributes;
            this.targetDataRepresentaion   = targetDataRep;

            this.AcquireCredentialsHandle(clientCredential);
        }
Beispiel #10
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="logger">Enable the log</param>
        /// <param name="contentServerName">The ContentServer name</param>
        /// <param name="hostedCacheServerName">The HostedCacheServer name</param>
        /// <param name="accountCredential">Account credential</param>
        /// <param name="securityPackageType">security package: NTLM, Negotiate, kerbrose</param>
        public BranchCacheDetector(Logger logger, string contentServerName, string hostedCacheServerName, AccountCredential accountCredential, SecurityPackageType securityPackageType = SecurityPackageType.Negotiate)
        {
            ContentServerName     = contentServerName;
            HostedCacheServerName = hostedCacheServerName;
            Credential            = accountCredential;
            SecurityPackageType   = securityPackageType;

            logWriter = logger;
            logWriter.AddLog(LogLevel.Information, string.Format("ContentServerName: {0}", ContentServerName));
            logWriter.AddLog(LogLevel.Information, string.Format("HostedCacheServerName: {0}", HostedCacheServerName));
            logWriter.AddLog(LogLevel.Information, string.Format("DomainName: {0}", Credential.DomainName));
            logWriter.AddLog(LogLevel.Information, string.Format("UserName: {0}", Credential.AccountName));
            logWriter.AddLog(LogLevel.Information, string.Format("UserPassword: {0}", Credential.Password));
            logWriter.AddLog(LogLevel.Information, string.Format("SecurityPackageType: {0}", SecurityPackageType.ToString()));
            logWriter.AddLineToLog(LogLevel.Information);
        }
        public FSDetector(Logger logger, 
            string targetSUT,
            AccountCredential accountCredential,
            SecurityPackageType securityPackageType)
        {
            SUTName = targetSUT;
            Credential = accountCredential;
            SecurityPackageType = securityPackageType;

            logWriter = logger;
            logWriter.AddLog(LogLevel.Information, string.Format("SutName: {0}", SUTName));
            logWriter.AddLog(LogLevel.Information, string.Format("DomainName: {0}", Credential.DomainName));
            logWriter.AddLog(LogLevel.Information, string.Format("UserName: {0}", Credential.AccountName));
            logWriter.AddLog(LogLevel.Information, string.Format("UserPassword: {0}", Credential.Password));
            logWriter.AddLog(LogLevel.Information, string.Format("SecurityPackageType: {0}", SecurityPackageType.ToString()));
            logWriter.AddLineToLog(LogLevel.Information);
        }
        public DtlsClientSecurityContext(
            SecurityPackageType packageType,
            CertificateCredential clientCredential,
            string serverPrincipal,
            ClientSecurityContextAttribute contextAttributes,
            SecurityTargetDataRepresentation targetDataRep)
        {
            if (clientCredential == null)
            {
                clientCredential = new CertificateCredential(null);
            }
            this.packageType               = packageType;
            this.serverPrincipalName       = serverPrincipal;
            this.securityContextAttributes = contextAttributes;
            this.targetDataRepresentaion   = targetDataRep;

            this.Context = new Sspi.DtlsClientSecurityContext(packageType, clientCredential, serverPrincipal, contextAttributes, targetDataRep) as IDtlsClientSecurityContext;
        }
Beispiel #13
0
 /// <summary>
 /// Constructor
 /// </summary>
 /// <param name="packageType">Specifies the name of the security package with which these credentials will be used
 /// </param>
 /// <param name="serverCredential">The credential of server, if null, use default user account.</param>
 /// <param name="serverPrincipal">Server principal name</param>
 /// <param name="contextAttributes">Bit flags that specify the attributes required by the server to establish
 /// the context</param>
 /// <param name="targetDataRep">The data representation, such as byte ordering, on the target. This parameter
 /// can be either SECURITY_NATIVE_DREP or SECURITY_NETWORK_DREP.</param>
 public SspiServerSecurityContext(
     SecurityPackageType packageType,
     AccountCredential serverCredential,
     string serverPrincipal,
     ServerSecurityContextAttribute contextAttributes,
     SecurityTargetDataRepresentation targetDataRep)
 {
     this.packageType               = packageType;
     this.serverPrincipalName       = serverPrincipal;
     this.securityContextAttributes = contextAttributes;
     this.targetDataRepresentaion   = targetDataRep;
     SspiUtility.AcquireCredentialsHandle(
         packageType,
         serverCredential,
         serverPrincipal,
         NativeMethods.SECPKG_CRED_INBOUND,
         out this.credentialHandle);
 }
        public TestConfig(ITestSite site)
        {
            ContentTransport = (ContentInformationTransport)Enum.Parse(typeof(ContentInformationTransport), site.Properties["ContentTransport"]);

            SupportBranchCacheV1 = bool.Parse(site.Properties["SupportBranchCacheV1"]);
            SupportBranchCacheV2 = bool.Parse(site.Properties["SupportBranchCacheV2"]);

            ContentServerComputerName = site.Properties["ContentServerComputerName"];
            HostedCacheServerComputerName = site.Properties["HostedCacheServerComputerName"];
            ClientPeerComputerName = site.Properties["ClientPeerComputerName"];

            DomainName = site.Properties["DomainName"];
            UserName = site.Properties["UserName"];
            UserPassword = site.Properties["UserPassword"];

            HashLevelType = (ServerHashLevel)Enum.Parse(typeof(ServerHashLevel), site.Properties["SupportedHashLevel"]);

            SecurityPackageType = (SecurityPackageType)Enum.Parse(typeof(SecurityPackageType), site.Properties["SecurityPackageType"]);

            ServerSecret = Encoding.Unicode.GetBytes(site.Properties["ServerSecret"]);

            Timeout = TimeSpan.FromSeconds(int.Parse(site.Properties["Timeout"]));
            RetryInterval = TimeSpan.FromSeconds(int.Parse(site.Properties["RetryInterval"]));
            NegativeTestTimeout = TimeSpan.FromSeconds(int.Parse(site.Properties["NegativeTestTimeout"]));

            SharedFolderName = site.Properties["SharedFolderName"];

            NameOfFileWithMultipleSegments = site.Properties["NameOfFileWithMultipleSegments"];
            NameOfFileWithMultipleBlocks = site.Properties["NameOfFileWithMultipleBlocks"];
            NameOfFileWithSingleBlock = site.Properties["NameOfFileWithSingleBlock"];

            WebsiteLocalPath = site.Properties["WebsiteLocalPath"];
            FileShareLocalPath = site.Properties["FileShareLocalPath"];

            SupportWebsiteForcedHashGeneration = bool.Parse(site.Properties["SupportWebsiteForcedHashGeneration"]);
            SupportFileShareForcedHashGeneration = bool.Parse(site.Properties["SupportFileShareForcedHashGeneration"]);

            ContentServerHTTPListenPort = int.Parse(site.Properties["ContentServerHTTPListenPort"]);
            HostedCacheServerHTTPListenPort = int.Parse(site.Properties["HostedCacheServerHTTPListenPort"]);
            HostedCacheServerHTTPSListenPort = int.Parse(site.Properties["HostedCacheServerHTTPSListenPort"]);
            ClientContentRetrievalListenPort = int.Parse(site.Properties["ClientContentRetrievalListenPort"]);
        }
        public DtlsServerSecurityContext(
            SecurityPackageType packageType,
            CertificateCredential serverCredential,
            string serverPrincipal,
            ServerSecurityContextAttribute contextAttributes,
            SecurityTargetDataRepresentation targetDataRep)
        {
            this.packageType = packageType;
            this.serverPrincipalName = serverPrincipal;
            this.securityContextAttributes = contextAttributes;
            this.targetDataRepresentaion = targetDataRep;
            SspiUtility.DtlsAcquireCredentialsHandle(
                packageType,
                serverCredential,
                serverPrincipal,
                NativeMethods.SECPKG_CRED_INBOUND,
                out this.credentialHandle);

            bStreamSizes = false;
            hasMoreFragments = false;
        }
 public uint SessionSetup(
     SESSION_SETUP_Request_SecurityMode_Values securityMode,
     SESSION_SETUP_Request_Capabilities_Values capabilities,
     SecurityPackageType securityPackageType,
     string serverName,
     byte[] token,
     out byte[] serverGssToken,
     ushort creditRequest = 64)
 {
     return(SessionSetup(
                Packet_Header_Flags_Values.NONE,
                SESSION_SETUP_Request_Flags.NONE,
                securityMode,
                capabilities,
                0,
                securityPackageType,
                serverName,
                token,
                out serverGssToken,
                creditRequest));
 }
Beispiel #17
0
        /// <summary>
        /// Set up connection with server.
        /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order
        /// </summary>
        /// <param name="server">server name of ip address</param>
        /// <param name="client">client name of ip address</param>
        /// <param name="domain">user's domain</param>
        /// <param name="userName">user's name</param>
        /// <param name="password">user's password</param>
        /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param>
        /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception>
        public void Connect(
            string server,
            string client,
            string domain,
            string userName,
            string password,
            TimeSpan timeout,
            SecurityPackageType securityPackage,
            bool useServerToken,
            bool transportPreferredSMB)
        {
            if (transportPreferredSMB)
            {
                transport = new SmbClientTransport();
            }
            else
            {
                transport = new Smb2ClientTransport();
            }

            transport.Connect(server, client, domain, userName, password, timeout, securityPackage, useServerToken);
        }
Beispiel #18
0
        /// <summary>
        /// Convert MechType to SecurityPackage enum
        /// </summary>
        /// <param name="mechType">The MechType value to be convert</param>
        /// <returns>The converted AuthMech enum value</returns>
        public static SecurityPackageType ConvertMechType(MechType mechType)
        {
            SecurityPackageType authType = SecurityPackageType.Unknown;

            if (ArrayUtility.CompareArrays <int>(mechType.Value, SspiLib.Consts.MsKerbOidInt))
            {
                authType = SecurityPackageType.Kerberos;
            }
            else if (ArrayUtility.CompareArrays <int>(mechType.Value, SspiLib.Consts.NlmpOidInt))
            {
                authType = SecurityPackageType.Ntlm;
            }
            else if (ArrayUtility.CompareArrays <int>(mechType.Value, SspiLib.Consts.KerbOidInt))
            {
                authType = SecurityPackageType.Kerberos;
            }
            else if (ArrayUtility.CompareArrays <int>(mechType.Value, SspiLib.Consts.NegoExOidInt))
            {
                authType = SecurityPackageType.Unknown;
            }

            return(authType);
        }
Beispiel #19
0
        /// <summary>
        /// Bind RPC server.
        /// </summary>
        /// <param name="swnClient">SWN rpc client</param>
        /// <param name="networkAddress">RPC network address</param>
        /// <param name="domainName">Domain name</param>
        /// <param name="userName">User name</param>
        /// <param name="password">Password</param>
        /// <param name="securityPackage">Security package</param>
        /// <param name="authLevel">Authentication level</param>
        /// <param name="timeout">Timeout</param>
        /// <param name="serverComputerName">ServerComputerName</param>
        /// <returns>Return true if success, otherwise return false</returns>
        public static bool BindServer(SwnClient swnClient, IPAddress networkAddress, string domainName, string userName, string password,
                                      SecurityPackageType securityPackage, RpceAuthenticationLevel authLevel, TimeSpan timeout, string serverComputerName = null)
        {
            AccountCredential accountCredential        = new AccountCredential(domainName, userName, password);
            string            cifsServicePrincipalName = string.Empty;

            if (!string.IsNullOrEmpty(serverComputerName))
            {
                cifsServicePrincipalName = "cifs/" + serverComputerName;
            }
            else
            {
                IPHostEntry hostEntry = null;
                try
                {
                    hostEntry = Dns.GetHostEntry(networkAddress);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Failed to resolve network address {0} with exception: {1}", networkAddress.ToString(), ex.Message));
                }

                if (hostEntry != null && !string.IsNullOrEmpty(hostEntry.HostName))
                {
                    cifsServicePrincipalName = "cifs/" + hostEntry.HostName;
                }
                else
                {
                    throw new Exception("Failed to get HostName from network address " + networkAddress.ToString());
                }
            }
            ClientSecurityContext securityContext =
                new SspiClientSecurityContext(
                    securityPackage,
                    accountCredential,
                    cifsServicePrincipalName,
                    ClientSecurityContextAttribute.Connection
                    | ClientSecurityContextAttribute.DceStyle
                    | ClientSecurityContextAttribute.Integrity
                    | ClientSecurityContextAttribute.ReplayDetect
                    | ClientSecurityContextAttribute.SequenceDetect
                    | ClientSecurityContextAttribute.UseSessionKey,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            try
            {
                //Bind
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Start to Bind RPC to {0}.", networkAddress.ToString());
                swnClient.SwnBind(networkAddress.ToString(), accountCredential, securityContext, authLevel, timeout);
            }
            catch (Exception ex)
            {
                BaseTestSite.Log.Add(LogEntryKind.Debug,
                                     "Bind server {0} failed. Exception: {1}",
                                     networkAddress.ToString(),
                                     ex.Message);
                swnClient.SwnUnbind(timeout);
                return(false);
            }

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Bind server {0} successfully.", networkAddress.ToString());
            return(true);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="securityPackageType">Security package type.</param>
 protected SecurityConfig(SecurityPackageType securityPackageType)
 {
     this.securityType = securityPackageType;
 }
        /// <summary>
        /// Set up connection with server.
        /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order
        /// </summary>
        /// <param name="server">server name</param>
        /// <param name="client">client name</param>
        /// <param name="domain">user's domain</param>
        /// <param name="userName">user's name</param>
        /// <param name="password">user's password</param>
        /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param>
        /// <exception cref="InvalidOperationException">Fail to set up connection with server</exception>
        public override void Connect(
            string server,
            string client,
            string domain,
            string userName,
            string password,
            TimeSpan timeout,
            SecurityPackageType securityPackage, 
            bool useServerToken)
        {
            this.internalTimeout = timeout;

            ConnectShare(server, 445, IpVersion.Any, domain, userName, password, IPC_SHARE, securityPackage, useServerToken);
        }
Beispiel #22
0
 /// <summary>
 /// Connect to a share indicated by shareName in server
 /// This will use smb over tcp as transport. Only one server
 /// can be connected at one time
 /// </summary>
 /// <param name="serverName">The server Name</param>
 /// <param name="port">The server port</param>
 /// <param name="ipVersion">The ip version</param>
 /// <param name="domain">The domain name</param>
 /// <param name="userName">The user name</param>
 /// <param name="password">The password</param>
 /// <param name="shareName">The share name</param>
 /// <param name="securityPackage">The security package</param>
 /// <param name="useServerToken">Whether to use token from server</param>
 /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
 public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain,
                                   string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Connect to a share indicated by shareName in server
        /// This will use smb over tcp as transport. Only one server
        /// can be connected at one time
        /// </summary>
        /// <param name="serverName">The server Name</param>
        /// <param name="port">The server port</param>
        /// <param name="ipVersion">The ip version</param>
        /// <param name="domain">The domain name</param>
        /// <param name="userName">The user name</param>
        /// <param name="password">The password</param>
        /// <param name="shareName">The share name</param>
        /// <param name="securityPackage">The security package</param>
        /// <param name="useServerToken">Whether to use token from server</param>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain,
            string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken)
        {
            smbClient.Connect(serverName, port, ipVersion, defaultBufferSize);

            InternalConnectShare(serverName, domain, userName, password, shareName, securityPackage);
        }
        internal static void DtlsAcquireCredentialsHandle(
            SecurityPackageType packageType,
            CertificateCredential certificateCredential,
            string serverPrincipal,
            uint fCredentialUse,
            out SecurityHandle credentialHandle)
        {
            string stringPackage = SspiUtility.GetPackageStringName(packageType);
            SecurityInteger expiryTime = new SecurityInteger();
            uint enabledProtocols;

            if (fCredentialUse == NativeMethods.SECPKG_CRED_OUTBOUND)
            {
                enabledProtocols = NativeMethods.SP_PROT_DTLS_CLIENT;
            }
            else
            {
                enabledProtocols = NativeMethods.SP_PROT_DTLS_SERVER;
            }

            SchannelCred schannelCred = new SchannelCred(certificateCredential, enabledProtocols);
            CredSspCred sspCred = new CredSspCred();
            IntPtr pAuthData = IntPtr.Zero;

            if (packageType == SecurityPackageType.Schannel)
            {
                pAuthData = SspiUtility.CreateAuthData(schannelCred);
            }
            else if (packageType == SecurityPackageType.CredSsp)
            {
                sspCred.pSchannelCred = SspiUtility.CreateAuthData(schannelCred);
                sspCred.pSpnegoCred = IntPtr.Zero;
                sspCred.Type = CredSspSubmitType.CredsspSubmitBufferBoth;
                pAuthData = SspiUtility.CreateAuthData(sspCred);
            }

            uint result = NativeMethods.AcquireCredentialsHandle(
                null,
                stringPackage,
                fCredentialUse,
                IntPtr.Zero,
                pAuthData,
                IntPtr.Zero,
                IntPtr.Zero,
                out credentialHandle,
                out expiryTime);
            //Free memory
            SspiUtility.FreeSchannelCred(schannelCred);
            if (pAuthData != IntPtr.Zero)
            {
                if (packageType == SecurityPackageType.CredSsp)
                {
                    Marshal.FreeHGlobal(sspCred.pSchannelCred);
                }
                Marshal.FreeHGlobal(pAuthData);
            }

            if (result != NativeMethods.SEC_E_OK)
            {
                throw new SspiException("AquireCredentialsHandle fails.", result);
            }
        }
Beispiel #25
0
        /// <summary>
        /// Get the specific configuration from the SecurityConfig list by the security type.
        /// </summary>
        /// <param name="configList">SecurityConfig list.</param>
        /// <param name="securityType">The security type.</param>
        /// <returns>The specific security configuration.</returns>
        internal static SecurityConfig GetSecurityConfig(SecurityConfig[] configList, SecurityPackageType securityType)
        {
            SecurityConfig sspiConfig = null;

            foreach (SecurityConfig configItem in configList)
            {
                if (configItem.SecurityType == securityType)
                {
                    return(configItem);
                }
                else if (configItem.SecurityType == SecurityPackageType.Unknown)
                {
                    // SSPI configuration is initialized as Unknown type
                    sspiConfig = configItem;
                }
            }

            return(sspiConfig);
        }
Beispiel #26
0
        private void executeButton_Click(object sender, EventArgs e)
        {
            try
            {
                if (!CheckInput())
                {
                    return;
                }

                logger.Clear();

                #region Read settings from UI

                var version       = (BranchCacheVersion)branchCacheVersionComboBox.SelectedItem;
                var operationMode = (OperationMode)operationModeComboBox.SelectedItem;
                var transport     = (ContentInformationTransport)transportComboBox.SelectedItem;

                var serverSecret = serverSecretTextBox.Text;
                var filePath     = filePathTextBox.Text;

                var           hashAlgoValue = (dwHashAlgo_Values)hashAlgorithmComboBox.SelectedItem;
                HashAlgorithm hashAlgorithm;
                HMAC          hmacAlgorithm;
                int           hashBlockSize;

                string server        = null;
                string file          = null;
                string sharedFolder  = null;
                Match  filePathMatch = null;
                switch (transport)
                {
                case ContentInformationTransport.PCCRTP:
                    filePathMatch = Regex.Match(filePath, httpFilePathPattern);
                    server        = filePathMatch.Groups["Server"].Value;
                    file          = filePathMatch.Groups["FileName"].Value;
                    break;

                case ContentInformationTransport.SMB2:
                    filePathMatch = Regex.Match(filePath, smb2FilePathPattern);
                    server        = filePathMatch.Groups["Server"].Value;
                    sharedFolder  = filePathMatch.Groups["SharedFolder"].Value;
                    file          = filePathMatch.Groups["FileName"].Value;
                    break;

                default:
                    throw new NotImplementedException();
                }


                SecurityPackageType securityPackageType = (SecurityPackageType)smb2AuthenticationComboBox.SelectedItem;

                string domainName   = domainNameTextBox.Text;
                string userName     = userNameTextBox.Text;
                string userPassword = userPasswordTextBox.Text;

                #endregion

                var timeout = TimeSpan.FromSeconds(60);

                byte[] content;
                byte[] contentInformation;

                Content_Information_Data_Structure    contentInformationStructure   = new Content_Information_Data_Structure();
                Content_Information_Data_Structure_V2 contentInformationStructureV2 = new Content_Information_Data_Structure_V2();

                #region Read content and content information

                if (operationMode == OperationMode.RemoteHashVerification)
                {
                    switch (transport)
                    {
                    case ContentInformationTransport.PCCRTP:
                        PccrtpClient  pccrtpClient  = new PccrtpClient();
                        PccrtpRequest pccrtpRequest = pccrtpClient.CreatePccrtpRequest(
                            server,
                            80,
                            file,
                            version);
                        PccrtpResponse pccrtpResponse = pccrtpClient.SendHttpRequest(
                            HttpVersionType.HttpVersion11,
                            pccrtpRequest,
                            (int)timeout.TotalMilliseconds);

                        if (pccrtpResponse.HttpResponse.ContentEncoding == "peerdist")
                        {
                            contentInformation = pccrtpResponse.PayloadData;

                            content = Utility.DownloadHTTPFile(server, file);
                        }
                        else
                        {
                            content = pccrtpResponse.PayloadData;

                            Thread.Sleep(5000);     // Wait for hash generation

                            pccrtpResponse = pccrtpClient.SendHttpRequest(
                                HttpVersionType.HttpVersion11,
                                pccrtpRequest,
                                (int)timeout.TotalMilliseconds);

                            contentInformation = pccrtpResponse.PayloadData;
                        }

                        break;

                    case ContentInformationTransport.SMB2:
                        using (Smb2ClientTransport smb2Client = new Smb2ClientTransport(timeout))
                        {
                            smb2Client.OpenFile(
                                server,
                                sharedFolder,
                                file,
                                securityPackageType,
                                domainName,
                                userName,
                                userPassword,
                                AccessMask.GENERIC_READ);

                            content = smb2Client.ReadAllBytes();

                            Thread.Sleep(5000);     // Wait for hash generation

                            HASH_HEADER hashHeader;
                            smb2Client.ReadHash(
                                SRV_READ_HASH_Request_HashType_Values.SRV_HASH_TYPE_PEER_DIST,
                                version == BranchCacheVersion.V1 ? SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_1 : SRV_READ_HASH_Request_HashVersion_Values.SRV_HASH_VER_2,
                                version == BranchCacheVersion.V1 ? SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_HASH_BASED : SRV_READ_HASH_Request_HashRetrievalType_Values.SRV_HASH_RETRIEVE_FILE_BASED,
                                0,
                                uint.MaxValue,
                                out hashHeader,
                                out contentInformation);
                        }

                        break;

                    default:
                        throw new NotImplementedException();
                    }

                    switch (version)
                    {
                    case BranchCacheVersion.V1:
                        contentInformationStructure = PccrcUtility.ParseContentInformation(contentInformation);
                        break;

                    case BranchCacheVersion.V2:
                        contentInformationStructureV2 = PccrcUtility.ParseContentInformationV2(contentInformation);
                        break;

                    default:
                        throw new NotImplementedException();
                    }
                }
                else
                {
                    content = File.ReadAllBytes(filePath);
                }

                #endregion

                #region Calculate hash and execute verification

                switch (version)
                {
                case BranchCacheVersion.V1:

                    if (operationMode == OperationMode.RemoteHashVerification)
                    {
                        PccrcUtility.GetHashAlgorithm(contentInformationStructure.dwHashAlgo, out hashAlgorithm, out hmacAlgorithm, out hashBlockSize);
                    }
                    else
                    {
                        PccrcUtility.GetHashAlgorithm(hashAlgoValue, out hashAlgorithm, out hmacAlgorithm, out hashBlockSize);
                    }
                    hmacAlgorithm.Key = hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes(serverSecret));

                    logger.LogInfo(
                        "Ks = Hash(ServerSecret): {0}",
                        Utility.ToHexString(hmacAlgorithm.Key));

                    logger.NewLine();

                    int blockTotalCount = content.Length / BLOCKBYTECOUNT;
                    if (content.Length > BLOCKBYTECOUNT * blockTotalCount)
                    {
                        blockTotalCount = blockTotalCount + 1;
                    }

                    int segmentCount = blockTotalCount / SEGMENTBLOCKCOUNT;
                    if (blockTotalCount > SEGMENTBLOCKCOUNT * segmentCount)
                    {
                        segmentCount = segmentCount + 1;
                    }

                    for (int segmentIndex = 0; segmentIndex < segmentCount; segmentIndex++)
                    {
                        logger.LogInfo("Segment{0}", segmentIndex);
                        logger.NewLine();
                        logger.Indent();

                        List <byte> blockHashList = new List <byte>();

                        List <byte> tempList = new List <byte>();

                        int blockCount = (segmentIndex == segmentCount - 1) ? (blockTotalCount % SEGMENTBLOCKCOUNT) : (SEGMENTBLOCKCOUNT);

                        for (int blockIndex = 0; blockIndex < blockCount; blockIndex++)
                        {
                            logger.LogInfo(
                                "Block{0} Offset {1} Length {2}",
                                blockIndex,
                                BLOCKBYTECOUNT * SEGMENTBLOCKCOUNT * segmentIndex + BLOCKBYTECOUNT * blockIndex,
                                BLOCKBYTECOUNT);
                            logger.NewLine();
                            logger.Indent();

                            var block = content.Skip(BLOCKBYTECOUNT * SEGMENTBLOCKCOUNT * segmentIndex + BLOCKBYTECOUNT * blockIndex).Take(BLOCKBYTECOUNT).ToArray();

                            byte[] blockHash = hashAlgorithm.ComputeHash(block);

                            logger.LogInfo("BlockHash{0} = Hash(Block): {1}", blockIndex, Utility.ToHexString(blockHash));

                            if (operationMode == OperationMode.RemoteHashVerification &&
                                !blockHash.SequenceEqual(contentInformationStructure.blocks[segmentIndex].BlockHashes.Skip(blockIndex * hashBlockSize).Take(hashBlockSize)))
                            {
                                logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.blocks[segmentIndex].BlockHashes.Skip(blockIndex * hashBlockSize).Take(hashBlockSize).ToArray()));
                            }

                            blockHashList.AddRange(blockHash);

                            logger.Unindent();
                            logger.NewLine();
                        }

                        byte[] hod = hashAlgorithm.ComputeHash(blockHashList.ToArray());

                        logger.LogInfo(
                            "HoD = Hash(BlockHash0 + BlockHash1 + ... + BlockHashN): {0}",
                            Utility.ToHexString(hod));

                        if (operationMode == OperationMode.RemoteHashVerification &&
                            !hod.SequenceEqual(contentInformationStructure.segments[segmentIndex].SegmentHashOfData))
                        {
                            logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.segments[segmentIndex].SegmentHashOfData));
                        }

                        logger.NewLine();

                        byte[] kp = hmacAlgorithm.ComputeHash(hod);

                        logger.LogInfo(
                            "Kp = HMAC(Ks, HoD): {0}",
                            Utility.ToHexString(kp));

                        if (operationMode == OperationMode.RemoteHashVerification &&
                            !kp.SequenceEqual(contentInformationStructure.segments[segmentIndex].SegmentSecret))
                        {
                            logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructure.segments[segmentIndex].SegmentSecret));
                        }

                        logger.NewLine();

                        tempList.AddRange(hod);
                        tempList.AddRange(Encoding.Unicode.GetBytes(HOHODK_APPEND_STRING));

                        byte[] hoHoDK = hashAlgorithm.ComputeHash(tempList.ToArray());

                        logger.LogInfo(
                            "hoHoDK = HMAC(HoD + \"MS_P2P_CACHING\"): {0}",
                            Utility.ToHexString(hoHoDK));

                        logger.NewLine();

                        logger.Unindent();
                    }
                    break;

                case BranchCacheVersion.V2:

                    PccrcUtility.GetHashAlgorithm(dwHashAlgoV2_Values.TRUNCATED_SHA512, out hashAlgorithm, out hmacAlgorithm);
                    hmacAlgorithm.Key = hashAlgorithm.ComputeHash(Encoding.Unicode.GetBytes(serverSecret)).Take(32).ToArray();

                    logger.LogInfo(
                        "Ks = Hash(ServerSecret): {0}",
                        Utility.ToHexString(hmacAlgorithm.Key));

                    logger.NewLine();

                    int segmentLength = BLOCKBYTECOUNT;
                    int chunkCount    = 1;

                    if (operationMode == OperationMode.RemoteHashVerification)
                    {
                        chunkCount = contentInformationStructureV2.chunks.Length;
                    }

                    int segmentOffset = 0;
                    for (int chunkIndex = 0; chunkIndex < chunkCount; chunkIndex++)
                    {
                        logger.LogInfo("Chunk{0}", chunkIndex);
                        logger.NewLine();
                        logger.Indent();

                        segmentCount = content.Length / segmentLength;
                        if (content.Length > segmentCount * segmentLength)
                        {
                            segmentCount++;
                        }

                        if (operationMode == OperationMode.RemoteHashVerification)
                        {
                            segmentCount = contentInformationStructureV2.chunks[chunkIndex].chunkData.Length;
                        }

                        for (int segmentIndex = 0; segmentIndex < segmentCount; ++segmentIndex)
                        {
                            logger.LogInfo(
                                "Segment{0} Offset {1} Length {2}",
                                segmentIndex,
                                segmentOffset,
                                BLOCKBYTECOUNT);
                            logger.NewLine();
                            logger.Indent();

                            if (operationMode == OperationMode.RemoteHashVerification)
                            {
                                segmentLength = (int)contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].cbSegment;
                            }

                            List <byte> tempList = new List <byte>();

                            var segment = content.Skip(segmentOffset).Take(segmentLength).ToArray();

                            segmentOffset += segmentLength;

                            //TRANCATED_SHA_512
                            byte[] hod = hashAlgorithm.ComputeHash(segment).Take(32).ToArray();

                            logger.LogInfo(
                                "HoD = Hash(Segment): {0}",
                                Utility.ToHexString(hod));

                            if (operationMode == OperationMode.RemoteHashVerification &&
                                !hod.SequenceEqual(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentHashOfData))
                            {
                                logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentHashOfData));
                            }

                            logger.NewLine();

                            byte[] kp = hmacAlgorithm.ComputeHash(hod).Take(32).ToArray();

                            logger.LogInfo(
                                "Kp = HMAC(Ks, HoD): {0}",
                                Utility.ToHexString(kp));

                            if (operationMode == OperationMode.RemoteHashVerification &&
                                !kp.SequenceEqual(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentSecret))
                            {
                                logger.LogError("Server Returned: {0}", Utility.ToHexString(contentInformationStructureV2.chunks[chunkIndex].chunkData[segmentIndex].SegmentSecret));
                            }

                            logger.NewLine();

                            tempList.AddRange(hod);
                            tempList.AddRange(Encoding.Unicode.GetBytes(HOHODK_APPEND_STRING));

                            byte[] hoHoDK = hashAlgorithm.ComputeHash(tempList.ToArray());

                            logger.LogInfo(
                                "hoHoDK = HMAC(HoD + \"MS_P2P_CACHING\"): {0}",
                                Utility.ToHexString(hoHoDK));

                            logger.NewLine();

                            logger.Unindent();
                        }
                    }

                    break;

                default:
                    throw new NotImplementedException();
                }

                if (operationMode == OperationMode.RemoteHashVerification)
                {
                    if (logger.HasError)
                    {
                        Utility.ShowMessageBox("Hash verification error found!", MessageBoxIcon.Error);
                    }
                    else
                    {
                        Utility.ShowMessageBox("Hash verification passed!", MessageBoxIcon.Information);
                    }
                }

                #endregion
            }
            catch (Exception ex)
            {
                Utility.ShowMessageBox(ex.Message + "\r\n\r\n" + ex.StackTrace, MessageBoxIcon.Error);
            }
        }
        /// <summary>
        /// Connect to a share indicated by shareName in server
        /// This will use smb over tcp as transport. Only one server
        /// can be connected at one time
        /// </summary>
        /// <param name="serverName">The server Name</param>
        /// <param name="port">The server port</param>
        /// <param name="ipVersion">The ip version</param>
        /// <param name="domain">The domain name</param>
        /// <param name="userName">The user name</param>
        /// <param name="password">The password</param>
        /// <param name="shareName">The share name</param>
        /// <param name="securityPackage">The security package</param>
        /// <param name="useServerToken">Whether to use token from server</param>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain,
            string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken)
        {
            IPHostEntry hostEntry = Dns.GetHostEntry(serverName);
            serverPrincipleName = Smb2Utility.GetPrincipleName(hostEntry.HostName);

            if (ipVersion == IpVersion.Ipv4)
            {
                foreach (var ip in hostEntry.AddressList)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                    {
                        client.ConnectOverTCP(ip);
                        break;
                    }
                }
            }
            else if (ipVersion == IpVersion.Ipv6)
            {
                foreach (var ip in hostEntry.AddressList)
                {
                    if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                    {
                        client.ConnectOverTCP(ip);
                        break;
                    }
                }
            }
            else
            {
                // if specified the IpVersion.Any, try ipv4 first, if failed, try ipv6
                try
                {
                    foreach (var ip in hostEntry.AddressList)
                    {
                        if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                        {
                            client.ConnectOverTCP(ip);
                            break;
                        }
                    }
                }
                catch (InvalidOperationException)
                {
                    foreach (var ip in hostEntry.AddressList)
                    {
                        if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6)
                        {
                            client.ConnectOverTCP(ip);
                            break;
                        }
                    }
                }
            }

            if (!client.IsConnected)
            {
                throw new InvalidOperationException("No valid IP address can be used to connect to the server.");
            }

            InternalConnectShare(domain, userName, password, shareName, internalTimeout,
                securityPackage, useServerToken);
        }
        internal static byte[] QuerySessionKey(SecurityPackageType packageType, ref SecurityHandle contextHandle)
        {
            IntPtr pSessionKey = IntPtr.Zero;
            byte[] sessionKey = null;

            if (packageType == SecurityPackageType.Schannel || packageType == SecurityPackageType.CredSsp)
            {
                pSessionKey = Marshal.AllocHGlobal(SchannelKeySize + SchannelIvSize);
                uint hResult = NativeMethods.QueryContextAttributes(
                    ref contextHandle,
                    NativeMethods.SECPKG_ATTR_EAP_KEY_BLOCK,
                    pSessionKey);
                if (hResult == NativeMethods.SEC_E_OK)
                {
                    if (pSessionKey != IntPtr.Zero)
                    {
                        sessionKey = new byte[SchannelKeySize];
                        Marshal.Copy(pSessionKey, sessionKey, 0, SchannelKeySize);
                    }
                }
                Marshal.FreeHGlobal(pSessionKey);
            }
            else
            {
                pSessionKey = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(SecurityPackageContextSessionKey)));
                uint hResult = NativeMethods.QueryContextAttributes(
                    ref contextHandle,
                    NativeMethods.SECPKG_ATTR_SESSION_KEY,
                    pSessionKey);
                if (hResult == NativeMethods.SEC_E_OK)
                {
                    if (pSessionKey != IntPtr.Zero)
                    {
                        SecurityPackageContextSessionKey contextSessionKey = (SecurityPackageContextSessionKey)
                            Marshal.PtrToStructure(pSessionKey, typeof(SecurityPackageContextSessionKey));

                        sessionKey = new byte[contextSessionKey.SessionKeyLength];
                        Marshal.Copy(contextSessionKey.SessionKey, sessionKey, 0, sessionKey.Length);
                        NativeMethods.FreeContextBuffer(contextSessionKey.SessionKey);
                    }
                }
                Marshal.FreeHGlobal(pSessionKey);
            }

            return sessionKey;
        }
        public void Smb2SessionSetup(SecurityPackageType authentication, string domain, string serverName, string userName, string password)
        {
            var sspiClientGss = new SspiClientSecurityContext(
                authentication,
                new AccountCredential(domain, userName, password),
                Smb2Utility.GetCifsServicePrincipalName(serverName),
                ClientSecurityContextAttribute.None,
                SecurityTargetDataRepresentation.SecurityNativeDrep
                );


            if (authentication == SecurityPackageType.Negotiate)
            {
                sspiClientGss.Initialize(serverGssToken);
            }
            else
            {
                sspiClientGss.Initialize(null);
            }

            Packet_Header packetHeader;

            SESSION_SETUP_Response sessionSetupResponse;

            uint status;

            while (true)
            {
                status = SessionSetup(
                    0,
                    RequestAndConsumeCredit(),
                    Packet_Header_Flags_Values.NONE,
                    GetMessageId(),
                    sessionId,
                    SESSION_SETUP_Request_Flags.NONE,
                    SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                    SESSION_SETUP_Request_Capabilities_Values.NONE,
                    sessionId,
                    sspiClientGss.Token,
                    out sessionId,
                    out serverGssToken,
                    out packetHeader,
                    out sessionSetupResponse
                    );

                UpdateCredit(packetHeader);

                if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && serverGssToken != null && serverGssToken.Length > 0)
                {
                    sspiClientGss.Initialize(serverGssToken);
                }

                if (status != Smb2Status.STATUS_MORE_PROCESSING_REQUIRED)
                {
                    break;
                }
            }

            if (status != Smb2Status.STATUS_SUCCESS)
            {
                throw new InvalidOperationException(String.Format("SessionSetup failed with {0:X08}.", status));
            }

            encryptionEnabled = sessionSetupResponse.SessionFlags.HasFlag(SessionFlags_Values.SESSION_FLAG_ENCRYPT_DATA);


            GenerateCryptoKeys(
                sessionId,
                sspiClientGss.SessionKey,
                signingRequired,
                encryptionEnabled
                );

            if (!encryptionEnabled)
            {
                signingRequired = true;
            }

            EnableSessionSigningAndEncryption(sessionId, signingRequired, encryptionEnabled);
        }
 /// <summary>
 /// Set up connection with server.
 /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order
 /// </summary>
 /// <param name="server">server name of ip address</param>
 /// <param name="client">client name of ip address</param>
 /// <param name="domain">user's domain</param>
 /// <param name="userName">user's name</param>
 /// <param name="password">user's password</param> 
 /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param>
 /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception>
 public abstract void Connect(
     string server,
     string client,
     string domain,
     string userName,
     string password,
     TimeSpan timeout,
     SecurityPackageType securityPackage, 
     bool useServerToken);
 /// <summary>
 /// Connect to a share indicated by shareName in server
 /// This will use smb over tcp as transport. Only one server
 /// can be connected at one time
 /// </summary>
 /// <param name="serverName">The server Name</param>
 /// <param name="port">The server port</param>
 /// <param name="ipVersion">The ip version</param>
 /// <param name="domain">The domain name</param>
 /// <param name="userName">The user name</param>
 /// <param name="password">The password</param>
 /// <param name="shareName">The share name</param>
 /// <param name="securityPackage">The security package</param>
 /// <param name="useServerToken">Whether to use token from server</param>
 /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
 public abstract void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain,
     string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken);
        /// <summary>
        /// Convert SecurityPackage type to package string used by SSPI.
        /// </summary>
        /// <param name="packageType">Package type</param>
        /// <returns>Package string used by SSPI</returns>
        /// <exception cref="ArgumentException">If packageType is not supported, throw this exception.</exception>
        internal static string GetPackageStringName(SecurityPackageType packageType)
        {
            string package = string.Empty;
            switch (packageType)
            {
                case SecurityPackageType.CredSsp:
                    package = CredSsp;
                    break;
                case SecurityPackageType.Kerberos:
                    package = Kerberos;
                    break;
                case SecurityPackageType.Negotiate:
                    package = Negotiate;
                    break;
                case SecurityPackageType.Ntlm:
                    package = Ntlm;
                    break;
                case SecurityPackageType.Schannel:
                    package = Schannel;
                    break;
                default:
                    throw new ArgumentException("Invlid packageType value.", "packageType");
            }

            return package;
        }
        public SspiClientSecurityContext(
            SecurityPackageType packageType,
            AccountCredential clientCredential,
            string serverPrincipal,
            ClientSecurityContextAttribute contextAttributes,
            SecurityTargetDataRepresentation targetDataRep)
        {
            this.packageType = packageType;
            this.serverPrincipalName = serverPrincipal;
            this.securityContextAttributes = contextAttributes;
            this.targetDataRepresentaion = targetDataRep;

            SspiUtility.AcquireCredentialsHandle(
                packageType,
                clientCredential,
                serverPrincipal,
                NativeMethods.SECPKG_CRED_OUTBOUND,
                out this.credentialHandle);
        }
        /// <summary>
        /// Bind RPC server.
        /// </summary>
        /// <param name="swnClient">SWN rpc client</param>
        /// <param name="networkAddress">RPC network address</param>
        /// <param name="domainName">Domain name</param>
        /// <param name="userName">User name</param>
        /// <param name="password">Password</param>
        /// <param name="securityPackage">Security package</param>
        /// <param name="authLevel">Authentication level</param>
        /// <param name="timeout">Timeout</param>
        /// <param name="serverComputerName">ServerComputerName</param>
        /// <returns>Return true if success, otherwise return false</returns>
        public static bool BindServer(SwnClient swnClient, IPAddress networkAddress, string domainName, string userName, string password,
            SecurityPackageType securityPackage, RpceAuthenticationLevel authLevel, TimeSpan timeout,string serverComputerName = null)
        {
            AccountCredential accountCredential = new AccountCredential(domainName, userName, password);
            string cifsServicePrincipalName = string.Empty;
            if (!string.IsNullOrEmpty(serverComputerName))
            {
                cifsServicePrincipalName = "cifs/" + serverComputerName;
            }
            else
            {
                IPHostEntry hostEntry = null;
                try
                {
                    hostEntry = Dns.GetHostEntry(networkAddress);
                }
                catch (Exception ex)
                {
                    throw new Exception(string.Format("Failed to resolve network address {0} with exception: {1}", networkAddress.ToString(), ex.Message));
                }

                if (hostEntry != null && !string.IsNullOrEmpty(hostEntry.HostName))
                {
                    cifsServicePrincipalName = "cifs/" + hostEntry.HostName;
                }
                else
                {
                    throw new Exception("Failed to get HostName from network address " + networkAddress.ToString());
                }
            }
            ClientSecurityContext securityContext =
                new SspiClientSecurityContext(
                    securityPackage,
                    accountCredential,
                    cifsServicePrincipalName,
                    ClientSecurityContextAttribute.Connection
                        | ClientSecurityContextAttribute.DceStyle
                        | ClientSecurityContextAttribute.Integrity
                        | ClientSecurityContextAttribute.ReplayDetect
                        | ClientSecurityContextAttribute.SequenceDetect
                        | ClientSecurityContextAttribute.UseSessionKey,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            try
            {
                //Bind
                BaseTestSite.Log.Add(LogEntryKind.Debug, "Start to Bind RPC to {0}.", networkAddress.ToString());
                swnClient.SwnBind(networkAddress.ToString(), accountCredential, securityContext, authLevel, timeout);
            }
            catch (Exception ex)
            {
                BaseTestSite.Log.Add(LogEntryKind.Debug,
                    "Bind server {0} failed. Exception: {1}",
                    networkAddress.ToString(),
                    ex.Message);
                swnClient.SwnUnbind(timeout);
                return false;
            }

            BaseTestSite.Log.Add(LogEntryKind.Debug, "Bind server {0} successfully.", networkAddress.ToString());
            return true;
        }
 /// <summary>
 /// Set up connection with server.
 /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order
 /// </summary>
 /// <param name="server">server name of ip address</param>
 /// <param name="client">client name of ip address</param>
 /// <param name="domain">user's domain</param>
 /// <param name="userName">user's name</param>
 /// <param name="password">user's password</param> 
 /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param>
 /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception>
 public override void Connect(
     string server,
     string client,
     string domain,
     string userName,
     string password,
     TimeSpan timeout,
     SecurityPackageType securityPackage,
     bool useServerToken)
 {
     serverPrincipleName = server;
     IPHostEntry hostEntry = Dns.GetHostEntry(server);
     this.client.ConnectOverTCP(hostEntry.AddressList[0]);
     InternalConnectShare(domain, userName, password, IPC_CONNECT_STRING, timeout, securityPackage, useServerToken);
 }
        internal static void AcquireCredentialsHandle(
            SecurityPackageType packageType,
            AccountCredential accountCredential,
            string serverPrincipal,
            uint fCredentialUse,
            out SecurityHandle credentialHandle)
        {
            string stringPackage = SspiUtility.GetPackageStringName(packageType);

            SecurityInteger expiryTime;
            SecurityWinntAuthIdentity authIdentity = new SecurityWinntAuthIdentity(accountCredential);
            IntPtr pAuthData = IntPtr.Zero;
            SchannelCred schannelCred = new SchannelCred();
            schannelCred.dwVersion = NativeMethods.SCHANNEL_CRED_VERSION;
            schannelCred.cCreds = 0;
            schannelCred.paCred = IntPtr.Zero;
            CredSspCred credSsp = new CredSspCred();

            switch (packageType)
            {
                case SecurityPackageType.Ntlm:
                case SecurityPackageType.Kerberos:
                case SecurityPackageType.Negotiate:
                    pAuthData = SspiUtility.CreateAuthData(authIdentity);
                    break;
                case SecurityPackageType.Schannel:
                    pAuthData = SspiUtility.CreateAuthData(schannelCred);
                    break;
                case SecurityPackageType.CredSsp:
                    credSsp.Type = CredSspSubmitType.CredsspSubmitBufferBoth;
                    credSsp.pSchannelCred = CreateAuthData(schannelCred);
                    credSsp.pSpnegoCred = CreateAuthData(authIdentity);
                    pAuthData = CreateAuthData(credSsp);
                    break;
                //default, if other values, exception will be thrown by GetPackageStringName.
                default:
                    throw new ArgumentException("Invlid packageType value.", "packageType");
            }

            uint result = NativeMethods.AcquireCredentialsHandle(
                serverPrincipal,
                stringPackage,
                fCredentialUse,
                IntPtr.Zero,
                pAuthData,
                IntPtr.Zero,
                IntPtr.Zero,
                out credentialHandle,
                out expiryTime);
            //Free memory
            switch (packageType)
            {
                case SecurityPackageType.Ntlm:
                case SecurityPackageType.Kerberos:
                case SecurityPackageType.Negotiate:
                    SspiUtility.FreeSecurityWinntAuthIdentity(authIdentity);
                    break;
                case SecurityPackageType.Schannel:
                    stringPackage = Schannel;
                    SspiUtility.FreeSchannelCred(schannelCred);
                    break;
                case SecurityPackageType.CredSsp:
                    SspiUtility.FreeSecurityWinntAuthIdentity(authIdentity);
                    SspiUtility.FreeSchannelCred(schannelCred);
                    SspiUtility.FreeCredSspCred(credSsp);
                    break;
                //default, if other values, exception will be thrown by GetPackageStringName.
                default:
                    throw new ArgumentException("Invlid packageType value.", "packageType");
            }
            Marshal.FreeHGlobal(pAuthData);

            if (result != NativeMethods.SEC_E_OK)
            {
                throw new SspiException("AquireCredentialsHandle failed", result);
            }
        }
        private void InternalConnectShare(string domain, string userName, string password, string shareName, TimeSpan timeout,
            SecurityPackageType securityPackage, bool useServerToken)
        {
            uint status;
            DialectRevision selectedDialect;
            Packet_Header header;
            byte[] serverGssToken;

            Array allDialects = Enum.GetValues(typeof(DialectRevision));
            DialectRevision[] validDialects = new DialectRevision[allDialects.Length - 2];
            int index = 0;
            foreach (var dialect in allDialects)
            {
                if ((DialectRevision)dialect != DialectRevision.Smb2Unknown && (DialectRevision)dialect != DialectRevision.Smb2Wildcard)
                {
                    validDialects[index++] = (DialectRevision)dialect;
                }
            }

            PreauthIntegrityHashID[] preauthIntegrityHashIDArray = null;
            EncryptionAlgorithm[] encryptionAlgorithmArray = null;
            if (validDialects.Contains(DialectRevision.Smb311))
            {
                preauthIntegrityHashIDArray = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 };
                encryptionAlgorithmArray = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM };
            }

            // Negotiate:
            NEGOTIATE_Response negotiateResponse;
            CheckStatusCode(
                client.Negotiate(
                    1,
                    1,
                    Packet_Header_Flags_Values.NONE,
                    messageId++,
                    // Will negotiate highest dialect server supports
                    validDialects,
                    SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                    Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_ENCRYPTION | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_LARGE_MTU,
                    clientGuid,
                    out selectedDialect,
                    out serverGssToken,
                    out header,
                    out negotiateResponse,
                    preauthHashAlgs: preauthIntegrityHashIDArray,
                    encryptionAlgs: encryptionAlgorithmArray));

            negotiatedDialect = selectedDialect;

            serverCapabilities = (Capabilities_Values)negotiateResponse.Capabilities;

            // 3.2.5.2: If the SecurityMode field in the SMB2 header of the response has the SMB2_NEGOTIATE_SIGNING_REQUIRED bit set,
            // the client MUST set Connection.RequireSigning to TRUE.
            // 3.2.5.3.1: If the global setting RequireMessageSigning is set to TRUE or
            // Connection.RequireSigning is set to TRUE then Session.SigningRequired MUST be set to TRUE
            bool session_SigningRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED);
            if (session_SigningRequired)
            {
                // 3.2.4.1.1: If the client signs the request, it MUST set the SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header.
                headerFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED;
            }

            // Session setup:
            SESSION_SETUP_Response sessionSetupResponse;

            SspiClientSecurityContext sspiClientGss =
                new SspiClientSecurityContext(
                    securityPackage,
                    new AccountCredential(domain, userName, password),
                    Smb2Utility.GetCifsServicePrincipalName(serverPrincipleName),
                    ClientSecurityContextAttribute.None,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            if (securityPackage == SecurityPackageType.Negotiate)
                sspiClientGss.Initialize(serverGssToken);
            else
                sspiClientGss.Initialize(null);

            do
            {
                status = client.SessionSetup(
                    1,
                    1,
                    Packet_Header_Flags_Values.NONE,
                    messageId++,
                    sessionId,
                    SESSION_SETUP_Request_Flags.NONE,
                    SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                    SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS,
                    0,
                    sspiClientGss.Token,
                    out sessionId,
                    out serverGssToken,
                    out header,
                    out sessionSetupResponse);

                CheckStatusCode(status);

                if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) &&
                    serverGssToken != null && serverGssToken.Length > 0)
                {
                    sspiClientGss.Initialize(serverGssToken);
                }
            } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED);

            // 3.2.4.1.1 If Connection.Dialect is "3.1.1" and the message being sent is a TREE_CONNECT Request and the session identified by SessionId has Session.EncryptData equal to FALSE
            bool treeconnect_SigningRequired = session_SigningRequired || (selectedDialect >= DialectRevision.Smb311);
            client.GenerateCryptoKeys(sessionId, sspiClientGss.SessionKey, treeconnect_SigningRequired, false);

            this.sessionId = header.SessionId;

            // Session Key will be used in the MS-LSA SDK, see LsaClient.cs Line 179 SessionKey
            // Insert the session key to the global context
            Smb2ClientSession smb2CliSession = new Smb2ClientSession();
            smb2CliSession.SessionKey = client.GetSessionKeyForAuthenticatedContext(sessionId);

            Smb2ClientConnection smb2CliConn = new Smb2ClientConnection();
            smb2CliConn.SessionTable = new Dictionary<ulong, Smb2ClientSession>();
            smb2CliConn.SessionTable.Add(sessionId, smb2CliSession);

            context.ConnectionTable = new Dictionary<string, Smb2ClientConnection>();
            context.ConnectionTable.Add("Smb2ClientConnection", smb2CliConn);

            // Tree connect:
            TREE_CONNECT_Response treeConnectResponse;

            status = client.TreeConnect(
                    1,
                    1,
                    treeconnect_SigningRequired? headerFlags| Packet_Header_Flags_Values.FLAGS_SIGNED:headerFlags,
                    messageId++,
                    sessionId,
                    "\\\\" + serverPrincipleName + "\\" + shareName,
                    out treeId,
                    out header,
                    out treeConnectResponse);

            this.treeId = header.TreeId;

            // For the messages followed by TREE_CONNECT, set them as signed/not signed following the normal proces
            client.EnableSessionSigningAndEncryption(sessionId, session_SigningRequired, false);
        }
        /// <summary>
        /// Connect share specified by shareName, this function does not issue tcp or netbios
        /// connect, it does Negotiate -> SessionSetup -> TreeConnect
        /// </summary>
        /// <param name="serverName">The server name</param>
        /// <param name="domain">The domain</param>
        /// <param name="userName">The user name</param>
        /// <param name="password">The password</param>
        /// <param name="shareName">The share name</param>
        /// <param name="securityPackage">The security package</param>
        private void InternalConnectShare(string serverName, string domain,
            string userName, string password, string shareName, SecurityPackageType securityPackage)
        {
            SmbPacket request;
            SmbPacket response;
            uint status;

            // Negotiate:
            request = this.smbClient.CreateNegotiateRequest(
                defaultSignState, new string[] { DialectNameString.NTLANMAN });
            response = this.SendAndExpectSmbPacket(request, internalTimeout, out status);

            if (status != 0)
            {
                throw new InvalidOperationException("Negotiate Failed. ErrorCode: " + status);
            }
            SecurityModes securityMode = (response as SmbNegotiateResponsePacket).SmbParameters.SecurityMode;
            this.isSignRequired = (securityMode & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)
                == SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;

            SmbSecurityPackage secPkg;

            switch (securityPackage)
            {
                case SecurityPackageType.Ntlm:
                    secPkg = SmbSecurityPackage.NTLM;
                    break;

                case SecurityPackageType.Kerberos:
                    secPkg = SmbSecurityPackage.Kerberos;
                    break;

                case SecurityPackageType.Negotiate:
                    secPkg = SmbSecurityPackage.Negotiate;
                    break;

                default:
                    throw new ArgumentException("Unsupported securityPackage: " + securityPackage.ToString());
            }

            // Session setup:
            request = this.smbClient.CreateFirstSessionSetupRequest(secPkg, serverName, domain, userName,
                password);
            response = this.SendAndExpectSmbPacket(request, internalTimeout, out status);

            while (status != 0)
            {
                if ((int)status == (int)SmbStatus.STATUS_MORE_PROCESSING_REQUIRED)
                {
                    this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid;
                    request = this.smbClient.CreateSecondSessionSetupRequest(this.uid, secPkg);
                    response = this.SendAndExpectSmbPacket(request, internalTimeout, out status);
                }
                else
                {
                    throw new InvalidOperationException("Session Setup Failed. ErrorCode: " + status);
                }
            }
            this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid;

            if (isSignRequired)
            {
                CifsClientPerSession session = this.smbClient.Context.GetSession(
                    this.smbClient.Context.Connection.ConnectionId, this.uid);
                this.sessionKey = session.SessionKey;
            }

            // Tree connect:
            string sharePath = "\\\\" + serverName + '\\' + shareName;
            request = this.smbClient.CreateTreeConnectRequest(this.uid, sharePath);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }
            response = this.SendAndExpectSmbPacket(request, internalTimeout, out status);

            if (status != 0)
            {
                throw new InvalidOperationException("Tree Connect Failed. ErrorCode: " + status);
            }
            this.treeId = (response as SmbTreeConnectAndxResponsePacket).SmbHeader.Tid;
        }
 /// <summary>
 /// Connect to a share indicated by shareName in server
 /// This will use smb over tcp as transport. Only one server
 /// can be connected at one time
 /// </summary>
 /// <param name="serverName">The server Name</param>
 /// <param name="serverIP">The ip of server</param>
 /// <param name="domain">The domain name</param>
 /// <param name="userName">The user name</param>
 /// <param name="password">The password</param>
 /// <param name="shareName">The share name</param>
 /// <param name="securityPackage">The security package</param>
 /// <param name="useServerToken">Whether to use token from server</param> 
 public void ConnectShare(string serverName, IPAddress serverIP, string domain,
     string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken)
 {
     serverPrincipleName = serverName;
     client.ConnectOverTCP(serverIP);
     InternalConnectShare(domain, userName, password, shareName, internalTimeout, securityPackage, useServerToken);
 }
Beispiel #40
0
        public uint Smb2SessionSetup(
            SecurityPackageType securityPackageType,
            string domainName,
            string userName,
            string password,
            string serverName)
        {
            uint status;
            SESSION_SETUP_Response sessionSetupResponse;

            SspiClientSecurityContext sspiClientGss =
                new SspiClientSecurityContext(
                    securityPackageType,
                    new AccountCredential(domainName, userName, password),
                    Smb2Utility.GetCifsServicePrincipalName(serverName),
                    ClientSecurityContextAttribute.None,
                    SecurityTargetDataRepresentation.SecurityNativeDrep
                    );

            // Server GSS token is used only for Negotiate authentication
            if (securityPackageType == SecurityPackageType.Negotiate)
            {
                sspiClientGss.Initialize(this.gssToken);
            }
            else
            {
                sspiClientGss.Initialize(null);
            }
            this.sessionId = 0;

            do
            {
                status = SessionSetup(
                    1,
                    64,
                    Packet_Header_Flags_Values.NONE,
                    this.messageId,
                    this.sessionId,
                    SESSION_SETUP_Request_Flags.NONE,
                    SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED,
                    SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS,
                    0,
                    sspiClientGss.Token,
                    out sessionId,
                    out this.gssToken,
                    out packetHeader,
                    out sessionSetupResponse
                    );

                CalculateSmb2AvailableCredits(1, packetHeader.CreditRequestResponse);

                if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) &&
                    this.gssToken != null && this.gssToken.Length > 0)
                {
                    sspiClientGss.Initialize(this.gssToken);
                }
            } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED);

            if (status == Smb2Status.STATUS_SUCCESS)
            {
                sessionKey = sspiClientGss.SessionKey;
                GenerateCryptoKeys(sessionId, sessionKey, true, false);
            }

            return(status);
        }
        public void OpenFile(
            string server,
            string share,
            string file,
            SecurityPackageType securityPackageType,
            string domainName,
            string userName,
            string password,
            AccessMask accessMask)
        {
            IPHostEntry hostEntry = Dns.GetHostEntry(server);
            client.ConnectOverTCP(hostEntry.AddressList[0]);
            serverPrincipleName = Smb2Utility.GetPrincipleName(hostEntry.HostName);

            Packet_Header header;
            NEGOTIATE_Response negotiateResponse;
            DialectRevision selectedDialect;
            byte[] serverGssToken;

            CheckStatusCode(
                Negotiate(
                1,
                1,
                messageId++,
                clientGuid,
                out selectedDialect,
                out serverGssToken,
                out header,
                out negotiateResponse));

            // 3.2.5.2: If the SecurityMode field in the SMB2 header of the response has the SMB2_NEGOTIATE_SIGNING_REQUIRED bit set,
            // the client MUST set Connection.RequireSigning to TRUE.
            // 3.2.5.3.1: If the global setting RequireMessageSigning is set to TRUE or
            // Connection.RequireSigning is set to TRUE then Session.SigningRequired MUST be set to TRUE
            bool session_SigningRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED);
            if (session_SigningRequired)
            {
                // 3.2.4.1.1: If the client signs the request, it MUST set the SMB2_FLAGS_SIGNED bit in the Flags field of the SMB2 header.
                headerFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED;
            }

            SESSION_SETUP_Response sessionSetupResponse;

            SspiClientSecurityContext sspiClientGss =
                new SspiClientSecurityContext(
                    securityPackageType,
                    new AccountCredential(domainName, userName, password),
                    Smb2Utility.GetCifsServicePrincipalName(server),
                    ClientSecurityContextAttribute.None,
                    SecurityTargetDataRepresentation.SecurityNativeDrep);

            if (securityPackageType == SecurityPackageType.Negotiate)
                sspiClientGss.Initialize(serverGssToken);
            else
                sspiClientGss.Initialize(null);

            uint status;
            do
            {
                status = client.SessionSetup(
                    1,
                    1,
                    Packet_Header_Flags_Values.NONE,
                    messageId++,
                    sessionId,
                    SESSION_SETUP_Request_Flags.NONE,
                    SESSION_SETUP_Request_SecurityMode_Values.NONE,
                    SESSION_SETUP_Request_Capabilities_Values.NONE,
                    0,
                    sspiClientGss.Token,
                    out sessionId,
                    out serverGssToken,
                    out header,
                    out sessionSetupResponse);

                CheckStatusCode(status);

                if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) &&
                    serverGssToken != null && serverGssToken.Length > 0)
                {
                    sspiClientGss.Initialize(serverGssToken);
                }
            } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED);

            client.GenerateCryptoKeys(sessionId, sspiClientGss.SessionKey, session_SigningRequired, false);

            TREE_CONNECT_Response treeConnectResponse;

            CheckStatusCode(
                TreeConnect(
                1,
                1,
                headerFlags,
                messageId++,
                sessionId,
                server,
                share,
                out header,
                out treeConnectResponse));

            CREATE_Response createResponse;
            Smb2CreateContextResponse[] serverCreateContexts;

            CheckStatusCode(
                client.Create(
                    1,
                    1,
                    headerFlags,
                    messageId++,
                    sessionId,
                    treeId,
                    file,
                    accessMask,
                    ShareAccess_Values.FILE_SHARE_READ,
                    CreateOptions_Values.NONE,
                    CreateDisposition_Values.FILE_OPEN_IF,
                    File_Attributes.NONE,
                    ImpersonationLevel_Values.Impersonation,
                    SecurityFlags_Values.NONE,
                    RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE,
                    null,
                    out fileId,
                    out serverCreateContexts,
                    out header,
                    out createResponse));
        }
        public void Connect(
            string protocolSequence,
            string networkAddress,
            string endpoint,
            AccountCredential transportCredential,
            TimeSpan timeout,
            SecurityPackageType securityPackage)
        {
            if (protocolSequence == null)
            {
                throw new ArgumentNullException("protocolSequence");
            }
            if (networkAddress == null)
            {
                throw new ArgumentNullException("networkAddress");
            }
            if (endpoint == null)
            {
                throw new ArgumentNullException("endpoint");
            }

            if (context.tcpTransport != null || context.fileServiceTransport != null)
            {
                throw new InvalidOperationException("RPCE is already connected.");
            }

            if (string.Compare(protocolSequence, RpceUtility.RPC_OVER_TCPIP_PROTOCOL_SEQUENCE, true) == 0)
            {
                IPAddress[] addresses = Dns.GetHostAddresses(networkAddress);
                if (addresses == null || addresses.Length == 0)
                {
                    throw new ArgumentException(
                        "Cannot resolve network address.",
                        "networkAddress");
                }
                IPAddress addr = addresses[0];

                int port;
                if (!int.TryParse(endpoint, out port))
                {
                    throw new ArgumentException("Invalid endpoint.", "endpoint");
                }

                SocketTransportConfig config = new SocketTransportConfig();
                config.BufferSize = Math.Max(context.MaxTransmitFragmentSize, context.MaxReceiveFragmentSize);
                config.RemoteIpAddress = addr;
                config.RemoteIpPort = port;
                config.Role = Role.Client;
                config.Type = StackTransportType.Tcp;

                context.tcpTransport = new TransportStack(config, RpceDecodePduCallback);
                context.tcpTransport.Connect();
            }
            else if (string.Compare(protocolSequence, RpceUtility.RPC_OVER_NAMED_PIPE_PROTOCOL_SEQUENCE, true) == 0)
            {
                if (!endpoint.StartsWith(
                    RpceUtility.NAMED_PIPE_ENDPOINT_PREFIX,
                    StringComparison.InvariantCultureIgnoreCase))
                {
                    throw new ArgumentException("endpoint format is incorrect.", "endpoint");
                }

                if (transportCredential == null)
                {
                    throw new ArgumentNullException("transportCredential");
                }

                timeoutForFsTransport = timeout;
                pipeTransceiveResponseQueue = new Queue<byte[]>();

                if (!RpceUtility.DisableSmb2)
                {
                    try
                    {
                        context.fileServiceTransport = new Smb2ClientTransport(timeout);
                        context.fileServiceTransport.ConnectShare(
                            networkAddress,
                            RpceUtility.NAMED_PIPE_PORT,
                            IpVersion.Any,
                            transportCredential.DomainName,
                            transportCredential.AccountName,
                            transportCredential.Password,
                            RpceUtility.NAMED_PIPE_SHARENAME,
                            securityPackage,
                            false);
                    }
                    catch
                    {
                        context.fileServiceTransport.Dispose();
                        context.fileServiceTransport = null;
                    }
                }

                if (context.fileServiceTransport == null)
                {
                    // Remote doesn't support SMB2, use SMB.
                    context.fileServiceTransport = new SmbClientTransport();
                    context.fileServiceTransport.ConnectShare(
                        networkAddress,
                        RpceUtility.NAMED_PIPE_PORT,
                        IpVersion.Any,
                        transportCredential.DomainName,
                        transportCredential.AccountName,
                        transportCredential.Password,
                        RpceUtility.NAMED_PIPE_SHARENAME,
                        securityPackage,
                        false);
                }

                context.fileServiceTransport.Create(
                    endpoint.Substring(RpceUtility.NAMED_PIPE_ENDPOINT_PREFIX.Length),
                    FsFileDesiredAccess.FILE_READ_DATA | FsFileDesiredAccess.FILE_WRITE_DATA
                    | FsFileDesiredAccess.FILE_APPEND_DATA
                    | FsFileDesiredAccess.FILE_READ_EA | FsFileDesiredAccess.FILE_WRITE_EA
                    | FsFileDesiredAccess.FILE_READ_ATTRIBUTES | FsFileDesiredAccess.FILE_WRITE_ATTRIBUTES
                    | FsFileDesiredAccess.READ_CONTROL | FsFileDesiredAccess.SYNCHRONIZE,
                    FsImpersonationLevel.Impersonation,
                    FsFileAttribute.NONE,
                    FsCreateDisposition.FILE_OPEN,
                    FsCreateOption.FILE_NON_DIRECTORY_FILE | FsCreateOption.FILE_OPEN_NO_RECALL);
            }
            else
            {
                throw new NotSupportedException("Specified protocol sequence is not supported.");
            }

            context.ProtocolSequence = protocolSequence;
            context.NetworkAddress = networkAddress;
            context.Endpoint = endpoint;

            // Make handle always different.
            handle = new IntPtr(Environment.TickCount);
        }
        /// <summary>
        /// Set up connection with server.
        /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order
        /// </summary>
        /// <param name="server">server name of ip address</param>
        /// <param name="client">client name of ip address</param>
        /// <param name="domain">user's domain</param>
        /// <param name="userName">user's name</param>
        /// <param name="password">user's password</param>
        /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param>
        /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception>
        public override void Connect(
            string server,
            string client,
            string domain,
            string userName,
            string password,
            TimeSpan timeout,
            SecurityPackageType securityPackage = SecurityPackageType.Ntlm,
            bool useServerToken = false)
        {
            this.cifsClient.Connect(server, client);

            SmbPacket request, response;
            uint status;

            // Negotiate:
            SMB_Dialect dialectLM21 = new SMB_Dialect();
            dialectLM21.BufferFormat = dialectBufferFormat;
            dialectLM21.DialectString = dialectLanMan21;
            SMB_Dialect dialectNTLM = new SMB_Dialect();
            dialectNTLM.BufferFormat = dialectBufferFormat;
            dialectNTLM.DialectString = dialectNtLanMan;
            request = this.cifsClient.CreateNegotiateRequest(new SMB_Dialect[] { dialectLM21, dialectNTLM });
            this.cifsClient.SendPacket(request);
            response = this.cifsClient.ExpectPacket(timeout);
            status = (response as SmbNegotiateResponsePacket).SmbHeader.Status;

            if (status != 0)
            {
                throw new ProtocolViolationException("Negotiate Failed. ErrorCode: " + status);
            }

            // Session setup:
            CifsUserAccount userAccount = new CifsUserAccount(domain, userName, password);
            request = this.cifsClient.CreateSessionSetupRequest(userAccount, nativeOS, nativeLanMan);
            this.cifsClient.SendPacket(request);
            response = this.cifsClient.ExpectPacket(timeout);
            SmbSessionSetupAndxResponsePacket sessionSetupResponse = response as SmbSessionSetupAndxResponsePacket;
            status = sessionSetupResponse.SmbHeader.Status;

            if (status != 0)
            {
                throw new ProtocolViolationException("Session Setup Failed. ErrorCode: " + status);
            }
            this.uid = sessionSetupResponse.SmbHeader.Uid;

            // Tree connect:
            string ipcAddress = "\\\\" + server + '\\' + ipcConnectString;
            request = this.cifsClient.CreateTreeConnectAndxRequest(this.uid, TreeConnectAndxFlags.NONE,
                ipcAddress, treeConnectService, null, null);
            this.cifsClient.SendPacket(request);
            response = this.cifsClient.ExpectPacket(timeout);
            SmbTreeConnectAndxResponsePacket treeConnectResponse = response as SmbTreeConnectAndxResponsePacket;
            status = treeConnectResponse.SmbHeader.Status;

            if (status != 0)
            {
                throw new ProtocolViolationException("Tree Connect Failed. ErrorCode: " + status);
            }
            this.treeId = treeConnectResponse.SmbHeader.Tid;
        }
Beispiel #44
0
        /// <summary>
        /// Set up connection with server.
        /// Including 4 steps: 1. Tcp connection 2. Negotiation 3. SessionSetup 4. TreeConnect in order
        /// </summary>
        /// <param name="server">server name of ip address</param>
        /// <param name="client">client name of ip address</param>
        /// <param name="domain">user's domain</param>
        /// <param name="userName">user's name</param>
        /// <param name="password">user's password</param>
        /// <param name="timeout">The pending time to get server's response in step 2, 3 or 4</param>
        /// <exception cref="System.Net.ProtocolViolationException">Fail to set up connection with server</exception>
        public override void Connect(
            string server,
            string client,
            string domain,
            string userName,
            string password,
            TimeSpan timeout,
            SecurityPackageType securityPackage = SecurityPackageType.Ntlm,
            bool useServerToken = false)
        {
            this.cifsClient.Connect(server, client);

            SmbPacket request, response;
            uint      status;

            // Negotiate:
            SMB_Dialect dialectLM21 = new SMB_Dialect();

            dialectLM21.BufferFormat  = dialectBufferFormat;
            dialectLM21.DialectString = dialectLanMan21;
            SMB_Dialect dialectNTLM = new SMB_Dialect();

            dialectNTLM.BufferFormat  = dialectBufferFormat;
            dialectNTLM.DialectString = dialectNtLanMan;
            request = this.cifsClient.CreateNegotiateRequest(new SMB_Dialect[] { dialectLM21, dialectNTLM });
            this.cifsClient.SendPacket(request);
            response = this.cifsClient.ExpectPacket(timeout);
            status   = (response as SmbNegotiateResponsePacket).SmbHeader.Status;

            if (status != 0)
            {
                throw new ProtocolViolationException("Negotiate Failed. ErrorCode: " + status);
            }

            // Session setup:
            CifsUserAccount userAccount = new CifsUserAccount(domain, userName, password);

            request = this.cifsClient.CreateSessionSetupRequest(userAccount, nativeOS, nativeLanMan);
            this.cifsClient.SendPacket(request);
            response = this.cifsClient.ExpectPacket(timeout);
            SmbSessionSetupAndxResponsePacket sessionSetupResponse = response as SmbSessionSetupAndxResponsePacket;

            status = sessionSetupResponse.SmbHeader.Status;

            if (status != 0)
            {
                throw new ProtocolViolationException("Session Setup Failed. ErrorCode: " + status);
            }
            this.uid = sessionSetupResponse.SmbHeader.Uid;

            // Tree connect:
            string ipcAddress = "\\\\" + server + '\\' + ipcConnectString;

            request = this.cifsClient.CreateTreeConnectAndxRequest(this.uid, TreeConnectAndxFlags.NONE,
                                                                   ipcAddress, treeConnectService, null, null);
            this.cifsClient.SendPacket(request);
            response = this.cifsClient.ExpectPacket(timeout);
            SmbTreeConnectAndxResponsePacket treeConnectResponse = response as SmbTreeConnectAndxResponsePacket;

            status = treeConnectResponse.SmbHeader.Status;

            if (status != 0)
            {
                throw new ProtocolViolationException("Tree Connect Failed. ErrorCode: " + status);
            }
            this.treeId = treeConnectResponse.SmbHeader.Tid;
        }
        /// <summary>
        /// Connect to a share indicated by shareName in server
        /// This will use smb over tcp as transport. Only one server
        /// can be connected at one time
        /// </summary>
        /// <param name="serverName">The server Name</param>
        /// <param name="port">The server port</param>
        /// <param name="ipVersion">The ip version</param>
        /// <param name="domain">The domain name</param>
        /// <param name="userName">The user name</param>
        /// <param name="password">The password</param>
        /// <param name="shareName">The share name</param>
        /// <param name="securityPackage">The security package</param>
        /// <param name="useServerToken">Whether to use token from server</param>
        /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
        public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain,
                                          string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken)
        {
            smbClient.Connect(serverName, port, ipVersion, defaultBufferSize);

            InternalConnectShare(serverName, domain, userName, password, shareName, securityPackage);
        }
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="securityPackageType">Security package type.</param>
 protected SecurityConfig(SecurityPackageType securityPackageType)
 {
     this.securityType = securityPackageType;
 }
 /// <summary>
 /// Connect to a share indicated by shareName in server
 /// This will use smb over tcp as transport. Only one server
 /// can be connected at one time
 /// </summary>
 /// <param name="serverName">The server Name</param>
 /// <param name="port">The server port</param>
 /// <param name="ipVersion">The ip version</param>
 /// <param name="domain">The domain name</param>
 /// <param name="userName">The user name</param>
 /// <param name="password">The password</param>
 /// <param name="shareName">The share name</param>
 /// <param name="securityPackage">The security package</param>
 /// <param name="useServerToken">Whether to use token from server</param>
 /// <exception cref="System.InvalidOperationException">Thrown if there is any error occurred</exception>
 public override void ConnectShare(string serverName, int port, IpVersion ipVersion, string domain,
     string userName, string password, string shareName, SecurityPackageType securityPackage, bool useServerToken)
 {
     throw new NotImplementedException();
 }
        /// <summary>
        /// Connect share specified by shareName, this function does not issue tcp or netbios
        /// connect, it does Negotiate -> SessionSetup -> TreeConnect
        /// </summary>
        /// <param name="serverName">The server name</param>
        /// <param name="domain">The domain</param>
        /// <param name="userName">The user name</param>
        /// <param name="password">The password</param>
        /// <param name="shareName">The share name</param>
        /// <param name="securityPackage">The security package</param>
        private void InternalConnectShare(string serverName, string domain,
                                          string userName, string password, string shareName, SecurityPackageType securityPackage)
        {
            SmbPacket request;
            SmbPacket response;
            uint      status;

            // Negotiate:
            request = this.smbClient.CreateNegotiateRequest(
                defaultSignState, new string[] { DialectNameString.NTLANMAN });
            response = this.SendAndExpectSmbPacket(request, internalTimeout, out status);

            if (status != 0)
            {
                throw new InvalidOperationException("Negotiate Failed. ErrorCode: " + status);
            }
            SecurityModes securityMode = (response as SmbNegotiateResponsePacket).SmbParameters.SecurityMode;

            this.isSignRequired = (securityMode & SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED)
                                  == SecurityModes.NEGOTIATE_SECURITY_SIGNATURES_REQUIRED;

            SmbSecurityPackage secPkg;

            switch (securityPackage)
            {
            case SecurityPackageType.Ntlm:
                secPkg = SmbSecurityPackage.NTLM;
                break;

            case SecurityPackageType.Kerberos:
                secPkg = SmbSecurityPackage.Kerberos;
                break;

            case SecurityPackageType.Negotiate:
                secPkg = SmbSecurityPackage.Negotiate;
                break;

            default:
                throw new ArgumentException("Unsupported securityPackage: " + securityPackage.ToString());
            }


            // Session setup:
            request = this.smbClient.CreateFirstSessionSetupRequest(secPkg, serverName, domain, userName,
                                                                    password);
            response = this.SendAndExpectSmbPacket(request, internalTimeout, out status);

            while (status != 0)
            {
                if ((int)status == (int)SmbStatus.STATUS_MORE_PROCESSING_REQUIRED)
                {
                    this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid;
                    request  = this.smbClient.CreateSecondSessionSetupRequest(this.uid, secPkg);
                    response = this.SendAndExpectSmbPacket(request, internalTimeout, out status);
                }
                else
                {
                    throw new InvalidOperationException("Session Setup Failed. ErrorCode: " + status);
                }
            }
            this.uid = (response as SmbSessionSetupAndxResponsePacket).SmbHeader.Uid;

            if (isSignRequired)
            {
                CifsClientPerSession session = this.smbClient.Context.GetSession(
                    this.smbClient.Context.Connection.ConnectionId, this.uid);
                this.sessionKey = session.SessionKey;
            }

            // Tree connect:
            string sharePath = "\\\\" + serverName + '\\' + shareName;

            request = this.smbClient.CreateTreeConnectRequest(this.uid, sharePath);

            if (this.isSignRequired)
            {
                request.Sign(this.NextSequenceNumber, this.sessionKey);
            }
            response = this.SendAndExpectSmbPacket(request, internalTimeout, out status);

            if (status != 0)
            {
                throw new InvalidOperationException("Tree Connect Failed. ErrorCode: " + status);
            }
            this.treeId = (response as SmbTreeConnectAndxResponsePacket).SmbHeader.Tid;
        }