예제 #1
0
        private void GetMaxTokenSize()
        {
            int count;
            SafeContextBufferHandle secPkgInfos;

            if (Sspi.EnumerateSecurityPackages(out count, out secPkgInfos) != SecurityStatus.SEC_E_OK)
            {
                throw new Win32Exception("Failed to EnumerateSecurityPackages");
            }

            for (int i = 0; i < count; i++)
            {
                var item = secPkgInfos.GetItem <SecPkgInfo>(i);
                if (string.Compare(item.GetName(), @"Schannel", true) == 0)
                {
                    maxTokenSize = item.cbMaxToken;
                    break;
                }
            }

            if (maxTokenSize == 0)
            {
                throw new Exception("Failed to retrive cbMaxToken for Schannel");
            }
        }
예제 #2
0
        public override void Start()
        {
            long num;

            Sspi.AcquireCredentialsHandle(CredentialUse.SECPKG_CRED_INBOUND, new SchannelCred(this.certificate, SchProtocols.TlsServer), out this.credential, out num);
            this.GetMaxTokenSize();
            base.Start();
        }
        public SipMicrosoftAuthentication(AuthSchemes scheme, IAccounts accounts, IUserz userz)
        {
            this.scheme   = scheme;
            this.accounts = accounts;
            this.userz    = userz;

            this.connectingAssociations = new ThreadSafe.Dictionary <int, SecurityAssociation>(new Dictionary <int, SecurityAssociation>());

            this.timer      = new Timer(RemoveExpiredSecurityAssociationsTimer, null, 0, 60 * 1000);
            this.credHandle = Sspi.SafeAcquireCredentialsHandle(scheme.ToString(), CredentialUse.SECPKG_CRED_BOTH);
        }
예제 #4
0
        public override void Start()
        {
            long expiry;

            Sspi.AcquireCredentialsHandle(
                CredentialUse.SECPKG_CRED_INBOUND,
                new SchannelCred(certificate, SchProtocols.TlsServer),
                out credential,
                out expiry);

            GetMaxTokenSize();

            base.Start();
        }
            public bool Authentication(SafeCredHandle credHandle, Methods method, byte[] realm, byte[] inToken, out ArraySegment <byte> outToken)
            {
                //idleTime = DateTime.UtcNow.AddMinutes(IdleMinutes);

                InitializeThreadStaticVars();

                secBufferDesc1.Buffers[0].SetBuffer(BufferType.SECBUFFER_TOKEN, inToken);
                secBufferDesc1.Buffers[1].SetBuffer(BufferType.SECBUFFER_PKG_PARAMS, method.ToByteArrayPart().Bytes);
                secBufferDesc1.Buffers[2].SetBuffer(BufferType.SECBUFFER_PKG_PARAMS, new byte[0]);
                secBufferDesc1.Buffers[3].SetBuffer(BufferType.SECBUFFER_PKG_PARAMS, new byte[0]);
                secBufferDesc1.Buffers[4].SetBuffer(BufferType.SECBUFFER_PKG_PARAMS, realm);
                secBufferDesc1.Buffers[5].SetBuffer(BufferType.SECBUFFER_CHANNEL_BINDINGS, new byte[0]);

                secBufferDesc2.Buffers[0].SetBuffer(BufferType.SECBUFFER_TOKEN, bytes1);
                secBufferDesc2.Buffers[1].SetBufferEmpty();

                var newHandle = (contextHandle.IsInvalid) ? new SafeCtxtHandle() : contextHandle;

                var result = Sspi.SafeAcceptSecurityContext(
                    ref credHandle,
                    ref contextHandle,
                    ref secBufferDesc1,
                    0,
                    TargetDataRep.SECURITY_NETWORK_DREP,
                    ref newHandle,
                    ref secBufferDesc2);

                Tracer.WriteInformation("SSPI Digest Auth: " + result.ToString());

                if (contextHandle.IsInvalid && newHandle.IsInvalid == false)
                {
                    contextHandle = newHandle;
                }

                if (result == SecurityStatus.SEC_E_OK)
                {
                    outToken = new ArraySegment <byte>();
                    isAuthenticationComplete = true;

                    return(true);
                }
                else
                {
                    outToken = new ArraySegment <byte>();
                    return(false);
                }
            }
            public void SignMessage(SipMessageWriter writer)
            {
                outSnum++;
                int srand2 = Environment.TickCount;

                InitializeThreadStaticVars();

                int length = SignatureBuffer.Generate(scheme, srand2, outSnum, targetname, writer, ref bytes1);

                if (bytes2.Length < maxSignatureSize)
                {
                    bytes2 = new byte[maxSignatureSize];
                }

                secBufferDesc1.Buffers[0].SetBuffer(BufferType.SECBUFFER_DATA, bytes1, 0, length);
                secBufferDesc1.Buffers[1].SetBuffer(BufferType.SECBUFFER_TOKEN, bytes2);

                var result = Sspi.SafeMakeSignature(contextHandle, ref secBufferDesc1, 100);

                Tracer.WriteInformation("Signature: " + result.ToString());

                if (Sspi.Succeeded(result))
                {
                    writer.WriteAuthenticationInfo(true, scheme, targetname, realm, Opaque, outSnum, srand2,
                                                   new ArraySegment <byte>(bytes2, 0, secBufferDesc1.Buffers[1].Size));

                    if (writer.IsResponse && writer.StatusCode >= 200 && writer.StatusCode <= 299)
                    {
                        if (writer.Method == Methods.Registerm && writer.Expires != int.MinValue)
                        {
                            idleTime = DateTime.UtcNow.AddSeconds(writer.Expires + 30);
                            idleTimeUpdatedByExpires = true;
                        }
                    }
                    else
                    {
                        // TODO: INVITE Session-Expires
                    }
                }
            }
