Author: spouliot
Date: 2008-02-15 15:04:48 -0500 (Fri, 15 Feb 2008)
New Revision: 95816

Modified:
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/ArrayFieldsShouldNotBeReadOnlyRule.cs
   trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/ChangeLog
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/MethodCallWithSubsetLinkDemandRule.cs
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/NativeFieldsShouldNotBeVisibleRule.cs
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/NonVirtualMethodWithInheritanceDemandRule.cs
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/SealedTypeWithInheritanceDemandRule.cs
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/SecureGetObjectDataOverridesRule.cs
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/StaticConstructorsShouldBePrivateRule.cs
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeExposeFieldsRule.cs
   
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeIsNotSubsetOfMethodSecurityRule.cs
   trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeLinkDemandRule.cs
Log:
2008-02-15  Sebastien Pouliot  <[EMAIL PROTECTED]>

        * ArrayFieldsShouldNotBeReadOnlyRule.cs
        * MethodCallWithSubsetLinkDemandRule.cs
        * NativeFieldsShouldNotBeVisibleRule.cs
        * NonVirtualMethodWithInheritanceDemandRule.cs
        * SealedTypeWithInheritanceDemandRule.cs
        * SecureGetObjectDataOverridesRule.cs
        * StaticConstructorsShouldBePrivateRule.cs
        * TypeExposeFieldsRule.cs
        * TypeIsNotSubsetOfMethodSecurityRule.cs
        * TypeLinkDemandRule.cs:
                Update rules wrt framework changes.



Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/ArrayFieldsShouldNotBeReadOnlyRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/ArrayFieldsShouldNotBeReadOnlyRule.cs
       2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/ArrayFieldsShouldNotBeReadOnlyRule.cs
       2008-02-15 20:04:48 UTC (rev 95816)
