Compare commits
7 Melakukan
feature/ma
...
8d685dc581
Penulis | SHA1 | Tanggal | |
---|---|---|---|
8d685dc581 | |||
ed43f5f700 | |||
10f00aeb45 | |||
67eb8b6428 | |||
f26fd19fb4 | |||
204a72da1f | |||
88816a4015 |
2
Makefile
2
Makefile
@ -2,7 +2,7 @@
|
||||
|
||||
CXXFLAGS=-std=c++17 -O0 -g -no-pie -pipe -MMD -Wall -Wextra
|
||||
RELEASE_CXXFLAGS=-std=c++17 -O3 -pipe -MMD -Wall -Wextra
|
||||
LDFLAGS=-lsqlite3 -lpthread -lcrypto -lstdc++fs -lseccomp
|
||||
LDFLAGS=-lsqlite3 -lpthread -lcrypto -lstdc++fs
|
||||
INCLUDEFLAGS=-I submodules/sqlitemoderncpp/hdr -I submodules/cpp-httplib -I submodules/qssb.h
|
||||
|
||||
CXX=g++
|
||||
|
14
qswiki.cpp
14
qswiki.cpp
@ -77,21 +77,21 @@ int main(int argc, char **argv)
|
||||
Logger::error() << "Sandbox is not supported, exiting";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if(argc < 2)
|
||||
{
|
||||
std::cerr << "no path to config file provided" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
std::string configpath = std::filesystem::absolute(argv[1]).string();
|
||||
if(!sandbox->enableForInit())
|
||||
{
|
||||
Logger::error() << "Sandboxing for init mode could not be activated.";
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if(argc < 2)
|
||||
{
|
||||
std::cerr << "no path to config file provided" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ConfigReader configreader(argv[1]);
|
||||
ConfigReader configreader(configpath);
|
||||
Config config = configreader.readConfig();
|
||||
|
||||
// TODO: config.connectiontring only works as long as we only support sqlite of course
|
||||
|
@ -26,16 +26,26 @@
|
||||
bool SandboxLinux::enableForInit()
|
||||
{
|
||||
umask(0027);
|
||||
struct qssb_policy policy = {0};
|
||||
int blacklisted_syscalls[] = {QSSB_SYS(execveat), QSSB_SYS(execve), -1};
|
||||
policy.blacklisted_syscalls = blacklisted_syscalls;
|
||||
policy.no_new_privs = 1;
|
||||
int result = qssb_enable_policy(&policy);
|
||||
if(result != 0)
|
||||
struct qssb_policy *policy = qssb_init_policy();
|
||||
if(policy == NULL)
|
||||
{
|
||||
Logger::error() << "Failed to install sandboxing policy (init): " << result;
|
||||
Logger::error() << "Failed to init sandboxing policy (init)";
|
||||
return false;
|
||||
}
|
||||
policy->namespace_options = QSSB_UNSHARE_USER;
|
||||
policy->drop_caps = 0;
|
||||
qssb_append_syscall_policy(policy, QSSB_SYSCALL_DENY_KILL_PROCESS, QSSB_SYS(execveat));
|
||||
qssb_append_syscall_policy(policy, QSSB_SYSCALL_DENY_KILL_PROCESS, QSSB_SYS(execve));
|
||||
qssb_append_syscall_default_policy(policy, QSSB_SYSCALL_ALLOW);
|
||||
|
||||
int result = qssb_enable_policy(policy);
|
||||
if(result != 0)
|
||||
{
|
||||
Logger::error() << "Failed to enable sandboxing policy (init): " << result;
|
||||
qssb_free_policy(policy);
|
||||
return false;
|
||||
}
|
||||
qssb_free_policy(policy);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -44,28 +54,34 @@ bool SandboxLinux::enablePreWorker(std::vector<std::string> fsPaths)
|
||||
std::sort(fsPaths.begin(), fsPaths.end(),
|
||||
[](const std::string &a, const std::string &b) { return a.length() < b.length(); });
|
||||
|
||||
struct qssb_path_policy *policies = new qssb_path_policy[fsPaths.size()];
|
||||
struct qssb_policy *policy = qssb_init_policy();
|
||||
if(policy == NULL)
|
||||
{
|
||||
Logger::error() << "Failed to init sandboxing policy (pre)";
|
||||
return false;
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < fsPaths.size(); i++)
|
||||
{
|
||||
policies[i].next = policies + (i + 1);
|
||||
policies[i].mountpoint = fsPaths[i].c_str();
|
||||
policies[i].policy = QSSB_MOUNT_ALLOW_READ | QSSB_MOUNT_ALLOW_WRITE;
|
||||
qssb_append_path_policy(policy, QSSB_FS_ALLOW_READ | QSSB_FS_ALLOW_WRITE, fsPaths[i].c_str());
|
||||
}
|
||||
policies[fsPaths.size() - 1].next = NULL;
|
||||
|
||||
struct qssb_policy policy = {0};
|
||||
policy.path_policies = policies;
|
||||
policy.namespace_options |= QSSB_UNSHARE_MOUNT;
|
||||
policy.namespace_options |= QSSB_UNSHARE_USER;
|
||||
int blacklisted_syscalls[] = {QSSB_SYS(execveat), QSSB_SYS(execve), -1};
|
||||
policy.blacklisted_syscalls = blacklisted_syscalls;
|
||||
int result = qssb_enable_policy(&policy);
|
||||
policy->namespace_options = QSSB_UNSHARE_MOUNT;
|
||||
policy->drop_caps = 0;
|
||||
policy->mount_path_policies_to_chroot = 1;
|
||||
|
||||
qssb_append_syscall_policy(policy, QSSB_SYSCALL_DENY_KILL_PROCESS, QSSB_SYS(execveat));
|
||||
qssb_append_syscall_policy(policy, QSSB_SYSCALL_DENY_KILL_PROCESS, QSSB_SYS(execve));
|
||||
qssb_append_syscall_default_policy(policy, QSSB_SYSCALL_ALLOW);
|
||||
|
||||
int result = qssb_enable_policy(policy);
|
||||
if(result != 0)
|
||||
{
|
||||
Logger::error() << "Failed to install sandboxing policy (preworker): %i" << result;
|
||||
qssb_free_policy(policy);
|
||||
return false;
|
||||
}
|
||||
delete[] policies;
|
||||
qssb_free_policy(policy);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -88,30 +104,35 @@ bool SandboxLinux::supported()
|
||||
}
|
||||
bool SandboxLinux::enableForWorker()
|
||||
{
|
||||
struct qssb_policy policy = {0};
|
||||
policy.drop_caps = 1;
|
||||
policy.not_dumpable = 1;
|
||||
policy.no_new_privs = 1;
|
||||
struct qssb_policy *policy = qssb_init_policy();
|
||||
if(policy == NULL)
|
||||
{
|
||||
Logger::error() << "Failed to init sandboxing policy (worker) ";
|
||||
return false;
|
||||
}
|
||||
policy->drop_caps = 1;
|
||||
policy->not_dumpable = 1;
|
||||
policy->no_new_privs = 1;
|
||||
policy->namespace_options = 0;
|
||||
|
||||
/* TODO: as said, a whitelist approach is better. As such, this list is bound to be incomplete in the
|
||||
* sense that more could be listed here and some critical ones are probably missing */
|
||||
int blacklisted_syscalls[] = {QSSB_SYS(setuid),
|
||||
QSSB_SYS(connect),
|
||||
QSSB_SYS(chroot),
|
||||
QSSB_SYS(pivot_root),
|
||||
QSSB_SYS(mount),
|
||||
QSSB_SYS(setns),
|
||||
QSSB_SYS(unshare),
|
||||
QSSB_SYS(ptrace),
|
||||
QSSB_SYS(personality),
|
||||
QSSB_SYS(prctl),
|
||||
-1};
|
||||
policy.blacklisted_syscalls = blacklisted_syscalls;
|
||||
if(qssb_enable_policy(&policy) != 0)
|
||||
|
||||
/* TODO: use qssb groups */
|
||||
long blacklisted_syscalls[] = {QSSB_SYS(setuid), QSSB_SYS(connect), QSSB_SYS(chroot), QSSB_SYS(pivot_root),
|
||||
QSSB_SYS(mount), QSSB_SYS(setns), QSSB_SYS(unshare), QSSB_SYS(ptrace),
|
||||
QSSB_SYS(personality), QSSB_SYS(prctl)};
|
||||
|
||||
qssb_append_syscalls_policy(policy, QSSB_SYSCALL_DENY_KILL_PROCESS, blacklisted_syscalls,
|
||||
sizeof(blacklisted_syscalls) / sizeof(blacklisted_syscalls[0]));
|
||||
qssb_append_syscall_default_policy(policy, QSSB_SYSCALL_ALLOW);
|
||||
|
||||
if(qssb_enable_policy(policy) != 0)
|
||||
{
|
||||
Logger::error() << "Sandbox: Activation of seccomp blacklist failed!";
|
||||
qssb_free_policy(policy);
|
||||
return false;
|
||||
}
|
||||
|
||||
qssb_free_policy(policy);
|
||||
return true;
|
||||
}
|
||||
|
@ -25,24 +25,13 @@ count integer
|
||||
CREATE TABLE category(id INTEGER PRIMARY KEY, name varchar(255));
|
||||
CREATE TABLE categorymember(id INTEGER PRIMARY KEY, category REFERENCES category(id), page REFERENCES page (id));
|
||||
CREATE INDEX revisionid ON revision (revisionid DESC);
|
||||
CREATE INDEX pagename ON page (name)
|
||||
;
|
||||
CREATE INDEX token ON session (token)
|
||||
;
|
||||
CREATE TRIGGER search_ai AFTER INSERT ON revision BEGIN
|
||||
DELETE FROM search WHERE page = new.page;
|
||||
INSERT INTO search(rowid, content, page) VALUES (new.id, new.content, new.page);
|
||||
END;
|
||||
CREATE TRIGGER search_au AFTER UPDATE ON revision BEGIN
|
||||
DELETE FROM search WHERE page = old.page;
|
||||
INSERT INTO search(rowid, content, page) VALUES (new.id, new.content, new.page);
|
||||
END;
|
||||
CREATE VIRTUAL TABLE search USING fts5(content, page UNINDEXED, content=revision,content_rowid=id)
|
||||
/* search(content,page) */;
|
||||
CREATE TABLE IF NOT EXISTS 'search_data'(id INTEGER PRIMARY KEY, block BLOB);
|
||||
CREATE TABLE IF NOT EXISTS 'search_idx'(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;
|
||||
CREATE TABLE IF NOT EXISTS 'search_docsize'(id INTEGER PRIMARY KEY, sz BLOB);
|
||||
CREATE TABLE IF NOT EXISTS 'search_config'(k PRIMARY KEY, v) WITHOUT ROWID;
|
||||
CREATE INDEX pagename ON page (name);
|
||||
CREATE INDEX token ON session (token);
|
||||
CREATE VIRTUAL TABLE search USING fts5(content, page UNINDEXED, content=revision,content_rowid=id);
|
||||
CREATE TRIGGER search_ad AFTER DELETE ON revision BEGIN
|
||||
INSERT INTO search(search, rowid, content, page) VALUES('delete', old.id, old.content, old.page);
|
||||
END;
|
||||
CREATE TRIGGER search_ai AFTER INSERT ON revision BEGIN
|
||||
INSERT INTO search(search, rowid, content, page) SELECT 'delete', id, content, page FROM revision WHERE page = new.page AND revisionid = new.revisionid - 1;
|
||||
INSERT INTO search(rowid, content, page) VALUES (new.id, new.content, new.page);
|
||||
END;
|
||||
|
Submodule submodules/cpp-httplib updated: 63643e6386...d87d0672a8
Submodule submodules/qssb.h updated: 9df2e9ee90...11d64c6fcf
@ -46,6 +46,12 @@ std::string utils::html_xss(std::string_view str)
|
||||
case '%':
|
||||
result += "%";
|
||||
break;
|
||||
case '\'':
|
||||
result += "'";
|
||||
break;
|
||||
case '&':
|
||||
result += "&";
|
||||
break;
|
||||
default:
|
||||
result += c;
|
||||
}
|
||||
@ -93,7 +99,7 @@ std::vector<std::string> utils::split(const std::string &str, char delim)
|
||||
// TODO: can easily break if we pass a regex here
|
||||
std::vector<std::string> utils::split(const std::string &str, const std::string &delim)
|
||||
{
|
||||
std::regex regex { delim + "+" };
|
||||
std::regex regex{delim + "+"};
|
||||
return split(str, regex);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user