2008-11-06 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.Security / MembershipProvider.cs
index 0a5ccfb5415820e06f34cfac6fb7b09ed6b50b08..812890ab3adc6668ed9a4d8beaeaeb48deb78b66 100644 (file)
 //
 
 #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 ()
                {
                }
@@ -70,24 +82,68 @@ namespace System.Web.Security
                
                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;
                }
 
-               [MonoTODO]
-               protected virtual byte[] DecryptPassword (byte[] encodedPassword)
+               internal const int SALT_BYTES = 16;
+               protected virtual byte [] DecryptPassword (byte [] encodedPassword)
                {
-                       throw new NotImplementedException ();
+                       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;
+                               }
+                       }
                }
 
-               [MonoTODO]
                protected virtual byte[] EncryptPassword (byte[] password)
                {
-                       throw new NotImplementedException ();
+                       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
 
+