public static SecurityContext Initialize(SecurityCredential credential, SspiContextFlags contextFlags, string servicePrincipalName, byte[] input, out byte[] output)
        {
            var context = new SecurityContext(credential, contextFlags);

            context.Initialize(servicePrincipalName, input, out output);
            return(context);
        }
 public SecurityContext(SecurityCredential credential, SspiContextFlags contextFlags)
     : base(IntPtr.Zero, true)
 {
     _handle                = new SspiHandle();
     _credential            = credential;
     _requestedContextFlags = contextFlags;
 }
        public void Test(string packageName, SspiContextFlags contextFlags)
        {
            var clientCredential = new SecurityCredential(packageName, SecurityCredentialUse.Outbound);
            clientCredential.Acquire();

            var serverCredential = new SecurityCredential(packageName, SecurityCredentialUse.Inbound);
            serverCredential.Acquire();

            var clientContext = new SecurityContext(clientCredential, contextFlags);
            var serverContext = new SecurityContext(serverCredential, contextFlags);

            byte[] clientToken;
            clientContext.Initialize(serverCredential.PrincipalName, null, out clientToken);

            while (true)
            {
                byte[] serverToken;
                serverContext.AcceptToken(clientToken, out serverToken);
                if (serverContext.IsInitialized && clientContext.IsInitialized)
                    break;

                clientContext.Initialize(serverCredential.PrincipalName, serverToken, out clientToken);
                if (clientContext.IsInitialized && serverContext.IsInitialized)
                    break;
            }

            clientContext.Dispose();
            serverContext.Dispose();

            clientCredential.Dispose();
            serverCredential.Dispose();
        }
 public SecurityContext(SecurityCredential credential, SspiContextFlags contextFlags)
     : base(IntPtr.Zero, true)
 {
     _handle = new SspiHandle();
     _credential = credential;
     _requestedContextFlags = contextFlags;
 }
예제 #5
0
 internal static extern uint AcceptSecurityContext(
     ref SspiHandle credentialHandle,
     ref SspiHandle inContextHandle,
     ref SecurityBufferDescriptor inputBuffer,
     SspiContextFlags requestedAttribs,
     DataRepresentation dataRepresentation,
     ref SspiHandle outContext,
     ref SecurityBufferDescriptor outputBuffer,
     out SspiContextFlags outputAttribs,
     out long timestamp);
예제 #6
0
 internal static int AcceptSecurityContext(
     SafeFreeCredentials credential,
     ref SafeDeleteContext refContext,
     SspiContextFlags inFlags,
     Endianness datarep,
     SecurityBuffer[] inputBuffers,
     SecurityBuffer outputBuffer,
     ref SspiContextFlags outFlags)
 {
     return(SafeDeleteContext.AcceptSecurityContext(credential, ref refContext, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags));
 }
예제 #7
0
 internal static int InitializeSecurityContext(
     SafeFreeCredentials credential,
     ref SafeDeleteContext context,
     string targetName,
     SspiContextFlags inFlags,
     Endianness datarep,
     SecurityBuffer[] inputBuffers,
     SecurityBuffer outputBuffer,
     ref SspiContextFlags outFlags)
 {
     return(SafeDeleteContext.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags));
 }
예제 #8
0
 public static extern uint InitializeSecurityContext(
     ref SspiHandle credentialHandle,
     ref SspiHandle inContextHandle,
     string targetName,
     SspiContextFlags flags,
     int reserved1,
     DataRepresentation dataRepresentation,
     ref SecurityBufferDescriptor inputBuffer,
     int reserved2,
     ref SspiHandle outContext,
     ref SecurityBufferDescriptor outputBuffer,
     out SspiContextFlags outAttributes,
     out long timestamp);
        public void Test(string packageName, SspiContextFlags contextFlags)
        {
            var clientCredential = new SecurityCredential(packageName, SecurityCredentialUse.Outbound);

            clientCredential.Acquire();

            var serverCredential = new SecurityCredential(packageName, SecurityCredentialUse.Inbound);

            serverCredential.Acquire();

            var clientContext = new SecurityContext(clientCredential, contextFlags);
            var serverContext = new SecurityContext(serverCredential, contextFlags);

            byte[] clientToken;
            clientContext.Initialize(serverCredential.PrincipalName, null, out clientToken);

            while (true)
            {
                byte[] serverToken;
                serverContext.AcceptToken(clientToken, out serverToken);
                if (serverContext.IsInitialized && clientContext.IsInitialized)
                {
                    break;
                }

                clientContext.Initialize(serverCredential.PrincipalName, serverToken, out clientToken);
                if (clientContext.IsInitialized && serverContext.IsInitialized)
                {
                    break;
                }
            }

            clientContext.Dispose();
            serverContext.Dispose();

            clientCredential.Dispose();
            serverCredential.Dispose();
        }
        void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding)
        {
            bool ownCredentialsHandle         = false;
            SafeDeleteContext securityContext = null;

            try
            {
                if (credentialsHandle == null)
                {
                    if (networkCredential == null || networkCredential == CredentialCache.DefaultNetworkCredentials)
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Outbound);
                    }
                    else
                    {
                        AuthIdentityEx authIdentity = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain);
                        credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", CredentialUse.Outbound, ref authIdentity);
                    }
                    ownCredentialsHandle = true;
                }

                SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory
                                               | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.ReplayDetect
                                               | SspiContextFlags.SequenceDetect;


                // we only accept Identity or Impersonation (Impersonation is default).
                if (tokenImpersonationLevel == TokenImpersonationLevel.Identification)
                {
                    fContextReq |= SspiContextFlags.InitIdentify;
                }

                SspiContextFlags contextFlags     = SspiContextFlags.Zero;
                SecurityBuffer   inSecurityBuffer = null;
                if (channelBinding != null)
                {
                    inSecurityBuffer = new SecurityBuffer(channelBinding);
                }
                SecurityBuffer outSecurityBuffer = new SecurityBuffer(0, BufferType.Token);

                int statusCode = SspiWrapper.InitializeSecurityContext(
                    credentialsHandle,
                    ref securityContext,
                    this.servicePrincipalName,
                    fContextReq,
                    Endianness.Native,
                    inSecurityBuffer,
                    outSecurityBuffer,
                    ref contextFlags);

                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    SecurityTraceRecordHelper.TraceChannelBindingInformation(null, false, channelBinding);
                }

                if (statusCode != (int)SecurityStatus.OK)
                {
                    if (statusCode == (int)SecurityStatus.ContinueNeeded)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode)));
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.FailInitializeSecurityContext), new Win32Exception(statusCode)));
                    }
                }

#if REMOVEGSS
                //
                // ... and strip GSS-framing from it
                //
                int offset = 0;
                int len    = outSecurityBuffer.token.Length;
                DEREncoding.VerifyTokenHeader(outSecurityBuffer.token, ref offset, ref len);
                this.apreq = SecurityUtils.CloneBuffer(outSecurityBuffer.token, offset, len);
#else
                this.apreq = outSecurityBuffer.token;
#endif

                // Expiration
                LifeSpan lifeSpan = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan);
                this.effectiveTime  = lifeSpan.EffectiveTimeUtc;
                this.expirationTime = lifeSpan.ExpiryTimeUtc;

                // SessionKey
                SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey);
            }
            finally
            {
                if (securityContext != null)
                {
                    securityContext.Close();
                }

                if (ownCredentialsHandle && credentialsHandle != null)
                {
                    credentialsHandle.Close();
                }
            }
        }
예제 #11
0
 static TlsSspiNegotiation()
 {
     StandardFlags       = SspiContextFlags.ReplayDetect | SspiContextFlags.Confidentiality | SspiContextFlags.AllocateMemory;
     ServerStandardFlags = StandardFlags | SspiContextFlags.AcceptExtendedError | SspiContextFlags.AcceptStream;
     ClientStandardFlags = StandardFlags | SspiContextFlags.InitManualCredValidation | SspiContextFlags.InitStream;
 }
        private void Initialize(TokenImpersonationLevel tokenImpersonationLevel, NetworkCredential networkCredential, System.IdentityModel.SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding)
        {
            bool flag = false;

            System.IdentityModel.SafeDeleteContext context = null;
            try
            {
                if (credentialsHandle == null)
                {
                    if ((networkCredential == null) || (networkCredential == CredentialCache.DefaultNetworkCredentials))
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", System.IdentityModel.CredentialUse.Outbound, new string[0]);
                    }
                    else
                    {
                        AuthIdentityEx authdata = new AuthIdentityEx(networkCredential.UserName, networkCredential.Password, networkCredential.Domain, new string[0]);
                        credentialsHandle = SspiWrapper.AcquireCredentialsHandle("Kerberos", System.IdentityModel.CredentialUse.Outbound, ref authdata);
                    }
                    flag = true;
                }
                SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
                if (tokenImpersonationLevel == TokenImpersonationLevel.Identification)
                {
                    inFlags |= SspiContextFlags.InitIdentify;
                }
                SspiContextFlags zero = SspiContextFlags.Zero;
                System.IdentityModel.SecurityBuffer inputBuffer = null;
                if (channelBinding != null)
                {
                    inputBuffer = new System.IdentityModel.SecurityBuffer(channelBinding);
                }
                System.IdentityModel.SecurityBuffer outputBuffer = new System.IdentityModel.SecurityBuffer(0, System.IdentityModel.BufferType.Token);
                int error = SspiWrapper.InitializeSecurityContext(credentialsHandle, ref context, this.servicePrincipalName, inFlags, System.IdentityModel.Endianness.Native, inputBuffer, outputBuffer, ref zero);
                switch (error)
                {
                case 0:
                    break;

                case 0x90312:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error)));

                default:
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailInitializeSecurityContext"), new Win32Exception(error)));
                }
                this.apreq = outputBuffer.token;
                LifeSpan span = (LifeSpan)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.Lifespan);
                this.effectiveTime  = span.EffectiveTimeUtc;
                this.expirationTime = span.ExpiryTimeUtc;
                SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(context, System.IdentityModel.ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey);
            }
            finally
            {
                if (context != null)
                {
                    context.Close();
                }
                if (flag && (credentialsHandle != null))
                {
                    credentialsHandle.Close();
                }
            }
        }
 internal static int InitializeSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext context, string targetName, SspiContextFlags inFlags, Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref SspiContextFlags outFlags)
 {
     return SafeDeleteContext.InitializeSecurityContext(credential, ref context, targetName, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags);
 }
 public static SecurityContext Initialize(SecurityCredential credential, SspiContextFlags contextFlags, string servicePrincipalName, byte[] input, out byte[] output)
 {
     var context = new SecurityContext(credential, contextFlags);
     context.Initialize(servicePrincipalName, input, out output);
     return context;
 }
