//
-// System.Web.Security.IMembershipProvider
+// System.Web.Security.MembershipProvider
//
// Authors:
// Ben Maurer (bmaurer@users.sourceforge.net)
// Lluis Sanchez Gual (lluis@novell.com)
//
// (C) 2003 Ben Maurer
-//
-
+// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
//
#if NET_2_0
+using System.ComponentModel;
using System.Configuration.Provider;
+using System.Web.Configuration;
+using System.Security.Cryptography;
+using System.Text;
namespace System.Web.Security
{
public abstract class MembershipProvider : ProviderBase
{
+ static readonly object validatingPasswordEvent = new object ();
+
+ EventHandlerList events = new EventHandlerList ();
+ public event MembershipValidatePasswordEventHandler ValidatingPassword {
+ add { events.AddHandler (validatingPasswordEvent, value); }
+ remove { events.RemoveHandler (validatingPasswordEvent, value); }
+ }
+
protected MembershipProvider ()
{
}
protected virtual void OnValidatingPassword (ValidatePasswordEventArgs args)
{
- if (ValidatingPassword != null)
- ValidatingPassword (this, args);
+ MembershipValidatePasswordEventHandler eh = events [validatingPasswordEvent] as MembershipValidatePasswordEventHandler;
+ if (eh != null)
+ eh (this, args);
+ }
+
+ SymmetricAlgorithm GetAlg (out byte [] decryptionKey)
+ {
+ MachineKeySection section = (MachineKeySection) WebConfigurationManager.GetSection ("system.web/machineKey");
+
+ if (section.DecryptionKey.StartsWith ("AutoGenerate"))
+ throw new ProviderException ("You must explicitly specify a decryption key in the <machineKey> section when using encrypted passwords.");
+
+ string alg_type = section.Decryption;
+ if (alg_type == "Auto")
+ alg_type = "AES";
+
+ SymmetricAlgorithm alg = null;
+ if (alg_type == "AES")
+ alg = Rijndael.Create ();
+ else if (alg_type == "3DES")
+ alg = TripleDES.Create ();
+ else
+ throw new ProviderException (String.Format ("Unsupported decryption attribute '{0}' in <machineKey> configuration section", alg_type));
+
+ decryptionKey = MachineKeySectionUtils.DecryptionKey192Bits (section);
+ return alg;
+ }
+
+ internal const int SALT_BYTES = 16;
+ protected virtual byte [] DecryptPassword (byte [] encodedPassword)
+ {
+ byte [] decryptionKey;
+
+ using (SymmetricAlgorithm alg = GetAlg (out decryptionKey)) {
+ alg.Key = decryptionKey;
+
+ using (ICryptoTransform decryptor = alg.CreateDecryptor ()) {
+
+ byte [] buf = decryptor.TransformFinalBlock (encodedPassword, 0, encodedPassword.Length);
+ byte [] rv = new byte [buf.Length - SALT_BYTES];
+
+ Array.Copy (buf, 16, rv, 0, buf.Length - 16);
+ return rv;
+ }
+ }
+ }
+
+ protected virtual byte[] EncryptPassword (byte[] password)
+ {
+ byte [] decryptionKey;
+ byte [] iv = new byte [SALT_BYTES];
+
+ Array.Copy (password, 0, iv, 0, Math.Min(password.Length, SALT_BYTES));
+
+ using (SymmetricAlgorithm alg = GetAlg (out decryptionKey)) {
+ using (ICryptoTransform encryptor = alg.CreateEncryptor (decryptionKey, iv)) {
+ return encryptor.TransformFinalBlock (password, 0, password.Length);
+ }
+ }
}
-
- public event MembershipValidatePasswordEventHandler ValidatingPassword;
}
}
#endif
+