Безопасность файлов

46

В версиях .NET Framework 1.0/1.1 не было простого способа работы со списками контроля доступа (access control list — ACL) для файлов, каталогов и ключей системного реестра. В те времена для этого обычно требовалось прибегать к средствам взаимодействия с СОМ и, следовательно, обладать более совершенными навыками работы с ACL.

После выхода .NET Framework 2.0 ситуация значительно изменилась, поскольку появилось пространство имен System.Security.AccessControl, которое гораздо упростило работу с ACL. С помощью этого пространства имен и сейчас можно легко манипулировать настройками безопасности для файлов, ключей системного реестра, сетевых дисков, объектов Active Directory и многого другого.

Чтение ACL для файла

Чтобы посмотреть на работу с System.Security.AccessControl, в данной статье рассматриваются способы манипулирования списками ACL как для файлов, так и для каталогов. Сначала будет показано, как просматривать ACL для конкретного файла. Это делается в консольном приложении, код которого приведен ниже:

using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;

namespace ACL
{
    class Program
    {
        private static string myFilePath;

        static void Main()
        {
            Console.Write("Введите полный путь к файлу: ");
            myFilePath = Console.ReadLine();

            try
            {
                using (FileStream myFile = new FileStream(
                    myFilePath, FileMode.Open, FileAccess.Read))
                    {
                        FileSecurity fileSec = myFile.GetAccessControl();
                        foreach (FileSystemAccessRule fileRule in
                            fileSec.GetAccessRules(true, true, typeof(NTAccount)))
                            {
                               Console.WriteLine("{0} {1} доступ {2} для {3}",myFilePath,
                                   fileRule.AccessControlType == AccessControlType.Allow ? "разрешен" : "запрещен",
                                   fileRule.FileSystemRights, fileRule.IdentityReference);
                            }
                    }
            }
            catch
            {
                Console.WriteLine("Некорректный путь к файлу!");
            }
            Console.ReadLine();
        }
    }
}
ACL файла

Чтобы пример заработал, первое, что нужно сделать — это включить ссылку на пространство имен System.Security.AccessControl. Дальше в программе это откроет доступ к классам FileSecurity и FileSystemAccessRule.

После извлечения и помещения указанного файла в объект FileStream данные ACL этого файла получаются с помощью метода GetAccessControl(), который теперь находится в объекте File. Затем полученная этим методом информация помещается в класс FileSecurity. Этот класс хранит права доступа к элементу, на который ссылается. Каждое из этих прав затем представлено в виде объекта FileSystemAccessRule. В цикле foreach осуществляется проход по всем правам доступа, которые находится в созданном объекте FileSecurity.

Добавление и удаление ACL для файла

С помощью тех же самых объектов, которые использовались в предыдущем примере, можно манипулировать ACL ресурса. Следующий пример кода представляет собой измененную версию предыдущего примера, в котором производилось считывание ACL для файла. Здесь ACL указанного файла сначала читаются, затем изменяются и снова читаются:

using System;
using System.IO;
using System.Security.AccessControl;
using System.Security.Principal;

namespace ACL
{
    class Program
    {
        private static string myFilePath;

        static void Main()
        {
            Console.Write("Введите полный путь к файлу: ");
            myFilePath = Console.ReadLine();

            try
            {
                using (FileStream myFile = new FileStream(
                    myFilePath, FileMode.Open, FileAccess.Read))
                    {
                        FileSecurity fileSec = myFile.GetAccessControl();
                        Console.WriteLine("Список ACL перед изменением: ");
                        foreach (FileSystemAccessRule fileRule in
                            fileSec.GetAccessRules(true, true, typeof(NTAccount)))
                            {
                               Console.WriteLine("{0} {1} доступ {2} для {3}",myFilePath,
                                   fileRule.AccessControlType == AccessControlType.Allow ? "разрешен" : "запрещен",
                                   fileRule.FileSystemRights, fileRule.IdentityReference);
                            }

                        Console.WriteLine("\nСписок ACL после изменений: ");
                        FileSystemAccessRule newRule = new FileSystemAccessRule(
                            new System.Security.Principal.NTAccount(@"admin"),
                            FileSystemRights.FullControl,
                            AccessControlType.Allow);
                        fileSec.AddAccessRule(newRule);
                        File.SetAccessControl(myFilePath, fileSec);
                        foreach (FileSystemAccessRule fileRule in
                                fileSec.GetAccessRules(true, true, typeof(NTAccount)))
                        {
                            Console.WriteLine("{0} {1} доступ {2} для {3}", myFilePath,
                                fileRule.AccessControlType == AccessControlType.Allow ? "разрешен" : "запрещен",
                                fileRule.FileSystemRights, fileRule.IdentityReference);
                        }
                    }
            }
            catch
            {
                Console.WriteLine("Некорректный путь к файлу!");
            }
            Console.ReadLine();
        }
    }
}
Изменение ACL

В приведенном коде с использованием объекта FileSystemAccessRule в ACL для файла добавляется новое правило доступа. Класс FileSystemAccessRule представляет собой абстрактный экземпляр записи контроля доступа (Access Control Entry — АСЕ). Запись АСЕ определяет применяемую учетную запись пользователя, тип доступа, а также разрешен этот доступ или запрещен. При создании нового экземпляра этого объекта создается новый экземпляр NTAccount, которому предоставляется полный доступ (FullControl) к файлу.

Несмотря на то что создается новый экземпляр NTAccount, он все равно должен ссылаться на существующего пользователя. Затем для назначения нового правила применяется метод AddAccessRule класса FileSecurity. После этого используется ссылка на объект FileSecurity для установки контроля доступа к обрабатываемому файлу с помощью метода SetAccessControl класса File.

Пройди тесты
Лучший чат для C# программистов