Merge pull request #2964 from ludovic-henry/sgen-monocontext
[mono.git] / mcs / class / referencesource / System.Web / Util / SecUtil.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="SecurityUtil.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>                                                                
5 //------------------------------------------------------------------------------
6
7 /*
8  * SecurityUtil class
9  * 
10  * Copyright (c) 1999 Microsoft Corporation
11  */
12
13 namespace System.Web.Util {
14     using System.Globalization;
15     using System.Web.Hosting;
16     using System.Collections;
17     using System.Collections.Specialized;
18     using System.Data;
19     using System.Data.SqlClient;
20     using System.Data.SqlTypes;
21     using System.Configuration.Provider;
22     using System.Configuration;
23     using System.Text.RegularExpressions;
24     using System.Web.DataAccess;
25
26     internal static class SecUtility {
27
28         internal static string GetDefaultAppName() {
29             try {
30                 string appName = HostingEnvironment.ApplicationVirtualPath;
31                 if (String.IsNullOrEmpty(appName)) {
32 #if !FEATURE_PAL
33                     // ROTORTODO: enable Process.MainModule or support an alternative 
34                     // naming scheme for (HttpRuntime.AppDomainAppVirtualPath == null)
35
36                     appName = System.Diagnostics.Process.GetCurrentProcess().
37                                      MainModule.ModuleName;
38
39                     int indexOfDot = appName.IndexOf('.');
40                     if (indexOfDot != -1) {
41                         appName = appName.Remove(indexOfDot);
42                     }
43 #endif // !FEATURE_PAL
44                 }
45
46                 if (String.IsNullOrEmpty(appName)) {
47                     return "/";
48                 }
49                 else {
50                     return appName;
51                 }
52             }
53             catch {
54                 return "/";
55             }
56         }
57
58         internal static string GetConnectionString(NameValueCollection config) {
59             Debug.Assert(config != null);
60
61             string connectionString = config["connectionString"];
62             if (!String.IsNullOrEmpty(connectionString)) {
63                 return connectionString;
64             }
65             else {
66                 string connectionStringName = config["connectionStringName"];
67                 if (String.IsNullOrEmpty(connectionStringName))
68                     throw new ProviderException(SR.GetString(SR.Connection_name_not_specified));
69
70                 connectionString = SqlConnectionHelper.GetConnectionString(connectionStringName, lookupConnectionString: true, appLevel: true);
71                 if (String.IsNullOrEmpty(connectionString)) {
72                     throw new ProviderException(SR.GetString(SR.Connection_string_not_found, connectionStringName));
73                 }
74                 else {
75                     return connectionString;
76                 }
77             }
78         }
79
80         // We don't trim the param before checking with password parameters
81         internal static bool ValidatePasswordParameter(ref string param, int maxSize) {
82             if (param == null) {
83                 return false;
84             }
85
86             if (param.Length < 1) {
87                 return false;
88             }
89
90             if (maxSize > 0 && (param.Length > maxSize) ) {
91                 return false;
92             }
93
94             return true;
95         }
96
97         internal static bool ValidateParameter(ref string param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize) {
98             if (param == null) {
99                 return !checkForNull;
100             }
101
102             param = param.Trim();
103             if ((checkIfEmpty && param.Length < 1) ||
104                  (maxSize > 0 && param.Length > maxSize) ||
105                  (checkForCommas && param.Contains(","))) {
106                 return false;
107             }
108
109             return true;
110         }
111
112         // We don't trim the param before checking with password parameters
113         internal static void CheckPasswordParameter(ref string param, int maxSize, string paramName) {
114             if (param == null) {
115                 throw new ArgumentNullException(paramName);
116             }
117
118             if (param.Length < 1) {
119                 throw new ArgumentException(SR.GetString(SR.Parameter_can_not_be_empty, paramName), paramName);
120             }
121
122             if (maxSize > 0 && param.Length > maxSize) {
123                 throw new ArgumentException(SR.GetString(SR.Parameter_too_long, paramName, maxSize.ToString(CultureInfo.InvariantCulture)), paramName);
124             }
125         }
126
127         internal static void CheckParameter(ref string param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize, string paramName) {
128             if (param == null) {
129                 if (checkForNull) {
130                     throw new ArgumentNullException(paramName);
131                 }
132
133                 return;
134             }
135
136             param = param.Trim();
137             if (checkIfEmpty && param.Length < 1) {
138                 throw new ArgumentException(SR.GetString(SR.Parameter_can_not_be_empty, paramName), paramName);
139             }
140
141             if (maxSize > 0 && param.Length > maxSize) {
142                 throw new ArgumentException(SR.GetString(SR.Parameter_too_long, paramName, maxSize.ToString(CultureInfo.InvariantCulture)), paramName);
143             }
144
145             if (checkForCommas && param.Contains(",")) {
146                 throw new ArgumentException(SR.GetString(SR.Parameter_can_not_contain_comma, paramName), paramName);
147             }
148         }
149
150         internal static void CheckArrayParameter(ref string[] param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize, string paramName) {
151             if (param == null) {
152                 throw new ArgumentNullException(paramName);
153             }
154
155             if (param.Length < 1) {
156                 throw new ArgumentException(SR.GetString(SR.Parameter_array_empty, paramName), paramName);
157             }
158
159             Hashtable values = new Hashtable(param.Length);
160             for (int i = param.Length - 1; i >= 0; i--) {
161                 SecUtility.CheckParameter(ref param[i], checkForNull, checkIfEmpty, checkForCommas, maxSize, 
162                     paramName + "[ " + i.ToString(CultureInfo.InvariantCulture) + " ]");
163                 if (values.Contains(param[i])) {
164                     throw new ArgumentException(SR.GetString(SR.Parameter_duplicate_array_element, paramName), paramName);
165                 }
166                 else {
167                     values.Add(param[i], param[i]);
168                 }
169             }
170         }
171
172         internal static bool GetBooleanValue(NameValueCollection config, string valueName, bool defaultValue) {
173             string sValue = config[valueName];
174             if (sValue == null) {
175                 return defaultValue;
176             }
177
178             bool result;
179             if (bool.TryParse(sValue, out result)) {
180                 return result;
181             }
182             else {
183                 throw new ProviderException(SR.GetString(SR.Value_must_be_boolean, valueName));
184             }
185         }
186
187         internal static int GetIntValue(NameValueCollection config, string valueName, int defaultValue, bool zeroAllowed, int maxValueAllowed) {
188             string sValue = config[valueName];
189
190             if (sValue == null) {
191                 return defaultValue;
192             }
193
194             int iValue;
195             if (!Int32.TryParse(sValue, out iValue)) {
196                 if (zeroAllowed) {
197                     throw new ProviderException(SR.GetString(SR.Value_must_be_non_negative_integer, valueName));
198                 }
199
200                 throw new ProviderException(SR.GetString(SR.Value_must_be_positive_integer, valueName));
201             }
202
203             if (zeroAllowed && iValue < 0) {
204                 throw new ProviderException(SR.GetString(SR.Value_must_be_non_negative_integer, valueName));
205             }
206
207             if (!zeroAllowed && iValue <= 0) {
208                 throw new ProviderException(SR.GetString(SR.Value_must_be_positive_integer, valueName));
209             }
210
211             if (maxValueAllowed > 0 && iValue > maxValueAllowed) {
212                 throw new ProviderException(SR.GetString(SR.Value_too_big, valueName, maxValueAllowed.ToString(CultureInfo.InvariantCulture)));
213             }
214
215             return iValue;
216         }
217
218         internal static int? GetNullableIntValue(NameValueCollection config, string valueName) {
219             int iValue;
220             string sValue = config[valueName];
221
222             if (sValue == null || !Int32.TryParse(sValue, out iValue)) {
223                 return null;
224             }
225
226             return iValue;
227         }
228
229 #if !FEATURE_PAL //
230         internal static void CheckSchemaVersion(ProviderBase provider, SqlConnection connection, string[] features, string version, ref int schemaVersionCheck) {
231             if (connection == null) {
232                 throw new ArgumentNullException("connection");
233             }
234
235             if (features == null) {
236                 throw new ArgumentNullException("features");
237             }
238
239             if (version == null) {
240                 throw new ArgumentNullException("version");
241             }
242
243             if (schemaVersionCheck == -1) {
244                 throw new ProviderException(SR.GetString(SR.Provider_Schema_Version_Not_Match, provider.ToString(), version));
245             }
246             else if (schemaVersionCheck == 0) {
247                 lock (provider) {
248                     if (schemaVersionCheck == -1) {
249                         throw new ProviderException(SR.GetString(SR.Provider_Schema_Version_Not_Match, provider.ToString(), version));
250                     }
251                     else if (schemaVersionCheck == 0) {
252                         int iStatus = 0;
253                         SqlCommand cmd = null;
254                         SqlParameter p = null;
255
256                         foreach (string feature in features) {
257                             cmd = new SqlCommand("dbo.aspnet_CheckSchemaVersion", connection);
258
259                             cmd.CommandType = CommandType.StoredProcedure;
260
261                             p = new SqlParameter("@Feature", feature);
262                             cmd.Parameters.Add(p);
263
264                             p = new SqlParameter("@CompatibleSchemaVersion", version);
265                             cmd.Parameters.Add(p);
266
267                             p = new SqlParameter("@ReturnValue", SqlDbType.Int);
268                             p.Direction = ParameterDirection.ReturnValue;
269                             cmd.Parameters.Add(p);
270
271                             cmd.ExecuteNonQuery();
272
273                             iStatus = ((p.Value != null) ? ((int)p.Value) : -1);
274                             if (iStatus != 0) {
275                                 schemaVersionCheck = -1;
276
277                                 throw new ProviderException(SR.GetString(SR.Provider_Schema_Version_Not_Match, provider.ToString(), version));
278                             }
279                         }
280
281                         schemaVersionCheck = 1;
282                     }
283                 }
284             }
285         }
286 #endif // !FEATURE_PAL
287     }
288 }