Bug #38939 MembershipUser.GetPassword(string answer) fails when incorrect answer is passed.

Submitted: 21 Aug 2008 14:19 Modified: 5 Sep 2008 16:30
Reporter: Craig Ritchie Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:5.2.3.0 OS:Windows
Assigned to: CPU Architecture:Any
Tags: MembershipUser GetPassword

[21 Aug 2008 14:19] Craig Ritchie
Description:
Event Type: Information
Event Source: MySQLMembershipProvider
Event Category: None
Event ID: 0
Date: 8/20/2008
Time: 9:02:39 PM
User: N/A
Description:
An exception occurred communicating with the data source.

Action: UpdateFailureCount

Exception: MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
at MySql.Data.MySqlClient.MySqlCommand.CheckState()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Web.Security.MySQLMembershipProvider.UpdateFailureCount(Int32 userId, String failureType, MySqlConnection connection)

How to repeat:
config settings:
  requiresQuestionAndAnswer="true"
  enablePasswordRetrieval="true"
  passwordFormat="Encrypted"

Create a user with a question and answer for password retrieval.
Attempt to call MembershipUser.GetPassword() with wrong answer.

The above exception should be the results.

Suggested fix:
I believe the offending code is the call to UpdateFailureCount within this 'if' statement:
if (this.RequiresQuestionAndAnswer && !this.CheckPassword(answer, dbpassword, passwordKey, format))
{
this.UpdateFailureCount(userId, "PasswordAnswer", connection);
throw new MembershipPasswordException(Resources.IncorrectPasswordAnswer);
}

Trying to reuse the connection in this call could be the problem. Everything seems to work if the correct password answer is passed to GetPassword().
[25 Aug 2008 9:34] Tonci Grgin
Hi Craig and thanks for your report. What puzzles me is what did you expect from c/NET in case wrong answer is provided?
[25 Aug 2008 13:44] Craig Ritchie
From: http://msdn.microsoft.com/en-us/library/kx96zecz.aspx

"GetPassword calls the MembershipProvider.GetPassword method of the membership provider referenced by the ProviderName property to retrieve the password for the membership user from the membership data store. If a password answer is required and an incorrect password answer is supplied, a MembershipPasswordException is thrown by the membership provider."

The exception that is thrown is not a MembershipPasswordException but a MySqlException regarding the reuse of a connection... which seems totally irrelevant to providing a wrong answer.

Further Information: Disassembled from SqlMembershipProvider:
public override string GetPassword(string username, string passwordAnswer)
{
    if (!this.EnablePasswordRetrieval)
    {
        throw new NotSupportedException(SR.GetString("Membership_PasswordRetrieval_not_supported"));
    }
    SecUtility.CheckParameter(ref username, true, true, true, 0x100, "username");
    string encodedPasswordAnswer = this.GetEncodedPasswordAnswer(username, passwordAnswer);
    SecUtility.CheckParameter(ref encodedPasswordAnswer, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false, 0x80, "passwordAnswer");
    int passwordFormat = 0;
    int status = 0;
    string pass = this.GetPasswordFromDB(username, encodedPasswordAnswer, this.RequiresQuestionAndAnswer, out passwordFormat, out status);
    if (pass != null)
    {
        return base.UnEncodePassword(pass, passwordFormat);
    }
    string exceptionText = this.GetExceptionText(status);
    if (this.IsStatusDueToBadPassword(status))
    {
        throw new MembershipPasswordException(exceptionText);
    }
    throw new ProviderException(exceptionText);
}

I guess the final answer is that I would expect some exception (preferably a MembershipPasswordException) indicating that the answer is incorrect as the MSDN document states.
[25 Aug 2008 13:47] Craig Ritchie
Sorry... looking back over the code I see where the proper exception is going to be thrown... but...

this line:
  this.UpdateFailureCount(userId, "PasswordAnswer", connection);
is failing so that this line:
  throw new MembershipPasswordException(Resources.IncorrectPasswordAnswer);
is never reached.
[28 Aug 2008 20:21] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/52874
[28 Aug 2008 20:22] Reggie Burnett
fixed in 5.3.0
[5 Sep 2008 16:30] Tony Bedford
An entry has been added to the 5.3.0 changelog:

When called with an incorrect password the MembershipProvider.GetPassword() method threw a MySQLException instead of a MembershipPasswordException.

Portions of this website are copyright © 2001, 2002 The PHP Group

Page generated in 0.056 sec. using MySQL 8.4.7-u6-cloud

Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the respective copyright holders.
It is not reviewed in advance by Oracle and does not necessarily represent the opinion of Oracle or any other party.