Merge pull request #3386 from alexanderkyte/nunit_lite_return_status
[mono.git] / mcs / class / referencesource / System.Web / Util / EnableViewStateMacRegistryHelper.cs
1 //------------------------------------------------------------------------------
2 // <copyright file="EnableViewStateMacRegistryHelper.cs" company="Microsoft">
3 //     Copyright (c) Microsoft Corporation.  All rights reserved.
4 // </copyright>
5 //------------------------------------------------------------------------------
6
7 namespace System.Web.Util {
8     using Microsoft.Win32;
9     using System;
10     using System.Globalization;
11     using System.Security.Permissions;
12
13     // See DevDiv #461378 for a description of why we authored the EnableViewStateMac patch using this helper class.
14     internal static class EnableViewStateMacRegistryHelper {
15
16         // Returns 'true' if the EnableViewStateMac patch (DevDiv #461378) is enabled,
17         // meaning that we always enforce EnableViewStateMac=true. Returns 'false' if
18         // the patch hasn't been activated on this machine.
19         public static readonly bool EnforceViewStateMac;
20
21         // Returns 'true' if all MAC validation errors should be considered harmless
22         // and ----ed.
23         public static readonly bool SuppressMacValidationErrorsAlways;
24
25         // Returns 'true' if we should suppress MAC validation errors from cross-page
26         // postbacks.
27         public static readonly bool SuppressMacValidationErrorsFromCrossPagePostbacks;
28
29         // Returns 'true' if we should write out a __VIEWSTATEGENERATOR field alongside
30         // each __VIEWSTATE field.
31         public static readonly bool WriteViewStateGeneratorField;
32
33         static EnableViewStateMacRegistryHelper() {
34             // If the reg key is applied, change the default values.
35             bool regKeyIsActive = IsMacEnforcementEnabledViaRegistry();
36             if (regKeyIsActive) {
37                 EnforceViewStateMac = true;
38                 SuppressMacValidationErrorsFromCrossPagePostbacks = true;
39             }
40
41             // Override the defaults with what the developer specified.
42             if (AppSettings.AllowInsecureDeserialization.HasValue) {
43                 EnforceViewStateMac = !AppSettings.AllowInsecureDeserialization.Value;
44
45                 // Exception: MAC errors from cross-page postbacks should be suppressed
46                 // if either the <appSettings> switch is set or the reg key is set.
47                 SuppressMacValidationErrorsFromCrossPagePostbacks |= !AppSettings.AllowInsecureDeserialization.Value;
48             }
49
50             SuppressMacValidationErrorsAlways = AppSettings.AlwaysIgnoreViewStateValidationErrors;
51             if (SuppressMacValidationErrorsAlways) {
52                 // Cross-page postbacks fall under the "always" umbrella
53                 SuppressMacValidationErrorsFromCrossPagePostbacks = true;
54             }
55             else {
56                 // Need to write the __VIEWSTATEGENERATOR field to differentiate between cross-page
57                 // and same-page postback scenarios.
58                 if (SuppressMacValidationErrorsFromCrossPagePostbacks) {
59                     WriteViewStateGeneratorField = true;
60                 }
61             }
62         }
63
64         [RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
65         private static bool IsMacEnforcementEnabledViaRegistry() {
66             try {
67                 string keyName = String.Format(CultureInfo.InvariantCulture, @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{0}", Environment.Version.ToString(3));
68                 int rawValue = (int)Registry.GetValue(keyName, "AspNetEnforceViewStateMac", defaultValue: 0 /* disabled by default */);
69                 return (rawValue != 0);
70             }
71             catch {
72                 // If we cannot read the registry for any reason, fail safe and assume enforcement is enabled.
73                 return true;
74             }
75         }
76     }
77 }