예제 #7
0
        private void GetMaxTokenSize()
        {
            int num;
            SafeContextBufferHandle safeContextBufferHandle;

            if (Sspi.EnumerateSecurityPackages(out num, out safeContextBufferHandle) != SecurityStatus.SEC_E_OK)
            {
                throw new Win32Exception("Failed to EnumerateSecurityPackages");
            }
            for (int i = 0; i < num; i++)
            {
                SecPkgInfo item = safeContextBufferHandle.GetItem <SecPkgInfo>(i);
                if (string.Compare(item.GetName(), "Schannel", true) == 0)
                {
                    this.maxTokenSize = item.cbMaxToken;
                    break;
                }
            }
            if (this.maxTokenSize == 0)
            {
                throw new Exception("Failed to retrive cbMaxToken for Schannel");
            }
        }
        private static MaxTokenSizes GetMaxTokenSizes()
        {
            int count;
            SafeContextBufferHandle secPkgInfos;

            if (Sspi.EnumerateSecurityPackages(out count, out secPkgInfos) != SecurityStatus.SEC_E_OK)
            {
                throw new Win32Exception("Failed to EnumerateSecurityPackages");
            }

            int ntlm = 0, kerberos = 0;

            for (int i = 0; i < count; i++)
            {
                var item = secPkgInfos.GetItem <SecPkgInfo>(i);

                if (string.Compare(item.GetName(), @"NTLM", true) == 0)
                {
                    ntlm = item.cbMaxToken;
                }
                if (string.Compare(item.GetName(), @"Kerberos", true) == 0)
                {
                    kerberos = item.cbMaxToken;
                }
            }

            if (ntlm == 0)
            {
                throw new Exception(@"Failed to retrive cbMaxToken for NTLM");
            }
            if (kerberos == 0)
            {
                throw new Exception(@"Failed to retrive cbMaxToken for Kerberos");
            }

            return(new MaxTokenSizes(ntlm, kerberos));
        }
            public ErrorCodes Authentication(SafeCredHandle credHandle, byte[] inToken, out ArraySegment <byte> outToken)
            {
                idleTime = DateTime.UtcNow.AddMinutes(IdleMinutes);

                InitializeThreadStaticVars();

                secBufferDesc1.Buffers[0].SetBuffer(BufferType.SECBUFFER_TOKEN, inToken);
                secBufferDesc1.Buffers[1].SetBufferEmpty();

                secBufferDesc2.Buffers[0].SetBuffer(BufferType.SECBUFFER_TOKEN, bytes1);
                secBufferDesc2.Buffers[1].SetBufferEmpty();

                var newHandle = (contextHandle.IsInvalid) ? new SafeCtxtHandle() : contextHandle;

                var result = Sspi.SafeAcceptSecurityContext(
                    ref credHandle,
                    ref contextHandle,
                    ref secBufferDesc1,
                    (int)(ContextReq.ASC_REQ_INTEGRITY | ContextReq.ASC_REQ_IDENTIFY |
                          ((scheme == AuthSchemes.Ntlm) ? ContextReq.ASC_REQ_DATAGRAM : ContextReq.ASC_REQ_MUTUAL_AUTH)),
                    TargetDataRep.SECURITY_NETWORK_DREP,
                    ref newHandle,
                    ref secBufferDesc2);

                Tracer.WriteInformation("Auth: " + result.ToString());

                if (contextHandle.IsInvalid && newHandle.IsInvalid == false)
                {
                    contextHandle = newHandle;
                }

                if (result == SecurityStatus.SEC_E_OK)
                {
                    outToken = new ArraySegment <byte>();
                    isAuthenticationComplete = true;

                    SecPkgContext_Sizes sizes;
                    if (Sspi.Failed(Sspi.SafeQueryContextAttributes(ref contextHandle, out sizes)))
                    {
                        return(ErrorCodes.QueryContextAttributesForSizesFailed);
                    }
                    maxSignatureSize = sizes.cbMaxSignature;

                    if (Sspi.Failed(Sspi.SafeQueryContextAttributes(ref contextHandle, out userName)))
                    {
                        return(ErrorCodes.QueryContextAttributesForUsernameFailed);
                    }

                    int slash = userName.IndexOf('\\');
                    if (slash >= 0)
                    {
                        userName = userName.Substring(slash + 1);
                    }

                    Tracer.WriteInformation("Username: " + userName);

                    expireTime = DateTime.UtcNow.AddHours(ExpirationHours);

                    return(ErrorCodes.Ok);
                }
                else if (result == SecurityStatus.SEC_I_CONTINUE_NEEDED)
                {
                    outToken = new ArraySegment <byte>(bytes1, 0, secBufferDesc2.Buffers[0].Size);
                    return(ErrorCodes.Continue);
                }
                else
                {
                    outToken = new ArraySegment <byte>();
                    return(ErrorCodes.SecurityViolation);
                }
            }
 public SspiDigestAuthorizationManager()
 {
     this.credHandle = Sspi.SafeAcquireCredentialsHandle(AuthSchemes.Digest.ToString(), CredentialUse.SECPKG_CRED_BOTH);
 }
 public InitializeStep(string servicePrincipalName, string authorizationId, Sspi.SecurityContext context, byte[] bytesToSendToServer)
 {
     _servicePrincipalName = servicePrincipalName;
     _authorizationId = authorizationId;
     _context = context;
     _bytesToSendToServer = bytesToSendToServer ?? new byte[0];
 }
