Changeset 569


Ignore:
Timestamp:
11/14/2008 2:14:26 PM (3 years ago)
Author:
lowjoel
Message:

Tighten the plugin loading criteria:
-Plugins are first loaded reflection-only, checking for the presence of the IPlugin interface being implemented. If it is not implemented, the DLL is skipped.
-The plugins are then checked for a public key. If the public key is different from the executing assembly, it is not trusted and therefore is foreign.
-Foreign plugins must be approved by the user explicitly before they are loaded.

The SettingsPanel? and the ManagerSettings? classes have therefore been updated.

Location:
branches/eraser6
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • branches/eraser6/Eraser/SettingsPanel.Designer.cs

    r498 r569  
    205205            //  
    206206            resources.ApplyResources(this.pluginsManager, "pluginsManager"); 
     207            this.pluginsManager.CheckBoxes = true; 
    207208            this.pluginsManager.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { 
    208209            this.pluginsManagerColName, 
  • branches/eraser6/Eraser/SettingsPanel.cs

    r562 r569  
    5959        private void OnNewPluginLoaded(PluginInstance instance) 
    6060        { 
    61             ListViewItem item = pluginsManager.Items.Add(instance.Plugin.Name); 
    62             item.SubItems.Add(instance.Plugin.Author); 
     61            ListViewItem item = new ListViewItem(); 
     62            if (instance.Plugin == null) 
     63            { 
     64                item.Text = System.IO.Path.GetFileNameWithoutExtension(instance.Assembly.Location); 
     65                item.SubItems.Add(instance.AssemblyInfo.Author); 
     66            } 
     67            else 
     68            { 
     69                item.Text = instance.Plugin.Name; 
     70                item.SubItems.Add(instance.Plugin.Author); 
     71            } 
     72 
     73            item.Checked = instance.Plugin != null || 
     74                Manager.ManagerLibrary.Instance.Settings.ApprovedPlugins.IndexOf( 
     75                    instance.AssemblyInfo.GUID) != -1; 
    6376            item.SubItems.Add(instance.Assembly.GetName().Version.ToString()); 
    64             item.SubItems.Add(instance.Path); 
     77            item.SubItems.Add(instance.Assembly.Location); 
    6578            item.Tag = instance; 
     79            pluginsManager.Items.Add(item); 
    6680        } 
    6781 
     
    340354 
    341355            EraserSettings settings = new EraserSettings(); 
     356            ManagerSettings managerSettings = ManagerLibrary.Instance.Settings; 
    342357            if (((Language)uiLanguage.SelectedItem).Name != settings.Language) 
    343358            { 
     
    346361                    S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Information); 
    347362            } 
    348             ManagerLibrary.Instance.Settings.DefaultFileErasureMethod = 
     363            managerSettings.DefaultFileErasureMethod = 
    349364                ((ErasureMethod)eraseFilesMethod.SelectedItem).GUID; 
    350             ManagerLibrary.Instance.Settings.DefaultUnusedSpaceErasureMethod = 
     365            managerSettings.DefaultUnusedSpaceErasureMethod = 
    351366                ((ErasureMethod)eraseUnusedMethod.SelectedItem).GUID; 
    352367 
    353368            PRNG newPRNG = (PRNG)erasePRNG.SelectedItem; 
    354             if (newPRNG.GUID != ManagerLibrary.Instance.Settings.ActivePRNG) 
     369            if (newPRNG.GUID != managerSettings.ActivePRNG) 
    355370            { 
    356371                MessageBox.Show(S._("The new randomness data source will only be used when " + 
    357372                    "the next task is run.\nCurrently running tasks will use the old source."), 
    358373                    S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Information); 
    359                 ManagerLibrary.Instance.Settings.ActivePRNG = newPRNG.GUID; 
    360             } 
    361             ManagerLibrary.Instance.Settings.EraseLockedFilesOnRestart = 
    362                 lockedAllow.Checked; 
    363             ManagerLibrary.Instance.Settings.ConfirmEraseOnRestart = 
    364                 lockedConfirm.Checked; 
    365  
     374                managerSettings.ActivePRNG = newPRNG.GUID; 
     375            } 
     376            managerSettings.EraseLockedFilesOnRestart = lockedAllow.Checked; 
     377            managerSettings.ConfirmEraseOnRestart = lockedConfirm.Checked; 
     378 
     379            managerSettings.PlausibleDeniability = plausibleDeniability.Checked; 
    366380            List<string> plausibleDeniabilityFilesList = new List<string>(); 
    367381            foreach (string str in this.plausibleDeniabilityFiles.Items) 
    368382                plausibleDeniabilityFilesList.Add(str); 
    369             ManagerLibrary.Instance.Settings.PlausibleDeniabilityFiles = plausibleDeniabilityFilesList; 
    370  
    371             ManagerLibrary.Instance.Settings.ExecuteMissedTasksImmediately = 
    372                 schedulerMissedImmediate.Checked; 
    373             ManagerLibrary.Instance.Settings.PlausibleDeniability = 
    374                 plausibleDeniability.Checked; 
     383            managerSettings.PlausibleDeniabilityFiles = plausibleDeniabilityFilesList; 
     384 
     385            managerSettings.ExecuteMissedTasksImmediately = schedulerMissedImmediate.Checked; 
     386 
     387            foreach (ListViewItem item in pluginsManager.Items) 
     388            { 
     389                PluginInstance plugin = (PluginInstance)item.Tag; 
     390                if (item.Checked) 
     391                { 
     392                    if (managerSettings.ApprovedPlugins.IndexOf(plugin.AssemblyInfo.GUID) == -1) 
     393                        managerSettings.ApprovedPlugins.Add(plugin.AssemblyInfo.GUID); 
     394                } 
     395                else 
     396                    managerSettings.ApprovedPlugins.Remove(plugin.AssemblyInfo.GUID); 
     397            } 
    375398        } 
    376399    } 
  • branches/eraser6/Manager/Plugins.cs

    r564 r569  
    2626using System.Reflection; 
    2727using System.Windows.Forms; 
     28using System.Runtime.InteropServices; 
    2829 
    2930namespace Eraser.Manager.Plugin 
     
    106107        public override void Load() 
    107108        { 
    108             AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(AssemblyResolve); 
     109            AppDomain.CurrentDomain.AssemblyResolve += AssemblyResolve; 
     110            AppDomain.CurrentDomain.ReflectionOnlyAssemblyResolve += ResolveReflectionDependency; 
    109111            string pluginsFolder = Path.Combine( 
    110112                Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), //Assembly location 
     
    116118                FileInfo file = new FileInfo(fileName); 
    117119                if (file.Extension.Equals(".dll")) 
    118                     LoadPlugin(file.FullName); 
     120                    try 
     121                    { 
     122                        LoadPlugin(file.FullName); 
     123                    } 
     124                    catch (BadImageFormatException) 
     125                    { 
     126                    } 
     127                    catch (FileLoadException) 
     128                    { 
     129                    } 
    119130            } 
    120131        } 
     
    140151        public override void LoadPlugin(string filePath) 
    141152        { 
    142             //Load the plugin 
    143             Assembly assembly = Assembly.LoadFrom(filePath); 
     153            //Create the PluginInstance structure 
     154            Assembly reflectAssembly = Assembly.ReflectionOnlyLoadFrom(filePath); 
     155            PluginInstance instance = new PluginInstance(reflectAssembly, null); 
     156            Type typePlugin = null; 
    144157 
    145158            //Iterate over every exported type, checking if it implements IPlugin 
    146             foreach (Type type in assembly.GetTypes()) 
    147             { 
    148                 if (!type.IsPublic || type.IsAbstract) 
    149                     //Not interesting. 
    150                     continue; 
    151  
     159            foreach (Type type in instance.Assembly.GetExportedTypes()) 
     160            { 
    152161                //Check for an implementation of IPlugin 
    153162                Type typeInterface = type.GetInterface("Eraser.Manager.Plugin.IPlugin", true); 
    154163                if (typeInterface != null) 
    155164                { 
    156                     //Create the PluginInstance structure 
    157                     PluginInstance instance = new PluginInstance(assembly, filePath, null); 
    158  
    159                     //Add the plugin to the list of loaded plugins 
    160                     lock (plugins) 
    161                         plugins.Add(instance); 
    162  
    163                     //Initialize the plugin 
    164                     IPlugin pluginInterface = (IPlugin)Activator.CreateInstance( 
    165                         assembly.GetType(type.ToString())); 
    166                     pluginInterface.Initialize(this); 
    167                     instance.Plugin = pluginInterface; 
    168  
    169                     //And broadcast the plugin load event 
    170                     OnPluginLoaded(instance); 
     165                    typePlugin = type; 
     166                    break; 
    171167                } 
    172168            } 
     169 
     170            //If the typePlugin type is empty the assembly doesn't implement IPlugin; we 
     171            //aren't interested. 
     172            if (typePlugin == null) 
     173                return; 
     174 
     175            //OK this assembly is a plugin 
     176            lock (plugins) 
     177                plugins.Add(instance); 
     178 
     179            //First check the plugin for the presence of a signature. 
     180            if (reflectAssembly.GetName().GetPublicKey().Length == 0) 
     181            { 
     182                //If the user did not allow the plug-in to load, don't load it. 
     183                if (ManagerLibrary.Instance.Settings.ApprovedPlugins. 
     184                    IndexOf(instance.AssemblyInfo.GUID) == -1) 
     185                { 
     186                    return; 
     187                } 
     188            } 
     189 
     190            //Load the plugin 
     191            instance.Assembly = Assembly.LoadFrom(filePath); 
     192 
     193            //Initialize the plugin 
     194            IPlugin pluginInterface = (IPlugin)Activator.CreateInstance( 
     195                instance.Assembly.GetType(typePlugin.ToString())); 
     196            pluginInterface.Initialize(this); 
     197            instance.Plugin = pluginInterface; 
     198 
     199            //And broadcast the plugin load event 
     200            OnPluginLoaded(instance); 
    173201        } 
    174202 
     
    182210        } 
    183211 
     212        Assembly ResolveReflectionDependency(object sender, ResolveEventArgs args) 
     213        { 
     214            return Assembly.ReflectionOnlyLoad(args.Name); 
     215        } 
     216 
    184217        private List<PluginInstance> plugins = new List<PluginInstance>(); 
    185218    } 
     
    190223    public class PluginInstance 
    191224    { 
    192         internal PluginInstance(Assembly assembly, string path, IPlugin plugin) 
     225        /// <summary> 
     226        /// Constructor 
     227        /// </summary> 
     228        /// <param name="assembly">The assembly representing this plugin.</param> 
     229        /// <param name="path">The path to the ass</param> 
     230        /// <param name="plugin"></param> 
     231        internal PluginInstance(Assembly assembly, IPlugin plugin) 
    193232        { 
    194233            Assembly = assembly; 
    195             Path = path; 
    196234            Plugin = plugin; 
    197235        } 
    198236 
    199         public Assembly Assembly; 
    200         public string Path; 
    201         public IPlugin Plugin; 
     237        /// <summary> 
     238        /// Gets the Assembly this plugin instance came from. 
     239        /// </summary> 
     240        public Assembly Assembly 
     241        { 
     242            get 
     243            { 
     244                return assembly; 
     245            } 
     246            internal set 
     247            { 
     248                assembly = value; 
     249 
     250                assemblyInfo.Version = assembly.GetName().Version; 
     251                IList<CustomAttributeData> attributes = CustomAttributeData.GetCustomAttributes(assembly); 
     252                foreach (CustomAttributeData attr in attributes) 
     253                    if (attr.Constructor.DeclaringType == typeof(GuidAttribute)) 
     254                        assemblyInfo.GUID = new Guid((string)attr.ConstructorArguments[0].Value); 
     255                    else if (attr.Constructor.DeclaringType == typeof(AssemblyCompanyAttribute)) 
     256                        assemblyInfo.Author = (string)attr.ConstructorArguments[0].Value; 
     257            } 
     258        } 
     259 
     260        /// <summary> 
     261        /// Gets the attributes of the assembly, loading from reflection-only sources. 
     262        /// </summary> 
     263        public AssemblyInfo AssemblyInfo 
     264        { 
     265            get 
     266            { 
     267                return assemblyInfo; 
     268            } 
     269            internal set 
     270            { 
     271                assemblyInfo = value; 
     272            } 
     273        } 
     274 
     275        /// <summary> 
     276        /// Gets the IPlugin interface which the plugin exposed. 
     277        /// </summary> 
     278        public IPlugin Plugin 
     279        { 
     280            get 
     281            { 
     282                return plugin; 
     283            } 
     284            internal set 
     285            { 
     286                plugin = value; 
     287            } 
     288        } 
     289 
     290        private Assembly assembly; 
     291        private AssemblyInfo assemblyInfo; 
     292        private IPlugin plugin; 
     293    } 
     294 
     295    /// <summary> 
     296    /// Reflection-only information retrieved from the assembly. 
     297    /// </summary> 
     298    public struct AssemblyInfo 
     299    { 
     300        /// <summary> 
     301        /// The GUID of the assembly. 
     302        /// </summary> 
     303        public Guid GUID; 
     304 
     305        /// <summary> 
     306        /// The publisher of the assembly. 
     307        /// </summary> 
     308        public string Author; 
     309 
     310        /// <summary> 
     311        /// The version of the assembly. 
     312        /// </summary> 
     313        public Version Version; 
    202314    } 
    203315 
  • branches/eraser6/Manager/Settings.cs

    r562 r569  
    250250 
    251251        /// <summary> 
     252        /// The GUIDs of unsigned plug-ins which the user has explicitly approved. 
     253        /// </summary> 
     254        public List<Guid> ApprovedPlugins 
     255        { 
     256            get 
     257            { 
     258                if (settings["ApprovedPlugins"] == null) 
     259                    return new List<Guid>(); 
     260                return (List<Guid>)settings["ApprovedPlugins"]; 
     261            } 
     262            set 
     263            { 
     264                settings["ApprovedPlugins"] = value; 
     265            } 
     266        } 
     267 
     268        /// <summary> 
    252269        /// The Settings object which is the data store of this object. 
    253270        /// </summary> 
Note: See TracChangeset for help on using the changeset viewer.