in Lib/Collectors/FileSystemCollector.cs [84:341]
public FileSystemObject FilePathToFileSystemObject(string path)
{
FileSystemObject obj = new FileSystemObject(path);
// Get Owner/Group
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
try
{
var fileSecurity = new FileSecurity(path, AccessControlSections.Owner);
IdentityReference? oid = fileSecurity.GetOwner(typeof(SecurityIdentifier));
obj.Owner = AsaHelpers.SidToName(oid);
}
catch (Exception e)
{
Log.Verbose("Failed to get owner for {0} ({1}:{2})", path, e.GetType(), e.Message);
}
try
{
var fileSecurity = new FileSecurity(path, AccessControlSections.Group);
IdentityReference? gid = fileSecurity.GetGroup(typeof(SecurityIdentifier));
obj.Group = AsaHelpers.SidToName(gid);
}
catch (Exception e)
{
Log.Verbose("Failed to get group for {0} ({1}:{2})", path, e.GetType(), e.Message);
}
try
{
var fileSecurity = new FileSecurity(path, AccessControlSections.Access);
var rules = fileSecurity.GetAccessRules(true, true, typeof(SecurityIdentifier));
obj.Permissions = new Dictionary<string, string>();
foreach (FileSystemAccessRule? rule in rules)
{
if (rule != null)
{
string name = AsaHelpers.SidToName(rule.IdentityReference);
foreach (var permission in rule.FileSystemRights.ToString().Split(','))
{
if (obj.Permissions.ContainsKey(name))
{
obj.Permissions[name] = $"{obj.Permissions[name]},{permission}";
}
else
{
obj.Permissions.Add(name, permission);
}
}
}
}
}
catch (Exception e)
{
Log.Verbose("Failed to get FileSecurity for {0} ({1}:{2})", path, e.GetType(), e.Message);
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
try
{
var file = new UnixSymbolicLinkInfo(path);
obj.Owner = file.OwnerUser.UserName;
obj.Group = file.OwnerGroup.GroupName;
obj.SetGid = file.IsSetGroup;
obj.SetUid = file.IsSetUser;
obj.Permissions = new Dictionary<string, string>();
if (file.FileAccessPermissions.ToString().Equals("AllPermissions", StringComparison.InvariantCulture))
{
obj.Permissions.Add("User", "Read,Write,Execute");
obj.Permissions.Add("Group", "Read,Write,Execute");
obj.Permissions.Add("Other", "Read,Write,Execute");
}
else
{
var keys = new List<string>() { "User", "Group", "Other" };
var splits = file.FileAccessPermissions.ToString().Split(',').Select(x => x.Trim());
foreach (var key in keys)
{
foreach (var permission in splits.Where((x) => x.StartsWith(key, StringComparison.InvariantCulture)))
{
if (permission.Contains("ReadWriteExecute", StringComparison.InvariantCulture))
{
obj.Permissions.Add(key, "Read,Write,Execute");
}
else
{
if (obj.Permissions.ContainsKey(key))
{
obj.Permissions[key] = $"{obj.Permissions[key]},{permission.Trim().Substring(key.Length)}";
}
else
{
obj.Permissions.Add(key, permission.Trim().Substring(key.Length));
}
}
}
}
}
}
catch (Exception e) when (
e is ArgumentNullException
|| e is ArgumentException
|| e is InvalidOperationException)
{
Log.Verbose("Failed to get permissions for {0} ({1}:{2})", path, e.GetType(), e.Message);
}
}
try
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
if (Directory.Exists(path))
{
var fileInfo = new DirectoryInfo(path);
if (fileInfo.Attributes.HasFlag(FileAttributes.ReparsePoint))
{
obj.IsLink = true;
obj.Target = NativeMethods.GetFinalPathName(path);
}
else
{
obj.IsDirectory = true;
}
}
else
{
var fileInfo = new FileInfo(path);
obj.Size = fileInfo.Length;
obj.SizeOnDisk = WindowsSizeOnDisk(fileInfo);
// This check is to try to prevent reading of cloud based files (like a dropbox
// folder) and subsequently causing a download, unless the user specifically requests
// it with DownloadCloud.
if (opts.DownloadCloud || obj.SizeOnDisk > 0 || WindowsFileSystemUtils.IsLocal(obj.Path))
{
obj.LastModified = File.GetLastWriteTimeUtc(path);
obj.Created = File.GetCreationTimeUtc(path);
if (opts.GatherHashes == true)
{
obj.ContentHash = FileSystemUtils.GetFileHash(fileInfo);
}
var exeType = FileSystemUtils.GetExecutableType(path);
if (exeType != EXECUTABLE_TYPE.NONE && exeType != EXECUTABLE_TYPE.UNKNOWN)
{
obj.IsExecutable = true;
}
if (exeType == EXECUTABLE_TYPE.WINDOWS)
{
obj.SignatureStatus = WindowsFileSystemUtils.GetSignatureStatus(path);
obj.Characteristics = WindowsFileSystemUtils.GetDllCharacteristics(path);
}
else if (exeType == EXECUTABLE_TYPE.MACOS)
{
obj.MacSignatureStatus = FileSystemUtils.GetMacSignature(path);
}
}
}
}
else
{
UnixSymbolicLinkInfo i = new UnixSymbolicLinkInfo(path);
obj.FileType = i.FileType.ToString();
obj.Size = i.Length;
obj.IsDirectory = false;
switch (i.FileType)
{
case FileTypes.SymbolicLink:
obj.IsLink = true;
obj.Target = i.ContentsPath;
break;
case FileTypes.Fifo:
case FileTypes.Socket:
case FileTypes.BlockDevice:
case FileTypes.CharacterDevice:
case FileTypes.Directory:
obj.IsDirectory = true;
if (path?.EndsWith(".app", StringComparison.InvariantCultureIgnoreCase) ?? false)
{
obj.MacSignatureStatus = FileSystemUtils.GetMacSignature(path);
}
break;
case FileTypes.RegularFile:
var fileInfo = new FileInfo(path);
obj.SizeOnDisk = i.BlocksAllocated * i.BlockSize;
if (opts.DownloadCloud || obj.SizeOnDisk > 0)
{
obj.LastModified = File.GetLastWriteTimeUtc(path);
obj.Created = File.GetCreationTimeUtc(path);
if (opts.GatherHashes)
{
obj.ContentHash = FileSystemUtils.GetFileHash(path);
}
var exeType = FileSystemUtils.GetExecutableType(path);
if (exeType != EXECUTABLE_TYPE.NONE && exeType != EXECUTABLE_TYPE.UNKNOWN)
{
obj.IsExecutable = true;
}
if (exeType == EXECUTABLE_TYPE.WINDOWS)
{
obj.SignatureStatus = WindowsFileSystemUtils.GetSignatureStatus(path);
obj.Characteristics = WindowsFileSystemUtils.GetDllCharacteristics(path);
}
else if (exeType == EXECUTABLE_TYPE.MACOS)
{
obj.MacSignatureStatus = FileSystemUtils.GetMacSignature(path);
}
}
break;
}
}
}
catch (Exception e) when (
e is ArgumentNullException ||
e is SecurityException ||
e is ArgumentException ||
e is UnauthorizedAccessException ||
e is PathTooLongException ||
e is NotSupportedException ||
e is InvalidOperationException ||
e is FileNotFoundException ||
e is Win32Exception ||
e is IOException)
{
Log.Verbose("Failed to create FileInfo from File at {0} ({1}:{2})", path, e.GetType(), e.Message);
}
catch (Exception e)
{
Log.Debug("Should be caught in DirectoryWalker {0} {1}", e.GetType().ToString(), path);
}
if (path is not null)
{
try
{
obj.LastModified = File.GetLastWriteTimeUtc(path);
obj.Created = File.GetCreationTimeUtc(path);
}
catch (Exception e)
{
Log.Verbose("Failed to get last modified for {0} ({1}:{2})", path, e.GetType(), e.Message);
}
}
return obj;
}