예제 #12
0
        private bool Handshake(ServerAsyncEventArgs ie, Server <C> .Connection <C> connection)
        {
            int num = 0;
            ServerAsyncEventArgs serverAsyncEventArgs = null;
            SspiContext          sspiContext          = connection.SspiContext;
            SecBufferDescEx      secBufferDescEx      = sspiContext.SecBufferDesc2[0];
            SecBufferDescEx      secBufferDescEx2     = sspiContext.SecBufferDesc2[1];
            bool result;

            try
            {
                if (sspiContext.Buffer.IsValid && ie != null && !sspiContext.Buffer.CopyTransferredFrom(ie, 0))
                {
                    result = false;
                }
                else
                {
                    while (true)
                    {
                        secBufferDescEx.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN;
                        if (sspiContext.Buffer.IsValid)
                        {
                            this.SetSecBuffer(ref secBufferDescEx.Buffers[0], sspiContext);
                        }
                        else
                        {
                            this.SetSecBuffer(ref secBufferDescEx.Buffers[0], ie);
                        }
                        secBufferDescEx.Buffers[1].SetBufferEmpty();
                        if (serverAsyncEventArgs == null)
                        {
                            serverAsyncEventArgs = EventArgsManager.Get();
                        }
                        serverAsyncEventArgs.AllocateBuffer();
                        secBufferDescEx2.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN;
                        secBufferDescEx2.Buffers[0].Size       = serverAsyncEventArgs.Count;
                        secBufferDescEx2.Buffers[0].Buffer     = serverAsyncEventArgs.Buffer;
                        secBufferDescEx2.Buffers[0].Offset     = serverAsyncEventArgs.Offset;
                        secBufferDescEx2.Buffers[1].SetBufferEmpty();
                        int            contextReq = 98332;
                        SafeCtxtHandle handle     = sspiContext.Handle.IsInvalid ? new SafeCtxtHandle() : sspiContext.Handle;
                        long           num2;
                        SecurityStatus securityStatus = Sspi.SafeAcceptSecurityContext(ref this.credential, ref sspiContext.Handle, ref secBufferDescEx, contextReq, TargetDataRep.SECURITY_NATIVE_DREP, ref handle, ref secBufferDescEx2, out num, out num2);
                        if (sspiContext.Handle.IsInvalid)
                        {
                            sspiContext.Handle = handle;
                        }
                        SecurityStatus securityStatus2 = securityStatus;
                        if (securityStatus2 == (SecurityStatus)2148074264u)
                        {
                            break;
                        }
                        if (securityStatus2 != (SecurityStatus)2148074273u)
                        {
                            if ((securityStatus == SecurityStatus.SEC_I_CONTINUE_NEEDED || securityStatus == SecurityStatus.SEC_E_OK || (Sspi.Failed(securityStatus) && (num & 32768) != 0)) && secBufferDescEx2.Buffers[0].Size > 0)
                            {
                                serverAsyncEventArgs.Count = secBufferDescEx2.Buffers[0].Size;
                                serverAsyncEventArgs.CopyAddressesFrom(ie);
                                serverAsyncEventArgs.LocalEndPoint = base.GetLocalEndpoint(ie.RemoteEndPoint.Address);
                                base.SendAsync(connection, serverAsyncEventArgs);
                                serverAsyncEventArgs = null;
                            }
                            int bufferIndex = secBufferDescEx.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0);
                            if (bufferIndex < 0)
                            {
                                sspiContext.Buffer.Free();
                            }
                            else if (sspiContext.Buffer.IsInvalid)
                            {
                                if (!sspiContext.Buffer.CopyTransferredFrom(ie, ie.BytesTransferred - secBufferDescEx.Buffers[bufferIndex].Size))
                                {
                                    goto Block_21;
                                }
                            }
                            else
                            {
                                sspiContext.Buffer.MoveToBegin(sspiContext.Buffer.BytesTransferred - secBufferDescEx.Buffers[bufferIndex].Size, secBufferDescEx.Buffers[bufferIndex].Size);
                            }
                            SecurityStatus securityStatus3 = securityStatus;
                            if (securityStatus3 == SecurityStatus.SEC_E_OK)
                            {
                                goto IL_2FF;
                            }
                            if (securityStatus3 != SecurityStatus.SEC_I_CONTINUE_NEEDED)
                            {
                                goto Block_23;
                            }
                            if (bufferIndex < 0)
                            {
                                goto Block_25;
                            }
                        }
                        else
                        {
                            if (serverAsyncEventArgs.Count >= this.maxTokenSize)
                            {
                                goto IL_1DC;
                            }
                            serverAsyncEventArgs.Count = this.maxTokenSize;
                            serverAsyncEventArgs.ReAllocateBuffer(false);
                        }
                    }
                    if (sspiContext.Buffer.IsInvalid && !sspiContext.Buffer.CopyTransferredFrom(ie, 0))
                    {
                        result = false;
                        return(result);
                    }
                    result = true;
                    return(result);

IL_1DC:
                    result = false;
                    return(result);

Block_21:
                    result = false;
                    return(result);

Block_23:
                    result = false;
                    return(result);

IL_2FF:
                    if (Sspi.SafeQueryContextAttributes(ref sspiContext.Handle, out sspiContext.StreamSizes) != SecurityStatus.SEC_E_OK)
                    {
                        result = false;
                        return(result);
                    }
                    sspiContext.Connected = true;
                    this.OnNewConnection(connection);
                    result = true;
                    return(result);

Block_25:
                    result = true;
                }
            }
            finally
            {
                if (serverAsyncEventArgs != null)
                {
                    EventArgsManager.Put(ref serverAsyncEventArgs);
                }
            }
            return(result);
        }