예제 #15
0
        private static unsafe int MustRunInitializeSecurityContext(SafeFreeCredentials inCredentials, void *inContextPtr, byte *targetName, SspiContextFlags inFlags, Endianness endianness, SecurityBufferDescriptor inputBuffer, SafeDeleteContext outContext, SecurityBufferDescriptor outputBuffer, ref SspiContextFlags attributes, SafeFreeContextBuffer handleTemplate)
        {
            long num;
            int  num1  = -1;
            bool flag  = false;
            bool flag1 = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                try
                {
                    inCredentials.DangerousAddRef(ref flag);
                    outContext.DangerousAddRef(ref flag1);
                }
                catch (Exception exception1)
                {
                    Exception exception = exception1;
                    if (Fx.IsFatal(exception))
                    {
                        throw;
                    }
                    if (flag)
                    {
                        inCredentials.DangerousRelease();
                        flag = false;
                    }
                    if (flag1)
                    {
                        outContext.DangerousRelease();
                        flag1 = false;
                    }
                    if (!(exception is ObjectDisposedException))
                    {
                        throw;
                    }
                }
            }
            finally
            {
                if (!flag)
                {
                    inCredentials = null;
                }
                else if (flag && flag1)
                {
                    SSPIHandle sSPIHandle = inCredentials._handle;
                    num1 = SafeDeleteContext.InitializeSecurityContextW(ref sSPIHandle, inContextPtr, targetName, inFlags, 0, endianness, inputBuffer, 0, ref outContext._handle, outputBuffer, ref attributes, out num);
                    if (outContext._EffectiveCredential == inCredentials || ((long)num1 & (ulong)-2147483648) != (long)0)
                    {
                        inCredentials.DangerousRelease();
                    }
                    else
                    {
                        if (outContext._EffectiveCredential != null)
                        {
                            outContext._EffectiveCredential.DangerousRelease();
                        }
                        outContext._EffectiveCredential = inCredentials;
                    }
                    outContext.DangerousRelease();
                    if (handleTemplate != null)
                    {
                        handleTemplate.Set((*(outputBuffer.UnmanagedPointer)).token);
                        if (handleTemplate.IsInvalid)
                        {
                            handleTemplate.SetHandleAsInvalid();
                        }
                    }
                }
                if (inContextPtr == null && ((long)num1 & (ulong)-2147483648) != (long)0)
                {
                    outContext._handle.SetToInvalid();
                }
            }
            return(num1);
        }
예제 #16
0
 internal static int AcceptSecurityContext(SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, SspiContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref SspiContextFlags outFlags)
 {
     unsafe
     {
         IntPtr *intPtrPointer;
         IntPtr *intPtrPointer1;
         if (inCredentials == null)
         {
             throw new ArgumentNullException("inCredentials");
         }
         SecurityBufferDescriptor securityBufferDescriptor = null;
         if (inSecBuffer != null)
         {
             securityBufferDescriptor = new SecurityBufferDescriptor(1);
         }
         else if (inSecBuffers != null)
         {
             securityBufferDescriptor = new SecurityBufferDescriptor((int)inSecBuffers.Length);
         }
         SecurityBufferDescriptor securityBufferDescriptor1 = new SecurityBufferDescriptor(1);
         bool       flag       = ((inFlags & SspiContextFlags.AllocateMemory) != SspiContextFlags.Zero ? true : false);
         int        num        = -1;
         SSPIHandle sSPIHandle = new SSPIHandle();
         if (refContext != null)
         {
             sSPIHandle = refContext._handle;
         }
         GCHandle[]            gCHandleArray         = null;
         GCHandle              gCHandle              = new GCHandle();
         SafeFreeContextBuffer safeFreeContextBuffer = null;
         try
         {
             gCHandle = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned);
             SecurityBufferStruct[] zero = new SecurityBufferStruct[(securityBufferDescriptor == null ? 1 : securityBufferDescriptor.Count)];
             try
             {
                 SecurityBufferStruct[] securityBufferStructArray  = zero;
                 SecurityBufferStruct[] securityBufferStructArray1 = securityBufferStructArray;
                 if (securityBufferStructArray == null || (int)securityBufferStructArray1.Length == 0)
                 {
                     intPtrPointer = null;
                 }
                 else
                 {
                     intPtrPointer = &securityBufferStructArray1[0];
                 }
                 if (securityBufferDescriptor != null)
                 {
                     securityBufferDescriptor.UnmanagedPointer = (void *)intPtrPointer;
                     gCHandleArray = new GCHandle[securityBufferDescriptor.Count];
                     for (int i = 0; i < securityBufferDescriptor.Count; i++)
                     {
                         SecurityBuffer securityBuffer = (inSecBuffer != null ? inSecBuffer : inSecBuffers[i]);
                         if (securityBuffer != null)
                         {
                             zero[i].count = securityBuffer.size;
                             zero[i].type  = securityBuffer.type;
                             if (securityBuffer.unmanagedToken != null)
                             {
                                 zero[i].token = securityBuffer.unmanagedToken.DangerousGetHandle();
                             }
                             else if (securityBuffer.token == null || (int)securityBuffer.token.Length == 0)
                             {
                                 zero[i].token = IntPtr.Zero;
                             }
                             else
                             {
                                 gCHandleArray[i] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned);
                                 zero[i].token    = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset);
                             }
                         }
                     }
                 }
                 SecurityBufferStruct[] zero1 = new SecurityBufferStruct[1];
                 try
                 {
                     SecurityBufferStruct[] securityBufferStructArray2 = zero1;
                     SecurityBufferStruct[] securityBufferStructArray3 = securityBufferStructArray2;
                     if (securityBufferStructArray2 == null || (int)securityBufferStructArray3.Length == 0)
                     {
                         intPtrPointer1 = null;
                     }
                     else
                     {
                         intPtrPointer1 = &securityBufferStructArray3[0];
                     }
                     securityBufferDescriptor1.UnmanagedPointer = (void *)intPtrPointer1;
                     zero1[0].count = outSecBuffer.size;
                     zero1[0].type  = outSecBuffer.type;
                     if (outSecBuffer.token == null || (int)outSecBuffer.token.Length == 0)
                     {
                         zero1[0].token = IntPtr.Zero;
                     }
                     else
                     {
                         zero1[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset);
                     }
                     if (flag)
                     {
                         safeFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle();
                     }
                     if (refContext == null || refContext.IsInvalid)
                     {
                         refContext = new SafeDeleteContext();
                     }
                     num = SafeDeleteContext.MustRunAcceptSecurityContext(inCredentials, (sSPIHandle.IsZero ? (void *)0 : (void *)(&sSPIHandle)), securityBufferDescriptor, inFlags, endianness, refContext, securityBufferDescriptor1, ref outFlags, safeFreeContextBuffer);
                     outSecBuffer.size = zero1[0].count;
                     outSecBuffer.type = zero1[0].type;
                     if (outSecBuffer.size <= 0)
                     {
                         outSecBuffer.token = null;
                     }
                     else
                     {
                         outSecBuffer.token = new byte[outSecBuffer.size];
                         Marshal.Copy(zero1[0].token, outSecBuffer.token, 0, outSecBuffer.size);
                     }
                 }
                 finally
                 {
                     intPtrPointer1 = null;
                 }
             }
             finally
             {
                 intPtrPointer = null;
             }
         }
         finally
         {
             if (gCHandleArray != null)
             {
                 for (int j = 0; j < (int)gCHandleArray.Length; j++)
                 {
                     if (gCHandleArray[j].IsAllocated)
                     {
                         gCHandleArray[j].Free();
                     }
                 }
             }
             if (gCHandle.IsAllocated)
             {
                 gCHandle.Free();
             }
             if (safeFreeContextBuffer != null)
             {
                 safeFreeContextBuffer.Close();
             }
         }
         return(num);
     }
 }
