/// <summary> /// Constructor. /// </summary> /// <param name="attributes">the attributes for server</param> /// <param name="nlmpConfig"> /// the config for nlmp client, this param maybe null. if null, spng does not support nlmp. /// </param> /// <param name="kileConfig"> /// the config for kile client, this param maybe null. if null, spng does not support Kerberos. /// </param> /// <exception cref="ArgumentException">at least one of nlmpConfig and kileConfig must not be null</exception> public SpngClientSecurityContext( ClientSecurityContextAttribute attributes, NlmpClientSecurityConfig nlmpConfig, KerberosClientSecurityConfig kileConfig) { InitializeClientSecurityContext(attributes, nlmpConfig, kileConfig, null); }
/// <summary> /// initialize the client security context. /// </summary> /// <param name="attributes">the attributes for server</param> /// <param name="nlmpConfig"> /// the config for nlmp client, this param maybe null. if null, spng does not support nlmp. /// </param> /// <param name="kileConfig"> /// the config for kile client, this param maybe null. if null, spng does not support Kerberos. /// </param> /// <param name="sspiConfig"> /// the config for sspi client, this param maybe null. if null, spng does not support sspi. /// </param> /// <exception cref="ArgumentException"> /// at least one of nlmpConfig, kileConfig and sspiConfig must not be null /// </exception> private void InitializeClientSecurityContext( ClientSecurityContextAttribute attributes, NlmpClientSecurityConfig nlmpConfig, KerberosClientSecurityConfig kileConfig, SspiClientSecurityConfig sspiConfig) { if (nlmpConfig == null && kileConfig == null && sspiConfig == null) { throw new ArgumentException("at least one of nlmpConfig, kileConfig and sspiConfig must not be null"); } List <SecurityConfig> configList = new List <SecurityConfig>(); // build the mech types List <MechType> mechTypes = new List <MechType>(); if (kileConfig != null) { configList.Add(kileConfig); mechTypes.Add(new MechType(Consts.KerbOidInt)); } if (nlmpConfig != null) { configList.Add(nlmpConfig); mechTypes.Add(new MechType(Consts.NlmpOidInt)); } if (sspiConfig != null) { configList.Add(sspiConfig); switch (sspiConfig.SecurityType) { case SecurityPackageType.Ntlm: mechTypes.Add(new MechType(Consts.NlmpOidInt)); break; case SecurityPackageType.Kerberos: mechTypes.Add(new MechType(Consts.KerbOidInt)); break; default: mechTypes.Add(new MechType(Consts.UnknownOidInt)); break; } } // build a spng config SpngClientSecurityConfig spngConfig = new SpngClientSecurityConfig(attributes, new MechTypeList(mechTypes.ToArray())); // add spng config to config list. configList.Insert(0, spngConfig); // initialize the spng client this.client = new SpngClient(spngConfig); this.needContinueProcessing = true; this.packageType = SecurityPackageType.Negotiate; this.securityConfigList = configList.ToArray(); }
/// <summary> /// Initialize the securityMechContext based on the security package type /// </summary> /// <param name="mechType">security mechanism type</param> /// <param name="inToken">the input security token</param> /// <exception cref="InvalidOperationException">Thrown if could not find the configuration.</exception> /// <exception cref="InvalidOperationException">Thrown when security configuration is unknown</exception> private void InitializeSecurityContext(MechType mechType, byte[] inToken) { SpngClientContext clientContext = this.client.Context as SpngClientContext; SecurityPackageType authType = SpngUtility.ConvertMechType(mechType); CurrentSecurityConfig = SpngUtility.GetSecurityConfig(this.securityConfigList, authType); if (CurrentSecurityConfig == null) { throw new InvalidOperationException("Missing configuration for " + authType.ToString()); } if (securityMechContext != null) { // re-enter. Nothing need to do return; } if (CurrentSecurityConfig.GetType() == typeof(KerberosClientSecurityConfig)) { KerberosClientSecurityConfig kileConfig = CurrentSecurityConfig as KerberosClientSecurityConfig; securityMechContext = new KerberosClientSecurityContext( kileConfig.ServiceName, kileConfig.ClientCredential, KerberosAccountType.User, kileConfig.KdcIpAddress, kileConfig.KdcPort, kileConfig.TransportType, kileConfig.SecurityAttributes); } else if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig)) { NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig; NlmpClientCredential cred = new NlmpClientCredential( nlmpConfig.TargetName, nlmpConfig.DomainName, nlmpConfig.AccountName, nlmpConfig.Password); securityMechContext = new NlmpClientSecurityContext(cred, nlmpConfig.SecurityAttributes); } else if (CurrentSecurityConfig.GetType() == typeof(SspiClientSecurityConfig)) { throw new InvalidOperationException("Only support Kerberos security config and NTLM security config"); } else { throw new InvalidOperationException("unknown security config"); } }
/// <summary> /// AcquireCredentialsHandle /// </summary> /// <param name="accountCredential"></param> protected void AcquireCredentialsHandle <T>(T accountCredential) { if (!string.IsNullOrEmpty(this.serverPrincipalName)) { this.serverPrincipalName = GetServicePrincipalName(this.serverPrincipalName); } switch (packageType) { case SecurityPackageType.Ntlm: { if (accountCredential is AccountCredential) { var credential = accountCredential as AccountCredential; this.Context = new NlmpClientSecurityContext( new NlmpClientCredential( this.serverPrincipalName, credential.DomainName, credential.AccountName, credential.Password) ); } else { throw new NotSupportedException("NTLM only support AccountCredential, Please provide an AccountCredential and try again."); } return; } case SecurityPackageType.Kerberos: { if (accountCredential is AccountCredential) { var credential = accountCredential as AccountCredential; IPAddress kdcIpAddress = (string.IsNullOrEmpty(KerberosContext.KDCComputerName) ? credential.DomainName : KerberosContext.KDCComputerName).ParseIPAddress(); this.Context = KerberosClientSecurityContext.CreateClientSecurityContext( this.serverPrincipalName, credential, KerberosAccountType.User, kdcIpAddress, KerberosContext.KDCPort, TransportType.TCP, this.securityContextAttributes ); } else { throw new NotSupportedException("Kerberos only support AccountCredential, Please provide an AccountCredential and try again."); } return; } case SecurityPackageType.Negotiate: { if (accountCredential is AccountCredential) { if (this.securityContextAttributes == ClientSecurityContextAttribute.None) { this.securityContextAttributes = ClientSecurityContextAttribute.MutualAuth; // MS-SPNG 3.3.3 The client MUST request Mutual Authentication services } var credential = accountCredential as AccountCredential; NlmpClientSecurityConfig nlmpSecurityConfig = new NlmpClientSecurityConfig(credential, this.serverPrincipalName, this.securityContextAttributes); IPAddress kdcIpAddress = (string.IsNullOrEmpty(KerberosContext.KDCComputerName) ? credential.DomainName : KerberosContext.KDCComputerName).ParseIPAddress(); KerberosClientSecurityConfig kerberosSecurityConfig = new KerberosClientSecurityConfig( credential, credential.AccountName, this.serverPrincipalName, kdcIpAddress, KerberosContext.KDCPort, this.securityContextAttributes, TransportType.TCP ); this.Context = new SpngClientSecurityContext(this.securityContextAttributes, nlmpSecurityConfig, kerberosSecurityConfig); } else { throw new NotSupportedException("Negotiate SSP only support AccountCredential, Please provide an AccountCredential and try again."); } return; } //case SecurityPackageType.Schannel: // throw new NotImplementedException(); //case SecurityPackageType.CredSsp: // throw new NotImplementedException(); //default: // throw new NotImplementedException(); } this.UseNativeSSP(accountCredential); }