16 Commits

Author SHA1 Message Date
8568fd1c46 Restore the check that makes sure mob paths start from their spawn point
This was added in 599bbedd and accidentally removed during the TableData
refactor in c960b062.
2024-10-19 04:26:09 +02:00
05a5303522 Fix one-off mobs respawning if their regenTime is 0 2024-10-19 04:25:08 +02:00
3365cb53b7 Only listen for monitor connections on localhost by default
This is to prevent accidental exposure of the monitor port to the public
internet if a server admin enables the monitor port without it being
properly firewalled. There is now a config option that lets you override
the address to bind to, so that it can still be made available to other
machines over private networks such as Wireguard.
2024-10-17 01:04:50 +02:00
5e92a58134 Print server types when starting servers
Should have done this back when I added serverType.
2024-10-17 01:04:50 +02:00
94064e1865 [sandbox] Print error message on seccomp sandbox violation
Co-authored-by: cpunch <sethtstubbs@gmail.com>
2024-10-17 01:04:50 +02:00
5e73ff272d [sandbox] Add make target for building without Landlock 2024-10-17 01:04:47 +02:00
197ccad0eb [sandbox] Landlock support
* Support disabling Landlock at compile time or runtime if unsupported,
  without disabling seccomp
* Support older Landlock ABI versions
* Support an extra arbitrary RW path, inteded for the coredump dir
* Support database locations other than the working directory
2024-10-17 01:03:06 +02:00
CakeLancelot
68b56e7c25 Docker: disable sandbox to fix crashes and update Dockerfile/compose.yml (#294)
Additionally:
* Add EXPOSE hints to Dockerfile
* as -> AS in Dockerfile to resolve warning
* Point docker-compose to our docker hub image
* Remove version property in docker-compose.yml as it was deprecated
2024-10-15 01:00:37 -05:00
CakeLancelot
cada1bcfd8 Update check-builds.yaml
* Install SQLite3 headers as they arent included in the Ubuntu 24.04 image (only includes CLI currently): https://github.com/actions/runner-images/blob/main/images/ubuntu/Ubuntu2404-Readme.md
* Change copy-artifacts task to also use ubuntu-latest
2024-10-14 22:48:41 -05:00
Juansecu
ca43a2996a BUILD - Fix build of Docker image for different archs (#293) 2024-10-14 17:22:45 -05:00
7c66041a6f Add make target for building without the sandbox 2024-10-12 15:42:26 +02:00
2c822e210b [bcrypt] Fix missing include on Windows
Co-authored-by: Jade Shrinemaiden <jadeshrinemaiden@gmail.com>
2024-10-12 15:15:36 +02:00
CakeLancelot
c116794c83 README updates
Create dockerhub pull badge
Change links from wiki to website
2024-10-08 22:00:45 -05:00
CakeLancelot
4ebda6066c Docker: add manual workflow dispatch and auto install QEMU 2024-10-08 21:52:05 -05:00
6de21277d6 Fix eruption attacks cancelling when no targets are in range 2024-10-08 19:18:00 -07:00
CakeLancelot
397700e909 Update version numbers in README 2024-10-06 23:26:36 -05:00
19 changed files with 277 additions and 37 deletions

View File

@@ -29,7 +29,7 @@ jobs:
submodules: recursive
fetch-depth: 0
- name: Install dependencies
run: sudo apt install clang cmake snap -y && sudo snap install powershell --classic
run: sudo apt install clang cmake snap libsqlite3-dev -y && sudo snap install powershell --classic
- name: Check compilation
run: |
$versions = "104", "728", "1013"
@@ -113,7 +113,7 @@ jobs:
copy-artifacts:
if: github.event_name != 'pull_request' && github.ref == 'refs/heads/master'
runs-on: ubuntu-22.04
runs-on: ubuntu-latest
needs: [windows-build, ubuntu-build]
env:
BOT_SSH_KEY: ${{ secrets.BOT_SSH_KEY }}

View File

@@ -3,6 +3,7 @@ name: Push Docker Image
on:
release:
types: [published]
workflow_dispatch:
jobs:
push-docker-image:
@@ -10,11 +11,6 @@ jobs:
runs-on: ubuntu-latest
permissions:
contents: read
strategy:
matrix:
platforms:
- linux/amd64
- linux/arm64
steps:
- uses: actions/checkout@v4
- name: Retrieve major version
@@ -28,11 +24,15 @@ jobs:
with:
password: ${{ secrets.DOCKERHUB_TOKEN }}
username: ${{ secrets.DOCKERHUB_USERNAME }}
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build and push the Docker image
uses: docker/build-push-action@v5
uses: docker/build-push-action@v6
with:
context: .
file: ./Dockerfile
platforms: ${{ matrix.platforms }}
platforms: linux/amd64,linux/arm64
push: true
tags: ${{ secrets.DOCKERHUB_REPOSITORY }}:${{ github.ref_name }},${{ secrets.DOCKERHUB_REPOSITORY }}:${{ steps.split.outputs._0 }},${{ secrets.DOCKERHUB_REPOSITORY }}:latest

View File

@@ -1,5 +1,5 @@
# build
FROM debian:stable-slim as build
FROM debian:stable-slim AS build
WORKDIR /usr/src/app
@@ -14,7 +14,7 @@ COPY vendor ./vendor
COPY .git ./.git
COPY Makefile CMakeLists.txt version.h.in ./
RUN make -j8
RUN make nosandbox -j$(nproc)
# prod
FROM debian:stable-slim
@@ -29,4 +29,8 @@ COPY sql ./sql
CMD ["/bin/fusion"]
LABEL Name=openfusion Version=0.0.2
EXPOSE 23000/tcp
EXPOSE 23001/tcp
EXPOSE 8001/tcp
LABEL Name=openfusion Version=1.6.0

View File

@@ -133,6 +133,8 @@ HDR=$(CHDR) $(CXXHDR)
all: $(SERVER)
windows: $(SERVER)
nosandbox: $(SERVER)
nolandlock: $(SERVER)
# assign Windows-specific values if targeting Windows
windows : CC=$(WIN_CC)
@@ -142,6 +144,9 @@ windows : CXXFLAGS=$(WIN_CXXFLAGS)
windows : LDFLAGS=$(WIN_LDFLAGS)
windows : SERVER=$(WIN_SERVER)
nosandbox : CFLAGS+=-DCONFIG_NOSANDBOX=1
nolandlock : CFLAGS+=-DCONFIG_NOLANDLOCK=1
.SUFFIXES: .o .c .cpp .h .hpp
.c.o:
@@ -163,7 +168,7 @@ version.h:
src/main.o: version.h
.PHONY: all windows clean nuke
.PHONY: all windows nosandbox nolandlock clean nuke
# only gets rid of OpenFusion objects, so we don't need to
# recompile the libs every time

View File

@@ -1,34 +1,35 @@
<p align="center"><img width="640" src="res/openfusion-hero.png" alt=""></p>
<p align="center"><img width="640" src="res/openfusion-hero.png" alt="OpenFusion Logo"></p>
<p align="center">
<a href="https://github.com/OpenFusionProject/OpenFusion/releases/latest"><img src="https://img.shields.io/github/v/release/OpenFusionProject/OpenFusion" alt="Current Release"></a>
<a href="https://github.com/OpenFusionProject/OpenFusion/actions/workflows/check-builds.yaml"><img src="https://github.com/OpenFusionProject/OpenFusion/actions/workflows/check-builds.yaml/badge.svg" alt="Workflow"></a>
<a href="https://hub.docker.com/repository/docker/openfusion/openfusion/"><img src="https://badgen.net/docker/pulls/openfusion/openfusion?icon=docker&label=pulls"></a>
<a href="https://discord.gg/DYavckB"><img src="https://img.shields.io/badge/chat-on%20discord-7289da.svg?logo=discord" alt="Discord"></a>
<a href="https://github.com/OpenFusionProject/OpenFusion/blob/master/LICENSE.md"><img src="https://img.shields.io/github/license/OpenFusionProject/OpenFusion" alt="License"></a>
</p>
OpenFusion is a reverse-engineered server for FusionFall. It primarily targets versions `beta-20100104` and `beta-20111013` of the original game, with [limited support](https://github.com/OpenFusionProject/OpenFusion/wiki/FusionFall-Version-Support) for others.
OpenFusion is a reverse-engineered server for FusionFall. It primarily targets versions `beta-20100104` and `beta-20111013` of the original game, with [limited support](https://openfusion.dev/docs/reference/fusionfall-version-support/) for others.
## Usage
### Getting Started
#### Method A: Installer (Easiest)
1. Download the client installer by clicking [here](https://github.com/OpenFusionProject/OpenFusion/releases/download/1.5.2/OpenFusionClient-1.5.2-Installer.exe) - choose to run the file.
1. Download the client installer by clicking [here](https://github.com/OpenFusionProject/OpenFusion/releases/download/1.6/OpenFusionClient-1.6-Installer.exe) - choose to run the file.
2. After a few moments, the client should open: you will be given a choice between two public servers by default. Select the one you wish to play and click connect.
3. To create an account, simply enter the details you wish to use at the login screen then click Log In. Do *not* click register, as this will just lead to a blank screen.
4. Make a new character, and enjoy the game! Your progress will be saved automatically, and you can resume playing by entering the login details you used in step 3.
#### Method B: Standalone .zip file
1. Download the client from [here](https://github.com/OpenFusionProject/OpenFusion/releases/download/1.5.2/OpenFusionClient-1.5.2.zip).
1. Download the client from [here](https://github.com/OpenFusionProject/OpenFusion/releases/download/1.6/OpenFusionClient-1.6.zip).
2. Extract it to a folder of your choice. Note: if you are upgrading from an older version, it is preferable to start with a fresh folder rather than overwriting a previous install.
3. Run OpenFusionClient.exe - you will be given a choice between two public servers by default. Select the one you wish to play and click connect.
4. To create an account, simply enter the details you wish to use at the login screen then click Log In. Do *not* click register, as this will just lead to a blank screen.
5. Make a new character, and enjoy the game! Your progress will be saved automatically, and you can resume playing by entering the login details you used in step 4.
Instructions for getting the client to run on Linux through Wine can be found [here](https://github.com/OpenFusionProject/OpenFusion/wiki/Running-the-game-client-on-Linux).
Instructions for getting the client to run on Linux through Wine can be found [here](https://openfusion.dev/docs/guides/running-on-linux/).
### Hosting a server
1. Grab `OpenFusionServer-1.5-Original.zip` or `OpenFusionServer-1.5-Academy.zip` from [here](https://github.com/OpenFusionProject/OpenFusion/releases/tag/1.5.2).
1. Grab `OpenFusionServer-1.6-Original.zip` or `OpenFusionServer-1.6-Academy.zip` from [here](https://github.com/OpenFusionProject/OpenFusion/releases/tag/1.6).
2. Extract it to a folder of your choice, then run `winfusion.exe` (Windows) or `fusion` (Linux) to start the server.
3. Add a new server to the client's list:
1. For Description, enter anything you want. This is what will show up in the server list.
@@ -79,17 +80,17 @@ This just works if you're all under the same LAN, but if you want to play over t
## Compiling
OpenFusion has one external dependency: SQLite. The oldest compatible version is `3.33.0`. You can install it on Windows using `vcpkg`, and on Unix/Linux using your distribution's package manager. For a more indepth guide on how to set up vcpkg, [read this guide on the wiki](https://github.com/OpenFusionProject/OpenFusion/wiki/Installing-SQLite-on-Windows-using-vcpkg).
OpenFusion has one external dependency: SQLite. The oldest compatible version is `3.33.0`. You can install it on Windows using `vcpkg`, and on Unix/Linux using your distribution's package manager. For a more indepth guide on how to set up vcpkg, [read this guide](https://openfusion.dev/docs/development/installing-sqlite-on-windows-using-vcpkg/).
You have two choices for compiling OpenFusion: the included Makefile and the included CMakeLists file.
### Makefile
A detailed compilation guide is available for Windows users in the wiki [using MinGW-w64 and MSYS2](https://github.com/OpenFusionProject/OpenFusion/wiki/Compilation-on-Windows). Otherwise, to compile it for the current platform you're on, just run `make` with the correct build tools installed (currently make and clang).
A detailed compilation guide is available for Windows users on the website [using MinGW-w64 and MSYS2](https://openfusion.dev/docs/development/compilation-on-windows-msys2-mingw/). Otherwise, to compile it for the current platform you're on, just run `make` with the correct build tools installed (currently make and clang).
### CMake
A detailed guide is available [on the wiki](https://github.com/OpenFusionProject/OpenFusion/wiki/Compilation-with-CMake-or-Visual-Studio) for people using regular old CMake or the version of CMake that comes with Visual Studio. tl;dr: `cmake -B build`
A detailed guide is available [in our documentation](https://openfusion.dev/docs/development/compilation-with-cmake-or-visual-studio/) for people using regular old CMake or the version of CMake that comes with Visual Studio. TL;DR: `cmake -B build`
## Contributing
@@ -107,4 +108,4 @@ Meanwhile the Academy server is more meant for legitimate playthroughs (default
When hosting a local server, you will have access to all commands by default (account level 1).
For a list of available commands, see [this wiki page](https://github.com/OpenFusionProject/OpenFusion/wiki/Ingame-Command-list).
For a list of available commands, see [this page](https://openfusion.dev/docs/reference/ingame-command-list/).

View File

@@ -102,5 +102,8 @@ eventmode=0
enabled=false
# the port to listen for connections on
port=8003
# The local IP to listen on.
# Do not change this unless you know what you're doing.
listenip=127.0.0.1
# how often the listeners should be updated (in milliseconds)
interval=5000

View File

@@ -1,11 +1,9 @@
version: '3.4'
services:
openfusion:
image: openfusion
build:
context: .
dockerfile: ./Dockerfile
image: openfusion/openfusion:latest
volumes:
- ./config.ini:/usr/src/app/config.ini
- ./database.db:/usr/src/app/database.db

View File

@@ -368,7 +368,6 @@ void Abilities::useNPCSkill(EntityRef npc, int skillID, std::vector<ICombatant*>
SkillData* skill = &SkillTable[skillID];
std::vector<SkillResult> results = handleSkill(skill, 0, src, affected);
if(results.empty()) return; // no effect; no need for confirmation packets
// lazy validation since skill results might be different sizes
if (!validOutVarPacket(sizeof(sP_FE2CL_NPC_SKILL_HIT), results.size(), MAX_SKILLRESULT_SIZE)) {

View File

@@ -478,6 +478,14 @@ void MobAI::deadStep(CombatNPC* npc, time_t currTime) {
if (self->groupLeader == self->id)
roamingStep(self, currTime);
/*
* If the mob hasn't fully despanwed yet, don't try to respawn it. This protects
* against the edge case where mobs with a very short regenTime would try to respawn
* before they've faded away; and would respawn even if they were meant to be removed.
*/
if (!self->despawned)
return;
if (self->killedTime != 0 && currTime - self->killedTime < self->regenTime * 100)
return;

View File

@@ -388,8 +388,21 @@ NPCPath* Transport::findApplicablePath(int32_t id, int32_t type, int taskID) {
void Transport::constructPathNPC(int32_t id, NPCPath* path) {
BaseNPC* npc = NPCManager::NPCs[id];
if (npc->kind == EntityKind::MOB)
((Mob*)(npc))->staticPath = true;
if (npc->kind == EntityKind::MOB) {
auto mob = (Mob*)npc;
mob->staticPath = true;
Vec3 firstPoint = path->points.front();
// Ensure that the first point coincides with the mob's spawn point.
if (mob->spawnX != firstPoint.x || mob->spawnY != firstPoint.y) {
std::cout << "[FATAL] The first point of the route for mob " << mob->id << " (type " << mob->type
<< ") does not correspond with its spawn point." << std::endl;
exit(1);
}
}
npc->loopingPath = path->isLoop;
// Interpolate

View File

@@ -428,7 +428,7 @@ void CNServer::removePollFD(int fd) {
}
void CNServer::start() {
std::cout << "Starting server at *:" << port << std::endl;
std::cout << "Starting " << serverType << " server at *:" << port << std::endl;
while (active) {
// the timeout is to ensure shard timers are ticking
int n = poll(fds.data(), fds.size(), 50);

View File

@@ -49,6 +49,7 @@ CNShardServer *shardServer = nullptr;
std::thread *shardThread = nullptr;
void startShard(CNShardServer* server) {
sandbox_thread_start();
server->start();
}
@@ -150,6 +151,8 @@ int main() {
/* not reached */
}
sandbox_init();
std::cout << "[INFO] Starting Server Threads..." << std::endl;
CNLoginServer loginServer(settings::LOGINPORT);
shardServer = new CNShardServer(settings::SHARDPORT);
@@ -157,6 +160,7 @@ int main() {
shardThread = new std::thread(startShard, (CNShardServer*)shardServer);
sandbox_start();
sandbox_thread_start();
loginServer.start();

View File

@@ -4,11 +4,16 @@
#if defined(__linux__) || defined(__OpenBSD__)
# if !defined(CONFIG_NOSANDBOX)
void sandbox_init();
void sandbox_start();
void sandbox_thread_start();
# else
#include <iostream>
inline void sandbox_init() {}
inline void sandbox_thread_start() {}
inline void sandbox_start() {
std::cout << "[WARN] Built without a sandbox" << std::endl;
}
@@ -17,5 +22,7 @@ inline void sandbox_start() {
#else
// stub for unsupported platforms
inline void sandbox_init() {}
inline void sandbox_start() {}
inline void sandbox_thread_start() {}
#endif

View File

@@ -13,6 +13,9 @@ static void eunveil(const char *path, const char *permissions) {
err(1, "unveil");
}
void sandbox_init() {}
void sandbox_thread_start() {}
void sandbox_start() {
/*
* There shouldn't ever be a reason to disable this one, but might as well

View File

@@ -4,6 +4,9 @@
#include "settings.hpp"
#include <stdlib.h>
#include <fcntl.h>
#include <filesystem>
#include <sys/prctl.h>
#include <sys/ptrace.h>
@@ -17,6 +20,10 @@
#include <linux/audit.h>
#include <linux/net.h> // for socketcall() args
#ifndef CONFIG_NOLANDLOCK
#include <linux/landlock.h>
#endif
/*
* Macros adapted from https://outflux.net/teach-seccomp/
* Relevant license:
@@ -54,7 +61,7 @@
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ERRNO|(_errno))
#define KILL_PROCESS \
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_KILL_PROCESS)
BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_TRAP)
/*
* Macros adapted from openssh's sandbox-seccomp-filter.c
@@ -297,25 +304,201 @@ static sock_fprog prog = {
ARRLEN(filter), filter
};
// our own wrapper for the seccomp() syscall
// Our own wrapper for the seccomp() syscall.
int seccomp(unsigned int operation, unsigned int flags, void *args) {
return syscall(__NR_seccomp, operation, flags, args);
}
void sandbox_start() {
#ifndef CONFIG_NOLANDLOCK
// Support compilation on systems that only have older Landlock headers.
#ifndef LANDLOCK_ACCESS_FS_REFER
#define LANDLOCK_ACCESS_FS_REFER 0
#endif
#ifndef LANDLOCK_ACCESS_FS_TRUNCATE
#define LANDLOCK_ACCESS_FS_TRUNCATE 0
#endif
struct landlock_ruleset_attr ruleset_attr = {
.handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE
| LANDLOCK_ACCESS_FS_WRITE_FILE
| LANDLOCK_ACCESS_FS_READ_DIR
| LANDLOCK_ACCESS_FS_MAKE_REG
| LANDLOCK_ACCESS_FS_MAKE_DIR
| LANDLOCK_ACCESS_FS_MAKE_SYM
| LANDLOCK_ACCESS_FS_MAKE_SOCK
| LANDLOCK_ACCESS_FS_MAKE_FIFO
| LANDLOCK_ACCESS_FS_MAKE_BLOCK
| LANDLOCK_ACCESS_FS_REMOVE_FILE
| LANDLOCK_ACCESS_FS_REMOVE_DIR
| LANDLOCK_ACCESS_FS_TRUNCATE
| LANDLOCK_ACCESS_FS_REFER
};
uint64_t landlock_perms = LANDLOCK_ACCESS_FS_READ_FILE
| LANDLOCK_ACCESS_FS_WRITE_FILE
| LANDLOCK_ACCESS_FS_TRUNCATE
| LANDLOCK_ACCESS_FS_MAKE_REG
| LANDLOCK_ACCESS_FS_REMOVE_FILE;
int landlock_fd;
bool landlock_supported;
/*
* Our own wrappers for Landlock syscalls.
*/
int landlock_create_ruleset(const struct landlock_ruleset_attr *attr, size_t size, uint32_t flags) {
return syscall(__NR_landlock_create_ruleset, attr, size, flags);
}
int landlock_add_rule(int ruleset_fd, enum landlock_rule_type rule_type, const void *rule_attr, uint32_t flags) {
return syscall(__NR_landlock_add_rule, ruleset_fd, rule_type, rule_attr, flags);
}
int landlock_restrict_self(int ruleset_fd, uint32_t flags) {
return syscall(__NR_landlock_restrict_self, ruleset_fd, flags);
}
static void landlock_path(std::string path, uint32_t perms) {
struct landlock_path_beneath_attr path_beneath = {
.allowed_access = perms
};
path_beneath.parent_fd = open(path.c_str(), O_PATH|O_CLOEXEC);
if (path_beneath.parent_fd < 0) {
perror(path.c_str());
exit(1);
}
if (landlock_add_rule(landlock_fd, LANDLOCK_RULE_PATH_BENEATH, &path_beneath, 0)) {
perror("landlock_add_rule");
exit(1);
}
close(path_beneath.parent_fd);
}
static bool landlock_detect() {
int abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
if (abi < 0) {
if (errno == ENOSYS || errno == EOPNOTSUPP) {
std::cout << "[WARN] No Landlock support on this system" << std::endl;
return false;
}
perror("landlock_create_ruleset");
exit(1);
}
std::cout << "[INFO] Detected Landlock ABI version: " << abi << std::endl;
switch (abi) {
case 1:
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_REFER;
landlock_perms &= ~LANDLOCK_ACCESS_FS_REFER;
// fallthrough
case 2:
ruleset_attr.handled_access_fs &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
landlock_perms &= ~LANDLOCK_ACCESS_FS_TRUNCATE;
}
return true;
}
static void landlock_init() {
std::cout << "[INFO] Setting up Landlock sandbox..." << std::endl;
landlock_supported = landlock_detect();
if (!landlock_supported)
return;
landlock_fd = landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
if (landlock_fd < 0) {
perror("landlock_create_ruleset");
exit(1);
}
std::string dbdir = std::filesystem::path(settings::DBPATH).parent_path();
// for the DB files (we can't rely on them being in the working directory)
landlock_path(dbdir == "" ? "." : dbdir, landlock_perms);
// for writing the gruntwork file
landlock_path(settings::TDATADIR, landlock_perms);
// for passowrd salting during account creation
landlock_path("/dev/urandom", LANDLOCK_ACCESS_FS_READ_FILE);
// for core dumps, optionally
if (settings::SANDBOXEXTRAPATH != "")
landlock_path(settings::SANDBOXEXTRAPATH, landlock_perms);
}
#endif // !CONFIG_NOLANDLOCK
static void sigsys_handler(int signo, siginfo_t *info, void *context) {
// report the unhandled syscall
std::cout << "[FATAL] Unhandled syscall " << info->si_syscall
<< " at " << std::hex << info->si_call_addr << " on arch " << info->si_arch << std::endl;
std::cout << "If you're unsure why this is happening, please read https://openfusion.dev/docs/development/the-sandbox/" << std::endl
<< "for more information and possibly open an issue at https://github.com/OpenFusionProject/OpenFusion/issues to report"
<< " needed changes in our seccomp filter." << std::endl;
exit(1);
}
void sandbox_init() {
if (!settings::SANDBOX) {
std::cout << "[WARN] Running without a sandbox" << std::endl;
return;
}
// listen to SIGSYS to report unhandled syscalls
struct sigaction sa = {};
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = sigsys_handler;
if (sigaction(SIGSYS, &sa, NULL) < 0) {
perror("sigaction");
exit(1);
}
#ifndef CONFIG_NOLANDLOCK
landlock_init();
#else
std::cout << "[WARN] Built without Landlock" << std::endl;
#endif
}
void sandbox_start() {
if (!settings::SANDBOX)
return;
std::cout << "[INFO] Starting seccomp-bpf sandbox..." << std::endl;
// Sandboxing starts in sandbox_thread_start().
}
void sandbox_thread_start() {
if (!settings::SANDBOX)
return;
if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) < 0) {
perror("prctl");
exit(1);
}
if (seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_TSYNC, &prog) < 0) {
#ifndef CONFIG_NOLANDLOCK
if (landlock_supported) {
if (landlock_restrict_self(landlock_fd, 0)) {
perror("landlock_restrict_self");
exit(1);
}
}
#endif
if (seccomp(SECCOMP_SET_MODE_FILTER, 0, &prog) < 0) {
perror("seccomp");
exit(1);
}

View File

@@ -180,9 +180,14 @@ SOCKET Monitor::init() {
}
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(settings::MONITORPORT);
if (!inet_pton(AF_INET, settings::MONITORLISTENIP.c_str(), &address.sin_addr)) {
std::cout << "Failed to set monitor listen address" << std::endl;
printSocketError("inet_pton");
exit(1);
}
if (SOCKETERROR(bind(listener, (struct sockaddr*)&address, sizeof(address)))) {
std::cout << "Failed to bind to monitor port" << std::endl;
printSocketError("bind");
@@ -206,7 +211,7 @@ SOCKET Monitor::init() {
exit(EXIT_FAILURE);
}
std::cout << "Monitor listening on *:" << settings::MONITORPORT << std::endl;
std::cout << "Monitor listening on " << settings::MONITORLISTENIP << ":" << settings::MONITORPORT << std::endl;
REGISTER_SHARD_TIMER(tick, settings::MONITORINTERVAL);

View File

@@ -9,6 +9,7 @@
// defaults :)
int settings::VERBOSITY = 1;
bool settings::SANDBOX = true;
std::string settings::SANDBOXEXTRAPATH = "";
int settings::LOGINPORT = 23000;
bool settings::APPROVEALLNAMES = true;
@@ -63,6 +64,7 @@ bool settings::DISABLEFIRSTUSEFLAG = true;
// monitor settings
bool settings::MONITORENABLED = false;
int settings::MONITORPORT = 8003;
std::string settings::MONITORLISTENIP = "127.0.0.1";
int settings::MONITORINTERVAL = 5000;
// event mode settings
@@ -85,6 +87,7 @@ void settings::init() {
VERBOSITY = reader.GetInteger("", "verbosity", VERBOSITY);
SANDBOX = reader.GetBoolean("", "sandbox", SANDBOX);
SANDBOXEXTRAPATH = reader.Get("", "sandboxextrapath", SANDBOXEXTRAPATH);
LOGINPORT = reader.GetInteger("login", "port", LOGINPORT);
APPROVEALLNAMES = reader.GetBoolean("login", "acceptallcustomnames", APPROVEALLNAMES);
AUTOCREATEACCOUNTS = reader.GetBoolean("login", "autocreateaccounts", AUTOCREATEACCOUNTS);
@@ -119,5 +122,6 @@ void settings::init() {
IZRACESCORECAPPED = reader.GetBoolean("shard", "izracescorecapped", IZRACESCORECAPPED);
MONITORENABLED = reader.GetBoolean("monitor", "enabled", MONITORENABLED);
MONITORPORT = reader.GetInteger("monitor", "port", MONITORPORT);
MONITORLISTENIP = reader.Get("monitor", "listenip", MONITORLISTENIP);
MONITORINTERVAL = reader.GetInteger("monitor", "interval", MONITORINTERVAL);
}

View File

@@ -5,6 +5,7 @@
namespace settings {
extern int VERBOSITY;
extern bool SANDBOX;
extern std::string SANDBOXEXTRAPATH;
extern int LOGINPORT;
extern bool APPROVEALLNAMES;
extern bool AUTOCREATEACCOUNTS;
@@ -37,6 +38,7 @@ namespace settings {
extern int EVENTMODE;
extern bool MONITORENABLED;
extern int MONITORPORT;
extern std::string MONITORLISTENIP;
extern int MONITORINTERVAL;
extern bool DISABLEFIRSTUSEFLAG;
extern bool IZRACESCORECAPPED;

View File

@@ -38,9 +38,10 @@ typedef __int64 ssize_t;
#include <wincrypt.h> /* CryptAcquireContext, CryptGenRandom */
#else
#include "bcrypt.h"
#include "ow-crypt.h"
#endif
#include "ow-crypt.h"
#define RANDBYTES (16)
static int try_close(int fd)