Exemplo n.º 1
0
        /// <summary>
        /// Handles incoming <see cref="AuthenticatePacket"/>s from clients trying to authenticate.
        /// </summary>
        /// <param name="connectionId">Original connection ID</param>
        /// <param name="packet">Incoming packet</param>
        private void authenticatePacketHandler(string connectionId, AuthenticatePacket packet)
        {
            // Check the supplied credentials are of the appropriate type
            if (packet.AuthType != authType)
            {
                // Fail the authentication attempt due to mismatched credential type
                sendFailedAuthResponsePacket(connectionId, AuthFailureReason.AuthType, string.Format("Wrong type of credentials supplied. The server only accepts \"{0}\" credentials.", authType.ToString()));

                RaiseLogEntry(new LogEventArgs(string.Format("Auth failure for {0}: Wrong credential type", connectionId.Highlight(HighlightType.ConnectionID)), LogLevel.DEBUG));

                // Stop here
                return;
            }

            lock (sessionsLock)
            {
                // Check whether a session exists for this connection or the supplied session ID is assigned to this connection
                if (!sessions.ContainsKey(connectionId) || sessions[connectionId].SessionId != packet.SessionId)
                {
                    // Fail the authentication attempt due to invalid session ID
                    sendFailedAuthResponsePacket(connectionId, AuthFailureReason.SessionId, "Could not find session for your connection. It may have expired. Try logging in again.");

                    RaiseLogEntry(new LogEventArgs(string.Format("Auth failure for {0}: No session found for this connection", connectionId.Highlight(HighlightType.ConnectionID)), LogLevel.DEBUG));

                    // Stop here
                    return;
                }

                // Get an alias of the session for simplicity
                Session session = sessions[connectionId];

                // Check if the session has expired
                if (session.Expiry.CompareTo(DateTime.UtcNow) <= 0)
                {
                    // Fail the authentication attempt due to expired session
                    sendFailedAuthResponsePacket(connectionId, AuthFailureReason.SessionId, "Session has expired. Try logging in again.");

                    RaiseLogEntry(new LogEventArgs(string.Format("Auth failure for {0} (SessID: {1}): Session expired", connectionId.Highlight(HighlightType.ConnectionID), session.SessionId.Highlight(HighlightType.SessionID)), LogLevel.DEBUG));

                    // Stop here
                    return;
                }

                lock (credentialStoreLock)
                {
                    // Check if user does not have an existing credential
                    if (!credentialStore.Credentials.ContainsKey(packet.Username))
                    {
                        // Exception for PhiKey, it should be a 'zero-configuration' solution
                        if (authType == AuthTypes.ClientKey)
                        {
                            // Create a new credential and add it to the credential store
                            Credential newCredential = new Credential
                            {
                                AuthType = AuthTypes.ClientKey,
                                Username = packet.Username,
                                Password = packet.Password
                            };
                            credentialStore.Credentials.Add(newCredential.Username, newCredential);
                        }
                        else
                        {
                            // Fail the authentication attempt due to missing credential
                            sendFailedAuthResponsePacket(connectionId, AuthFailureReason.Credentials, string.Format("No credential found for the username \"{0}\".", packet.Username.Highlight(HighlightType.Username)));

                            RaiseLogEntry(new LogEventArgs(string.Format("Auth failure for {0} (SessID: {1}): No credentials found for {2}", connectionId.Highlight(HighlightType.ConnectionID), session.SessionId.Highlight(HighlightType.SessionID), packet.Username.Highlight(HighlightType.Username)), LogLevel.DEBUG));

                            // Stop here
                            return;
                        }
                    }

                    // Add username to the session
                    session.Username = packet.Username;

                    // Get an alias of the user's credential for simplicity
                    Credential credential = credentialStore.Credentials[session.Username];

                    // Check if the credential is not for our current auth type
                    if (credential.AuthType != authType)
                    {
                        // Delete the offending credential
                        credentialStore.Credentials.Remove(session.Username);

                        // Fail the authentication attempt due to invalid stored credential
                        sendFailedAuthResponsePacket(connectionId, AuthFailureReason.InternalServerError, "Server's stored credential did not match its accepted authentication type. Try logging in again.");

                        RaiseLogEntry(new LogEventArgs(string.Format("Auth failure for {0} (SessID: {1}): Stored credentials for {2} are of wrong type ({3})", connectionId.Highlight(HighlightType.ConnectionID), session.SessionId.Highlight(HighlightType.SessionID), packet.Username.Highlight(HighlightType.Username), credential.AuthType.ToString()), LogLevel.DEBUG));

                        // Stop here
                        return;
                    }

                    // Check if the password does not match the stored credential
                    // This check is ignored if the auth type is 'ClientKey' as the password does not matter
                    if (authType == AuthTypes.ClientKey && packet.Password != credential.Password)
                    {
                        // Fail the authentication attempt due to mismatching password
                        sendFailedAuthResponsePacket(connectionId, AuthFailureReason.Credentials, "Invalid password provided.");

                        RaiseLogEntry(new LogEventArgs(string.Format("Auth failure for {0} (SessID: {1}): Wrong password provided for {2}", connectionId.Highlight(HighlightType.ConnectionID), session.SessionId.Highlight(HighlightType.SessionID), packet.Username.Highlight(HighlightType.Username)), LogLevel.DEBUG));

                        // Stop here
                        return;
                    }

                    // Auth attempt made it through the gauntlet, time to accept it as a valid request

                    // Mark the session as authenticated
                    session.Authenticated = true;

                    // Extend their session by 30 minutes
                    TimeSpan expiresIn = TimeSpan.FromMinutes(30);
                    session.Expiry = DateTime.UtcNow + expiresIn;

                    // Approve the authentication attempt
                    sendSuccessfulAuthResponsePacket(connectionId, session.SessionId, (int)expiresIn.TotalMilliseconds);

                    // Log this momentous occasion
                    RaiseLogEntry(new LogEventArgs(string.Format("User \"{0}\" (ConnID: {1}, SessID: {2}) successfully authenticated", session.Username.Highlight(HighlightType.Username), session.ConnectionId.Highlight(HighlightType.ConnectionID), session.SessionId.Highlight(HighlightType.SessionID))));
                }
            }
        }
Exemplo n.º 2
0
 /// <summary>
 /// Send the Authentication challenge request
 /// </summary>
 /// <param name="message"></param>
 /// <param name="actionContext"></param>
 private void challenge(HttpActionContext actionContext, string message, AuthTypes scheme)
 {
   var body = new { error = message };
   actionContext.Response = actionContext.Request.CreateResponse(HttpStatusCode.Unauthorized, body);
   actionContext.Response.Headers.Add("WWW-Authenticate", scheme.ToString());
 }