예제 #17
0
 internal static extern uint AcceptSecurityContext(
     ref SspiHandle credentialHandle,
     ref SspiHandle inContextHandle,
     ref SecurityBufferDescriptor inputBuffer,
     SspiContextFlags requestedAttribs,
     DataRepresentation dataRepresentation,
     ref SspiHandle outContext,
     ref SecurityBufferDescriptor outputBuffer,
     out SspiContextFlags outputAttribs,
     out long timestamp);
 public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
 {
     this.ThrowIfDisposed();
     int error = 0;
     SspiContextFlags inFlags = SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
     if (this.doMutualAuth)
     {
         inFlags |= SspiContextFlags.MutualAuth;
     }
     if (this.impersonationLevel == TokenImpersonationLevel.Delegation)
     {
         inFlags |= SspiContextFlags.Delegate;
     }
     else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Identification))
     {
         inFlags |= SspiContextFlags.InitIdentify;
     }
     else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Anonymous))
     {
         inFlags |= SspiContextFlags.InitAnonymous;
     }
     ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy);
     if (this.isServer)
     {
         if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy))
         {
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.ServiceModel.SR.GetString("SecurityChannelBindingMissing")));
         }
         if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
         {
             inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
         }
         if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy)
         {
             inFlags |= SspiContextFlags.ChannelBindingProxyBindings;
         }
     }
     List<SecurityBuffer> list = new List<SecurityBuffer>(2);
     if (incomingBlob != null)
     {
         list.Add(new SecurityBuffer(incomingBlob, BufferType.Token));
     }
     if (this.isServer)
     {
         if (helper.ShouldAddChannelBindingToASC())
         {
             list.Add(new SecurityBuffer(helper.ChannelBinding));
         }
     }
     else if (helper.ChannelBinding != null)
     {
         list.Add(new SecurityBuffer(helper.ChannelBinding));
     }
     SecurityBuffer[] inputBuffers = null;
     if (list.Count > 0)
     {
         inputBuffers = list.ToArray();
     }
     SecurityBuffer outputBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token);
     if (!this.isServer)
     {
         error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
     }
     else
     {
         bool flag = this.securityContext == null;
         SspiContextFlags contextFlags = this.contextFlags;
         error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
         if ((error == -2146893048) && !flag)
         {
             this.contextFlags = contextFlags;
             this.CloseContext();
             error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
         }
     }
     if ((error & -2147483648) != 0)
     {
         if (((!this.isServer && this.interactiveNegoLogonEnabled) && (System.ServiceModel.Security.SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint) error))) && SspiWrapper.IsNegotiateExPackagePresent())
         {
             if (this.MaxPromptAttempts >= 1)
             {
                 throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidClientCredentials")));
             }
             IntPtr zero = IntPtr.Zero;
             uint num2 = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out zero, ref this.saveClientCredentialsOnSspiUi);
             if (num2 == 0)
             {
                 IntPtr ppNewAuthIdentity = IntPtr.Zero;
                 if (!this.allowNtlm)
                 {
                     UnsafeNativeMethods.SspiExcludePackage(zero, "NTLM", out ppNewAuthIdentity);
                 }
                 else
                 {
                     ppNewAuthIdentity = zero;
                 }
                 this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity);
                 if (IntPtr.Zero != ppNewAuthIdentity)
                 {
                     UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity);
                 }
                 this.CloseContext();
                 this.MaxPromptAttempts++;
                 return this.GetOutgoingBlob(null, channelbinding, protectionPolicy);
             }
             if (IntPtr.Zero != zero)
             {
                 UnsafeNativeMethods.SspiFreeAuthIdentity(zero);
             }
             this.CloseContext();
             this.isCompleted = true;
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int) num2, System.ServiceModel.SR.GetString("SspiErrorOrInvalidClientCredentials")));
         }
         this.CloseContext();
         this.isCompleted = true;
         if (this.isServer || (((error != -2146893042) && (error != -2146893053)) && (error != -2146893022)))
         {
             throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidSspiNegotiation")));
         }
         throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("IncorrectSpnOrUpnSpecified", new object[] { this.servicePrincipalName })));
     }
     if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
     {
         if (this.isServer)
         {
             SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this);
         }
         else
         {
             SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this);
         }
     }
     if (error == 0)
     {
         this.isCompleted = true;
         if ((this.isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == SspiContextFlags.Zero)) && ((string.Compare(this.ProtocolName, "Kerberos", StringComparison.OrdinalIgnoreCase) != 0) && helper.ShouldCheckServiceBinding))
         {
             helper.CheckServiceBinding(this.securityContext, this.servicePrincipalName);
         }
     }
     return outputBuffer.token;
 }
예제 #19
0
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            this.ThrowIfDisposed();
            int error = 0;
            SspiContextFlags inFlags = SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;

            if (this.doMutualAuth)
            {
                inFlags |= SspiContextFlags.MutualAuth;
            }
            if (this.impersonationLevel == TokenImpersonationLevel.Delegation)
            {
                inFlags |= SspiContextFlags.Delegate;
            }
            else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Identification))
            {
                inFlags |= SspiContextFlags.InitIdentify;
            }
            else if (!this.isServer && (this.impersonationLevel == TokenImpersonationLevel.Anonymous))
            {
                inFlags |= SspiContextFlags.InitAnonymous;
            }
            ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy);

            if (this.isServer)
            {
                if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy))
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.ServiceModel.SR.GetString("SecurityChannelBindingMissing")));
                }
                if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }
                if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    inFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                }
            }
            List <SecurityBuffer> list = new List <SecurityBuffer>(2);

            if (incomingBlob != null)
            {
                list.Add(new SecurityBuffer(incomingBlob, BufferType.Token));
            }
            if (this.isServer)
            {
                if (helper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(helper.ChannelBinding));
                }
            }
            else if (helper.ChannelBinding != null)
            {
                list.Add(new SecurityBuffer(helper.ChannelBinding));
            }
            SecurityBuffer[] inputBuffers = null;
            if (list.Count > 0)
            {
                inputBuffers = list.ToArray();
            }
            SecurityBuffer outputBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token);

            if (!this.isServer)
            {
                error = SspiWrapper.InitializeSecurityContext(this.credentialsHandle, ref this.securityContext, this.servicePrincipalName, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
            }
            else
            {
                bool             flag         = this.securityContext == null;
                SspiContextFlags contextFlags = this.contextFlags;
                error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
                if ((error == -2146893048) && !flag)
                {
                    this.contextFlags = contextFlags;
                    this.CloseContext();
                    error = SspiWrapper.AcceptSecurityContext(this.credentialsHandle, ref this.securityContext, inFlags, Endianness.Network, inputBuffers, outputBuffer, ref this.contextFlags);
                }
            }
            if ((error & -2147483648) != 0)
            {
                if (((!this.isServer && this.interactiveNegoLogonEnabled) && (System.ServiceModel.Security.SecurityUtils.IsOSGreaterThanOrEqualToWin7() && SspiWrapper.IsSspiPromptingNeeded((uint)error))) && SspiWrapper.IsNegotiateExPackagePresent())
                {
                    if (this.MaxPromptAttempts >= 1)
                    {
                        throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidClientCredentials")));
                    }
                    IntPtr zero = IntPtr.Zero;
                    uint   num2 = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out zero, ref this.saveClientCredentialsOnSspiUi);
                    if (num2 == 0)
                    {
                        IntPtr ppNewAuthIdentity = IntPtr.Zero;
                        if (!this.allowNtlm)
                        {
                            UnsafeNativeMethods.SspiExcludePackage(zero, "NTLM", out ppNewAuthIdentity);
                        }
                        else
                        {
                            ppNewAuthIdentity = zero;
                        }
                        this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity);
                        if (IntPtr.Zero != ppNewAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity);
                        }
                        this.CloseContext();
                        this.MaxPromptAttempts++;
                        return(this.GetOutgoingBlob(null, channelbinding, protectionPolicy));
                    }
                    if (IntPtr.Zero != zero)
                    {
                        UnsafeNativeMethods.SspiFreeAuthIdentity(zero);
                    }
                    this.CloseContext();
                    this.isCompleted = true;
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)num2, System.ServiceModel.SR.GetString("SspiErrorOrInvalidClientCredentials")));
                }
                this.CloseContext();
                this.isCompleted = true;
                if (this.isServer || (((error != -2146893042) && (error != -2146893053)) && (error != -2146893022)))
                {
                    throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("InvalidSspiNegotiation")));
                }
                throw System.ServiceModel.DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error, System.ServiceModel.SR.GetString("IncorrectSpnOrUpnSpecified", new object[] { this.servicePrincipalName })));
            }
            if (System.ServiceModel.DiagnosticUtility.ShouldTraceInformation)
            {
                if (this.isServer)
                {
                    SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this);
                }
                else
                {
                    SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this);
                }
            }
            if (error == 0)
            {
                this.isCompleted = true;
                if ((this.isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == SspiContextFlags.Zero)) && ((string.Compare(this.ProtocolName, "Kerberos", StringComparison.OrdinalIgnoreCase) != 0) && helper.ShouldCheckServiceBinding))
                {
                    helper.CheckServiceBinding(this.securityContext, this.servicePrincipalName);
                }
            }
            return(outputBuffer.token);
        }
