AuroraRuntime/Source/IO/FS/FileTrust.Unix.cpp

182 lines
4.2 KiB
C++

/***
Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: FileTrust.Unix.cpp
Date: 2023-1-25
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "FS.hpp"
#include "FileTrust.Unix.hpp"
#include <sys/xattr.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
namespace Aurora::IO::FS
{
AUKN_SYM bool BlockFile(const AuString &path)
{
auto srcPath = NormalizePathRet(path);
if (srcPath.empty())
{
SysPushErrorMemory();
return {};
}
AuString subdir;
if ((path.size() > 1) &&
((path[path.size() - 1] == '/') ||
(path[path.size() - 1] == '\\')))
{
subdir = srcPath.substr(0, srcPath.size() - 1);
}
else
{
subdir = srcPath;
}
GoUpToSeparator(subdir, subdir);
subdir = "file:///" + subdir;
if (::setxattr(srcPath.c_str(), "user.xdg.origin.url", subdir.c_str(), subdir.size(), XATTR_CREATE) == -1)
{
if (errno == EEXIST)
{
if (::setxattr(srcPath.c_str(), "user.xdg.origin.url", subdir.c_str(), subdir.size(), XATTR_REPLACE) == -1)
{
return false;
}
}
}
if (::setxattr(srcPath.c_str(), "user.xdg.referrer.url", subdir.c_str(), subdir.size(), XATTR_CREATE) == -1)
{
if (errno == EEXIST)
{
if (::setxattr(srcPath.c_str(), "user.xdg.referrer.url", subdir.c_str(), subdir.size(), XATTR_REPLACE) == -1)
{
return false;
}
}
}
mode_t mode { 0644 };
struct stat s;
if (::stat(srcPath.c_str(), &s) == 0)
{
mode = s.st_mode;
mode &= ~( 0111 );
}
if (::chmod(srcPath.c_str(), mode) != 0)
{
SysPushErrorIO("BlockFile chmod failed: {}", path);
}
return true;
}
AUKN_SYM bool UnblockFile(const AuString &path)
{
auto srcPath = NormalizePathRet(path);
if (srcPath.empty())
{
SysPushErrorMemory();
return {};
}
::removexattr(srcPath.c_str(), "user.xdg.origin.url");
::removexattr(srcPath.c_str(), "user.xdg.referrer.url");
mode_t mode { 0644 };
struct stat s;
if (::stat(srcPath.c_str(), &s) == 0)
{
mode = s.st_mode;
mode &= ~(0111);
}
if (::chmod(srcPath.c_str(), mode) != 0)
{
SysPushErrorIO("UnblockFile chmod failed: {}", path);
}
return AuFS::FileExists(srcPath);
}
AUKN_SYM bool TrustFile(const AuString &path)
{
struct stat s;
mode_t mode { 0755 };
auto srcPath = NormalizePathRet(path);
if (srcPath.empty())
{
SysPushErrorMemory();
return {};
}
if (::stat(srcPath.c_str(), &s) == 0)
{
mode = s.st_mode;
mode |= 0111;
}
if (::chmod(srcPath.c_str(), mode) != 0)
{
SysPushErrorIO("chmod failed: {}", path);
return false;
}
return true;
}
AUKN_SYM bool IsFileBlocked(const AuString &path)
{
auto srcPath = NormalizePathRet(path);
if (srcPath.empty())
{
SysPushErrorMemory();
return {};
}
auto length = ::getxattr(srcPath.c_str(), "user.xdg.referrer.url", nullptr, 0);
if (length > 0)
{
return true;
}
length = ::getxattr(srcPath.c_str(), "user.xdg.origin.url", nullptr, 0);
if (length > 0)
{
return true;
}
return false;
}
AUKN_SYM bool IsFileTrusted(const AuString &path)
{
struct stat s;
auto srcPath = NormalizePathRet(path);
if (srcPath.empty())
{
SysPushErrorMemory();
return {};
}
if (::stat(srcPath.c_str(), &s) == 0)
{
return (s.st_mode & 0111) != 0;
}
else
{
return false;
}
}
}