예제 #13
0
        private bool DecryptData(ref ServerAsyncEventArgs e, Server <C> .Connection <C> connection)
        {
            SspiContext     sspiContext   = connection.SspiContext;
            SecBufferDescEx secBufferDesc = sspiContext.SecBufferDesc5;

            if (sspiContext.Buffer.IsValid && e != null && !sspiContext.Buffer.CopyTransferredFrom(e, 0))
            {
                return(false);
            }
            SecurityStatus securityStatus2;

            while (true)
            {
                secBufferDesc.Buffers[0].BufferType = BufferType.SECBUFFER_DATA;
                if (sspiContext.Buffer.IsValid)
                {
                    this.SetSecBuffer(ref secBufferDesc.Buffers[0], sspiContext);
                }
                else
                {
                    this.SetSecBuffer(ref secBufferDesc.Buffers[0], e);
                }
                secBufferDesc.Buffers[1].SetBufferEmpty();
                secBufferDesc.Buffers[2].SetBufferEmpty();
                secBufferDesc.Buffers[3].SetBufferEmpty();
                secBufferDesc.Buffers[4].SetBufferEmpty();
                SecurityStatus securityStatus = Sspi.SafeDecryptMessage(ref sspiContext.Handle, ref secBufferDesc, 0u, null);
                int            bufferIndex    = secBufferDesc.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0);
                int            bufferIndex2   = secBufferDesc.GetBufferIndex(BufferType.SECBUFFER_DATA, 0);
                securityStatus2 = securityStatus;
                if (securityStatus2 != SecurityStatus.SEC_E_OK)
                {
                    break;
                }
                if (bufferIndex2 < 0)
                {
                    return(false);
                }
                if (sspiContext.Buffer.IsInvalid)
                {
                    if (bufferIndex >= 0 && !sspiContext.Buffer.CopyFrom(secBufferDesc.Buffers[bufferIndex]))
                    {
                        return(false);
                    }
                    e.Offset           = secBufferDesc.Buffers[bufferIndex2].Offset;
                    e.BytesTransferred = secBufferDesc.Buffers[bufferIndex2].Size;
                    e.SetMaxCount();
                    if (!this.OnReceived(connection, ref e))
                    {
                        return(false);
                    }
                }
                else
                {
                    ArraySegment <byte> buffer = sspiContext.Buffer.Detach();
                    if (bufferIndex >= 0 && !sspiContext.Buffer.CopyFrom(secBufferDesc.Buffers[bufferIndex]))
                    {
                        return(false);
                    }
                    ServerAsyncEventArgs serverAsyncEventArgs = EventArgsManager.Get();
                    base.PrepareEventArgs(connection, serverAsyncEventArgs);
                    serverAsyncEventArgs.AttachBuffer(buffer);
                    serverAsyncEventArgs.Offset           = secBufferDesc.Buffers[bufferIndex2].Offset;
                    serverAsyncEventArgs.BytesTransferred = secBufferDesc.Buffers[bufferIndex2].Size;
                    serverAsyncEventArgs.SetMaxCount();
                    bool flag = this.OnReceived(connection, ref serverAsyncEventArgs);
                    if (serverAsyncEventArgs != null)
                    {
                        EventArgsManager.Put(serverAsyncEventArgs);
                    }
                    if (!flag)
                    {
                        return(false);
                    }
                }
                if (bufferIndex < 0)
                {
                    return(true);
                }
            }
            return(securityStatus2 != SecurityStatus.SEC_I_RENEGOTIATE && securityStatus2 == (SecurityStatus)2148074264u && (!sspiContext.Buffer.IsInvalid || sspiContext.Buffer.CopyTransferredFrom(e, 0)));
        }