예제 #20
0
        internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
        {
            if (!this.isAuthenticated)
            {
                bool flag = false;
                SafeDeleteContext refContext = null;
                SafeCloseHandle   token      = null;
                byte[]            request    = this.request;
                try
                {
                    if (credentialsHandle == null)
                    {
                        credentialsHandle = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound, new string[0]);
                        flag = true;
                    }
                    SspiContextFlags inFlags = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality | SspiContextFlags.SequenceDetect | SspiContextFlags.ReplayDetect;
                    ExtendedProtectionPolicyHelper helper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy);
                    if (((helper.PolicyEnforcement == PolicyEnforcement.Always) && (helper.ChannelBinding == null)) && (helper.ProtectionScenario != ProtectionScenario.TrustedProxy))
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("SecurityChannelBindingMissing")));
                    }
                    if (helper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                    {
                        inFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                    }
                    if (helper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                    {
                        inFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                    }
                    SspiContextFlags      zero         = SspiContextFlags.Zero;
                    SecurityBuffer        outputBuffer = new SecurityBuffer(0, BufferType.Token);
                    List <SecurityBuffer> list         = new List <SecurityBuffer>(2)
                    {
                        new SecurityBuffer(request, 2)
                    };
                    if (helper.ShouldAddChannelBindingToASC())
                    {
                        list.Add(new SecurityBuffer(helper.ChannelBinding));
                    }
                    SecurityBuffer[] inputBuffers = null;
                    if (list.Count > 0)
                    {
                        inputBuffers = list.ToArray();
                    }
                    int error = SspiWrapper.AcceptSecurityContext(credentialsHandle, ref refContext, inFlags, Endianness.Native, inputBuffers, outputBuffer, ref zero);
                    switch (error)
                    {
                    case 0:
                        break;

                    case 0x90312:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosMultilegsNotSupported"), new Win32Exception(error)));

                    case -2146893056:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("KerberosApReqInvalidOrOutOfMemory"), new Win32Exception(error)));

                    default:
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(System.IdentityModel.SR.GetString("FailAcceptSecurityContext"), new Win32Exception(error)));
                    }
                    LifeSpan span                  = (LifeSpan)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.Lifespan);
                    DateTime effectiveTimeUtc      = span.EffectiveTimeUtc;
                    DateTime expiryTimeUtc         = span.ExpiryTimeUtc;
                    SecuritySessionKeyClass class2 = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(refContext, ContextAttribute.SessionKey);
                    this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(class2.SessionKey);
                    error = SspiWrapper.QuerySecurityContextToken(refContext, out token);
                    if (error != 0)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(error));
                    }
                    System.Security.Principal.WindowsIdentity windowsIdentity = new System.Security.Principal.WindowsIdentity(token.DangerousGetHandle(), "Kerberos");
                    base.Initialize(this.id, "Kerberos", effectiveTimeUtc, expiryTimeUtc, windowsIdentity, false);
                    this.isAuthenticated = true;
                }
                finally
                {
                    if (token != null)
                    {
                        token.Close();
                    }
                    if (refContext != null)
                    {
                        refContext.Close();
                    }
                    if (flag && (credentialsHandle != null))
                    {
                        credentialsHandle.Close();
                    }
                }
            }
        }
