Changeset 1255


Ignore:
Timestamp:
10/03/09 01:12:12 (5 years ago)
Author:
cjax
Message:

Replace the RegistrySettings? class with IFFSSettings class for our secure settings management.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/eraser6/Eraser/Program.cs

    r1192 r1255  
    3030using System.Runtime.Serialization; 
    3131using System.Runtime.Serialization.Formatters.Binary; 
     32using System.Security.Permissions; 
    3233using System.Globalization; 
    3334using System.Reflection; 
     
    266267        /// File name of the Eraser task list. 
    267268        /// </summary> 
    268         private const string TaskListFileName = @"Task List.ersx"; 
     269        private static readonly string TaskListFileName = @"Task List.ersx"; 
    269270 
    270271        /// <summary> 
     
    276277        /// Path to the Eraser settings key (relative to HKCU) 
    277278        /// </summary> 
    278         public const string SettingsPath = @"SOFTWARE\Eraser\Eraser 6"; 
     279        public static readonly string SettingsPath = @"SOFTWARE\Eraser\Eraser 6"; 
     280 
     281        /// <summary> 
     282        /// File name of the IFFS file container 
     283        /// </summary> 
     284        public static readonly string IFFSFileName = @"Settings.erdb"; 
     285 
     286        /// <summary> 
     287        /// Path to eraser IFFS file container 
     288        /// </summary> 
     289        public static readonly string IFFSPath = Path.Combine(AppDataPath, IFFSFileName); 
    279290    } 
    280291 
     
    348359                    //has been closed. 
    349360                    MainForm.FormClosed += OnExitInstance; 
    350  
     361                 
    351362                    if (ShowMainForm) 
    352363                        Application.Run(MainForm); 
     
    10201031                    throw new ArgumentException(string.Format(CultureInfo.CurrentCulture, 
    10211032                        "The file {0} does not exist.", param)); 
    1022                  
     1033 
    10231034                files.Add(param); 
    10241035                return true; 
     
    11911202        { 
    11921203            AddTaskCommandLine taskArgs = (AddTaskCommandLine)Arguments; 
    1193              
     1204 
    11941205            //Create the task, and set the method to use. 
    11951206            Task task = new Task(); 
    1196             ErasureMethod method = taskArgs.ErasureMethod == Guid.Empty ?  
     1207            ErasureMethod method = taskArgs.ErasureMethod == Guid.Empty ? 
    11971208                ErasureMethodManager.Default : 
    11981209                ErasureMethodManager.GetInstance(taskArgs.ErasureMethod); 
     
    13061317    } 
    13071318 
     1319    /// <summary> 
     1320    /// This class provides a File Based Win32 Registry using .NET 
     1321    /// binary serialization. 
     1322    /// </summary> 
    13081323    internal class Settings : Manager.SettingsManager 
    13091324    { 
    13101325        /// <summary> 
    1311         /// Registry-based storage backing for the Settings class. 
    1312         /// </summary> 
    1313         private class RegistrySettings : Manager.Settings, IDisposable 
     1326        /// IFFS based setting managment 
     1327        /// </summary> 
     1328        private class IFFSSettings : Manager.Settings, IDisposable 
    13141329        { 
    13151330            /// <summary> 
     
    13171332            /// </summary> 
    13181333            /// <param name="key">The registry key to look for the settings in.</param> 
    1319             public RegistrySettings(RegistryKey key) 
    1320             { 
    1321                 this.key = key; 
     1334            public IFFSSettings(IFFS.Handle handle) 
     1335            { 
     1336                this.handle = handle; 
    13221337            } 
    13231338 
    13241339            #region IDisposable Members 
    13251340 
    1326             ~RegistrySettings() 
     1341            ~IFFSSettings() 
    13271342            { 
    13281343                Dispose(false); 
     
    13381353            { 
    13391354                if (disposing) 
    1340                     key.Close(); 
     1355                    handle.Close(); 
     1356 
     1357                foreach (var hFile in hFiles.Values) 
     1358                    hFile.Close(); 
     1359 
     1360                hFiles.Clear(); 
    13411361            } 
    13421362 
    13431363            #endregion 
    13441364 
     1365            private Dictionary<String, IFFS.Handle> hFiles = new Dictionary<string, IFFS.Handle>(); 
    13451366            public override object this[string setting] 
    13461367            { 
    13471368                get 
    13481369                { 
    1349                     //Get the raw registry value 
    1350                     object rawResult = key.GetValue(setting, null); 
    1351  
    1352                     //Check if it is a serialised object 
    1353                     byte[] resultArray = rawResult as byte[]; 
    1354                     if (resultArray != null) 
     1370                    IFFS.Handle hFile = null; 
     1371 
     1372                    // Open a handle to the settings file 
     1373                    if (hFiles.ContainsKey(setting)) 
    13551374                    { 
    1356                         using (MemoryStream stream = new MemoryStream(resultArray)) 
    1357                             try 
    1358                             { 
    1359                                 return new BinaryFormatter().Deserialize(stream); 
    1360                             } 
    1361                             catch (SerializationException) 
    1362                             { 
    1363                                 key.DeleteValue(setting); 
    1364                                 MessageBox.Show(S._("Could not load the setting {0} for plugin {1}. " + 
    1365                                     "The setting has been lost.", key, pluginID.ToString()), 
    1366                                     S._("Eraser"), MessageBoxButtons.OK, MessageBoxIcon.Error, 
    1367                                     MessageBoxDefaultButton.Button1, 
    1368                                     S.IsRightToLeft(null) ? MessageBoxOptions.RtlReading : 0); 
    1369                             } 
     1375                        hFile = hFiles[setting]; 
    13701376                    } 
    13711377                    else 
    13721378                    { 
    1373                         return rawResult; 
     1379                        hFiles.Add(setting, hFile = IFFS.Open(handle, setting)); 
    13741380                    } 
    13751381 
     1382                    try 
     1383                    { 
     1384                        if (hFile.IsValid) 
     1385                        { 
     1386                            return IFFS.GetFileData(hFile); 
     1387                        } 
     1388                    } 
     1389                    catch 
     1390                    { 
     1391                        hFiles.Remove(setting); 
     1392                        hFile.Close(); 
     1393                        throw; 
     1394                    } 
     1395 
    13761396                    return null; 
    13771397                } 
    13781398                set 
    13791399                { 
    1380                     if (value == null) 
     1400                    IFFS.Handle hFile = null; 
     1401 
     1402                    if (hFiles.ContainsKey(setting)) 
    13811403                    { 
    1382                         key.DeleteValue(setting); 
     1404                        hFile = hFiles[setting]; 
    13831405                    } 
    13841406                    else 
    13851407                    { 
    1386                         if (value is bool) 
    1387                             key.SetValue(setting, value, RegistryValueKind.DWord); 
    1388                         else if ((value is int) || (value is uint)) 
    1389                             key.SetValue(setting, value, RegistryValueKind.DWord); 
    1390                         else if ((value is long) || (value is ulong)) 
    1391                             key.SetValue(setting, value, RegistryValueKind.QWord); 
    1392                         else if (value is string) 
    1393                             key.SetValue(setting, value, RegistryValueKind.String); 
    1394                         else 
    1395                             using (MemoryStream stream = new MemoryStream()) 
     1408                        hFiles.Add(setting, hFile = IFFS.CreateFile(handle, setting)); 
     1409                    } 
     1410 
     1411                    if (!hFile.IsValid && hFiles.ContainsKey(setting)) 
     1412                    { 
     1413                        hFiles.Remove(setting); 
     1414                        hFile.Close(); 
     1415                        this[setting] = value; 
     1416                    } 
     1417                    else 
     1418                        try 
     1419                        { 
     1420                            if (value == null) 
    13961421                            { 
    1397                                 new BinaryFormatter().Serialize(stream, value); 
    1398                                 key.SetValue(setting, stream.ToArray(), RegistryValueKind.Binary); 
     1422                                IFFS.Delete(hFile); 
    13991423                            } 
     1424                            else 
     1425                            { 
     1426                                IFFS.FileNode file = IFFS.GetFile(hFile); 
     1427                                file.Data = value; 
     1428                                file.DataType = Type.GetTypeFromHandle(Type.GetTypeHandle(value)); 
     1429                            } 
     1430                        } 
     1431                        catch 
     1432                        { 
     1433                            hFile.Close(); 
     1434                            hFiles.Remove(setting); 
     1435                            throw; 
     1436                        } 
     1437                } 
     1438            } 
     1439 
     1440            /// <summary> 
     1441            /// The handle where the data is stored. 
     1442            /// </summary> 
     1443            private IFFS.Handle handle; 
     1444        } 
     1445 
     1446        public override void Save() 
     1447        { 
     1448            Stream.Position = 0; 
     1449            Stream.SetLength(0); 
     1450            Instance.Serialize(Stream); 
     1451        } 
     1452 
     1453#if DEBUG 
     1454        private static bool MonteCarloTestHasRun = false; 
     1455 
     1456        private void MonteCarloTest() 
     1457        { 
     1458            Random rand = new Random(); 
     1459            const int MAX_ITERATIONS = 64; 
     1460 
     1461            IFFS.Handle hMonteCarlo = IFFS.CreateDirectory(Instance.RootHandle, "MonteCarlo"); 
     1462 
     1463            if (!MonteCarloTestHasRun) 
     1464                for (int iterations = 0; iterations < MAX_ITERATIONS; iterations++) 
     1465                { 
     1466                    const int MAX_VALUE = 1024 * 16; 
     1467 
     1468                    for (int i = 0; i < MAX_VALUE; i++) 
     1469                        IFFS.CreateFile(hMonteCarlo, i.ToString()); 
     1470 
     1471                    for (int i = 0; i < MAX_VALUE; i++) 
     1472                    { 
     1473                        IFFS.Handle hFile = IFFS.Open(hMonteCarlo, rand.Next(0, MAX_VALUE).ToString()); 
     1474                        IFFS.GetFile(hFile).Data = i; 
    14001475                    } 
    1401                 } 
    1402             } 
    1403  
    1404             /// <summary> 
    1405             /// The GUID of the plugin whose settings this object is storing. 
    1406             /// </summary> 
    1407             private Guid pluginID; 
    1408  
    1409             /// <summary> 
    1410             /// The registry key where the data is stored. 
    1411             /// </summary> 
    1412             private RegistryKey key; 
    1413         } 
    1414  
    1415         public override void Save() 
    1416         { 
    1417         } 
     1476 
     1477                    Save(); 
     1478                } 
     1479 
     1480            if (!IFFS.Delete(hMonteCarlo) && !MonteCarloTestHasRun) 
     1481                throw new Exception(); 
     1482            else 
     1483                Save(); 
     1484 
     1485            MonteCarloTestHasRun = true; 
     1486        } 
     1487#endif 
    14181488 
    14191489        protected override Manager.Settings GetSettings(Guid guid) 
    14201490        { 
    1421             RegistryKey eraserKey = null; 
    1422  
    1423             try 
    1424             { 
    1425                 //Open the registry key containing the settings 
    1426                 eraserKey = Registry.CurrentUser.OpenSubKey(Program.SettingsPath, true); 
    1427                 if (eraserKey == null) 
    1428                     eraserKey = Registry.CurrentUser.CreateSubKey(Program.SettingsPath); 
    1429  
    1430                 RegistryKey pluginsKey = eraserKey.OpenSubKey(guid.ToString(), true); 
    1431                 if (pluginsKey == null) 
    1432                     pluginsKey = eraserKey.CreateSubKey(guid.ToString()); 
    1433  
    1434                 //Return the Settings object. 
    1435                 return new RegistrySettings(pluginsKey); 
    1436             } 
    1437             finally 
    1438             { 
    1439                 if (eraserKey != null) 
    1440                     eraserKey.Close(); 
     1491            IFFS.Handle hPlugin = IFFS.CreateDirectory(Instance.RootHandle, guid.ToString()); 
     1492 
     1493            return new IFFSSettings(hPlugin); 
     1494        } 
     1495 
     1496        /// <summary> 
     1497        /// Our encrypted filestream handle 
     1498        /// </summary> 
     1499        protected static CryptoFileStream Stream { get; set; } 
     1500 
     1501        /// <summary> 
     1502        /// Create a new instance of the IFFS manager. 
     1503        /// </summary> 
     1504        /// <param name="key">key for the underlying cryptostream</param> 
     1505        /// <param name="iv">iv for the underlying cryptostream</param> 
     1506        /// <throws>SerializationException</throws> 
     1507        /// <returns></returns> 
     1508        static IFFS CreateIFFSInstance(byte[] key, byte[] iv) 
     1509        {            
     1510            // create a new file stream for our settings 
     1511            Stream = new CryptoFileStream(key, iv, 
     1512                Program.IFFSPath, 
     1513                FileMode.OpenOrCreate,/* doesnt matter if it was not created before */ 
     1514                FileAccess.ReadWrite, /* we need IO for get/set */ 
     1515                FileShare.None);      /* make sure we fully lock this file */ 
     1516             
     1517            IFFS newInstance = null; 
     1518                         
     1519            if (Stream.Length != 0) 
     1520            { 
     1521                long OriginalPosition = Stream.Position; 
     1522                try 
     1523                { 
     1524                    newInstance = new IFFS(Stream); 
     1525                } 
     1526                catch (SerializationException) 
     1527                { 
     1528                    // XXX for future ref, if this happens could be 
     1529                    // due to invalid credentials dont erase the  
     1530                    // settings.  
     1531                    // lets roll back 
     1532                    Stream.Position = OriginalPosition; 
     1533                    throw; 
     1534                } 
     1535            } 
     1536 
     1537            if (newInstance == null) 
     1538            { 
     1539                return new IFFS(); 
     1540            } 
     1541            else 
     1542            { 
     1543                return newInstance; 
     1544            } 
     1545        } 
     1546 
     1547        /// <summary> 
     1548        /// Global IFFS instance management methods 
     1549        /// </summary> 
     1550        private static IFFS instance = null; 
     1551        protected static IFFS Instance 
     1552        { 
     1553            get 
     1554            { 
     1555                if (instance != null) 
     1556                { 
     1557                    return instance; 
     1558                } 
     1559 
     1560                /// XXX currently no user login is implemented 
     1561                /// predefined and determinable key and iv is 
     1562                /// generated.  
     1563 
     1564                // Hash algorithm 
     1565                System.Security.Cryptography.SHA512Managed Hash = new System.Security.Cryptography.SHA512Managed(); 
     1566 
     1567                // use a per user seed for our key/iv generation 
     1568                string UserID = System.Security.Principal.WindowsIdentity.GetCurrent().User.Value; 
     1569 
     1570                // Key and IV for our CryptoStream 
     1571                byte[] defaultKey = Hash.ComputeHash(Encoding.UTF8.GetBytes(UserID)); 
     1572                byte[] defaultIV = Hash.ComputeHash(defaultKey); 
     1573 
     1574                try 
     1575                { 
     1576                    instance = CreateIFFSInstance(defaultKey, defaultIV); 
     1577                } 
     1578                catch (SerializationException) 
     1579                { 
     1580                    // this happens when serialization fails 
     1581                    // howerver if the wrong credentials were 
     1582                    // supplied this is not a corrupt archive. 
     1583                    // lets ask the user on the appropriate action. 
     1584 
     1585                    string message = S._("Could not load the setting. To clear current settings click 'ok'"); 
     1586                    DialogResult answer = MessageBox.Show(message, S._("Eraser"), 
     1587                        MessageBoxButtons.RetryCancel, MessageBoxIcon.Error, 
     1588                        MessageBoxDefaultButton.Button1, 
     1589                        S.IsRightToLeft(null) ? MessageBoxOptions.RtlReading : 0); 
     1590 
     1591                    if (answer == DialogResult.Cancel) 
     1592                    { 
     1593                        throw new NotImplementedException("Not Implemented"); 
     1594                    } 
     1595                    else // (answer == DialogResult.Ok) 
     1596                    { 
     1597                        // nothing to do 
     1598                    } 
     1599                } 
     1600 
     1601                if (instance == null) 
     1602                { 
     1603                    return instance = new IFFS(); 
     1604                } 
     1605                 
     1606                return instance; 
     1607            } 
     1608            set 
     1609            { 
     1610                instance = value; 
    14411611            } 
    14421612        } 
Note: See TracChangeset for help on using the changeset viewer.