예제 #14
0
        public override unsafe void SendAsync(ServerAsyncEventArgs e)
        {
            try
            {
                var connection = GetTcpConnection(e.RemoteEndPoint);

                OnBeforeSend(connection, e);

                if (connection == null)
                {
                    e.Completed   = Send_Completed;
                    e.SocketError = SocketError.NotConnected;
                    e.OnCompleted(null);
                    return;
                }

                var context = connection.SspiContext;
                var sizes   = context.StreamSizes;

                var dataCount = e.Count;

                if (e.OffsetOffset >= sizes.cbHeader)
                {
                    e.OffsetOffset -= sizes.cbHeader;
                    e.Count         = sizes.cbHeader + dataCount + sizes.cbTrailer;
                    e.ReAllocateBuffer(true);
                }
                else
                {
                    throw new NotImplementedException("Ineffective way not implemented. Need to move buffer for SECBUFFER_STREAM_HEADER.");
                }

                var message = new SecBufferDescEx(
                    new SecBufferEx[]
                {
                    new SecBufferEx()
                    {
                        BufferType = BufferType.SECBUFFER_STREAM_HEADER, Buffer = e.Buffer, Size = sizes.cbHeader, Offset = e.Offset,
                    },
                    new SecBufferEx()
                    {
                        BufferType = BufferType.SECBUFFER_DATA, Buffer = e.Buffer, Size = dataCount, Offset = e.Offset + sizes.cbHeader,
                    },
                    new SecBufferEx()
                    {
                        BufferType = BufferType.SECBUFFER_STREAM_TRAILER, Buffer = e.Buffer, Size = sizes.cbTrailer, Offset = e.Offset + sizes.cbHeader + dataCount,
                    },
                    new SecBufferEx()
                    {
                        BufferType = BufferType.SECBUFFER_EMPTY,
                    },
                });

                Sspi.EncryptMessage(
                    ref context.Handle,
                    ref message,
                    0,
                    null);

                e.Count = message.Buffers[0].Size + message.Buffers[1].Size + message.Buffers[2].Size;
                e.ReAllocateBuffer(true);

                base.SendAsync(connection, e);
            }
            catch (SspiException ex)
            {
                e.SocketError = SocketError.Fault;
                OnFailed(new ServerInfoEventArgs(realEndPoint, ex));
            }
        }
