Ejemplo n.º 1
0
 /// <summary>
 /// Creates the command packet's header and returns a BinaryWriter so the caller
 /// can write the command packet's payload.
 /// </summary>
 /// <param name="ms">A MemoryStream to write the command packet.</param>
 /// <param name="command">A WinAuthProtocolCommands that specifies the command.</param>
 /// <returns>A BinaryWriter that contains the command packet's header.</returns>
 protected BinaryWriter GetBinaryWriter(MemoryStream ms, WinAuthProtocolCommands command)
 {
     BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8);
     bw.Write(WinAuthProtocol.PROTOCOL_IDENTIFIER);
     bw.Write((byte)command);
     return bw;
 }
        /// <summary>
        /// Creates the command packet's header and returns a BinaryWriter so the caller
        /// can write the command packet's payload.
        /// </summary>
        /// <param name="ms">A MemoryStream to write the command packet.</param>
        /// <param name="command">A WinAuthProtocolCommands that specifies the command.</param>
        /// <returns>A BinaryWriter that contains the command packet's header.</returns>
        protected BinaryWriter GetBinaryWriter(MemoryStream ms, WinAuthProtocolCommands command)
        {
            BinaryWriter bw = new BinaryWriter(ms, Encoding.UTF8);

            bw.Write(WinAuthProtocol.PROTOCOL_IDENTIFIER);
            bw.Write((byte)command);
            return(bw);
        }
        /// <summary>
        /// Handles the response to the <see cref="US.OpenServer.Protocols.WinAuth.WinAuthProtocolCommands.AUTHENTICATE"/>
        /// command packet.
        /// </summary>
        /// <remarks>
        /// <para>
        /// When an <see cref="US.OpenServer.Protocols.WinAuth.WinAuthProtocolCommands.AUTHENTICATED"/>
        /// response is received, notifies the <see cref="US.OpenServer.SessionBase"/> the
        /// client is authenticated enabling the session to allow execution of higher
        /// protocol layers. Finally, signals the <see cref="Authenticate(String, String, String)" />
        /// function to unblock the calling thread.
        /// </para>
        /// <para>
        /// When an <see cref="US.OpenServer.Protocols.WinAuth.WinAuthProtocolCommands.ACCESS_DENIED"/>
        /// response is received, logs the error then signals the <see cref="Authenticate(String, String, String)" />
        /// function to unblock the calling thread.
        /// </para>
        /// <para>
        /// When an <see cref="US.OpenServer.Protocols.WinAuth.WinAuthProtocolCommands.ERROR"/>
        /// response is received, logs the error then signals the <see cref="Authenticate(String, String, String)" />
        /// function to unblock the calling thread.
        /// </para>
        /// <para>
        /// Prior to authentication the session disallows all protocols commands.
        /// </para>
        /// </remarks>
        /// <param name="br">A BinaryReader that contains the command packet.</param>
        public override void OnPacketReceived(BinaryReader br)
        {
            lock (this)
            {
                if (Session == null)
                {
                    return;
                }

                WinAuthProtocolCommands command = (WinAuthProtocolCommands)br.ReadByte();
                switch (command)
                {
                case WinAuthProtocolCommands.AUTHENTICATED:
                    IsAuthenticated         = true;
                    Session.IsAuthenticated = true;

                    AuthenticationSuccessful?.Invoke(Session.Address, Session.UserName);

                    Log(Level.Info, "Authenticated.");
                    Monitor.PulseAll(this);
                    break;

                case WinAuthProtocolCommands.ACCESS_DENIED:

                    AuthenticationFailed?.Invoke(Session.Address, Session.UserName);

                    Log(Level.Notice, "Access denied.");
                    Monitor.PulseAll(this);
                    break;

                case WinAuthProtocolCommands.ERROR:
                {
                    string errorMessage = br.ReadString();

                    AuthenticationError?.Invoke(Session.Address, Session.UserName, errorMessage);

                    Log(Level.Notice, errorMessage);
                    Monitor.PulseAll(this);
                    break;
                }

                default:
                    Log(Level.Error, string.Format("Invalid or unsupported command.  Command: {0}", command));
                    break;
                }
            }
        }
        /// <summary>
        /// Handles the <see cref="US.OpenServer.Protocols.WinAuth.WinAuthProtocolCommands.AUTHENTICATE"/>
        /// command packet request.
        /// </summary>
        /// <param name="br">A BinaryReader that contains the command packet.</param>
        public override void OnPacketReceived(BinaryReader br)
        {
            lock (this)
            {
                if (Session == null)
                {
                    return;
                }

                WinAuthProtocolCommands command = (WinAuthProtocolCommands)br.ReadByte();
                try
                {
                    switch (command)
                    {
                    case WinAuthProtocolCommands.AUTHENTICATE:

                        string userName = br.ReadString();
                        string password = br.ReadString();
                        string domain   = br.ReadString();

                        try
                        {
                            // I commented ou this line because it constantly hindered my
                            // Authentication no matter what.
                            //wp = GetPrincipal(userName, password, domain);

                            if (!Authenticate(userName, password))
                            {
                                throw new Exception("Insufficient privileges.");
                            }

                            UserId          = userName;
                            UserName        = userName;
                            IsAuthenticated = true;

                            Session.UserName               = userName;
                            Session.IsAuthenticated        = true;
                            Session.AuthenticationProtocol = this;

                            Log(Level.Info, string.Format(@"Authenticated {0}\{1}.", domain, userName));

                            MemoryStream ms = new MemoryStream();
                            GetBinaryWriter(ms, WinAuthProtocolCommands.AUTHENTICATED);

                            //Fires the authentication succefull event
                            AuthenticationSuccessful?.Invoke(Session.Address, Session.UserName);

                            Session.Send(ms);
                        }
                        catch (Exception ex)
                        {
                            Log(Level.Notice, string.Format(@"Access denied.  {0}.  User: {1}\{2}", ex.Message, domain, userName));

                            MemoryStream ms = new MemoryStream();
                            GetBinaryWriter(ms, WinAuthProtocolCommands.ACCESS_DENIED);
                            Session.Send(ms);
                        }
                        break;

                    default:
                        throw new Exception("Invalid or unsupported command.");
                    }
                }
                catch (Exception ex)
                {
                    Log(Level.Error, string.Format("{0}  Command: {1}", ex.Message, command));

                    MemoryStream ms = new MemoryStream();
                    BinaryWriter bw = GetBinaryWriter(ms, WinAuthProtocolCommands.ERROR);
                    bw.Write(ex.Message);
                    Session.Send(ms);
                }
            }
        }