コード例 #1
0
        public override object GetContextAttribute(object context, GSSAttributeName attributeName)
        {
            AuthContext authContext = context as AuthContext;

            if (authContext != null)
            {
                switch (attributeName)
                {
                case GSSAttributeName.AccessToken:
                    return(SSPIHelper.GetAccessToken(authContext.ServerContext));

                case GSSAttributeName.DomainName:
                    return(authContext.DomainName);

                case GSSAttributeName.IsGuest:
                    return(authContext.IsGuest);

                case GSSAttributeName.MachineName:
                    return(authContext.WorkStation);

                case GSSAttributeName.OSVersion:
                    return(authContext.OSVersion);

                case GSSAttributeName.SessionKey:
                    return(SSPIHelper.GetSessionKey(authContext.ServerContext));

                case GSSAttributeName.UserName:
                    return(authContext.UserName);
                }
            }

            return(null);
        }
コード例 #2
0
        public override NTStatus GetChallengeMessage(out object context, byte[] negotiateMessageBytes, out byte[] challengeMessageBytes)
        {
            SecHandle serverContext;

            try
            {
                challengeMessageBytes = SSPIHelper.GetType2Message(negotiateMessageBytes, out serverContext);
            }
            catch (Exception)
            {
                context = null;
                challengeMessageBytes = null;
                // We assume that the problem is not with our implementation.
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            context = new AuthContext(serverContext);
            return(NTStatus.SEC_I_CONTINUE_NEEDED);
        }
コード例 #3
0
        public override bool DeleteSecurityContext(ref object context)
        {
            AuthContext authContext = context as AuthContext;

            if (authContext == null)
            {
                return(false);
            }

            SecHandle handle  = ((AuthContext)context).ServerContext;
            uint      result  = SSPIHelper.DeleteSecurityContext(ref handle);
            bool      success = (result == 0); // SEC_E_OK

            if (success)
            {
                context = null;
            }
            return(success);
        }
コード例 #4
0
        /// <summary>
        /// Authenticate will return false when the password is correct in these cases:
        /// 1. The correct password is blank and 'limitblankpassworduse' is set to 1.
        /// 2. The user is listed in the "Deny access to this computer from the network" list.
        /// </summary>
        public override NTStatus Authenticate(object context, byte[] authenticateMessageBytes)
        {
            AuthenticateMessage message;

            try
            {
                message = new AuthenticateMessage(authenticateMessageBytes);
            }
            catch (Exception)
            {
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            AuthContext authContext = context as AuthContext;

            if (authContext == null)
            {
                // There are two possible reasons for authContext to be null:
                // 1. We have a bug in our implementation, let's assume that's not the case,
                //    according to [MS-SMB2] 3.3.5.5.1 we aren't allowed to return SEC_E_INVALID_HANDLE anyway.
                // 2. The client sent AuthenticateMessage without sending NegotiateMessage first,
                //    in this case the correct response is SEC_E_INVALID_TOKEN.
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            authContext.DomainName  = message.DomainName;
            authContext.UserName    = message.UserName;
            authContext.WorkStation = message.WorkStation;
            if (message.Version != null)
            {
                authContext.OSVersion = message.Version.ToString();
            }

            if ((message.NegotiateFlags & NegotiateFlags.Anonymous) > 0 ||
                !IsUserExists(message.UserName))
            {
                if (this.EnableGuestLogin)
                {
                    authContext.IsGuest = true;
                    return(NTStatus.STATUS_SUCCESS);
                }
                else
                {
                    return(NTStatus.STATUS_LOGON_FAILURE);
                }
            }

            bool success;

            try
            {
                success = SSPIHelper.AuthenticateType3Message(authContext.ServerContext, authenticateMessageBytes);
            }
            catch (Exception)
            {
                // We assume that the problem is not with our implementation.
                return(NTStatus.SEC_E_INVALID_TOKEN);
            }

            if (success)
            {
                return(NTStatus.STATUS_SUCCESS);
            }
            else
            {
                Win32Error result = (Win32Error)Marshal.GetLastWin32Error();
                // Windows will permit fallback when these conditions are met:
                // 1. The guest user account is enabled.
                // 2. The guest user account does not have a password set.
                // 3. The specified account does not exist.
                //    OR:
                //    The password is correct but 'limitblankpassworduse' is set to 1 (logon over a network is disabled for accounts without a password).
                bool allowFallback = (result == Win32Error.ERROR_ACCOUNT_RESTRICTION);
                if (allowFallback && this.EnableGuestLogin)
                {
                    authContext.IsGuest = true;
                    return(NTStatus.STATUS_SUCCESS);
                }
                else
                {
                    return(ToNTStatus(result));
                }
            }
        }