예제 #15
0
        private unsafe bool Handshake(ServerAsyncEventArgs ie, Connection <C> connection)
        {
            int contextAttr         = 0;
            ServerAsyncEventArgs oe = null;
            var context             = connection.SspiContext;
            var input  = context.SecBufferDesc2[0];
            var output = context.SecBufferDesc2[1];

            try
            {
                if (context.Buffer.IsValid && ie != null)
                {
                    if (context.Buffer.CopyTransferredFrom(ie, 0) == false)
                    {
                        return(false);
                    }
                }

                for (; ;)
                {
                    // prepare input buffer
                    //
                    input.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN;
                    if (context.Buffer.IsValid)
                    {
                        SetSecBuffer(ref input.Buffers[0], context);
                    }
                    else
                    {
                        SetSecBuffer(ref input.Buffers[0], ie);
                    }

                    input.Buffers[1].SetBufferEmpty();


                    // prepare output buffer
                    //
                    if (oe == null)
                    {
                        oe = EventArgsManager.Get();
                    }
                    oe.AllocateBuffer();

                    output.Buffers[0].BufferType = BufferType.SECBUFFER_TOKEN;
                    output.Buffers[0].Size       = oe.Count;
                    output.Buffers[0].Buffer     = oe.Buffer;
                    output.Buffers[0].Offset     = oe.Offset;

                    output.Buffers[1].SetBufferEmpty();


                    // prepare some args and call SSPI
                    //
                    int contextReq = (int)(ContextReq.ASC_REQ_SEQUENCE_DETECT |
                                           ContextReq.ASC_REQ_REPLAY_DETECT |
                                           ContextReq.ASC_REQ_CONFIDENTIALITY |
                                           ContextReq.ASC_REQ_EXTENDED_ERROR |
                                           ContextReq.ASC_REQ_STREAM);

                    var newHandle = (context.Handle.IsInvalid) ? new SafeCtxtHandle() : context.Handle;

                    long timeStamp;

                    var result = Sspi.SafeAcceptSecurityContext(
                        ref credential,
                        ref context.Handle,
                        ref input,
                        contextReq,
                        TargetDataRep.SECURITY_NATIVE_DREP,
                        ref newHandle,
                        ref output,
                        out contextAttr,
                        out timeStamp);

                    if (context.Handle.IsInvalid)
                    {
                        context.Handle = newHandle;
                    }


                    // proccess non-critical errors
                    //
                    switch (result)
                    {
                    case SecurityStatus.SEC_E_INCOMPLETE_MESSAGE:

                        if (context.Buffer.IsInvalid)
                        {
                            if (context.Buffer.CopyTransferredFrom(ie, 0) == false)
                            {
                                return(false);
                            }
                        }
                        return(true);


                    case SecurityStatus.SEC_E_BUFFER_TOO_SMALL:

                        if (oe.Count < maxTokenSize)
                        {
                            oe.Count = maxTokenSize;
                            oe.ReAllocateBuffer(false);
                            continue;
                        }
                        return(false);
                    }


                    // send response to client
                    //
                    if (result == SecurityStatus.SEC_I_CONTINUE_NEEDED || result == SecurityStatus.SEC_E_OK ||
                        (Sspi.Failed(result) && (contextAttr & (int)ContextAttr.ASC_RET_EXTENDED_ERROR) != 0))
                    {
                        if (output.Buffers[0].Size > 0)
                        {
                            oe.Count = output.Buffers[0].Size;
                            oe.CopyAddressesFrom(ie);
                            oe.LocalEndPoint = GetLocalEndpoint(ie.RemoteEndPoint.Address);

                            base.SendAsync(connection, oe);
                            oe = null;
                        }
                    }


                    // move extra data to buffer
                    //
                    int extraIndex = input.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0);

                    if (extraIndex < 0)
                    {
                        context.Buffer.Free();
                    }
                    else
                    {
                        if (context.Buffer.IsInvalid)
                        {
                            if (context.Buffer.CopyTransferredFrom(ie,
                                                                   ie.BytesTransferred - input.Buffers[extraIndex].Size) == false)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            context.Buffer.MoveToBegin(context.Buffer.BytesTransferred - input.Buffers[extraIndex].Size,
                                                       input.Buffers[extraIndex].Size);
                        }
                    }


                    // proccess error-codes
                    //
                    switch (result)
                    {
                    case SecurityStatus.SEC_E_OK:

                        if (Sspi.SafeQueryContextAttributes(ref context.Handle, out context.StreamSizes)
                            != SecurityStatus.SEC_E_OK)
                        {
                            return(false);
                        }

                        context.Connected = true;
                        OnNewConnection(connection);

                        return(true);


                    case SecurityStatus.SEC_I_CONTINUE_NEEDED:

                        if (extraIndex >= 0)
                        {
                            continue;
                        }

                        return(true);


                    default:
                        return(false);
                    }
                }
            }
            finally
            {
                if (oe != null)
                {
                    EventArgsManager.Put(ref oe);
                }
            }
        }
            public bool VerifySignature(SipMessageReader reader, Credentials credentials)
            {
                bool result = false;

                InitializeThreadStaticVars();

                int length = SignatureBuffer.Generate(scheme, credentials.Crand, credentials.Cnum, targetname, reader, ref bytes1);

                secBufferDesc1.Buffers[0].SetBuffer(BufferType.SECBUFFER_DATA, bytes1, 0, length);

                if (bytes2.Length < credentials.Response.Length / 2)
                {
                    bytes2 = new byte[credentials.Response.Length];
                }

                if (HexEncoding.TryParseHex(credentials.Response.ToArraySegment(), bytes2) >= 0)
                {
                    secBufferDesc1.Buffers[1].SetBuffer(BufferType.SECBUFFER_TOKEN, bytes2, 0, credentials.Response.Length / 2);

                    var result2 = Sspi.SafeVerifySignature(contextHandle, ref secBufferDesc1, 100);

                    Tracer.WriteInformation("VerifySignature: " + result2.ToString());

                    result = Sspi.Succeeded(result2);
                }

                {
                    //if (auth.Cnum > _LastCnum + SlidingWindowSize || auth.Cnum < _LastCnum - SlidingWindowSize || auth.Cnum == 0)
                    //    // cnum в не скользящего окна
                    //    throw new AuthenticationManager.MessageDiscardException();

                    //// индекс верхней границы скользящего окна
                    //int index = auth.Cnum >= SlidingWindowSize ? (auth.Cnum - SlidingWindowSize) % SlidingWindowSize : auth.Cnum - 1;
                    //if (auth.Cnum > _LastCnum)
                    //{
                    //    // индекс нижней границы скользящего окна
                    //    int lindex = _LastCnum >= SlidingWindowSize ? (_LastCnum - SlidingWindowSize + 1) % SlidingWindowSize : _LastCnum;

                    //    // смещение скользящего окна
                    //    if (lindex > index)
                    //    {
                    //        while (lindex < SlidingWindowSize)
                    //            _SlidingWindow[lindex++] = false;
                    //        lindex = 0;
                    //    }

                    //    while (lindex < index)
                    //        _SlidingWindow[lindex++] = false;

                    //    _LastCnum = auth.Cnum;
                    //}
                    //else
                    //{
                    //    if (_SlidingWindow[index] == true)
                    //        // дублирование cnum
                    //        throw new AuthenticationManager.MessageDiscardException();
                    //}

                    //_SlidingWindow[index] = true;

                    // удаление обработанного поля заголовка
                    //message.Header.Headers[message.Header.FindHeaderIndex(auth_name, auth_index)].IsRemoved = true;


                    //message.Verified = true;
                }

                if (idleTimeUpdatedByExpires == false)
                {
                    idleTime = DateTime.UtcNow.AddMinutes(IdleMinutes);
                }

                return(result);
            }