@@ -33,25 +33,25 @@
 
 namespace Gendarme.Rules.Security {
 
-       public class ArrayFieldsShouldNotBeReadOnlyRule : ITypeRule {
+       [Problem ("This type contains read-only array(s), however values inside 
the array(s) are not read-only.")]
+       [Solution ("Replace the array with a method returning a clone of the 
array or a read-only collection.")]
+       public class ArrayFieldsShouldNotBeReadOnlyRule : Rule, ITypeRule {
 
-               public MessageCollection CheckType (TypeDefinition type, Runner 
runner)
+               public RuleResult CheckType (TypeDefinition type)
                {
+                       // rule does not apply to interface and enumerations 
??? struct ???
                        if (type.IsInterface || type.IsEnum)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
-                       MessageCollection results = null;
                        foreach (FieldDefinition field in type.Fields) {
-                               if (field.IsInitOnly && field.IsVisible () && 
field.FieldType.IsArray ()) { //IsInitOnly == readonly
-                                       if (results == null)
-                                               results = new MessageCollection 
();
-                                       Location loc = new Location (field);
-                                       Message msg = new Message ("This array 
field is InitOnly (readonly). The readonly attribute does not apply to the 
elements of the array.", loc, MessageType.Warning);
-                                       results.Add (msg);
+                               //IsInitOnly == readonly
+                               if (field.IsInitOnly && field.IsVisible () && 
field.FieldType.IsArray ()) {
+                                       // Medium = this will work as long as 
no code starts "playing" with the array values
+                                       Runner.Report (field, Severity.Medium, 
Confidence.Total, String.Empty);
                                }
                        }
 
-                       return results;
+                       return Runner.CurrentRuleResult;
                }
        }
 }

Modified: trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/ChangeLog
===================================================================
--- trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/ChangeLog   
2008-02-15 20:00:48 UTC (rev 95815)
+++ trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/ChangeLog   
2008-02-15 20:04:48 UTC (rev 95816)
@@ -1,3 +1,17 @@
+2008-02-15  Sebastien Pouliot  <[EMAIL PROTECTED]>
+
+       * ArrayFieldsShouldNotBeReadOnlyRule.cs
+       * MethodCallWithSubsetLinkDemandRule.cs
+       * NativeFieldsShouldNotBeVisibleRule.cs
+       * NonVirtualMethodWithInheritanceDemandRule.cs
+       * SealedTypeWithInheritanceDemandRule.cs
+       * SecureGetObjectDataOverridesRule.cs
+       * StaticConstructorsShouldBePrivateRule.cs
+       * TypeExposeFieldsRule.cs
+       * TypeIsNotSubsetOfMethodSecurityRule.cs
+       * TypeLinkDemandRule.cs:
+               Update rules wrt framework changes.
+
 2008-01-21  Sebastien Pouliot  <[EMAIL PROTECTED]>
 
        * ArrayFieldsShouldNotBeReadOnlyRule.cs: New. Rule that warns 

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/MethodCallWithSubsetLinkDemandRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/MethodCallWithSubsetLinkDemandRule.cs
       2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/MethodCallWithSubsetLinkDemandRule.cs
       2008-02-15 20:04:48 UTC (rev 95816)
@@ -28,15 +28,17 @@
 
 using System;
 using System.Security;
-using System.Security.Permissions;
 
 using Mono.Cecil;
 using Mono.Cecil.Cil;
+
 using Gendarme.Framework;
 
 namespace Gendarme.Rules.Security {
 
-       public class MethodCallWithSubsetLinkDemandRule : IMethodRule {
+       [Problem ("This method is less protected than some methods it calls.")]
+       [Solution ("Ensure that the LinkDemand on this method is a superset of 
any LinkDemand present on called methods.")]
+       public class MethodCallWithSubsetLinkDemandRule : Rule, IMethodRule {
 
                private static PermissionSet GetLinkDemand (MethodDefinition 
method)
                {
@@ -61,45 +63,38 @@
                        return calleeLinkDemand.IsSubsetOf (GetLinkDemand 
(caller));
                }
 
-               public MessageCollection CheckMethod (MethodDefinition method, 
Runner runner)
+               public RuleResult CheckMethod (MethodDefinition method)
                {
                        // #1 - rule apply to methods are publicly accessible
                        //      note that the type doesn't have to be public 
(indirect access)
                        if (!method.IsPublic)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        // #2 - rule apply only if the method has a body (e.g. 
p/invokes, icalls don't)
                        //      otherwise we don't know what it's calling
                        if (!method.HasBody)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        // *** ok, the rule applies! ***
 
                        // #3 - look for every method we call
-                       MessageCollection mc = null;
                        foreach (Instruction ins in method.Body.Instructions) {
                                switch (ins.OpCode.Code) {
                                case Code.Call:
                                case Code.Callvirt:
                                case Code.Calli:
-                                       MethodDefinition callee = 
AssemblyManager.GetMethod (ins.Operand);
-                                       if (callee == null) {
-                                               return runner.RuleSuccess; // 
ignore (missing reference)
-                                       }
+                                       MethodDefinition callee = (ins.Operand 
as MethodDefinition);
+                                       if (callee == null)
+                                               continue;
+
                                        // 4 - and if it has security, ensure 
we don't reduce it's strength
                                        if ((callee.SecurityDeclarations.Count 
> 0) && !Check (method, callee)) {
-                                               Location loc = new Location 
(method, ins.Offset);
-                                               Message msg = new Message 
("Method doesn't have a subset of the LinkDemand", loc, MessageType.Warning); 
-                                               if (mc == null)
-                                                       mc = new 
MessageCollection (msg);
-                                               else
-                                                       mc.Add (msg);
-                                               return runner.RuleFailure;
+                                               Runner.Report (method, ins, 
Severity.High, Confidence.High, String.Empty);
                                        }
                                        break;
                                }
                        }
-                       return mc;
+                       return Runner.CurrentRuleResult;
                }
        }
 }

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/NativeFieldsShouldNotBeVisibleRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/NativeFieldsShouldNotBeVisibleRule.cs
       2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/NativeFieldsShouldNotBeVisibleRule.cs
       2008-02-15 20:04:48 UTC (rev 95816)
@@ -33,29 +33,29 @@
 
 namespace Gendarme.Rules.Security {
 
-       public class NativeFieldsShouldNotBeVisibleRule : ITypeRule {
+       [Problem ("This type expose native fields that aren't read-only.")]
+       [Solution ("Native fields are best hidden or, if required, read-only.")]
+       public class NativeFieldsShouldNotBeVisibleRule : Rule, ITypeRule {
 
-               public MessageCollection CheckType (TypeDefinition type, Runner 
runner)
+               public RuleResult CheckType (TypeDefinition type)
                {
+                       // rule does not apply to interface and enumerations
                        if (type.IsInterface || type.IsEnum)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
-                       MessageCollection results = null;
                        foreach (FieldDefinition field in type.Fields) {
                                if (!field.IsVisible ())
                                        continue;
 
                                //not readonly native fields or arrays of 
native fields
-                               if ((field.FieldType.IsNative () && 
!field.IsInitOnly) || (field.FieldType.IsArray () && 
field.FieldType.GetOriginalType ().IsNative ())) {
-                                       if (results == null)
-                                               results = new MessageCollection 
();
-                                       Location loc = new Location (field);
-                                       Message msg = new Message ("This is a 
native field. Native fields should be InitOnly (readonly) or not be visible at 
all.", loc, MessageType.Warning);
-                                       results.Add (msg);
+                               if ((field.FieldType.IsNative () && 
!field.IsInitOnly) || 
+                                       (field.FieldType.IsArray () && 
field.FieldType.GetOriginalType ().IsNative ())) {
+
+                                       Runner.Report (field, Severity.Medium, 
Confidence.Total, String.Empty);
                                }
                        }
 
-                       return results;
+                       return Runner.CurrentRuleResult;
                }
        }
 }

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/NonVirtualMethodWithInheritanceDemandRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/NonVirtualMethodWithInheritanceDemandRule.cs
        2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/NonVirtualMethodWithInheritanceDemandRule.cs
        2008-02-15 20:04:48 UTC (rev 95816)
@@ -4,7 +4,7 @@
 // Authors:
 //     Sebastien Pouliot <[EMAIL PROTECTED]>
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005,2008 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -34,13 +34,15 @@
 
 namespace Gendarme.Rules.Security {
 
-       public class NonVirtualMethodWithInheritanceDemandRule : IMethodRule {
+       [Problem ("This non-virtual method has an InheritanceDemand that the 
runtime will never execute.")]
+       [Solution ("Review the InheritanceDemand on this method and either 
remove it or change its SecurityAction to, probably, a LinkDemand.")]
+       public class NonVirtualMethodWithInheritanceDemandRule : Rule, 
IMethodRule {
 
-               public MessageCollection CheckMethod (MethodDefinition method, 
Runner runner)
+               public RuleResult CheckMethod (MethodDefinition method)
                {
-                       // #1 - this rule apply only to methods with an 
inheritance demand
+                       // this rule apply only to methods with an inheritance 
demand
                        if (method.SecurityDeclarations.Count == 0)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        bool inherit = false;
                        foreach (SecurityDeclaration declsec in 
method.SecurityDeclarations) {
@@ -52,15 +54,16 @@
                                }
                        }
                        if (!inherit)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        // *** ok, the rule applies! ***
 
-                       // #2 - InheritanceDemand doesn't make sense on methods 
that cannot be overriden
-                       if(method.IsVirtual)
-                               return runner.RuleSuccess;
-                       else
-                               return runner.RuleFailure;
+                       // InheritanceDemand doesn't make sense on methods that 
cannot be overriden
+                       if (method.IsVirtual)
+                               return RuleResult.Success;
+
+                       Runner.Report (method, Severity.Low, Confidence.Total, 
String.Empty);
+                       return RuleResult.Failure;
                }
        }
 }

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/SealedTypeWithInheritanceDemandRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/SealedTypeWithInheritanceDemandRule.cs
      2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/SealedTypeWithInheritanceDemandRule.cs
      2008-02-15 20:04:48 UTC (rev 95816)
@@ -4,7 +4,7 @@
 // Authors:
 //     Sebastien Pouliot <[EMAIL PROTECTED]>
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005,2008 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -34,24 +34,26 @@
 
 namespace Gendarme.Rules.Security {
 
-       public class SealedTypeWithInheritanceDemandRule : ITypeRule {
+       [Problem ("This sealed type has an InheritanceDemand that the runtime 
will never execute.")]
+       [Solution ("Review the InheritanceDemand on this type and either remove 
it or change its SecurityAction to, probably, a LinkDemand.")]
+       public class SealedTypeWithInheritanceDemandRule : Rule, ITypeRule {
 
-               public MessageCollection CheckType (TypeDefinition type, Runner 
runner)
+               public RuleResult CheckType (TypeDefinition type)
                {
                        // 1 - this applies only to sealed types
                        if (!type.IsSealed)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        // 2 - the type must have an InheritanceDemand
                        if (type.SecurityDeclarations.Count == 0)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        foreach (SecurityDeclaration declsec in 
type.SecurityDeclarations) {
-                               if (declsec.Action == 
SecurityAction.InheritDemand)
-                                       return runner.RuleFailure;
+                               if (declsec.Action == 
SecurityAction.InheritDemand) {
+                                       Runner.Report (type, Severity.Low, 
Confidence.Total, String.Empty);
+                               }
                        }
-                       // the action wasn't an inheritance demand check
-                       return runner.RuleSuccess;
+                       return Runner.CurrentRuleResult;
                }
        }
 }

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/SecureGetObjectDataOverridesRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/SecureGetObjectDataOverridesRule.cs
 2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/SecureGetObjectDataOverridesRule.cs
 2008-02-15 20:04:48 UTC (rev 95816)
@@ -4,7 +4,7 @@
 // Authors:
 //     Sebastien Pouliot <[EMAIL PROTECTED]>
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005,2008 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -34,11 +34,17 @@
 
 using Mono.Cecil;
 using Gendarme.Framework;
+using Gendarme.Framework.Helpers;
+using Gendarme.Framework.Rocks;
 
 namespace Gendarme.Rules.Security {
 
-       public class SecureGetObjectDataOverridesRule: IMethodRule {
+       [Problem ("The method is not protected correctly against a 
serialization attack.")]
+       [Solution ("A security Demand for SerializationFormatter should protect 
this method.")]
+       public class SecureGetObjectDataOverridesRule : Rule, ITypeRule {
 
+               private const string NotFound = "No [Link]Demand were found.";
+
                static PermissionSet _ruleSet;
 
                static PermissionSet RuleSet {
@@ -52,58 +58,47 @@
                        }
                }
 
-               public MessageCollection CheckMethod (MethodDefinition method, 
Runner runner)
+               public RuleResult CheckType (TypeDefinition type)
                {
-                       // check that the method is called "GetObjectData"
-                       if (method.Name != "GetObjectData")
-                               return runner.RuleSuccess;
+                       // rule applies only to types that implements 
ISerializable
+                       if (!type.Implements 
("System.Runtime.Serialization.ISerializable"))
+                               return RuleResult.DoesNotApply;
 
-                       // check parameters
-                       if (method.Parameters.Count != 2)
-                               return runner.RuleSuccess;
-                       if (method.Parameters[0].ParameterType.ToString () != 
"System.Runtime.Serialization.SerializationInfo")
-                               return runner.RuleSuccess;
-                       if (method.Parameters[1].ParameterType.ToString () != 
"System.Runtime.Serialization.StreamingContext")
-                               return runner.RuleSuccess;
+                       MethodDefinition method = type.GetMethod 
(MethodSignatures.GetObjectData);
+                       if (method == null)
+                               return RuleResult.DoesNotApply;
 
-                       // check for ISerializable
-                       bool iserialize = false;
-                       TypeDefinition type = (TypeDefinition) 
method.DeclaringType;
-                       if (type.Interfaces.Count > 0) {
-                               // check if the type implements the 
"ISerializable" interface
-                               foreach (TypeReference iface in 
type.Interfaces) {
-                                       if (iface.FullName == 
"System.Runtime.Serialization.ISerializable") {
-                                               iserialize = true;
-                                               break;
-                                       }
-                               }
-                       }
-                       if (!iserialize) {
-                               // then it's (recursively) base type may 
implements the "ISerializable" interface
-                               // FIXME - while it's unlikely we have the 
right signature without ISerializable
-                               // (leading to false positive) we should fix 
this using Cecil recent resolver
-                       }
-
                        // *** ok, the rule applies! ***
 
                        // is there any security applied ?
-                       if (method.SecurityDeclarations.Count < 1)
-                               return runner.RuleFailure;
+                       if (method.SecurityDeclarations.Count < 1) {
+                               Runner.Report (method, Severity.High, 
Confidence.Total, NotFound);
+                               return RuleResult.Failure;
+                       }
 
                        // the SerializationFormatter must be a subset of the 
one (of the) demand(s)
+                       bool demand = false;
                        foreach (SecurityDeclaration declsec in 
method.SecurityDeclarations) {
                                switch (declsec.Action) {
                                case Mono.Cecil.SecurityAction.Demand:
                                case Mono.Cecil.SecurityAction.NonCasDemand:
                                case Mono.Cecil.SecurityAction.LinkDemand:
                                case Mono.Cecil.SecurityAction.NonCasLinkDemand:
-                                       if (RuleSet.IsSubsetOf 
(declsec.PermissionSet))
-                                               return runner.RuleSuccess;
+                                       demand = true;
+                                       if (!RuleSet.IsSubsetOf 
(declsec.PermissionSet)) {
+                                               string message = String.Format 
("{0} is not a subset of {1} permission set",
+                                                       
"SerializationFormatter", declsec.Action);
+                                               Runner.Report (method, 
Severity.High, Confidence.Total, message);
+                                       }
                                        break;
                                }
                        }
 
-                       return runner.RuleFailure;
+                       // there was no [NonCas][Link]Demand but other actions 
are possible
+                       if (!demand)
+                               Runner.Report (method, Severity.High, 
Confidence.Total, NotFound);
+
+                       return Runner.CurrentRuleResult;
                }
        }
 }

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/StaticConstructorsShouldBePrivateRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/StaticConstructorsShouldBePrivateRule.cs
    2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/StaticConstructorsShouldBePrivateRule.cs
    2008-02-15 20:04:48 UTC (rev 95816)
@@ -30,27 +30,29 @@
 
 namespace Gendarme.Rules.Security {
 
-       public class StaticConstructorsShouldBePrivateRule : ITypeRule {
+       [Problem ("Static constructors must be private because otherwise they 
may be called once or multiple times from user code.")]
+       [Solution ("Change the static constructor visibility to private.")]
+       public class StaticConstructorsShouldBePrivateRule : Rule, ITypeRule {
 
-               public MessageCollection CheckType (TypeDefinition 
typeDefinition, Runner runner)
+               public RuleResult CheckType (TypeDefinition type)
                {
-                       if (typeDefinition.Constructors.Count == 0)
-                               return runner.RuleSuccess;
+                       // rule does not apply if type has no ctor
+                       if (type.Constructors.Count == 0)
+                               return RuleResult.DoesNotApply;
 
-                       MethodDefinition violatingConstructor = null;
-                       foreach (MethodDefinition constructor in 
typeDefinition.Constructors) {
+                       MethodDefinition private_static_ctor = null;
+                       foreach (MethodDefinition constructor in 
type.Constructors) {
                                if (constructor.IsStatic && 
!constructor.IsPrivate) {
-                                       violatingConstructor = constructor;
+                                       private_static_ctor = constructor;
                                        break; // there cannot be two .cctor's 
so we can stop looking
                                }
                        }
 
-                       if (violatingConstructor == null)
-                               return runner.RuleSuccess;
+                       if (private_static_ctor == null)
+                               return RuleResult.Success;
 
-                       Location loc = new Location (violatingConstructor);
-                       Message msg = new Message ("Static constructors must be 
private because otherwise they may be called once or multiple times from user 
code.", loc, MessageType.Error);
-                       return new MessageCollection (msg);
+                       Runner.Report (private_static_ctor, Severity.Critical, 
Confidence.High, string.Empty);
+                       return RuleResult.Failure;
                }
        }
 }

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeExposeFieldsRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeExposeFieldsRule.cs 
    2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeExposeFieldsRule.cs 
    2008-02-15 20:04:48 UTC (rev 95816)
@@ -4,7 +4,7 @@
 // Authors:
 //     Sebastien Pouliot <[EMAIL PROTECTED]>
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005,2008 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -31,26 +31,25 @@
 using System.Text;
 
 using Mono.Cecil;
+
 using Gendarme.Framework;
+using Gendarme.Framework.Rocks;
 
 namespace Gendarme.Rules.Security {
 
-       public class TypeExposeFieldsRule : ITypeRule {
+       [Problem ("This type has a LinkDemand but expose some public fields.")]
+       [Solution ("Remove the public fields from the class or change the field 
visibility.")]
+       public class TypeExposeFieldsRule : Rule, ITypeRule {
 
-               public MessageCollection CheckType (TypeDefinition type, Runner 
runner)
+               public RuleResult CheckType (TypeDefinition type)
                {
-                       // #1 - rule apply to types (and nested types) that are 
publicly visible
-                       switch (type.Attributes & 
TypeAttributes.VisibilityMask) {
-                       case TypeAttributes.Public:
-                       case TypeAttributes.NestedPublic:
-                               break;
-                       default:
-                               return runner.RuleSuccess;
-                       }
+                       // rule apply only to visible types
+                       if (!type.IsVisible ())
+                               return RuleResult.DoesNotApply;
 
-                       // #2 - rule apply to type is protected by a Demand or 
a LinkDemand
+                       // rule apply only to types protected by either a 
Demand or a LinkDemand
                        if (type.SecurityDeclarations.Count == 0)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        bool demand = false;
                        foreach (SecurityDeclaration declsec in 
type.SecurityDeclarations) {
@@ -63,16 +62,17 @@
                        }
 
                        if (!demand)
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        // *** ok, the rule applies! ***
 
-                       // #3 - so it shouldn't have any public fields
+                       // type shouldn't have any public fields
                        foreach (FieldDefinition field in type.Fields) {
-                               if ((field.Attributes & FieldAttributes.Public) 
== FieldAttributes.Public)
-                                       return runner.RuleFailure;
+                               if (field.IsPublic) {
+                                       Runner.Report (field, 
Severity.Critical, Confidence.Total, String.Empty);
+                               }
                        }
-                       return runner.RuleSuccess;
+                       return Runner.CurrentRuleResult;
                }
        }
 }

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeIsNotSubsetOfMethodSecurityRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeIsNotSubsetOfMethodSecurityRule.cs
      2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeIsNotSubsetOfMethodSecurityRule.cs
      2008-02-15 20:04:48 UTC (rev 95816)
@@ -4,7 +4,7 @@
 // Authors:
 //     Sebastien Pouliot <[EMAIL PROTECTED]>
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005,2008 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -36,7 +36,9 @@
 
 namespace Gendarme.Rules.Security {
 
-       public class TypeIsNotSubsetOfMethodSecurityRule : ITypeRule {
+       [Problem ("This type has declarative security permission that aren't a 
subset of the security on some of it's methods.")]
+       [Solution ("Ensure that the type security is a subset of any method 
security. This rule doesn't apply for LinkDemand an Inheritance demands as both 
the type and methods security will be executed.")]
+       public class TypeIsNotSubsetOfMethodSecurityRule : Rule, ITypeRule {
 
                private PermissionSet assert;
                private PermissionSet deny;
@@ -80,10 +82,11 @@
                        return apply;
                }
 
-               public MessageCollection CheckType (TypeDefinition type, Runner 
runner)
+               public RuleResult CheckType (TypeDefinition type)
                {
+                       // rule applies only if type has security declarations
                        if (!RuleDoesAppliesToType (type))
-                               return runner.RuleSuccess;
+                               return RuleResult.DoesNotApply;
 
                        // *** ok, the rule applies! ***
 
@@ -99,32 +102,31 @@
                                                if (assert == null)
                                                        continue;
                                                if (!assert.IsSubsetOf 
(declsec.PermissionSet))
-                                                       return 
runner.RuleFailure;
+                                                       Runner.Report (method, 
Severity.High, Confidence.Total, "Assert");
                                                break;
                                        case Mono.Cecil.SecurityAction.Deny:
                                                if (deny == null)
                                                        continue;
                                                if (!deny.IsSubsetOf 
(declsec.PermissionSet))
-                                                       return 
runner.RuleFailure;
+                                                       Runner.Report (method, 
Severity.High, Confidence.Total, "Deny");
                                                break;
                                        case 
Mono.Cecil.SecurityAction.PermitOnly:
                                                if (permitonly == null)
                                                        continue;
                                                if (!permitonly.IsSubsetOf 
(declsec.PermissionSet))
-                                                       return 
runner.RuleFailure;
+                                                       Runner.Report (method, 
Severity.High, Confidence.Total, "PermitOnly");
                                                break;
                                        case Mono.Cecil.SecurityAction.Demand:
                                        case 
Mono.Cecil.SecurityAction.NonCasDemand:
                                                if (demand == null)
                                                        continue;
                                                if (!demand.IsSubsetOf 
(declsec.PermissionSet))
-                                                       return 
runner.RuleFailure;
+                                                       Runner.Report (method, 
Severity.High, Confidence.Total, "Demand");
                                                break;
                                        }
                                }
                        }
-                       // other types security applies
-                       return runner.RuleSuccess;
+                       return Runner.CurrentRuleResult;
                }
        }
 }

Modified: 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeLinkDemandRule.cs
===================================================================
--- 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeLinkDemandRule.cs   
    2008-02-15 20:00:48 UTC (rev 95815)
+++ 
trunk/mono-tools/gendarme/rules/Gendarme.Rules.Security/TypeLinkDemandRule.cs   
    2008-02-15 20:04:48 UTC (rev 95816)
@@ -4,7 +4,7 @@
 // Authors:
 //     Sebastien Pouliot <[EMAIL PROTECTED]>
 //
-// Copyright (C) 2005 Novell, Inc (http://www.novell.com)
+// Copyright (C) 2005,2008 Novell, Inc (http://www.novell.com)
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -32,29 +32,25 @@
 
 using Mono.Cecil;
 using Gendarme.Framework;
+using Gendarme.Framework.Rocks;
 
 namespace Gendarme.Rules.Security {
 
-       public class TypeLinkDemandRule: ITypeRule {
+       [Problem ("The type isn't sealed and has a LinkDemand. It should also 
have an InheritanceDemand for the same permissions.")]
+       [Solution ("Add an InheritanceDemand for the same permissions (as the 
LinkDemand) or seal the class.")]
+       public class TypeLinkDemandRule : Rule, ITypeRule {
 
-               public MessageCollection CheckType (TypeDefinition type, Runner 
runner)
+               public RuleResult CheckType (TypeDefinition type)
                {
-                       // #1 - rule apply to types (and nested types) that are 
publicly visible
-                       switch (type.Attributes & 
TypeAttributes.VisibilityMask) {
-                       case TypeAttributes.Public:
-                       case TypeAttributes.NestedPublic:
-                               break;
-                       default:
-                               return runner.RuleSuccess;
-                       }
+                       // rule apply only to types that
+                       // - are publicly visible
+                       // - are not sealed
+                       if (type.IsSealed || !type.IsVisible ())
+                               return RuleResult.DoesNotApply;
 
-                       // #2 - rule apply to types that aren't sealed
-                       if (type.IsSealed)
-                               return runner.RuleSuccess;
-
                        PermissionSet link = null;
                        PermissionSet inherit = null;
-                       // #3 - rule apply to types with a LinkDemand
+                       // rule apply to types with a LinkDemand
                        foreach (SecurityDeclaration declsec in 
type.SecurityDeclarations) {
                                switch (declsec.Action) {
                                case Mono.Cecil.SecurityAction.LinkDemand:
@@ -68,29 +64,33 @@
                                }
                        }
 
+                       // no LinkDemand == no problem
                        if (link == null)
-                               return runner.RuleSuccess; // no LinkDemand == 
no problem
+                               return RuleResult.DoesNotApply;
 
-                       // #4 - rule apply if there are virtual methods defined
+                       // rule apply if there are virtual methods defined
                        bool virt = false;
                        foreach (MethodDefinition method in type.Methods) {
-                               // #5 - ensure that the method is declared in 
this type (i.e. not in a parent)
+                               // ensure that the method is declared in this 
type (i.e. not in a parent)
                                if (method.IsVirtual && ((method.DeclaringType 
as TypeDefinition) == type))
                                        virt = true;
                        }
 
+                       // no virtual method == no problem
                        if (!virt)
-                               return runner.RuleSuccess; // no virtual method 
== no problem
+                               return RuleResult.DoesNotApply;
 
                        // *** ok, the rule applies! ***
 
-                       // #5 - and ensure the LinkDemand is a subset of the 
InheritanceDemand
-                       if (inherit == null)
-                               return runner.RuleFailure; // LinkDemand 
without InheritanceDemand
-                       if (link.IsSubsetOf (inherit))
-                               return runner.RuleSuccess;
-                       else
-                               return runner.RuleFailure;
+                       // Ensure the LinkDemand is a subset of the 
InheritanceDemand
+
+                       if (inherit == null) {
+                               // LinkDemand without InheritanceDemand
+                               Runner.Report (type, Severity.High, 
Confidence.High, "LinkDemand is present but no InheritanceDemand is 
specified.");
+                       } else if (!link.IsSubsetOf (inherit)) {
+                               Runner.Report (type, Severity.High, 
Confidence.High, "LinkDemand is not a subset of InheritanceDemand.");
+                       }
+                       return Runner.CurrentRuleResult;
                }
        }
 }

_______________________________________________
Mono-patches maillist  -  [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches

Reply via email to