예제 #21
0
        internal static unsafe int InitializeSecurityContext(SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, string targetName, SspiContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref SspiContextFlags outFlags)
        {
            if (inCredentials == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inCredentials");
            }
            SecurityBufferDescriptor inputBuffer = null;

            if (inSecBuffer != null)
            {
                inputBuffer = new SecurityBufferDescriptor(1);
            }
            else if (inSecBuffers != null)
            {
                inputBuffer = new SecurityBufferDescriptor(inSecBuffers.Length);
            }
            SecurityBufferDescriptor outputBuffer = new SecurityBufferDescriptor(1);
            bool       flag   = (inFlags & SspiContextFlags.AllocateMemory) != SspiContextFlags.Zero;
            int        num    = -1;
            SSPIHandle handle = new SSPIHandle();

            if (refContext != null)
            {
                handle = refContext._handle;
            }
            GCHandle[]            handleArray    = null;
            GCHandle              handle2        = new GCHandle();
            SafeFreeContextBuffer handleTemplate = null;

            try
            {
                handle2 = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned);
                SecurityBufferStruct[] structArray = new SecurityBufferStruct[(inputBuffer == null) ? 1 : inputBuffer.Count];
                try
                {
                    SecurityBufferStruct[] structArray3;
                    if (((structArray3 = structArray) == null) || (structArray3.Length == 0))
                    {
                        ptrRef = null;
                        goto Label_00A9;
                    }
                    fixed(IntPtr *ptrRef = structArray3)
                    {
Label_00A9:
                        if (inputBuffer != null)
                        {
                            inputBuffer.UnmanagedPointer = (void *)ptrRef;
                            handleArray = new GCHandle[inputBuffer.Count];
                            for (int i = 0; i < inputBuffer.Count; i++)
                            {
                                SecurityBuffer buffer2 = (inSecBuffer != null) ? inSecBuffer : inSecBuffers[i];
                                if (buffer2 != null)
                                {
                                    structArray[i].count = buffer2.size;
                                    structArray[i].type  = buffer2.type;
                                    if (buffer2.unmanagedToken != null)
                                    {
                                        structArray[i].token = buffer2.unmanagedToken.DangerousGetHandle();
                                    }
                                    else if ((buffer2.token == null) || (buffer2.token.Length == 0))
                                    {
                                        structArray[i].token = IntPtr.Zero;
                                    }
                                    else
                                    {
                                        handleArray[i]       = GCHandle.Alloc(buffer2.token, GCHandleType.Pinned);
                                        structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer2.token, buffer2.offset);
                                    }
                                }
                            }
                        }
                        SecurityBufferStruct[] structArray2 = new SecurityBufferStruct[1];
                        try
                        {
                            SecurityBufferStruct[] structArray4;
                            if (((structArray4 = structArray2) == null) || (structArray4.Length == 0))
                            {
                                ptrRef2 = null;
                                goto Label_01CF;
                            }
                            fixed(IntPtr *ptrRef2 = structArray4)
                            {
Label_01CF:
                                outputBuffer.UnmanagedPointer = (void *)ptrRef2;
                                structArray2[0].count         = outSecBuffer.size;
                                structArray2[0].type          = outSecBuffer.type;
                                if ((outSecBuffer.token == null) || (outSecBuffer.token.Length == 0))
                                {
                                    structArray2[0].token = IntPtr.Zero;
                                }
                                else
                                {
                                    structArray2[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset);
                                }
                                if (flag)
                                {
                                    handleTemplate = SafeFreeContextBuffer.CreateEmptyHandle();
                                }
                                if ((refContext == null) || refContext.IsInvalid)
                                {
                                    refContext = new SafeDeleteContext();
                                }
                                if ((targetName == null) || (targetName.Length == 0))
                                {
                                    targetName = " ";
                                }
                                fixed(char *str = ((char *)targetName))
                                {
                                    char *chPtr = str;

                                    num = MustRunInitializeSecurityContext(inCredentials, handle.IsZero ? null : ((void *)&handle), (targetName == " ") ? null : ((byte *)chPtr), inFlags, endianness, inputBuffer, refContext, outputBuffer, ref outFlags, handleTemplate);
                                }
                                outSecBuffer.size = structArray2[0].count;
                                outSecBuffer.type = structArray2[0].type;
                                if (outSecBuffer.size > 0)
                                {
                                    outSecBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(outSecBuffer.size);
                                    Marshal.Copy(structArray2[0].token, outSecBuffer.token, 0, outSecBuffer.size);
                                    return(num);
                                }
                                outSecBuffer.token = null;
                                return(num);
                            }
                        }
                        finally
                        {
                            ptrRef2 = null;
                        }
                        return(num);
                    }
                }
                finally
                {
                    ptrRef = null;
                }
            }
            finally
            {
                if (handleArray != null)
                {
                    for (int j = 0; j < handleArray.Length; j++)
                    {
                        if (handleArray[j].IsAllocated)
                        {
                            handleArray[j].Free();
                        }
                    }
                }
                if (handle2.IsAllocated)
                {
                    handle2.Free();
                }
                if (handleTemplate != null)
                {
                    handleTemplate.Close();
                }
            }
            return(num);
        }
        // This internal API is not thread-safe.  It is acceptable since ..
        // 1) From public OM, Initialize happens at ctor time.
        // 2) From internal OM (Sfx), Initialize happens right after ctor (single thread env).
        //    i.e. ReadToken and then AuthenticateToken.
        internal void Initialize(SafeFreeCredentials credentialsHandle, ChannelBinding channelBinding, ExtendedProtectionPolicy extendedProtectionPolicy)
        {
            if (this.isAuthenticated)
            {
                return;
            }
            bool ownCredentialsHandle         = false;
            SafeDeleteContext securityContext = null;
            SafeCloseHandle   tokenHandle     = null;

#if RECOMPUTEGSS
            int    tokenSize  = DEREncoding.TokenSize(this.request.Length);
            byte[] rawRequest = new byte[tokenSize];
            int    offset     = 0;
            int    len        = this.request.Length;
            DEREncoding.MakeTokenHeader(this.request.Length, rawRequest, ref offset, ref len);
            System.Buffer.BlockCopy(this.request, 0, rawRequest, offset, this.request.Length);
#else
            byte[] rawRequest = this.request;
#endif

            try
            {
                if (credentialsHandle == null)
                {
                    credentialsHandle    = SspiWrapper.AcquireDefaultCredential("Kerberos", CredentialUse.Inbound);
                    ownCredentialsHandle = true;
                }

                SspiContextFlags fContextReq = SspiContextFlags.AllocateMemory | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.Confidentiality
                                               | SspiContextFlags.ReplayDetect
                                               | SspiContextFlags.SequenceDetect;

                ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelBinding, extendedProtectionPolicy);

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing)));
                }

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    fContextReq |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }

                if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    fContextReq |= SspiContextFlags.ChannelBindingProxyBindings;
                }

                SspiContextFlags contextFlags      = SspiContextFlags.Zero;
                SecurityBuffer   outSecurityBuffer = new SecurityBuffer(0, BufferType.Token);

                List <SecurityBuffer> list = new List <SecurityBuffer>(2);
                list.Add(new SecurityBuffer(rawRequest, BufferType.Token));

                if (policyHelper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }

                SecurityBuffer[] inSecurityBuffer = null;
                if (list.Count > 0)
                {
                    inSecurityBuffer = list.ToArray();
                }

                int statusCode = SspiWrapper.AcceptSecurityContext(credentialsHandle,
                                                                   ref securityContext,
                                                                   fContextReq,
                                                                   Endianness.Native,
                                                                   inSecurityBuffer,
                                                                   outSecurityBuffer,
                                                                   ref contextFlags);


                if (DiagnosticUtility.ShouldTraceInformation)
                {
                    SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, true, channelBinding);
                }

                if (statusCode != (int)SecurityStatus.OK)
                {
                    if (statusCode == (int)SecurityStatus.ContinueNeeded)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosMultilegsNotSupported), new Win32Exception(statusCode)));
                    }
                    else if (statusCode == (int)SecurityStatus.OutOfMemory)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.KerberosApReqInvalidOrOutOfMemory), new Win32Exception(statusCode)));
                    }
                    else
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
                                  new SecurityTokenException(SR.GetString(SR.FailAcceptSecurityContext), new Win32Exception(statusCode)));
                    }
                }

                // Expiration
                LifeSpan lifeSpan       = (LifeSpan)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.Lifespan);
                DateTime effectiveTime  = lifeSpan.EffectiveTimeUtc;
                DateTime expirationTime = lifeSpan.ExpiryTimeUtc;

                // SessionKey
                SecuritySessionKeyClass sessionKey = (SecuritySessionKeyClass)SspiWrapper.QueryContextAttributes(securityContext, ContextAttribute.SessionKey);
                this.symmetricSecurityKey = new InMemorySymmetricSecurityKey(sessionKey.SessionKey);

                // WindowsSecurityToken
                statusCode = SspiWrapper.QuerySecurityContextToken(securityContext, out tokenHandle);
                if (statusCode != (int)SecurityStatus.OK)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode));
                }

                WindowsIdentity windowsIdentity = new WindowsIdentity(tokenHandle.DangerousGetHandle(), SecurityUtils.AuthTypeKerberos);
                Initialize(this.id, SecurityUtils.AuthTypeKerberos, effectiveTime, expirationTime, windowsIdentity, false);

                // Authenticated
                this.isAuthenticated = true;
            }
            finally
            {
                if (tokenHandle != null)
                {
                    tokenHandle.Close();
                }

                if (securityContext != null)
                {
                    securityContext.Close();
                }

                if (ownCredentialsHandle && credentialsHandle != null)
                {
                    credentialsHandle.Close();
                }
            }
        }
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            ThrowIfDisposed();
            int statusCode = 0;

            // use the confidentiality option to ensure we can encrypt messages
            SspiContextFlags requestedFlags = SspiContextFlags.Confidentiality
                                            | SspiContextFlags.ReplayDetect
                                            | SspiContextFlags.SequenceDetect;

            if (this.doMutualAuth)
            {
                requestedFlags |= SspiContextFlags.MutualAuth;
            }

            if (this.impersonationLevel == TokenImpersonationLevel.Delegation)
            {
                requestedFlags |= SspiContextFlags.Delegate;
            }
            else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Identification)
            {
                requestedFlags |= SspiContextFlags.InitIdentify;
            }
            else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Anonymous)
            {
                requestedFlags |= SspiContextFlags.InitAnonymous;
            }

            ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy);

            if (isServer)
            {
                if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing)));
                }

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    requestedFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }

                if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    requestedFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                }
            }

            List<SecurityBuffer> list = new List<SecurityBuffer>(2);

            if (incomingBlob != null)
            {
                list.Add(new SecurityBuffer(incomingBlob, BufferType.Token));
            }

            // when deciding if the channel binding should be added to the security buffer
            // it is necessary to differentiate between  client and server.
            // Server rules were added to policyHelper as they are shared with Kerb and I want them consistent
            // Client adds if not null.
            if (this.isServer)
            {
                if (policyHelper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }
            }
            else
            {
                if (policyHelper.ChannelBinding != null)
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }
            }

            SecurityBuffer[] inSecurityBuffer = null;
            if (list.Count > 0)
            {
                inSecurityBuffer = list.ToArray();
            }

            SecurityBuffer outSecurityBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token);

            if (!this.isServer)
            {
                //client session
                statusCode = SspiWrapper.InitializeSecurityContext(this.credentialsHandle,
                                                                    ref this.securityContext,
                                                                    this.servicePrincipalName,
                                                                    requestedFlags,
                                                                    Endianness.Network,
                                                                    inSecurityBuffer,
                                                                    outSecurityBuffer,
                                                                    ref this.contextFlags);
            }
            else
            {
                // server session
                //This check is to save an unnecessary ASC call.
                bool isServerSecurityContextNull = this.securityContext == null;
                SspiContextFlags serverContextFlags = this.contextFlags;

                statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle,
                                                                ref this.securityContext,
                                                                requestedFlags,
                                                                Endianness.Network,
                                                                inSecurityBuffer,
                                                                outSecurityBuffer,
                                                                ref this.contextFlags);

                if (statusCode == (int)SecurityStatus.InvalidToken && !isServerSecurityContextNull)
                {
                    // Call again into ASC after deleting the Securitycontext. If this securitycontext is not deleted 
                    // then when the client sends NTLM blob the service will treat it as Nego2blob and will fail to authenticate the client.
                    this.contextFlags = serverContextFlags;
                    CloseContext();
                    statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle,
                                                                    ref this.securityContext,
                                                                    requestedFlags,
                                                                    Endianness.Network,
                                                                    inSecurityBuffer,
                                                                    outSecurityBuffer,
                                                                    ref this.contextFlags);
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                IMD.SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, this.isServer, channelbinding);
            }

            if ((statusCode & unchecked((int)0x80000000)) != 0)
            {
                if (!this.isServer
                    && this.interactiveNegoLogonEnabled
                    && SecurityUtils.IsOSGreaterThanOrEqualToWin7()
                    && SspiWrapper.IsSspiPromptingNeeded((uint)statusCode)
                    && SspiWrapper.IsNegotiateExPackagePresent())
                {
                    // If we have prompted enough number of times (DefaultMaxPromptAttempts) with wrong credentials, then we do not prompt again and throw. 
                    if (MaxPromptAttempts >= DefaultMaxPromptAttempts)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidClientCredentials)));
                    }

                    IntPtr ppAuthIdentity = IntPtr.Zero;
                    uint errorCode = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out ppAuthIdentity, ref this.saveClientCredentialsOnSspiUi);
                    if (errorCode == (uint)CredentialStatus.Success)
                    {
                        IntPtr ppNewAuthIdentity = IntPtr.Zero;

                        if (!this.allowNtlm)
                        {
                            // When Ntlm is  explicitly disabled we don't want the collected 
                            //creds from the Kerb/NTLM tile to be used for NTLM auth.

                            uint status = UnsafeNativeMethods.SspiExcludePackage(ppAuthIdentity, "NTLM", out ppNewAuthIdentity);
                        }
                        else
                        {
                            ppNewAuthIdentity = ppAuthIdentity;
                        }

                        this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity);

                        if (IntPtr.Zero != ppNewAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity);
                        }

                        CloseContext();

                        MaxPromptAttempts++;
                        return this.GetOutgoingBlob(null, channelbinding, protectionPolicy);
                    }
                    else
                    {
                        // Call into SspiPromptForCredential had an error. Time to throw.
                        if (IntPtr.Zero != ppAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppAuthIdentity);
                        }

                        CloseContext();
                        this.isCompleted = true;
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)errorCode, SR.GetString(SR.SspiErrorOrInvalidClientCredentials)));
                    }
                }

                CloseContext();
                this.isCompleted = true;
                if (!this.isServer && (statusCode == (int)SecurityStatus.TargetUnknown
                    || statusCode == (int)SecurityStatus.WrongPrincipal))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.IncorrectSpnOrUpnSpecified, this.servicePrincipalName)));
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidSspiNegotiation)));
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                if (this.isServer)
                {
                    SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this);
                }
                else
                {
                    SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this);
                }
            }

            if (statusCode == (int)SecurityStatus.OK)
            {
                // we're done
                this.isCompleted = true;

                // These must all be true to check service binding
                // 1. we are the service (listener)
                // 2. caller is not anonymous
                // 3. protocol is not Kerberos
                // 4. policy is set to check service binding
                // 
                if (isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == 0) && (string.Compare(this.ProtocolName, NegotiationInfoClass.Kerberos, StringComparison.OrdinalIgnoreCase) != 0) && policyHelper.ShouldCheckServiceBinding)
                {
                    // in the server case the servicePrincipalName is the defaultServiceBinding
                   
                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        string serviceBindingNameSentByClient;
                        SspiWrapper.QuerySpecifiedTarget(securityContext, out serviceBindingNameSentByClient);
                        IMD.SecurityTraceRecordHelper.TraceServiceNameBindingOnServer( serviceBindingNameSentByClient, this.servicePrincipalName, policyHelper.ServiceNameCollection);
                    }
                    
                    policyHelper.CheckServiceBinding(this.securityContext, this.servicePrincipalName);
                }
            }
            else
            {
                // we need to continue
            }

            return outSecurityBuffer.token;
        }
 private static unsafe int MustRunInitializeSecurityContext(SafeFreeCredentials inCredentials, void* inContextPtr, byte* targetName, SspiContextFlags inFlags, Endianness endianness, SecurityBufferDescriptor inputBuffer, SafeDeleteContext outContext, SecurityBufferDescriptor outputBuffer, ref SspiContextFlags attributes, SafeFreeContextBuffer handleTemplate)
 {
     int num = -1;
     bool success = false;
     bool flag2 = false;
     RuntimeHelpers.PrepareConstrainedRegions();
     try
     {
         inCredentials.DangerousAddRef(ref success);
         outContext.DangerousAddRef(ref flag2);
     }
     catch (Exception exception)
     {
         if (success)
         {
             inCredentials.DangerousRelease();
             success = false;
         }
         if (flag2)
         {
             outContext.DangerousRelease();
             flag2 = false;
         }
         if (!(exception is ObjectDisposedException))
         {
             throw;
         }
     }
     finally
     {
         if (!success)
         {
             inCredentials = null;
         }
         else if (success && flag2)
         {
             long num2;
             num = InitializeSecurityContextW(ref inCredentials._handle, inContextPtr, targetName, inFlags, 0, endianness, inputBuffer, 0, ref outContext._handle, outputBuffer, ref attributes, out num2);
             if ((outContext._EffectiveCredential != inCredentials) && ((num & 0x80000000L) == 0L))
             {
                 if (outContext._EffectiveCredential != null)
                 {
                     outContext._EffectiveCredential.DangerousRelease();
                 }
                 outContext._EffectiveCredential = inCredentials;
             }
             else
             {
                 inCredentials.DangerousRelease();
             }
             outContext.DangerousRelease();
             if (handleTemplate != null)
             {
                 handleTemplate.Set(outputBuffer.UnmanagedPointer.token);
                 if (handleTemplate.IsInvalid)
                 {
                     handleTemplate.SetHandleAsInvalid();
                 }
             }
         }
         if ((inContextPtr == null) && ((num & 0x80000000L) != 0L))
         {
             outContext._handle.SetToInvalid();
         }
     }
     return num;
 }
