Changeset 1981


Ignore:
Timestamp:
4/28/2010 8:26:57 AM (4 years ago)
Author:
lowjoel
Message:

Allow different types of loading policies for plugins. The old CoreAttribute? has been superseded by the LoadingPolicyAttribute?. This allows us to specify the loading policy for plugins such as BlackBox? which will have the same strong name as the main program, an Authenticode signature, but should not be loaded by default.

Location:
trunk/eraser
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser/Eraser.BlackBox/Eraser.BlackBox.csproj

    r1980 r1981  
    116116    </ProjectReference> 
    117117  </ItemGroup> 
    118   <ItemGroup> 
    119     <None Include="Strong Name.snk" /> 
    120   </ItemGroup> 
    121118  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> 
    122119  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.  
  • trunk/eraser/Eraser.BlackBox/Plugin.cs

    r1979 r1981  
    4747        public string Name 
    4848        { 
    49             get { throw new NotImplementedException(); } 
     49            get { return "Eraser BlackBox"; } 
    5050        } 
    5151 
    5252        public string Author 
    5353        { 
    54             get { throw new NotImplementedException(); } 
     54            get { return "The Eraser Project <eraser-development@lists.sourceforge.net>"; } 
    5555        } 
    5656 
    5757        public bool Configurable 
    5858        { 
    59             get { throw new NotImplementedException(); } 
     59            get { return false; } 
    6060        } 
    6161 
  • trunk/eraser/Eraser.BlackBox/Properties/AssemblyInfo.cs

    r1973 r1981  
    2424// The following GUID is for the ID of the typelib if this project is exposed to COM 
    2525[assembly: Guid("3460478d-ed1b-4ecc-96c9-2ca0e8500557")] 
     26 
     27// The plugin is an optional Eraser plugin, which should default to not load. 
     28[assembly: Eraser.Manager.Plugin.LoadingPolicy(Eraser.Manager.Plugin.LoadingPolicy.DefaultOff)] 
  • trunk/eraser/Eraser.DefaultPlugins/Properties/AssemblyInfo.cs

    r1682 r1981  
    2626 
    2727// The plugin is a Core Eraser plugin, declare it so. 
    28 [assembly: Eraser.Manager.Plugin.Core] 
     28[assembly: Eraser.Manager.Plugin.LoadingPolicy(Eraser.Manager.Plugin.LoadingPolicy.Core)] 
  • trunk/eraser/Eraser.Manager/Plugins.cs

    r1815 r1981  
    2323using System.Collections.Generic; 
    2424using System.Text; 
     25using System.Linq; 
     26 
    2527using System.IO; 
    2628using System.Reflection; 
     
    213215                plugins.Add(instance); 
    214216 
    215             //The plugin was not disabled or it was loaded for the first time. Check 
    216             //the plugin for the presence of a valid signature. 
     217            //If the plugin does not have an approval or denial, check for the presence of 
     218            //a valid signature. 
    217219            IDictionary<Guid, bool> approvals = ManagerLibrary.Settings.PluginApprovals; 
    218             if ((reflectAssembly.GetName().GetPublicKey().Length == 0 || 
     220            if (!approvals.ContainsKey(instance.AssemblyInfo.Guid) && 
     221                (reflectAssembly.GetName().GetPublicKey().Length == 0 || 
    219222                !Security.VerifyStrongName(filePath) || 
    220                 instance.AssemblyAuthenticode == null) && 
    221                 !approvals.ContainsKey(instance.AssemblyInfo.Guid)) 
     223                instance.AssemblyAuthenticode == null)) 
    222224            { 
    223225                return; 
    224226            } 
    225227 
    226             //Load the plugin 
     228            //The plugin either is explicitly allowed or disallowed to load, or 
     229            //it has an Authenticode Signature as well as a Strong Name. Get the 
     230            //loading policy of the plugin. 
    227231            instance.Assembly = Assembly.LoadFrom(filePath); 
    228  
    229             //See if the plugin belongs to us (same signature) and if the assembly 
    230             //declares an IsCore attribute. 
    231             if (reflectAssembly.GetName().GetPublicKey().Length == 
    232                 Assembly.GetExecutingAssembly().GetName().GetPublicKey().Length) 
    233             { 
    234                 bool sameKey = true; 
    235                 byte[] reflectAssemblyKey = reflectAssembly.GetName().GetPublicKey(); 
    236                 byte[] thisAssemblyKey = Assembly.GetExecutingAssembly().GetName().GetPublicKey(); 
    237                 for (int i = 0, j = reflectAssemblyKey.Length; i != j; ++i) 
    238                     if (reflectAssemblyKey[i] != thisAssemblyKey[i]) 
     232            LoadingPolicy policy = LoadingPolicy.None; 
     233            { 
     234                object[] attr = instance.Assembly.GetCustomAttributes(typeof(LoadingPolicyAttribute), true); 
     235                if (attr.Length != 0) 
     236                { 
     237                    policy = ((LoadingPolicyAttribute)attr[0]).Policy; 
     238 
     239                    //If the loading policy is that the plugin is Core, we need to verify 
     240                    //the public key of the assembly. 
     241                    if (policy == LoadingPolicy.Core && 
     242                        !reflectAssembly.GetName().GetPublicKey().SequenceEqual( 
     243                            Assembly.GetExecutingAssembly().GetName().GetPublicKey())) 
    239244                    { 
    240                         sameKey = false; 
    241                         break; 
     245                        policy = LoadingPolicy.None; 
    242246                    } 
    243  
    244                 //Check for the IsCore attribute. 
    245                 if (sameKey) 
     247                } 
     248            } 
     249 
     250            bool loadPlugin = false; 
     251 
     252            //If the loading policy is such that the plugin is a core plugin, ALWAYS load it. 
     253            if (policy == LoadingPolicy.Core) 
     254                loadPlugin = true; 
     255 
     256            //The plugin is not a core plugin, is there an approval or denial? 
     257            else if (approvals.ContainsKey(instance.AssemblyInfo.Guid)) 
     258                loadPlugin = approvals[instance.AssemblyInfo.Guid]; 
     259 
     260            //There's no approval or denial, what is the specified loading policy? 
     261            else 
     262                loadPlugin = policy != LoadingPolicy.DefaultOff; 
     263 
     264 
     265            if (loadPlugin) 
     266            { 
     267                try 
    246268                { 
    247                     object[] attr = instance.Assembly.GetCustomAttributes(typeof(CoreAttribute), true); 
    248                     if (attr.Length != 0) 
    249                         instance.IsCore = true; 
     269                    //Initialize the plugin 
     270                    IPlugin pluginInterface = (IPlugin)Activator.CreateInstance( 
     271                        instance.Assembly.GetType(typePlugin.ToString())); 
     272                    pluginInterface.Initialize(this); 
     273                    instance.Plugin = pluginInterface; 
     274 
     275                    //And broadcast the plugin load event 
     276                    OnPluginLoaded(this, new PluginLoadedEventArgs(instance)); 
    250277                } 
    251             } 
    252  
    253             //See if the user disabled this plugin (users cannot disable Core plugins) 
    254             if (approvals.ContainsKey(instance.AssemblyInfo.Guid) && 
    255                 !approvals[instance.AssemblyInfo.Guid] && !instance.IsCore) 
    256             { 
    257                 return; 
    258             } 
    259  
    260             try 
    261             { 
    262                 //Initialize the plugin 
    263                 IPlugin pluginInterface = (IPlugin)Activator.CreateInstance( 
    264                     instance.Assembly.GetType(typePlugin.ToString())); 
    265                 pluginInterface.Initialize(this); 
    266                 instance.Plugin = pluginInterface; 
    267  
    268                 //And broadcast the plugin load event 
    269                 OnPluginLoaded(this, new PluginLoadedEventArgs(instance)); 
    270             } 
    271             catch (System.Security.SecurityException e) 
    272             { 
    273                 MessageBox.Show(S._("Could not load the plugin {0}.\n\nThe error returned was: {1}", 
    274                     filePath, e.Message), S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Error, 
    275                     MessageBoxDefaultButton.Button1, Localisation.IsRightToLeft(null) ? 
    276                         MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign : 0); 
     278                catch (System.Security.SecurityException e) 
     279                { 
     280                    MessageBox.Show(S._("Could not load the plugin {0}.\n\nThe error returned was: {1}", 
     281                        filePath, e.Message), S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Error, 
     282                        MessageBoxDefaultButton.Button1, Localisation.IsRightToLeft(null) ? 
     283                            MessageBoxOptions.RtlReading | MessageBoxOptions.RightAlign : 0); 
     284                } 
    277285            } 
    278286        } 
     
    310318            Assembly = assembly; 
    311319            Plugin = plugin; 
    312             IsCore = false; 
    313320 
    314321            //Verify the certificate in the assembly. 
     
    361368        /// therefore cannot be disabled.) 
    362369        /// </summary> 
    363         public bool IsCore { get; internal set; } 
     370        public LoadingPolicy LoadingPolicy { get; internal set; } 
    364371 
    365372        /// <summary> 
     
    477484 
    478485    /// <summary> 
    479     /// Declares that the entity referenced is a core plugin and cannot be unloaded. 
    480     /// Only plugins signed with the same signature as the Manager library will be 
    481     /// considered to be safe and therefore checked for this attribute. 
    482     /// </summary> 
    483     [AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)] 
    484     public sealed class CoreAttribute : Attribute 
    485     { 
     486    /// Loading policies applicable for a given plugin. 
     487    /// </summary> 
     488    public enum LoadingPolicy 
     489    { 
     490        /// <summary> 
     491        /// The host decides the best policy for loading the plugin. 
     492        /// </summary> 
     493        None, 
     494 
     495        /// <summary> 
     496        /// The host will enable the plugin by default. 
     497        /// </summary> 
     498        DefaultOn, 
     499 
     500        /// <summary> 
     501        /// The host will disable the plugin by default 
     502        /// </summary> 
     503        DefaultOff, 
     504 
     505        /// <summary> 
     506        /// The host must always load the plugin. 
     507        /// </summary> 
     508        /// <remarks>For this policy to have an effect, the plugin assembly must 
     509        /// have the same Strong Name as the loading assembly, otherwise it defaults 
     510        /// to None.</remarks> 
     511        Core 
     512    } 
     513 
     514    /// <summary> 
     515    /// Declares the loading policy for the assembly containing the plugin. Only 
     516    /// plugins signed with an Authenticode signature will be trusted and have 
     517    /// this attribute checked at initialisation. 
     518    /// </summary> 
     519    [AttributeUsage(AttributeTargets.Assembly, Inherited = false, AllowMultiple = false)] 
     520    public sealed class LoadingPolicyAttribute : Attribute 
     521    { 
     522        /// <summary> 
     523        /// Constructor. 
     524        /// </summary> 
     525        /// <param name="policy">The policy used for loading the plugin.</param> 
     526        public LoadingPolicyAttribute(LoadingPolicy policy) 
     527        { 
     528            Policy = policy; 
     529        } 
     530 
     531        /// <summary> 
     532        /// The loading policy to be applied to the assembly. 
     533        /// </summary> 
     534        public LoadingPolicy Policy 
     535        { 
     536            get; 
     537            set; 
     538        } 
    486539    } 
    487540} 
  • trunk/eraser/Eraser.Util/Eraser.Util.csproj

    r1976 r1981  
    6363    </Reference> 
    6464    <Reference Include="System.Data" /> 
     65    <Reference Include="System.Data.Linq"> 
     66      <RequiredTargetFramework>3.5</RequiredTargetFramework> 
     67    </Reference> 
    6568    <Reference Include="System.Drawing" /> 
    6669    <Reference Include="System.Management" /> 
  • trunk/eraser/Eraser/SettingsPanel.cs

    r1802 r1981  
    7777            //Visually display the other metadata associated with the assembly 
    7878            item.ImageIndex = e.Instance.AssemblyAuthenticode == null ? -1 : 0; 
    79             item.Group = e.Instance.IsCore ? pluginsManager.Groups[0] : 
    80                 pluginsManager.Groups[1]; 
     79            item.Group = e.Instance.LoadingPolicy == LoadingPolicy.Core ? 
     80                pluginsManager.Groups[0] : pluginsManager.Groups[1]; 
    8181            item.SubItems.Add(e.Instance.Assembly.GetName().Version.ToString()); 
    8282            item.SubItems.Add(e.Instance.Assembly.Location); 
     
    308308            ListViewItem item = pluginsManager.Items[e.Index]; 
    309309            PluginInstance instance = (PluginInstance)item.Tag; 
    310             if (instance.IsCore) 
     310            if (instance.LoadingPolicy == LoadingPolicy.Core) 
    311311                e.NewValue = CheckState.Checked; 
    312312        } 
Note: See TracChangeset for help on using the changeset viewer.