/// <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"); } }
private void SpngNegotiationAcceptIncomplete(byte[] inToken) { byte[] securityToken = null; bool isNeedWrap = true; if ((inToken == null) || (inToken.Length == 0)) { throw new ArgumentNullException("inToken"); } byte[] mechListMic = null; if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig)) { NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig; if ((nlmpConfig.SecurityAttributes & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle) { isNeedWrap = false; } } securityToken = isNeedWrap ? UnwrapNegotiationToken(inToken, out mechListMic) : inToken; if (!securityMechContext.NeedContinueProcessing) { this.needContinueProcessing = false; this.client.Context.NegotiationState = SpngNegotiationState.AcceptCompleted; this.token = null; if (isNeedWrap && mechListMic != null && !this.client.VerifyMechListMIC(securityMechContext, mechListMic)) { throw new InvalidOperationException("Invalid MechListMic"); } } else { securityMechContext.Initialize(securityToken); if (!securityMechContext.NeedContinueProcessing) { this.needMechListMic = true; } this.token = isNeedWrap ? WrapNegotiationToken(SpngPayloadType.NegResp, securityMechContext.Token) : securityMechContext.Token; } }
/// <summary> /// Initialize the context from a token, and generate a new token. /// </summary> /// <param name="inToken">the token from server. "inToken" must be null when invoked first time.</param> /// <exception cref="ArgumentNullException">Except invoked at the first time, the "inToken" MUST not be null /// when invoking Initialize.</exception> /// <exception cref="InvalidOperationException">The internal state is invalid when invoking Initialize.</exception> /// <exception cref="InvalidOperationException">Invalid MechListMic</exception> public override void Initialize(byte[] inToken) { byte[] securityToken = null; MechTypeList serverMechList = null; bool isNeedWrap = true; switch (this.client.Context.NegotiationState) { case SpngNegotiationState.Initial: if ((inToken == null) || (inToken.Length == 0)) // Client Initiation Mode { InitializeSecurityContext(this.client.Config.MechList.Elements[0], securityToken); this.client.Context.NegotiationState = SpngNegotiationState.AcceptIncomplete; } else { try { securityToken = UnwrapInitialNegToken2(inToken, out serverMechList); this.client.NegotiateMechType(serverMechList); if (this.client.Context.NegotiationState == SpngNegotiationState.Reject) { //Negotiation failed. Do not need to throw exception in this case. return; } } catch { // check if reauth token SpngNegotiationToken negToken = new SpngNegotiationToken(); negToken.FromBytes(inToken); this.client.Context.NegotiatedMechType = negToken.SupportedMechType; // try use preview MechType to do Re-Initialize securityToken = null; } InitializeSecurityContext(this.client.Context.NegotiatedMechType, securityToken); } if (this.client.Context.NegotiationState == SpngNegotiationState.AcceptIncomplete) // server prefered mechtype can find from local support mechtype list. { try { securityMechContext.Initialize(securityToken); } catch { securityMechContext = null; // try use NTLM InitializeSecurityContext(this.client.Config.MechList.Elements[1], securityToken); this.client.Context.NegotiationState = SpngNegotiationState.AcceptIncomplete; securityMechContext.Initialize(securityToken); } } else { securityMechContext.Initialize(null); } if (this.client.Context.NegotiationState == SpngNegotiationState.SspiNegotiation) { //SSPI negotiation already has an SPNG wrapper. this.token = securityToken; } else { if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig)) { NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig; if ((nlmpConfig.SecurityAttributes & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle) { isNeedWrap = false; } } if (isNeedWrap) { this.token = WrapInitialNegToken(securityMechContext.Token); } else { this.token = securityMechContext.Token; } } break; case SpngNegotiationState.RequestMic: if ((inToken == null) || (inToken.Length == 0)) { throw new ArgumentNullException("inToken"); } securityToken = UnwrapNegotiationToken(inToken); this.needMechListMic = true; this.client.Context.NegotiationState = SpngNegotiationState.AcceptIncomplete; securityMechContext.Initialize(securityToken); if (securityMechContext.Token != null) { this.token = WrapNegotiationToken(SpngPayloadType.NegResp, securityMechContext.Token); } break; case SpngNegotiationState.AcceptIncomplete: if ((inToken == null) || (inToken.Length == 0)) { throw new ArgumentNullException("inToken"); } byte[] mechListMic = null; if (CurrentSecurityConfig.GetType() == typeof(NlmpClientSecurityConfig)) { NlmpClientSecurityConfig nlmpConfig = CurrentSecurityConfig as NlmpClientSecurityConfig; if ((nlmpConfig.SecurityAttributes & ClientSecurityContextAttribute.DceStyle) == ClientSecurityContextAttribute.DceStyle) { isNeedWrap = false; } } if (isNeedWrap) { securityToken = UnwrapNegotiationToken(inToken, out mechListMic); if (!securityMechContext.NeedContinueProcessing) { this.needContinueProcessing = false; this.client.Context.NegotiationState = SpngNegotiationState.AcceptCompleted; this.token = null; if (mechListMic != null && !this.client.VerifyMechListMIC(securityMechContext, mechListMic)) { throw new InvalidOperationException("Invalid MechListMic"); } } else { securityMechContext.Initialize(securityToken); if (!securityMechContext.NeedContinueProcessing) { this.needMechListMic = true; } this.token = WrapNegotiationToken(SpngPayloadType.NegResp, securityMechContext.Token); } } else { this.needContinueProcessing = false; if (!securityMechContext.NeedContinueProcessing) { this.client.Context.NegotiationState = SpngNegotiationState.AcceptCompleted; this.token = null; } else { securityToken = inToken; securityMechContext.Initialize(securityToken); this.token = securityMechContext.Token; } } break; case SpngNegotiationState.AcceptCompleted: throw new InvalidOperationException("Authentication completed!"); case SpngNegotiationState.SspiNegotiation: if (securityMechContext != null) { securityMechContext.Initialize(inToken); } break; default: // MUST be SpngNegotiationState.Reject throw new InvalidOperationException("Authentication rejected!"); } }