예제 #25
0
 private static extern unsafe int AcceptSecurityContext(ref SSPIHandle credentialHandle, [In] void *inContextPtr, [In] SecurityBufferDescriptor inputBuffer, [In] SspiContextFlags inFlags, [In] Endianness endianness, ref SSPIHandle outContextPtr, [In][Out] SecurityBufferDescriptor outputBuffer, [In][Out] ref SspiContextFlags attributes, out long timestamp);
예제 #26
0
        public byte[] GetOutgoingBlob(byte[] incomingBlob, ChannelBinding channelbinding, ExtendedProtectionPolicy protectionPolicy)
        {
            ThrowIfDisposed();
            int statusCode = 0;

            // use the confidentiality option to ensure we can encrypt messages
            SspiContextFlags requestedFlags = SspiContextFlags.Confidentiality
                                              | SspiContextFlags.ReplayDetect
                                              | SspiContextFlags.SequenceDetect;

            if (this.doMutualAuth)
            {
                requestedFlags |= SspiContextFlags.MutualAuth;
            }

            if (this.impersonationLevel == TokenImpersonationLevel.Delegation)
            {
                requestedFlags |= SspiContextFlags.Delegate;
            }
            else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Identification)
            {
                requestedFlags |= SspiContextFlags.InitIdentify;
            }
            else if (this.isServer == false && this.impersonationLevel == TokenImpersonationLevel.Anonymous)
            {
                requestedFlags |= SspiContextFlags.InitAnonymous;
            }

            ExtendedProtectionPolicyHelper policyHelper = new ExtendedProtectionPolicyHelper(channelbinding, protectionPolicy);

            if (isServer)
            {
                if (policyHelper.PolicyEnforcement == PolicyEnforcement.Always && policyHelper.ChannelBinding == null && policyHelper.ProtectionScenario != ProtectionScenario.TrustedProxy)
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new SecurityTokenException(SR.GetString(SR.SecurityChannelBindingMissing)));
                }

                if (policyHelper.PolicyEnforcement == PolicyEnforcement.WhenSupported)
                {
                    requestedFlags |= SspiContextFlags.ChannelBindingAllowMissingBindings;
                }

                if (policyHelper.ProtectionScenario == ProtectionScenario.TrustedProxy)
                {
                    requestedFlags |= SspiContextFlags.ChannelBindingProxyBindings;
                }
            }

            List <SecurityBuffer> list = new List <SecurityBuffer>(2);

            if (incomingBlob != null)
            {
                list.Add(new SecurityBuffer(incomingBlob, BufferType.Token));
            }

            // when deciding if the channel binding should be added to the security buffer
            // it is necessary to differentiate between  client and server.
            // Server rules were added to policyHelper as they are shared with Kerb and I want them consistent
            // Client adds if not null.
            if (this.isServer)
            {
                if (policyHelper.ShouldAddChannelBindingToASC())
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }
            }
            else
            {
                if (policyHelper.ChannelBinding != null)
                {
                    list.Add(new SecurityBuffer(policyHelper.ChannelBinding));
                }
            }

            SecurityBuffer[] inSecurityBuffer = null;
            if (list.Count > 0)
            {
                inSecurityBuffer = list.ToArray();
            }

            SecurityBuffer outSecurityBuffer = new SecurityBuffer(this.tokenSize, BufferType.Token);

            if (!this.isServer)
            {
                //client session
                statusCode = SspiWrapper.InitializeSecurityContext(this.credentialsHandle,
                                                                   ref this.securityContext,
                                                                   this.servicePrincipalName,
                                                                   requestedFlags,
                                                                   Endianness.Network,
                                                                   inSecurityBuffer,
                                                                   outSecurityBuffer,
                                                                   ref this.contextFlags);
            }
            else
            {
                // server session
                //This check is to save an unnecessary ASC call.
                bool             isServerSecurityContextNull = this.securityContext == null;
                SspiContextFlags serverContextFlags          = this.contextFlags;

                statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle,
                                                               ref this.securityContext,
                                                               requestedFlags,
                                                               Endianness.Network,
                                                               inSecurityBuffer,
                                                               outSecurityBuffer,
                                                               ref this.contextFlags);

                if (statusCode == (int)SecurityStatus.InvalidToken && !isServerSecurityContextNull)
                {
                    // Call again into ASC after deleting the Securitycontext. If this securitycontext is not deleted
                    // then when the client sends NTLM blob the service will treat it as Nego2blob and will fail to authenticate the client.
                    this.contextFlags = serverContextFlags;
                    CloseContext();
                    statusCode = SspiWrapper.AcceptSecurityContext(this.credentialsHandle,
                                                                   ref this.securityContext,
                                                                   requestedFlags,
                                                                   Endianness.Network,
                                                                   inSecurityBuffer,
                                                                   outSecurityBuffer,
                                                                   ref this.contextFlags);
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                IMD.SecurityTraceRecordHelper.TraceChannelBindingInformation(policyHelper, this.isServer, channelbinding);
            }

            if ((statusCode & unchecked ((int)0x80000000)) != 0)
            {
                if (!this.isServer &&
                    this.interactiveNegoLogonEnabled &&
                    SecurityUtils.IsOSGreaterThanOrEqualToWin7() &&
                    SspiWrapper.IsSspiPromptingNeeded((uint)statusCode) &&
                    SspiWrapper.IsNegotiateExPackagePresent())
                {
                    // If we have prompted enough number of times (DefaultMaxPromptAttempts) with wrong credentials, then we do not prompt again and throw.
                    if (MaxPromptAttempts >= DefaultMaxPromptAttempts)
                    {
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidClientCredentials)));
                    }

                    IntPtr ppAuthIdentity = IntPtr.Zero;
                    uint   errorCode      = SspiWrapper.SspiPromptForCredential(this.servicePrincipalName, this.clientPackageName, out ppAuthIdentity, ref this.saveClientCredentialsOnSspiUi);
                    if (errorCode == (uint)CredentialStatus.Success)
                    {
                        IntPtr ppNewAuthIdentity = IntPtr.Zero;

                        if (!this.allowNtlm)
                        {
                            // When Ntlm is  explicitly disabled we don't want the collected
                            //creds from the Kerb/NTLM tile to be used for NTLM auth.

                            uint status = UnsafeNativeMethods.SspiExcludePackage(ppAuthIdentity, "NTLM", out ppNewAuthIdentity);
                        }
                        else
                        {
                            ppNewAuthIdentity = ppAuthIdentity;
                        }

                        this.credentialsHandle = SspiWrapper.AcquireCredentialsHandle(this.clientPackageName, CredentialUse.Outbound, ref ppNewAuthIdentity);

                        if (IntPtr.Zero != ppNewAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppNewAuthIdentity);
                        }

                        CloseContext();

                        MaxPromptAttempts++;
                        return(this.GetOutgoingBlob(null, channelbinding, protectionPolicy));
                    }
                    else
                    {
                        // Call into SspiPromptForCredential had an error. Time to throw.
                        if (IntPtr.Zero != ppAuthIdentity)
                        {
                            UnsafeNativeMethods.SspiFreeAuthIdentity(ppAuthIdentity);
                        }

                        CloseContext();
                        this.isCompleted = true;
                        throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception((int)errorCode, SR.GetString(SR.SspiErrorOrInvalidClientCredentials)));
                    }
                }

                CloseContext();
                this.isCompleted = true;
                if (!this.isServer && (statusCode == (int)SecurityStatus.TargetUnknown ||
                                       statusCode == (int)SecurityStatus.WrongPrincipal))
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.IncorrectSpnOrUpnSpecified, this.servicePrincipalName)));
                }
                else
                {
                    throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new Win32Exception(statusCode, SR.GetString(SR.InvalidSspiNegotiation)));
                }
            }

            if (DiagnosticUtility.ShouldTraceInformation)
            {
                if (this.isServer)
                {
                    SecurityTraceRecordHelper.TraceServiceOutgoingSpnego(this);
                }
                else
                {
                    SecurityTraceRecordHelper.TraceClientOutgoingSpnego(this);
                }
            }

            if (statusCode == (int)SecurityStatus.OK)
            {
                // we're done
                this.isCompleted = true;

                // These must all be true to check service binding
                // 1. we are the service (listener)
                // 2. caller is not anonymous
                // 3. protocol is not Kerberos
                // 4. policy is set to check service binding
                //
                if (isServer && ((this.contextFlags & SspiContextFlags.AcceptAnonymous) == 0) && (string.Compare(this.ProtocolName, NegotiationInfoClass.Kerberos, StringComparison.OrdinalIgnoreCase) != 0) && policyHelper.ShouldCheckServiceBinding)
                {
                    // in the server case the servicePrincipalName is the defaultServiceBinding

                    if (DiagnosticUtility.ShouldTraceInformation)
                    {
                        string serviceBindingNameSentByClient;
                        SspiWrapper.QuerySpecifiedTarget(securityContext, out serviceBindingNameSentByClient);
                        IMD.SecurityTraceRecordHelper.TraceServiceNameBindingOnServer(serviceBindingNameSentByClient, this.servicePrincipalName, policyHelper.ServiceNameCollection);
                    }

                    policyHelper.CheckServiceBinding(this.securityContext, this.servicePrincipalName);
                }
            }
            else
            {
                // we need to continue
            }

            return(outSecurityBuffer.token);
        }