예제 #17
0
 public override void SendAsync(ServerAsyncEventArgs e)
 {
     try
     {
         Server <C> .Connection <C> tcpConnection = base.GetTcpConnection(e.RemoteEndPoint);
         base.OnBeforeSend(tcpConnection, e);
         if (tcpConnection == null)
         {
             e.Completed   = new ServerAsyncEventArgs.CompletedEventHandler(base.Send_Completed);
             e.SocketError = SocketError.NotConnected;
             e.OnCompleted(null);
         }
         else
         {
             SspiContext sspiContext = tcpConnection.SspiContext;
             SecPkgContext_StreamSizes streamSizes = sspiContext.StreamSizes;
             int count = e.Count;
             if (e.OffsetOffset < streamSizes.cbHeader)
             {
                 throw new NotImplementedException("Ineffective way not implemented. Need to move buffer for SECBUFFER_STREAM_HEADER.");
             }
             e.OffsetOffset -= streamSizes.cbHeader;
             e.Count         = streamSizes.cbHeader + count + streamSizes.cbTrailer;
             e.ReAllocateBuffer(true);
             SecBufferDescEx secBufferDescEx = new SecBufferDescEx(new SecBufferEx[]
             {
                 new SecBufferEx
                 {
                     BufferType = BufferType.SECBUFFER_STREAM_HEADER,
                     Buffer     = e.Buffer,
                     Size       = streamSizes.cbHeader,
                     Offset     = e.Offset
                 },
                 new SecBufferEx
                 {
                     BufferType = BufferType.SECBUFFER_DATA,
                     Buffer     = e.Buffer,
                     Size       = count,
                     Offset     = e.Offset + streamSizes.cbHeader
                 },
                 new SecBufferEx
                 {
                     BufferType = BufferType.SECBUFFER_STREAM_TRAILER,
                     Buffer     = e.Buffer,
                     Size       = streamSizes.cbTrailer,
                     Offset     = e.Offset + streamSizes.cbHeader + count
                 },
                 new SecBufferEx
                 {
                     BufferType = BufferType.SECBUFFER_VERSION
                 }
             });
             Sspi.EncryptMessage(ref sspiContext.Handle, ref secBufferDescEx, 0u, null);
             e.Count = secBufferDescEx.Buffers[0].Size + secBufferDescEx.Buffers[1].Size + secBufferDescEx.Buffers[2].Size;
             e.ReAllocateBuffer(true);
             base.SendAsync(tcpConnection, e);
         }
     }
     catch (SspiException error)
     {
         e.SocketError = SocketError.Fault;
         this.OnFailed(new ServerInfoEventArgs(this.realEndPoint, error));
     }
 }
 public NegotiateStep(string authorizationId, Sspi.SecurityContext context, byte[] bytesToSendToServer)
 {
     _authorizationId = authorizationId;
     _context = context;
     _bytesToSendToServer = bytesToSendToServer ?? new byte[0];
 }
