Merge pull request #569 from knocte/fix_cairo_profile_versions_problem
[mono.git] / mcs / class / System.Web.Mvc / System.Web.Mvc / AntiForgeryData.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc {\r
14     using System;\r
15     using System.Security.Cryptography;\r
16     using System.Text;\r
17 \r
18     internal sealed class AntiForgeryData {\r
19 \r
20         private const string AntiForgeryTokenFieldName = "__RequestVerificationToken";\r
21 \r
22         private const int TokenLength = 128 / 8;\r
23         private static RNGCryptoServiceProvider _prng = new RNGCryptoServiceProvider();\r
24 \r
25         private string _salt;\r
26         private string _value;\r
27 \r
28         public AntiForgeryData() {\r
29         }\r
30 \r
31         // copy constructor\r
32         public AntiForgeryData(AntiForgeryData token) {\r
33             if (token == null) {\r
34                 throw new ArgumentNullException("token");\r
35             }\r
36 \r
37             CreationDate = token.CreationDate;\r
38             Salt = token.Salt;\r
39             Value = token.Value;\r
40         }\r
41 \r
42         public DateTime CreationDate {\r
43             get;\r
44             set;\r
45         }\r
46 \r
47         public string Salt {\r
48             get {\r
49                 return _salt ?? String.Empty;\r
50             }\r
51             set {\r
52                 _salt = value;\r
53             }\r
54         }\r
55 \r
56         public string Value {\r
57             get {\r
58                 return _value ?? String.Empty;\r
59             }\r
60             set {\r
61                 _value = value;\r
62             }\r
63         }\r
64 \r
65         private static string Base64EncodeForCookieName(string s) {\r
66             byte[] rawBytes = Encoding.UTF8.GetBytes(s);\r
67             string base64String = Convert.ToBase64String(rawBytes);\r
68 \r
69             // replace base64-specific characters with characters that are safe for a cookie name\r
70             return base64String.Replace('+', '.').Replace('/', '-').Replace('=', '_');\r
71         }\r
72 \r
73         private static string GenerateRandomTokenString() {\r
74             byte[] tokenBytes = new byte[TokenLength];\r
75             _prng.GetBytes(tokenBytes);\r
76 \r
77             string token = Convert.ToBase64String(tokenBytes);\r
78             return token;\r
79         }\r
80 \r
81         // If the app path is provided, we're generating a cookie name rather than a field name, and the cookie names should\r
82         // be unique so that a development server cookie and an IIS cookie - both running on localhost - don't stomp on\r
83         // each other.\r
84         internal static string GetAntiForgeryTokenName(string appPath) {\r
85             if (String.IsNullOrEmpty(appPath)) {\r
86                 return AntiForgeryTokenFieldName;\r
87             }\r
88             else {\r
89                 return AntiForgeryTokenFieldName + "_" + Base64EncodeForCookieName(appPath);\r
90             }\r
91         }\r
92 \r
93         public static AntiForgeryData NewToken() {\r
94             string tokenString = GenerateRandomTokenString();\r
95             return new AntiForgeryData() {\r
96                 CreationDate = DateTime.Now,\r
97                 Value = tokenString\r
98             };\r
99         }\r
100 \r
101     }\r
102 }\r