Beispiel #1
0
 private void GrantPermissions(CtpNetStream stream, CtpAccount account, string loginName, List <string> grantedRoles, List <string> deniedRoles)
 {
     stream.LoginName   = loginName;
     stream.AccountName = account.Name;
     stream.GrantedRoles.UnionWith(account.ImplicitRoles);
     stream.GrantedRoles.UnionWith(account.ExplicitRoles.Union(grantedRoles));
     stream.GrantedRoles.ExceptWith(deniedRoles);
 }
Beispiel #2
0
        public bool IsCertificateTrusted(CtpNetStream stream, ClientDone clientDone)
        {
            if (!TryFindCertificate(stream.RemoteCertificate.GetCertHashString(), out var cert, out var account))
            {
                return(false);
            }

            if (!account.IsIPAllowed(stream.RemoteEndpoint.Address))
            {
                return(false);
            }

            GrantPermissions(stream, account, clientDone.LoginName, clientDone.GrantedRoles, clientDone.DeniedRoles);
            return(true);
        }
Beispiel #3
0
        public bool IsCertificateTrusted(CtpNetStream stream, CertificateProof proof)
        {
            var eph = new EphemeralCertificate(proof.EphemeralCertificate);

            if (!TryFindCertificate(HexToString(eph.TrustedCertThumbprint), out var signingCert, out var account))
            {
                return(false);
            }

            if (!eph.ValidateSignature(signingCert))
            {
                return(false);
            }

            if (!account.IsIPAllowed(stream.RemoteEndpoint.Address))
            {
                return(false);
            }

            GrantPermissions(stream, account, eph.LoginName, eph.GrantedRoles, eph.DeniedRoles);

            return(true);
        }
Beispiel #4
0
        public CtpNetStream Connect()
        {
            Log.Publish(MessageLevel.Info, "Attempting Connection");

            var socket = new TcpClient();

            socket.SendTimeout    = 3000;
            socket.ReceiveTimeout = 3000;
            var connect = socket.BeginConnect(m_remoteEndpoint.Address, m_remoteEndpoint.Port, null, null);
            var success = connect.AsyncWaitHandle.WaitOne(3000);

            if (!success)
            {
                socket.Close();
                throw new TimeoutException("Failed to connect");
            }
            socket.EndConnect(connect);
            var netStream = socket.GetStream();

            SslStream sslStream = null;

            using (var handshake = m_authentication.StartHandshake())
            {
                if (handshake.UseSSL)
                {
                    sslStream = new SslStream(netStream, false, ValidateCertificate, null, EncryptionPolicy.RequireEncryption);
                    sslStream.AuthenticateAsClient(string.Empty, handshake.GetCertificateCollection(), SslProtocols.Tls12, false);
                    var session = new CtpNetStream(socket, netStream, sslStream);

                    var cmd = session.Read();
                    if (cmd.CommandName == "ServerDone")
                    {
                        if (!handshake.IsCertificateTrusted(sslStream.RemoteCertificate, (ServerDone)cmd))
                        {
                            m_authentication.AuthenticationFailed();
                            session.Send(new AuthFailure("Negotiated Certificate is not trusted: " + sslStream.RemoteCertificate.ToString()));
                            session.Dispose();
                            throw new Exception("Certificate is not trusted");
                        }
                    }
                    else if (cmd.CommandName == "CertificateProof")
                    {
                        if (!handshake.IsCertificateTrusted(sslStream.RemoteCertificate, (CertificateProof)cmd))
                        {
                            m_authentication.AuthenticationFailed();
                            session.Send(new AuthFailure("Negotiated Certificate is not trusted: " + sslStream.RemoteCertificate.ToString()));
                            session.Dispose();
                            throw new Exception("Certificate is not trusted");
                        }
                    }
                    else
                    {
                        m_authentication.AuthenticationFailed();
                        session.Send(new AuthFailure("Unrecognized Auth Command: " + cmd.CommandName));
                        session.Dispose();
                        throw new Exception("Unrecognized Auth Command: " + cmd.CommandName);
                    }

                    if (handshake.IsEphemeralCertificate)
                    {
                        session.Send(handshake.GetCertificateProof());
                    }
                    else
                    {
                        session.Send(handshake.GetClientDone());
                    }

                    cmd = session.Read();
                    if (cmd.CommandName != "AuthSuccess")
                    {
                        m_authentication.AuthenticationFailed();
                        session.Send(new AuthFailure("Expecting AuthSuccess, received: " + cmd.CommandName));
                        session.Dispose();
                        throw new Exception("Expecting AuthSuccess, received: " + cmd.CommandName);
                    }
                    Log.Publish(MessageLevel.Info, "SSL Session Completed");
                    return(session);
                }
                else
                {
                    var session = new CtpNetStream(socket, netStream, null);
                    Log.Publish(MessageLevel.Info, "Non SSL Session Completed");
                    return(session);
                }
            }
        }
            private void Process()
            {
                try
                {
                    TcpClient        socket    = m_client;
                    NetworkStream    netStream = socket.GetStream();
                    IServerHandshake config    = m_server.m_config.StartHandshake();
                    CtpNetStream     session;

                    if (config.UseSSL)
                    {
                        var ssl = new SslStream(netStream, false, UserCertificateValidationCallback, null, EncryptionPolicy.RequireEncryption);
                        ssl.AuthenticateAsServer(config.GetCertificate(), true, SslProtocols.Tls12, false);
                        session = new CtpNetStream(socket, netStream, ssl);

                        if (config.IsEphemeralCertificate)
                        {
                            session.Send(config.GetCertificateProof());
                        }
                        else
                        {
                            session.Send(config.GetServerDone());
                        }

                        var cmd = session.Read();

                        if (cmd.CommandName == "ClientDone")
                        {
                            if (!config.IsCertificateTrusted(session, (ClientDone)cmd))
                            {
                                session.Send(new AuthFailure("Negotiated Certificate is not trusted: " + ssl.RemoteCertificate.ToString()));
                                session.Dispose();
                                throw new Exception("Certificate is not trusted");
                            }
                        }
                        else if (cmd.CommandName == "CertificateProof")
                        {
                            if (!config.IsCertificateTrusted(session, (CertificateProof)cmd))
                            {
                                session.Send(new AuthFailure("Negotiated Certificate is not trusted: " + ssl.RemoteCertificate.ToString()));
                                session.Dispose();
                                throw new Exception("Certificate is not trusted");
                            }
                        }
                        else
                        {
                            session.Send(new AuthFailure("Unrecognized Auth Command: " + cmd.CommandName));
                            session.Dispose();
                            throw new Exception("Unrecognized Auth Command: " + cmd.CommandName);
                        }
                        session.Send(new AuthSuccess());
                    }
                    else
                    {
                        session = new CtpNetStream(socket, netStream, null);
                    }

                    m_server.OnSessionCompleted(session);
                }
                catch (Exception e)
                {
                    Logger.SwallowException(e, "Failed to authenticate client, Safely Disconnecting");
                    //Swallow the exception since a failed connection attempt can safely be ignored by the server.
                }
            }
 protected virtual void OnSessionCompleted(CtpNetStream token)
 {
     SessionCompleted?.Invoke(token);
 }