예제 #19
0
        unsafe private bool DecryptData(ref ServerAsyncEventArgs e, Connection <C> connection)
        {
            var context = connection.SspiContext;
            var message = context.SecBufferDesc5;

            if (context.Buffer.IsValid && e != null)
            {
                if (context.Buffer.CopyTransferredFrom(e, 0) == false)
                {
                    return(false);
                }
            }

            for (; ;)
            {
                // prepare buffer
                //
                message.Buffers[0].BufferType = BufferType.SECBUFFER_DATA;
                if (context.Buffer.IsValid)
                {
                    SetSecBuffer(ref message.Buffers[0], context);
                }
                else
                {
                    SetSecBuffer(ref message.Buffers[0], e);
                }

                message.Buffers[1].SetBufferEmpty();
                message.Buffers[2].SetBufferEmpty();
                message.Buffers[3].SetBufferEmpty();
                message.Buffers[4].SetBufferEmpty();



                // call SSPI
                //
                var result = Sspi.SafeDecryptMessage(ref context.Handle, ref message, 0, null);


                // analize result
                //
                int extraIndex = message.GetBufferIndex(BufferType.SECBUFFER_EXTRA, 0);
                int dataIndex  = message.GetBufferIndex(BufferType.SECBUFFER_DATA, 0);

                switch (result)
                {
                case SecurityStatus.SEC_E_OK:

                    if (dataIndex >= 0)
                    {
                        if (context.Buffer.IsInvalid)
                        {
                            if (extraIndex >= 0)
                            {
                                if (context.Buffer.CopyFrom(message.Buffers[extraIndex]) == false)
                                {
                                    return(false);
                                }
                            }

                            e.Offset           = message.Buffers[dataIndex].Offset;
                            e.BytesTransferred = message.Buffers[dataIndex].Size;
                            e.SetMaxCount();

                            if (OnReceived(connection, ref e) == false)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            var buffer = context.Buffer.Detach();

                            if (extraIndex >= 0)
                            {
                                if (context.Buffer.CopyFrom(message.Buffers[extraIndex]) == false)
                                {
                                    return(false);
                                }
                            }


                            // create eventarg and call onreceived event
                            //
                            var e2 = EventArgsManager.Get();

                            base.PrepareEventArgs(connection, e2);

                            e2.AttachBuffer(buffer);
                            e2.Offset           = message.Buffers[dataIndex].Offset;
                            e2.BytesTransferred = message.Buffers[dataIndex].Size;
                            e2.SetMaxCount();

                            bool continue1 = OnReceived(connection, ref e2);

                            if (e2 != null)
                            {
                                EventArgsManager.Put(e2);
                            }

                            if (continue1 == false)
                            {
                                return(false);
                            }
                        }

                        if (extraIndex >= 0)
                        {
                            continue;
                        }

                        return(true);
                    }

                    return(false);


                case SecurityStatus.SEC_E_INCOMPLETE_MESSAGE:

                    if (context.Buffer.IsInvalid)
                    {
                        if (context.Buffer.CopyTransferredFrom(e, 0) == false)
                        {
                            return(false);
                        }
                    }

                    return(true);


                case SecurityStatus.SEC_I_RENEGOTIATE:

                    // MSDN: Renegotiation is not supported for Schannel kernel mode. The
                    // caller should either ignore this return value or shut down the
                    // connection.
                    // If the value is ignored, either the client or the server might shut
                    // down the connection as a result.

                    return(false);


                default:
                    return(false);
                }
            }
        }