예제 #27
0
 internal static extern unsafe int InitializeSecurityContextW(ref SSPIHandle credentialHandle, [In] void *inContextPtr, [In] byte *targetName, [In] SspiContextFlags inFlags, [In] int reservedI, [In] Endianness endianness, [In] SecurityBufferDescriptor inputBuffer, [In] int reservedII, ref SSPIHandle outContextPtr, [In][Out] SecurityBufferDescriptor outputBuffer, [In][Out] ref SspiContextFlags attributes, out long timestamp);
 internal static int AcceptSecurityContext(SafeFreeCredentials credential, ref SafeDeleteContext refContext, SspiContextFlags inFlags, Endianness datarep, SecurityBuffer[] inputBuffers, SecurityBuffer outputBuffer, ref SspiContextFlags outFlags)
 {
     return SafeDeleteContext.AcceptSecurityContext(credential, ref refContext, inFlags, datarep, null, inputBuffers, outputBuffer, ref outFlags);
 }
예제 #29
0
        //-------------------------------------------------------------------
        internal static unsafe int AcceptSecurityContext(
            SafeFreeCredentials inCredentials,
            ref SafeDeleteContext refContext,
            SspiContextFlags inFlags,
            Endianness endianness,
            SecurityBuffer inSecBuffer,
            SecurityBuffer[] inSecBuffers,
            SecurityBuffer outSecBuffer,
            ref SspiContextFlags outFlags)
        {

            if (inCredentials == null)
            {
                throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inCredentials");
            }

            SecurityBufferDescriptor inSecurityBufferDescriptor = null;
            if (inSecBuffer != null)
            {
                inSecurityBufferDescriptor = new SecurityBufferDescriptor(1);
            }
            else if (inSecBuffers != null)
            {
                inSecurityBufferDescriptor = new SecurityBufferDescriptor(inSecBuffers.Length);
            }
            SecurityBufferDescriptor outSecurityBufferDescriptor = new SecurityBufferDescriptor(1);

            // actually this is returned in outFlags
            bool isSspiAllocated = (inFlags & SspiContextFlags.AllocateMemory) != 0 ? true : false;

            int errorCode = -1;
            SSPIHandle contextHandle = new SSPIHandle();
            if (refContext != null)
            {
                contextHandle = refContext._handle;
            }

            // these are pinned user byte arrays passed along with SecurityBuffers
            GCHandle[] pinnedInBytes = null;
            GCHandle pinnedOutBytes = new GCHandle();
            // optional output buffer that may need to be freed
            SafeFreeContextBuffer outFreeContextBuffer = null;

            try
            {
                pinnedOutBytes = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned);

                SecurityBufferStruct[] inUnmanagedBuffer = new SecurityBufferStruct[inSecurityBufferDescriptor == null ? 1 : inSecurityBufferDescriptor.Count];
                fixed (void* inUnmanagedBufferPtr = inUnmanagedBuffer)
                {
                    if (inSecurityBufferDescriptor != null)
                    {
                        // Fix Descriptor pointer that points to unmanaged SecurityBuffers
                        inSecurityBufferDescriptor.UnmanagedPointer = inUnmanagedBufferPtr;
                        pinnedInBytes = new GCHandle[inSecurityBufferDescriptor.Count];
                        SecurityBuffer securityBuffer;
                        for (int index = 0; index < inSecurityBufferDescriptor.Count; ++index)
                        {
                            securityBuffer = inSecBuffer != null ? inSecBuffer : inSecBuffers[index];
                            if (securityBuffer != null)
                            {
                                // Copy the SecurityBuffer content into unmanaged place holder
                                inUnmanagedBuffer[index].count = securityBuffer.size;
                                inUnmanagedBuffer[index].type = securityBuffer.type;
                                // use the unmanaged token if it's not null; otherwise use the managed buffer
                                if (securityBuffer.unmanagedToken != null)
                                {
                                    inUnmanagedBuffer[index].token = securityBuffer.unmanagedToken.DangerousGetHandle();
                                }
                                else if (securityBuffer.token == null || securityBuffer.token.Length == 0)
                                {
                                    inUnmanagedBuffer[index].token = IntPtr.Zero;
                                }
                                else
                                {
                                    pinnedInBytes[index] = GCHandle.Alloc(securityBuffer.token, GCHandleType.Pinned);
                                    inUnmanagedBuffer[index].token = Marshal.UnsafeAddrOfPinnedArrayElement(securityBuffer.token, securityBuffer.offset);
                                }
                            }
                        }
                    }
                    SecurityBufferStruct[] outUnmanagedBuffer = new SecurityBufferStruct[1];
                    fixed (void* outUnmanagedBufferPtr = outUnmanagedBuffer)
                    {
                        // Fix Descriptor pointer that points to unmanaged SecurityBuffers
                        outSecurityBufferDescriptor.UnmanagedPointer = outUnmanagedBufferPtr;
                        // Copy the SecurityBuffer content into unmanaged place holder
                        outUnmanagedBuffer[0].count = outSecBuffer.size;
                        outUnmanagedBuffer[0].type = outSecBuffer.type;
                        if (outSecBuffer.token == null || outSecBuffer.token.Length == 0)
                        {
                            outUnmanagedBuffer[0].token = IntPtr.Zero;
                        }
                        else
                        {
                            outUnmanagedBuffer[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset);
                        }
                        if (isSspiAllocated)
                        {
                            outFreeContextBuffer = SafeFreeContextBuffer.CreateEmptyHandle();
                        }

                        if (refContext == null || refContext.IsInvalid)
                        {
                            refContext = new SafeDeleteContext();
                        }
                        errorCode = MustRunAcceptSecurityContext(
                            inCredentials,
                            contextHandle.IsZero ? null : &contextHandle,
                            inSecurityBufferDescriptor,
                            inFlags,
                            endianness,
                            refContext,
                            outSecurityBufferDescriptor,
                            ref outFlags,
                            outFreeContextBuffer
                            );

                        // Get unmanaged buffer with index 0 as the only one passed into PInvoke
                        outSecBuffer.size = outUnmanagedBuffer[0].count;
                        outSecBuffer.type = outUnmanagedBuffer[0].type;
                        if (outSecBuffer.size > 0)
                        {
                            outSecBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(outSecBuffer.size);
                            Marshal.Copy(outUnmanagedBuffer[0].token, outSecBuffer.token, 0, outSecBuffer.size);
                        }
                        else
                        {
                            outSecBuffer.token = null;
                        }
                    }
                }
            }
            finally
            {
                if (pinnedInBytes != null)
                {
                    for (int index = 0; index < pinnedInBytes.Length; index++)
                    {
                        if (pinnedInBytes[index].IsAllocated)
                        {
                            pinnedInBytes[index].Free();
                        }
                    }
                }
                if (pinnedOutBytes.IsAllocated)
                {
                    pinnedOutBytes.Free();
                }
                if (outFreeContextBuffer != null)
                {
                    outFreeContextBuffer.Close();
                }
            }

            return errorCode;
        }
예제 #30
0
        private static unsafe int MustRunInitializeSecurityContext(SafeFreeCredentials inCredentials, void *inContextPtr, byte *targetName, SspiContextFlags inFlags, Endianness endianness, SecurityBufferDescriptor inputBuffer, SafeDeleteContext outContext, SecurityBufferDescriptor outputBuffer, ref SspiContextFlags attributes, SafeFreeContextBuffer handleTemplate)
        {
            int  num     = -1;
            bool success = false;
            bool flag2   = false;

            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                inCredentials.DangerousAddRef(ref success);
                outContext.DangerousAddRef(ref flag2);
            }
            catch (Exception exception)
            {
                if (success)
                {
                    inCredentials.DangerousRelease();
                    success = false;
                }
                if (flag2)
                {
                    outContext.DangerousRelease();
                    flag2 = false;
                }
                if (!(exception is ObjectDisposedException))
                {
                    throw;
                }
            }
            finally
            {
                if (!success)
                {
                    inCredentials = null;
                }
                else if (success && flag2)
                {
                    long num2;
                    num = InitializeSecurityContextW(ref inCredentials._handle, inContextPtr, targetName, inFlags, 0, endianness, inputBuffer, 0, ref outContext._handle, outputBuffer, ref attributes, out num2);
                    if ((outContext._EffectiveCredential != inCredentials) && ((num & 0x80000000L) == 0L))
                    {
                        if (outContext._EffectiveCredential != null)
                        {
                            outContext._EffectiveCredential.DangerousRelease();
                        }
                        outContext._EffectiveCredential = inCredentials;
                    }
                    else
                    {
                        inCredentials.DangerousRelease();
                    }
                    outContext.DangerousRelease();
                    if (handleTemplate != null)
                    {
                        handleTemplate.Set(outputBuffer.UnmanagedPointer.token);
                        if (handleTemplate.IsInvalid)
                        {
                            handleTemplate.SetHandleAsInvalid();
                        }
                    }
                }
                if ((inContextPtr == null) && ((num & 0x80000000L) != 0L))
                {
                    outContext._handle.SetToInvalid();
                }
            }
            return(num);
        }
예제 #31
0
 public static extern uint InitializeSecurityContext(
     ref SspiHandle credentialHandle,
     ref SspiHandle inContextHandle,
     string targetName,
     SspiContextFlags flags,
     int reserved1,
     DataRepresentation dataRepresentation,
     ref SecurityBufferDescriptor inputBuffer,
     int reserved2,
     ref SspiHandle outContext,
     ref SecurityBufferDescriptor outputBuffer,
     out SspiContextFlags outAttributes,
     out long timestamp);
