/*** Copyright (C) 2023 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: FileTrust.Unix.cpp Date: 2023-1-25 Author: Reece ***/ #include #include "FS.hpp" #include "FileTrust.Unix.hpp" #include #include #include #include #include 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; } } }