2008-11-06 Marek Habersack <mhabersack@novell.com>
[mono.git] / mcs / class / System.Web / System.Web.Security / FormsAuthentication.cs
index 08c4ab587d637c707e0f75eae09ba03ad2d41261..2b9fb52057e913afbb863747753db08cce05da05 100644 (file)
@@ -37,6 +37,7 @@ using System.Text;
 using System.Web;
 using System.Web.Configuration;
 using System.Web.Util;
+using System.Globalization;
 
 namespace System.Web.Security
 {
@@ -49,6 +50,51 @@ namespace System.Web.Security
 
                static string authConfigPath = "system.web/authentication";
                static string machineKeyConfigPath = "system.web/machineKey";
+#if TARGET_J2EE
+               const string Forms_initialized = "Forms.initialized";
+               const string Forms_cookieName = "Forms.cookieName";
+               const string Forms_cookiePath = "Forms.cookiePath";
+               const string Forms_timeout = "Forms.timeout";
+               const string Forms_protection = "Forms.protection";
+               const string Forms_init_vector = "Forms.init_vector";
+               static bool initialized
+               {
+                       get {
+                               object o = AppDomain.CurrentDomain.GetData (Forms_initialized);
+                               return o != null ? (bool) o : false;
+                       }
+                       set { AppDomain.CurrentDomain.SetData (Forms_initialized, value); }
+               }
+               static string cookieName
+               {
+                       get { return (string) AppDomain.CurrentDomain.GetData (Forms_cookieName); }
+                       set { AppDomain.CurrentDomain.SetData (Forms_cookieName, value); }
+               }
+               static string cookiePath
+               {
+                       get { return (string) AppDomain.CurrentDomain.GetData (Forms_cookiePath); }
+                       set { AppDomain.CurrentDomain.SetData (Forms_cookiePath, value); }
+               }
+               static int timeout
+               {
+                       get {
+                               object o = AppDomain.CurrentDomain.GetData (Forms_timeout);
+                               return o != null ? (int) o : 0;
+                       }
+                       set { AppDomain.CurrentDomain.SetData (Forms_timeout, value); }
+               }
+               static FormsProtectionEnum protection
+               {
+                       get { return (FormsProtectionEnum) AppDomain.CurrentDomain.GetData (Forms_protection); }
+                       set { AppDomain.CurrentDomain.SetData (Forms_protection, value); }
+               }
+               static byte [] init_vector
+               {
+                       get { return (byte []) AppDomain.CurrentDomain.GetData (Forms_init_vector); }
+                       set { AppDomain.CurrentDomain.SetData (Forms_init_vector, value); }
+               }
+               static object locker = new object ();
+#else
                static bool initialized;
                static string cookieName;
                static string cookiePath;
@@ -56,17 +102,85 @@ namespace System.Web.Security
                static FormsProtectionEnum protection;
                static object locker = new object ();
                static byte [] init_vector; // initialization vector used for 3DES
+#endif
 #if NET_1_1
+#if TARGET_J2EE
+               const string Forms_requireSSL = "Forms.requireSSL";
+               const string Forms_slidingExpiration = "Forms.slidingExpiration";
+
+               static bool requireSSL
+               {
+                       get {
+                               object o = AppDomain.CurrentDomain.GetData (Forms_requireSSL);
+                               return o != null ? (bool) o : false;
+                       }
+                       set { AppDomain.CurrentDomain.SetData (Forms_requireSSL, value); }
+               }
+               static bool slidingExpiration
+               {
+                       get {
+                               object o = AppDomain.CurrentDomain.GetData (Forms_slidingExpiration);
+                               return o != null ? (bool) o : false;
+                       }
+                       set { AppDomain.CurrentDomain.SetData (Forms_slidingExpiration, value); }
+               }
+#else
                static bool requireSSL;
                static bool slidingExpiration;
 #endif
+#endif
 #if NET_2_0
+#if TARGET_J2EE
+               const string Forms_cookie_domain = "Forms.cookie_domain";
+               const string Forms_cookie_mode = "Forms.cookie_mode";
+               const string Forms_cookies_supported = "Forms.cookies_supported";
+               const string Forms_default_url = "Forms.default_url";
+               const string Forms_enable_crossapp_redirects = "Forms.enable_crossapp_redirects";
+               const string Forms_login_url = "Forms.login_url";
+               static string cookie_domain
+               {
+                       get { return (string) AppDomain.CurrentDomain.GetData (Forms_cookie_domain); }
+                       set { AppDomain.CurrentDomain.SetData (Forms_cookie_domain, value); }
+               }
+               static HttpCookieMode cookie_mode
+               {
+                       get { return (HttpCookieMode) AppDomain.CurrentDomain.GetData (Forms_cookie_mode); }
+                       set { AppDomain.CurrentDomain.SetData (Forms_cookie_mode, value); }
+               }
+               static bool cookies_supported
+               {
+                       get {
+                               object o = AppDomain.CurrentDomain.GetData (Forms_cookies_supported);
+                               return o != null ? (bool) o : false;
+                       }
+                       set { AppDomain.CurrentDomain.SetData (Forms_cookies_supported, value); }
+               }
+               static string default_url
+               {
+                       get { return (string) AppDomain.CurrentDomain.GetData (Forms_default_url); }
+                       set { AppDomain.CurrentDomain.SetData (Forms_default_url, value); }
+               }
+               static bool enable_crossapp_redirects
+               {
+                       get {
+                               object o = AppDomain.CurrentDomain.GetData (Forms_enable_crossapp_redirects);
+                               return o != null ? (bool) o : false;
+                       }
+                       set { AppDomain.CurrentDomain.SetData (Forms_enable_crossapp_redirects, value); }
+               }
+               static string login_url
+               {
+                       get { return (string) AppDomain.CurrentDomain.GetData (Forms_login_url); }
+                       set { AppDomain.CurrentDomain.SetData (Forms_login_url, value); }
+               }
+#else
                static string cookie_domain;
                static HttpCookieMode cookie_mode;
                static bool cookies_supported;
                static string default_url;
                static bool enable_crossapp_redirects;
                static string login_url;
+#endif
 #endif
                // same names and order used in xsp
                static string [] indexFiles = { "index.aspx",
@@ -89,6 +203,7 @@ namespace System.Web.Security
                        if (context == null)
                                throw new HttpException ("Context is null!");
 
+                       name = name.ToLower ();
 #if NET_2_0
                        AuthenticationSection section = (AuthenticationSection) WebConfigurationManager.GetSection (authConfigPath);
                        FormsAuthenticationCredentials config = section.Forms.Credentials;
@@ -120,6 +235,18 @@ namespace System.Web.Security
                        return (password == stored);
                }
 
+#if NET_2_0
+               static byte [] GetDecryptionKey (MachineKeySection config)
+               {
+                       return MachineKeySectionUtils.DecryptionKey192Bits (config);
+               }
+#else
+               static byte [] GetDecryptionKey (MachineKeyConfig config)
+               {
+                       return config.DecryptionKey192Bits;
+               }
+#endif
+               
                static FormsAuthenticationTicket Decrypt2 (byte [] bytes)
                {
                        if (protection == FormsProtectionEnum.None)
@@ -135,7 +262,7 @@ namespace System.Web.Security
                        byte [] result = bytes;
                        if (all || protection == FormsProtectionEnum.Encryption) {
                                ICryptoTransform decryptor;
-                               decryptor = TripleDES.Create ().CreateDecryptor (config.DecryptionKey192Bits, init_vector);
+                               decryptor = TripleDES.Create ().CreateDecryptor (GetDecryptionKey (config), init_vector);
                                result = decryptor.TransformFinalBlock (bytes, 0, bytes.Length);
                                bytes = null;
                        }
@@ -155,7 +282,7 @@ namespace System.Web.Security
                                        count = SHA1_hash_size; // 3DES and SHA1
 
 #if NET_2_0
-                               byte [] vk = config.ValidationKeyBytes;
+                               byte [] vk = MachineKeySectionUtils.ValidationKeyBytes (config);
 #else
                                byte [] vk = config.ValidationKey;
 #endif
@@ -197,7 +324,7 @@ namespace System.Web.Security
 
                        FormsAuthenticationTicket ticket;
 #if NET_2_0
-                       byte [] bytes = MachineKeySection.GetBytes (encryptedTicket, encryptedTicket.Length);
+                       byte [] bytes = MachineKeySectionUtils.GetBytes (encryptedTicket, encryptedTicket.Length);
 #else
                        byte [] bytes = MachineKeyConfig.GetBytes (encryptedTicket, encryptedTicket.Length);
 #endif
@@ -230,7 +357,7 @@ namespace System.Web.Security
                        if (all || protection == FormsProtectionEnum.Validation) {
                                byte [] valid_bytes = null;
 #if NET_2_0
-                               byte [] vk = config.ValidationKeyBytes;
+                               byte [] vk = MachineKeySectionUtils.ValidationKeyBytes (config);
 #else
                                byte [] vk = config.ValidationKey;
 #endif
@@ -264,7 +391,7 @@ namespace System.Web.Security
 
                        if (all || protection == FormsProtectionEnum.Encryption) {
                                ICryptoTransform encryptor;
-                               encryptor = TripleDES.Create ().CreateEncryptor (config.DecryptionKey192Bits, init_vector);
+                               encryptor = TripleDES.Create ().CreateEncryptor (GetDecryptionKey (config), init_vector);
                                result = encryptor.TransformFinalBlock (result, 0, result.Length);
                        }
 
@@ -310,6 +437,11 @@ namespace System.Web.Security
                        return cookie;
                }
 
+               internal static string ReturnUrl
+               {
+                       get { return HttpContext.Current.Request ["RETURNURL"]; }
+               }
+
                public static string GetRedirectUrl (string userName, bool createPersistentCookie)
                {
                        if (userName == null)
@@ -317,7 +449,7 @@ namespace System.Web.Security
 
                        Initialize ();
                        HttpRequest request = HttpContext.Current.Request;
-                       string returnUrl = request ["RETURNURL"];
+                       string returnUrl = ReturnUrl;
                        if (returnUrl != null)
                                return returnUrl;
 
@@ -342,11 +474,17 @@ namespace System.Web.Security
 
                static string GetHexString (byte [] bytes)
                {
-                       StringBuilder result = new StringBuilder (bytes.Length * 2);
-                       foreach (byte b in bytes)
-                               result.AppendFormat ("{0:X2}", (int) b);
-
-                       return result.ToString ();
+                       const int letterPart = 55;
+                       const int numberPart = 48;
+                       char [] result = new char [bytes.Length * 2];
+                       for (int i = 0; i < bytes.Length; i++) {
+                               int tmp = (int) bytes [i];
+                               int second = tmp & 15;
+                               int first = (tmp >> 4) & 15;
+                               result [(i * 2)] = (char) (first > 9 ? letterPart + first : numberPart + first);
+                               result [(i * 2) + 1] = (char) (second > 9 ? letterPart + second : numberPart + second);
+                       }
+                       return new string (result);
                }
 
                public static string HashPasswordForStoringInConfigFile (string password, string passwordFormat)
@@ -358,9 +496,9 @@ namespace System.Web.Security
                                throw new ArgumentNullException ("passwordFormat");
 
                        byte [] bytes;
-                       if (String.Compare (passwordFormat, "MD5", true) == 0) {
+                       if (String.Compare (passwordFormat, "MD5", true, CultureInfo.InvariantCulture) == 0) {
                                bytes = MD5.Create ().ComputeHash (Encoding.UTF8.GetBytes (password));
-                       } else if (String.Compare (passwordFormat, "SHA1", true) == 0) {
+                       } else if (String.Compare (passwordFormat, "SHA1", true, CultureInfo.InvariantCulture) == 0) {
                                bytes = SHA1.Create ().ComputeHash (Encoding.UTF8.GetBytes (password));
                        } else {
                                throw new ArgumentException ("The format must be either MD5 or SHA1", "passwordFormat");
@@ -431,12 +569,14 @@ namespace System.Web.Security
                        }
                }
 
+#if NET_2_0
                static string MapUrl (string url) {
                        if (UrlUtils.IsRelativeUrl (url))
                                return UrlUtils.Combine (HttpRuntime.AppDomainAppVirtualPath, url);
                        else
                                return UrlUtils.ResolveVirtualPathFromAppAbsolute (url);
                }
+#endif
 
                public static void RedirectFromLoginPage (string userName, bool createPersistentCookie)
                {
@@ -506,6 +646,10 @@ namespace System.Web.Security
                        expiration_cookie.Expires = new DateTime (1999, 10, 12);
                        expiration_cookie.Path = cookiePath;
                        cc.Add (expiration_cookie);
+
+#if NET_2_0
+                       Roles.DeleteCookie ();
+#endif
                }
 
                public static string FormsCookieName
@@ -575,13 +719,14 @@ namespace System.Web.Security
                        // TODO: if ? is in LoginUrl (legal?), ? in query (legal?) ...
                        Redirect (LoginUrl + "?" + extraQueryString);
                }
-#endif
-               private static void Redirect (string url)
+
+               static void Redirect (string url)
                {
                        HttpContext.Current.Response.Redirect (url);
                }
+#endif
 
-               private static void Redirect (string url, bool end)
+               static void Redirect (string url, bool end)
                {
                        HttpContext.Current.Response.Redirect (url, end);
                }