예제 #32
0
        // After PINvoke call the method will fix the handleTemplate.handle with the returned value.
        // The caller is responsible for creating a correct SafeFreeContextBuffer_XXX flavour or null can be passed if no handle is returned.
        // This method is run as non-interruptible.
        static unsafe int MustRunAcceptSecurityContext(
            SafeFreeCredentials inCredentials,
            void* inContextPtr,
            SecurityBufferDescriptor inputBuffer,
            SspiContextFlags inFlags,
            Endianness endianness,
            SafeDeleteContext outContext,
            SecurityBufferDescriptor outputBuffer,
            ref SspiContextFlags outFlags,
            SafeFreeContextBuffer handleTemplate)
        {
            int errorCode = -1;
            bool b1 = false;
            bool b2 = false;

            // Run the body of this method as a non-interruptible block.
            RuntimeHelpers.PrepareConstrainedRegions();

            try
            {
                inCredentials.DangerousAddRef(ref b1);
                outContext.DangerousAddRef(ref b2);
            }
            catch (Exception e)
            {
                if (System.Runtime.Fx.IsFatal(e))
                    throw;
                
                if (b1)
                {
                    inCredentials.DangerousRelease();
                    b1 = false;
                }
                if (b2)
                {
                    outContext.DangerousRelease();
                    b2 = false;
                }
                if (!(e is ObjectDisposedException))
                    throw;
            }
            finally
            {
                long timeStamp;
                if (!b1)
                {
                    // caller should retry
                    inCredentials = null;
                }
                else if (b1 && b2)
                {

                    SSPIHandle credentialHandle = inCredentials._handle;
                    // PreSharp Bug: Call 'Marshal.GetLastWin32Error' or 'Marshal.GetHRForLastWin32Error' before any other interop call. 
#pragma warning suppress 56523 // This API does not set Win32 Last Error.
                    errorCode = AcceptSecurityContext(
                        ref credentialHandle,
                        inContextPtr,
                        inputBuffer,
                        inFlags,
                        endianness,
                        ref outContext._handle,
                        outputBuffer,
                        ref outFlags,
                        out timeStamp
                        );

                    //
                    // When a credential handle is first associated with the context we keep credential
                    // ref count bumped up to ensure ordered finalization.
                    // If the credential handle has been changed we de-ref the old one and associate the
                    //  context with the new cred handle but only if the call was successful.
                    if (outContext._EffectiveCredential != inCredentials && (errorCode & 0x80000000) == 0)
                    {
                        // Disassociate the previous credential handle
                        if (outContext._EffectiveCredential != null)
                            outContext._EffectiveCredential.DangerousRelease();
                        outContext._EffectiveCredential = inCredentials;
                    }
                    else
                    {
                        inCredentials.DangerousRelease();
                    }

                    outContext.DangerousRelease();

                    // The idea is that SSPI has allocated a block and filled up outUnmanagedBuffer+8 slot with the pointer.
                    if (handleTemplate != null)
                    {
                        handleTemplate.Set(((SecurityBufferStruct*)outputBuffer.UnmanagedPointer)->token); //ATTN: on 64 BIT that is still +8 cause of 2* c++ unsigned long == 8 bytes
                        if (handleTemplate.IsInvalid)
                        {
                            handleTemplate.SetHandleAsInvalid();
                        }
                    }
                    if (inContextPtr == null && (errorCode & 0x80000000) != 0)
                    {
                        // an error on the first call, need to set the out handle to invalid value
                        outContext._handle.SetToInvalid();
                    }
                }
            }
            return errorCode;
        }
 static TlsSspiNegotiation()
 {
     StandardFlags = SspiContextFlags.ReplayDetect | SspiContextFlags.Confidentiality | SspiContextFlags.AllocateMemory;
     ServerStandardFlags = StandardFlags | SspiContextFlags.AcceptExtendedError | SspiContextFlags.AcceptStream;
     ClientStandardFlags = StandardFlags | SspiContextFlags.InitManualCredValidation | SspiContextFlags.InitStream;
 }
 internal static unsafe int InitializeSecurityContext(SafeFreeCredentials inCredentials, ref SafeDeleteContext refContext, string targetName, SspiContextFlags inFlags, Endianness endianness, SecurityBuffer inSecBuffer, SecurityBuffer[] inSecBuffers, SecurityBuffer outSecBuffer, ref SspiContextFlags outFlags)
 {
     if (inCredentials == null)
     {
         throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("inCredentials");
     }
     SecurityBufferDescriptor inputBuffer = null;
     if (inSecBuffer != null)
     {
         inputBuffer = new SecurityBufferDescriptor(1);
     }
     else if (inSecBuffers != null)
     {
         inputBuffer = new SecurityBufferDescriptor(inSecBuffers.Length);
     }
     SecurityBufferDescriptor outputBuffer = new SecurityBufferDescriptor(1);
     bool flag = (inFlags & SspiContextFlags.AllocateMemory) != SspiContextFlags.Zero;
     int num = -1;
     SSPIHandle handle = new SSPIHandle();
     if (refContext != null)
     {
         handle = refContext._handle;
     }
     GCHandle[] handleArray = null;
     GCHandle handle2 = new GCHandle();
     SafeFreeContextBuffer handleTemplate = null;
     try
     {
         handle2 = GCHandle.Alloc(outSecBuffer.token, GCHandleType.Pinned);
         SecurityBufferStruct[] structArray = new SecurityBufferStruct[(inputBuffer == null) ? 1 : inputBuffer.Count];
         try
         {
             SecurityBufferStruct[] structArray3;
             if (((structArray3 = structArray) == null) || (structArray3.Length == 0))
             {
                 ptrRef = null;
                 goto Label_00A9;
             }
             fixed (IntPtr* ptrRef = structArray3)
             {
             Label_00A9:
                 if (inputBuffer != null)
                 {
                     inputBuffer.UnmanagedPointer = (void*) ptrRef;
                     handleArray = new GCHandle[inputBuffer.Count];
                     for (int i = 0; i < inputBuffer.Count; i++)
                     {
                         SecurityBuffer buffer2 = (inSecBuffer != null) ? inSecBuffer : inSecBuffers[i];
                         if (buffer2 != null)
                         {
                             structArray[i].count = buffer2.size;
                             structArray[i].type = buffer2.type;
                             if (buffer2.unmanagedToken != null)
                             {
                                 structArray[i].token = buffer2.unmanagedToken.DangerousGetHandle();
                             }
                             else if ((buffer2.token == null) || (buffer2.token.Length == 0))
                             {
                                 structArray[i].token = IntPtr.Zero;
                             }
                             else
                             {
                                 handleArray[i] = GCHandle.Alloc(buffer2.token, GCHandleType.Pinned);
                                 structArray[i].token = Marshal.UnsafeAddrOfPinnedArrayElement(buffer2.token, buffer2.offset);
                             }
                         }
                     }
                 }
                 SecurityBufferStruct[] structArray2 = new SecurityBufferStruct[1];
                 try
                 {
                     SecurityBufferStruct[] structArray4;
                     if (((structArray4 = structArray2) == null) || (structArray4.Length == 0))
                     {
                         ptrRef2 = null;
                         goto Label_01CF;
                     }
                     fixed (IntPtr* ptrRef2 = structArray4)
                     {
                     Label_01CF:
                         outputBuffer.UnmanagedPointer = (void*) ptrRef2;
                         structArray2[0].count = outSecBuffer.size;
                         structArray2[0].type = outSecBuffer.type;
                         if ((outSecBuffer.token == null) || (outSecBuffer.token.Length == 0))
                         {
                             structArray2[0].token = IntPtr.Zero;
                         }
                         else
                         {
                             structArray2[0].token = Marshal.UnsafeAddrOfPinnedArrayElement(outSecBuffer.token, outSecBuffer.offset);
                         }
                         if (flag)
                         {
                             handleTemplate = SafeFreeContextBuffer.CreateEmptyHandle();
                         }
                         if ((refContext == null) || refContext.IsInvalid)
                         {
                             refContext = new SafeDeleteContext();
                         }
                         if ((targetName == null) || (targetName.Length == 0))
                         {
                             targetName = " ";
                         }
                         fixed (char* str = ((char*) targetName))
                         {
                             char* chPtr = str;
                             num = MustRunInitializeSecurityContext(inCredentials, handle.IsZero ? null : ((void*) &handle), (targetName == " ") ? null : ((byte*) chPtr), inFlags, endianness, inputBuffer, refContext, outputBuffer, ref outFlags, handleTemplate);
                         }
                         outSecBuffer.size = structArray2[0].count;
                         outSecBuffer.type = structArray2[0].type;
                         if (outSecBuffer.size > 0)
                         {
                             outSecBuffer.token = DiagnosticUtility.Utility.AllocateByteArray(outSecBuffer.size);
                             Marshal.Copy(structArray2[0].token, outSecBuffer.token, 0, outSecBuffer.size);
                             return num;
                         }
                         outSecBuffer.token = null;
                         return num;
                     }
                 }
                 finally
                 {
                     ptrRef2 = null;
                 }
                 return num;
             }
         }
         finally
         {
             ptrRef = null;
         }
     }
     finally
     {
         if (handleArray != null)
         {
             for (int j = 0; j < handleArray.Length; j++)
             {
                 if (handleArray[j].IsAllocated)
                 {
                     handleArray[j].Free();
                 }
             }
         }
         if (handle2.IsAllocated)
         {
             handle2.Free();
         }
         if (handleTemplate != null)
         {
             handleTemplate.Close();
         }
     }
     return num;
 }