Files
MosisService/src/main/cpp/sandbox/permission_gate.cpp

198 lines
7.5 KiB
C++

#include "permission_gate.h"
#include "lua_sandbox.h"
#include <lua.hpp>
#include <algorithm>
namespace mosis {
//=============================================================================
// PERMISSION DATABASE
//=============================================================================
static const std::unordered_map<std::string, PermissionInfo> PERMISSIONS = {
// Normal permissions (auto-granted when declared)
{"internet", {PermissionCategory::Normal, "Access the internet"}},
{"vibrate", {PermissionCategory::Normal, "Vibrate the device"}},
{"wake_lock", {PermissionCategory::Normal, "Keep device awake"}},
{"notifications", {PermissionCategory::Normal, "Show notifications"}},
{"alarms", {PermissionCategory::Normal, "Set alarms"}},
{"nfc", {PermissionCategory::Normal, "Use NFC"}},
// Dangerous permissions (require user consent)
{"camera", {PermissionCategory::Dangerous, "Access the camera"}},
{"microphone", {PermissionCategory::Dangerous, "Record audio"}},
{"location.fine", {PermissionCategory::Dangerous, "Access precise location"}},
{"location.coarse", {PermissionCategory::Dangerous, "Access approximate location"}},
{"contacts.read", {PermissionCategory::Dangerous, "Read contacts"}},
{"contacts.write", {PermissionCategory::Dangerous, "Modify contacts"}},
{"storage.external", {PermissionCategory::Dangerous, "Access external storage"}},
{"storage.shared", {PermissionCategory::Dangerous, "Access shared storage"}},
{"sensors.motion", {PermissionCategory::Dangerous, "Access motion sensors"}},
{"bluetooth", {PermissionCategory::Dangerous, "Use Bluetooth"}},
{"bluetooth.scan", {PermissionCategory::Dangerous, "Scan for Bluetooth devices"}},
{"calendar.read", {PermissionCategory::Dangerous, "Read calendar"}},
{"calendar.write", {PermissionCategory::Dangerous, "Modify calendar"}},
{"phone.call", {PermissionCategory::Dangerous, "Make phone calls"}},
{"phone.read_state", {PermissionCategory::Dangerous, "Read phone state"}},
{"sms.read", {PermissionCategory::Dangerous, "Read SMS messages"}},
{"sms.send", {PermissionCategory::Dangerous, "Send SMS messages"}},
// Signature permissions (system apps only)
{"system.settings", {PermissionCategory::Signature, "Modify system settings"}},
{"system.install", {PermissionCategory::Signature, "Install apps"}},
{"system.uninstall", {PermissionCategory::Signature, "Uninstall apps"}},
{"system.admin", {PermissionCategory::Signature, "Device administrator"}},
{"system.overlay", {PermissionCategory::Signature, "Display over other apps"}},
{"system.wallpaper", {PermissionCategory::Signature, "Set wallpaper"}},
};
//=============================================================================
// CONSTRUCTOR
//=============================================================================
PermissionGate::PermissionGate(const SandboxContext& context)
: m_context(context)
, m_last_gesture(std::chrono::steady_clock::time_point::min())
{
}
//=============================================================================
// PERMISSION INFO
//=============================================================================
PermissionCategory PermissionGate::GetCategory(const std::string& permission) {
auto it = PERMISSIONS.find(permission);
if (it != PERMISSIONS.end()) {
return it->second.category;
}
// Unknown permissions default to Dangerous for safety
return PermissionCategory::Dangerous;
}
const PermissionInfo* PermissionGate::GetPermissionInfo(const std::string& permission) {
auto it = PERMISSIONS.find(permission);
if (it != PERMISSIONS.end()) {
return &it->second;
}
return nullptr;
}
//=============================================================================
// PERMISSION CHECKING
//=============================================================================
bool PermissionGate::HasPermission(const std::string& permission) const {
auto category = GetCategory(permission);
switch (category) {
case PermissionCategory::Normal:
return CheckNormalPermission(permission);
case PermissionCategory::Dangerous:
return CheckDangerousPermission(permission);
case PermissionCategory::Signature:
return CheckSignaturePermission(permission);
}
return false;
}
bool PermissionGate::Check(lua_State* L, const std::string& permission) {
if (!HasPermission(permission)) {
luaL_error(L, "permission denied: %s", permission.c_str());
return false;
}
return true;
}
bool PermissionGate::IsDeclared(const std::string& permission) const {
const auto& declared = m_context.permissions;
return std::find(declared.begin(), declared.end(), permission) != declared.end();
}
bool PermissionGate::CheckNormalPermission(const std::string& permission) const {
// Normal permissions are auto-granted if declared in manifest
return IsDeclared(permission);
}
bool PermissionGate::CheckDangerousPermission(const std::string& permission) const {
// Must be declared in manifest
if (!IsDeclared(permission)) {
return false;
}
// System apps get dangerous permissions automatically
if (m_context.is_system_app) {
return true;
}
// Regular apps need runtime grant
return m_runtime_grants.count(permission) > 0;
}
bool PermissionGate::CheckSignaturePermission(const std::string& permission) const {
// Only system apps get signature permissions
if (!m_context.is_system_app) {
return false;
}
// Must still be declared
return IsDeclared(permission);
}
//=============================================================================
// USER GESTURE TRACKING
//=============================================================================
void PermissionGate::RecordUserGesture() {
m_last_gesture = std::chrono::steady_clock::now();
}
bool PermissionGate::HasRecentUserGesture(int ms) const {
// If no gesture has been recorded, return false
if (m_last_gesture == std::chrono::steady_clock::time_point::min()) {
return false;
}
auto now = std::chrono::steady_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(now - m_last_gesture);
return elapsed.count() < ms;
}
//=============================================================================
// RUNTIME GRANTS
//=============================================================================
void PermissionGate::GrantPermission(const std::string& permission) {
// Can only grant dangerous permissions
auto category = GetCategory(permission);
if (category == PermissionCategory::Dangerous) {
m_runtime_grants.insert(permission);
}
}
void PermissionGate::RevokePermission(const std::string& permission) {
m_runtime_grants.erase(permission);
}
//=============================================================================
// QUERIES
//=============================================================================
const std::vector<std::string>& PermissionGate::GetDeclaredPermissions() const {
return m_context.permissions;
}
std::vector<std::string> PermissionGate::GetGrantedPermissions() const {
std::vector<std::string> granted;
for (const auto& perm : m_context.permissions) {
if (HasPermission(perm)) {
granted.push_back(perm);
}
}
return granted;
}
} // namespace mosis