protected SHARE_INFO_502_I GetShareInfo(string sharePath) { using (SrvsClient srvsClient = new SrvsClient(TestConfig.Timeout)) { ClientSecurityContext securityContext = new SspiClientSecurityContext( TestConfig.DefaultSecurityPackage, TestConfig.AccountCredential, Smb2Utility.GetCifsServicePrincipalName(TestConfig.SutComputerName), ClientSecurityContextAttribute.Connection | ClientSecurityContextAttribute.DceStyle | ClientSecurityContextAttribute.Integrity | ClientSecurityContextAttribute.ReplayDetect | ClientSecurityContextAttribute.SequenceDetect | ClientSecurityContextAttribute.UseSessionKey, SecurityTargetDataRepresentation.SecurityNativeDrep); srvsClient.Bind(TestConfig.SutComputerName, TestConfig.AccountCredential, securityContext); SHARE_INFO?shareInfo; uint retVal = srvsClient.NetrShareGetInfo(@"\\" + TestConfig.SutComputerName, sharePath, SHARE_ENUM_STRUCT_LEVEL.Level502, out shareInfo); if (retVal != 0 || shareInfo == null || shareInfo.Value.ShareInfo502 == null) { BaseTestSite.Assert.Fail("Fail to get share info through MS-SRVS."); } srvsClient.UnBind(); return(shareInfo.Value.ShareInfo502.Value); } }
/// <summary> /// Performs CredSSP authentication. /// </summary> /// <exception cref="IOException">Raised when attempting to read from/write to the remote connection which /// has been closed</exception> /// <exception cref="EndOfStreamException">Raised when the username or password doesn't match or authentication /// fails</exception> public void Authenticate() { // Authenticated already, do nothing if (isAuthenticated) { return; } credential = new AccountCredential(domain, userName, password); byte[] receivedBuffer = new byte[MaxBufferSize]; int bytesReceived = 0; // Dispose the context as it may be timed out if (context != null) { context.Dispose(); } context = new SspiClientSecurityContext( SecurityPackageType.CredSsp, credential, serverPrincipal, attribute, SecurityTargetDataRepresentation.SecurityNativeDrep); context.Initialize(null); // Get first token byte[] token = context.Token; // SSL handshake while (context.NeedContinueProcessing) { // Send handshake request clientStream.Write(token, 0, token.Length); // Get handshake resopnse bytesReceived = clientStream.Read(receivedBuffer, 0, receivedBuffer.Length); // The remote connection has been closed if (bytesReceived == 0) { throw new EndOfStreamException("Authentication failed: remote connection has been closed."); } byte[] inToken = new byte[bytesReceived]; Array.Copy(receivedBuffer, inToken, bytesReceived); // Get next token from response context.Initialize(inToken); token = context.Token; } // Send the last token, handshake over, CredSSP is established // Note if there're errors during authentication, an SSPIException will be raised // and isAuthentication will not be true. clientStream.Write(token, 0, token.Length); isAuthenticated = true; }
/// <summary> /// dispose the gssapi /// </summary> internal void DisposeGssApi() { if (this.GssApi == null) { return; } SspiClientSecurityContext sspiSecurityContext = this.GssApi as SspiClientSecurityContext; if (sspiSecurityContext != null) { sspiSecurityContext.Dispose(); } }
/// <summary> /// Implements IDisposable interface(from NetworkStream) /// </summary> /// <param name="disposing">Indicates if there's managed resource to release</param> protected override void Dispose(bool disposing) { if (!this.disposed) { if (disposing) { // Clean managed resource CloseClientStream(); if (context != null) { context.Dispose(); context = null; } } this.disposed = true; this.isAuthenticated = false; } base.Dispose(disposing); }
/// <summary> /// Connect to server. /// </summary> /// <param name="client">Fsrvp client.</param> /// <param name="server">The name of server.</param> /// <returns>Return true if success, otherwise return false.</returns> private bool ConnectServer(ref FsrvpClient client, string server) { AccountCredential accountCredential = new AccountCredential(TestConfig.DomainName, TestConfig.UserName, TestConfig.UserPassword); ClientSecurityContext securityContext = new SspiClientSecurityContext( TestConfig.DefaultSecurityPackage, accountCredential, Smb2Utility.GetCifsServicePrincipalName(server), ClientSecurityContextAttribute.Connection | ClientSecurityContextAttribute.DceStyle | ClientSecurityContextAttribute.Integrity | ClientSecurityContextAttribute.ReplayDetect | ClientSecurityContextAttribute.SequenceDetect | ClientSecurityContextAttribute.UseSessionKey, SecurityTargetDataRepresentation.SecurityNativeDrep); // This indicates that the RPC message is just integrity-protected. client.Context.AuthenticationLevel = TestConfig.DefaultRpceAuthenticationLevel; try { BaseTestSite.Log.Add(LogEntryKind.Debug, "Connect to server {0}.", server); client.BindOverNamedPipe(server, accountCredential, securityContext, new TimeSpan(0, 0, (int)FsrvpUtility.FSRVPTimeoutInSeconds)); } catch (InvalidOperationException ex) { BaseTestSite.Log.Add(LogEntryKind.Debug, "Connect to server {0} failed. Exception: {1}", server, ex.Message); client.Unbind(TestConfig.Timeout); return(false); } BaseTestSite.Log.Add(LogEntryKind.Debug, "Connect to server {0} successfully.", server); return(true); }
/// <summary> /// Generate the Generic Security Service (GSS) Kerberos authentication token for a user. /// </summary> /// <param name="user">The user.</param> /// <returns>The GSS Kerberos authentication token in type of DRS_SecBuffer.</returns> public static DRS_SecBufferDesc GetAuthenticationToken(string account, string pwd, string domain, string spn) { ClientSecurityContextAttribute contextAttr = ClientSecurityContextAttribute.Connection | //ClientSecurityContextAttribute.Integrity | ClientSecurityContextAttribute.Confidentiality //| //ClientSecurityContextAttribute.UseSessionKey //| //ClientSecurityContextAttribute.Delegate ; SspiClientSecurityContext securityContext = new SspiClientSecurityContext( SecurityPackageType.Kerberos, new AccountCredential(domain, account, pwd), spn, contextAttr, SecurityTargetDataRepresentation.SecurityNativeDrep); //securityContext.Initialize(null); string kdcIpAddr = GetIPAddress(domain); byte[] token = GenerateGssApToken(kdcIpAddr, account, pwd, domain, spn, KerberosAccountType.User); DRS_SecBufferDesc pClientCreds = new DRS_SecBufferDesc(); pClientCreds.ulVersion = ulVersion_Values.V1; //pClientCreds.Buffers = null; pClientCreds.cBuffers = 1; pClientCreds.Buffers = new DRS_SecBuffer[1]; DRS_SecBuffer secBuf = new DRS_SecBuffer(); secBuf.BufferType = BufferType_Values.SECBUFFER_TOKEN; secBuf.pvBuffer = token; secBuf.cbBuffer = (uint)secBuf.pvBuffer.Length; pClientCreds.Buffers[0] = secBuf; return(pClientCreds); }
public void UserLogon( DetectionInfo info, Smb2Client client, out ulong messageId, out ulong sessionId, out Guid clientGuid, out NEGOTIATE_Response negotiateResp, out bool encryptionRequired) { messageId = 1; sessionId = 0; logWriter.AddLog(LogLevel.Information, "Client connects to server"); client.ConnectOverTCP(SUTIpAddress); #region Negotiate DialectRevision selectedDialect; byte[] gssToken; Packet_Header header; clientGuid = Guid.NewGuid(); logWriter.AddLog(LogLevel.Information, "Client sends multi-protocol Negotiate to server"); MultiProtocolNegotiate( client, 1, 1, Packet_Header_Flags_Values.NONE, messageId++, info.requestDialect, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES | Capabilities_Values.GLOBAL_CAP_ENCRYPTION, clientGuid, out selectedDialect, out gssToken, out header, out negotiateResp); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("NEGOTIATE", header.Status); throw new Exception(string.Format("NEGOTIATE failed with {0}", Smb2Status.GetStatusCode(header.Status))); } #endregion #region Session Setup SESSION_SETUP_Response sessionSetupResp; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( SecurityPackageType, Credential, Smb2Utility.GetCifsServicePrincipalName(SUTName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); // Server GSS token is used only for Negotiate authentication when enabled if (SecurityPackageType == SecurityPackageType.Negotiate) { sspiClientGss.Initialize(gssToken); } else { sspiClientGss.Initialize(null); } do { logWriter.AddLog(LogLevel.Information, "Client sends SessionSetup to server"); client.SessionSetup( 1, 64, 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 gssToken, out header, out sessionSetupResp); if ((header.Status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || header.Status == Smb2Status.STATUS_SUCCESS) && gssToken != null && gssToken.Length > 0) { sspiClientGss.Initialize(gssToken); } } while (header.Status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("SESSIONSETUP", header.Status); throw new Exception(string.Format("SESSIONSETUP failed with {0}", Smb2Status.GetStatusCode(header.Status))); } byte[] sessionKey; sessionKey = sspiClientGss.SessionKey; encryptionRequired = sessionSetupResp.SessionFlags == SessionFlags_Values.SESSION_FLAG_ENCRYPT_DATA; client.GenerateCryptoKeys( sessionId, sessionKey, info.smb2Info.IsRequireMessageSigning, // Enable signing according to the configuration of SUT encryptionRequired, null, false); #endregion }
public uint Smb2AlternativeChannelSessionSetup( Smb2OverSmbdTestClient mainChannelClient, string domainName, string userName, string password, string serverName, SESSION_SETUP_Request_SecurityMode_Values securityMode = SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, SESSION_SETUP_Request_Capabilities_Values capabilities = SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS, ushort creditRequest = 64) { sessionId = mainChannelClient.sessionId; sessionKey = mainChannelClient.sessionKey; Smb2SetSessionSigningAndEncryption(true, false); Packet_Header header; SESSION_SETUP_Response sessionSetupResponse; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( SecurityPackageType.Negotiate, new AccountCredential(domainName, userName, password), Smb2Utility.GetCifsServicePrincipalName(serverName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep ); // Server GSS token is used only for Negotiate authentication sspiClientGss.Initialize(gssToken); uint status; do { status = SessionSetup( 1, creditRequest, Packet_Header_Flags_Values.FLAGS_SIGNED, messageId, sessionId, SESSION_SETUP_Request_Flags.SESSION_FLAG_BINDING, securityMode, capabilities, 0, sspiClientGss.Token, out sessionId, out gssToken, out header, out sessionSetupResponse ); CalculateSmb2AvailableCredits(1, packetHeader.CreditRequestResponse); if ((status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || status == Smb2Status.STATUS_SUCCESS) && gssToken != null && gssToken.Length > 0) { sspiClientGss.Initialize(gssToken); } } while (status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); if (status == Smb2Status.STATUS_SUCCESS) { sessionKey = sspiClientGss.SessionKey; Smb2SetSessionSigningAndEncryption(true, false, true); } return(status); }
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); }
/// <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> /// Connect to the Server and establish the named pipe transport. /// </summary> private void ConnectToServer() { smb2Client = new Smb2Client(smb2ClientTimeout); if (IPAddress.TryParse(serverName, out var serverIp)) { smb2Client.ConnectOverTCP(serverIp); } else { var serverHostEntry = Dns.GetHostEntry(serverName); smb2Client.ConnectOverTCP(serverHostEntry.AddressList[0]); } var validDialects = new DialectRevision[] { DialectRevision.Smb2002, DialectRevision.Smb21, DialectRevision.Smb30, DialectRevision.Smb302, DialectRevision.Smb311 }; var preauthIntegrityHashIDs = new PreauthIntegrityHashID[] { PreauthIntegrityHashID.SHA_512 }; var encryptionAlgorithms = new EncryptionAlgorithm[] { EncryptionAlgorithm.ENCRYPTION_AES128_GCM, EncryptionAlgorithm.ENCRYPTION_AES128_CCM }; var status = smb2Client.Negotiate( creditCharge: 1, creditRequest: 1, flags: defaultFlags, messageId: messageId++, // Will negotiate highest dialect server supports dialects: validDialects, securityMode: SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, capabilities: Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_ENCRYPTION | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_LARGE_MTU, clientGuid: Guid.NewGuid(), out var selectedDialect, out var serverGssToken, out Packet_Header _, out var negotiateResponse, preauthHashAlgs: preauthIntegrityHashIDs, encryptionAlgs: encryptionAlgorithms); CheckStatusCode(status, nameof(Smb2Client.Negotiate)); var sessionSiginingRequired = negotiateResponse.SecurityMode.HasFlag(NEGOTIATE_Response_SecurityMode_Values.NEGOTIATE_SIGNING_REQUIRED); if (sessionSiginingRequired) { defaultFlags |= Packet_Header_Flags_Values.FLAGS_SIGNED; } var usedSecurityPackageType = (SecurityPackageType)Enum.Parse(typeof(SecurityPackageType), securityPackage); var sspiClientGss = new SspiClientSecurityContext( usedSecurityPackageType, new AccountCredential(domainName, userName, password), Smb2Utility.GetCifsServicePrincipalName(serverName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); if (usedSecurityPackageType == SecurityPackageType.Negotiate && useServerGssToken) { sspiClientGss.Initialize(serverGssToken); } else { sspiClientGss.Initialize(null); } do { status = smb2Client.SessionSetup( creditCharge: 1, creditRequest: 1, flags: Packet_Header_Flags_Values.NONE, messageId: messageId++, sessionId: sessionId, sessionSetupFlags: SESSION_SETUP_Request_Flags.NONE, securityMode: SESSION_SETUP_Request_SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, capabilities: SESSION_SETUP_Request_Capabilities_Values.GLOBAL_CAP_DFS, previousSessionId: 0, clientGssToken: sspiClientGss.Token, out sessionId, out serverGssToken, out _, out _); CheckStatusCode(status, nameof(Smb2Client.SessionSetup)); 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); var treeConnectSigningRequired = sessionSiginingRequired || (selectedDialect >= DialectRevision.Smb311); smb2Client.GenerateCryptoKeys( sessionId, sspiClientGss.SessionKey, treeConnectSigningRequired, false); status = smb2Client.TreeConnect( creditCharge: 1, creditRequest: 1, flags: treeConnectSigningRequired ? defaultFlags | Packet_Header_Flags_Values.FLAGS_SIGNED : defaultFlags, messageId: messageId++, sessionId: sessionId, $"\\\\{serverName}\\IPC$", out treeId, out _, out _); CheckStatusCode(status, nameof(Smb2Client.TreeConnect)); smb2Client.EnableSessionSigningAndEncryption(sessionId, sessionSiginingRequired, false); status = smb2Client.Create( creditCharge: 1, creditRequest: 1, flags: defaultFlags, messageId: messageId++, sessionId: sessionId, treeId: treeId, path: pipeName, desiredAccess: AccessMask.GENERIC_READ | AccessMask.GENERIC_WRITE, shareAccess: ShareAccess_Values.FILE_SHARE_READ, createOptions: CreateOptions_Values.NONE, createDispositions: CreateDisposition_Values.FILE_OPEN_IF, fileAttributes: File_Attributes.NONE, impersonationLevel: ImpersonationLevel_Values.Impersonation, securityFlag: SecurityFlags_Values.NONE, requestedOplockLevel: RequestedOplockLevel_Values.OPLOCK_LEVEL_NONE, createContexts: null, out fileId, out _, out _, out _); CheckStatusCode(status, nameof(Smb2Client.Create)); }
private bool UserLogon(DetectionInfo info, Smb2Client client, out ulong messageId, out ulong sessionId, out Guid clientGuid, out NEGOTIATE_Response negotiateResp) { messageId = 0; sessionId = 0; client.ConnectOverTCP(Dns.GetHostAddresses(info.ContentServerName)[0]); #region Negotiate DialectRevision selectedDialect; byte[] gssToken; Packet_Header header; clientGuid = Guid.NewGuid(); client.Negotiate( 1, 1, Packet_Header_Flags_Values.NONE, messageId++, new DialectRevision[] { DialectRevision.Smb30 }, SecurityMode_Values.NEGOTIATE_SIGNING_ENABLED, Capabilities_Values.GLOBAL_CAP_DFS | Capabilities_Values.GLOBAL_CAP_DIRECTORY_LEASING | Capabilities_Values.GLOBAL_CAP_LARGE_MTU | Capabilities_Values.GLOBAL_CAP_LEASING | Capabilities_Values.GLOBAL_CAP_MULTI_CHANNEL | Capabilities_Values.GLOBAL_CAP_PERSISTENT_HANDLES, clientGuid, out selectedDialect, out gssToken, out header, out negotiateResp); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("NEGOTIATE", header.Status); throw new Exception(string.Format("NEGOTIATE failed with {0}", Smb2Status.GetStatusCode(header.Status))); } #endregion #region Session Setup SESSION_SETUP_Response sessionSetupResp; SspiClientSecurityContext sspiClientGss = new SspiClientSecurityContext( SecurityPackageType, Credential, Smb2Utility.GetCifsServicePrincipalName(ContentServerName), ClientSecurityContextAttribute.None, SecurityTargetDataRepresentation.SecurityNativeDrep); // Server GSS token is used only for Negotiate authentication when enabled if (SecurityPackageType == SecurityPackageType.Negotiate) { sspiClientGss.Initialize(gssToken); } else { sspiClientGss.Initialize(null); } do { client.SessionSetup( 1, 64, 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 gssToken, out header, out sessionSetupResp); if ((header.Status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED || header.Status == Smb2Status.STATUS_SUCCESS) && gssToken != null && gssToken.Length > 0) { sspiClientGss.Initialize(gssToken); } } while (header.Status == Smb2Status.STATUS_MORE_PROCESSING_REQUIRED); if (header.Status != Smb2Status.STATUS_SUCCESS) { LogFailedStatus("SESSIONSETUP", header.Status); throw new Exception(string.Format("SESSIONSETUP failed with {0}", Smb2Status.GetStatusCode(header.Status))); } byte[] sessionKey; sessionKey = sspiClientGss.SessionKey; client.GenerateCryptoKeys(sessionId, sessionKey, true, false, null, false); #endregion return(true); }
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); }