Stable gateway backend: mbedTLS, 8MB READY, JSON-safe parsing

- BearSSL replaced with mbedTLS (TLSv1.3 passes Cloudflare)
- 8MB frame cap + truncation-proof gateway op/seq scanner
- Thread-safe compat, locked logging, atomic config with template
- Daemon keeps last-good config, persistent presence timer
- 256B token buffers, weak-libc shims, portable build preflights
- Tests: gateway spoof + OOM cases pass

Still open: display names fall back to titleId in sandbox,
cover art needs shared Discord app assets. Backend fully functional.
This commit is contained in:
SirHumza committed 2026-09-19 01:03:17 +02:00
1 parent 1ca687f8fb
commit bf5579d6da
292 files changed
+208830 -384

No files matched your search

+8 -7
View File
@@ -25,8 +25,8 @@ DAEMON_SRC := $(ORBISRPC)/log.c $(ORBISRPC)/cfg.c $(ORBISRPC)/jsonlite.c $(ORBI
PLUGIN_SRC := $(SRCDIR)/plugin.c $(SRCDIR)/compat.c
CFILES := $(PLUGIN_SRC) $(DAEMON_SRC)
OBJS := $(patsubst %.c,$(INTDIR)/%.o,$(notdir $(CFILES)))
BEAR_SRC := $(shell find $(ROOT)/third_party/bearssl/src -name '*.c' | sort)
BEAR_OBJS := $(patsubst $(ROOT)/third_party/bearssl/src/%.c,$(INTDIR)/bear/%.o,$(BEAR_SRC))
MBED_SRC := $(shell find $(ROOT)/third_party/mbedtls/library -name '*.c' ! -name 'net_sockets.c' ! -name 'timing.c' ! -name 'entropy_poll.c' | sort)
MBED_OBJS := $(patsubst $(ROOT)/third_party/mbedtls/library/%.c,$(INTDIR)/mbed/%.o,$(MBED_SRC))
LIBS := -lSceLibcInternal -lSceNet -lSceNetCtl \
-lSceSysmodule -lSceUserService -lSceAppInstUtil -lSceAppContent \
@@ -34,12 +34,13 @@ LIBS := -lSceLibcInternal -lSceNet -lSceNetCtl \
EXTRAFLAGS := $(DEBUG_FLAGS) -std=gnu11 -Wall -Wno-unused \
-Wno-int-conversion -Wno-incompatible-pointer-types \
-Wno-address-of-packed-member
-Wno-address-of-packed-member \
-DMBEDTLS_NO_PLATFORM_ENTROPY
CFLAGS := --target=x86_64-pc-freebsd12-elf -fPIC -funwind-tables -c $(EXTRAFLAGS) \
-isysroot $(TOOLCHAIN) -isystem $(TOOLCHAIN)/include \
-I$(GH_SDK)/include -I$(GH_SDK) -I$(ORBISRPC) -I$(SRCDIR) \
-I$(ROOT)/third_party/bearssl/inc -I$(ROOT)/third_party/bearssl/src
-I$(ROOT)/third_party/mbedtls/include
LDFLAGS := -m elf_x86_64 -pie --script $(TOOLCHAIN)/link.x -e _init --eh-frame-hdr \
-L$(TOOLCHAIN)/lib -L$(GH_SDK) $(LIBS)
@@ -64,12 +65,12 @@ $(INTDIR)/%.o: $(ORBISRPC)/%.c
$(INTDIR)/plugin.o: $(SRCDIR)/plugin.c
$(CC) $(CFLAGS) -o $@ $<
$(INTDIR)/bear/%.o: $(ROOT)/third_party/bearssl/src/%.c
$(INTDIR)/mbed/%.o: $(ROOT)/third_party/mbedtls/library/%.c
@mkdir -p $(dir $@)
$(CC) $(CFLAGS) -o $@ $<
$(TARGET): $(OBJS) $(BEAR_OBJS)
$(LD) $(GH_SDK)/build/crtprx.o $(OBJS) $(BEAR_OBJS) -o $(TARGET_ELF) $(LDFLAGS)
$(TARGET): $(OBJS) $(MBED_OBJS)
$(LD) $(GH_SDK)/build/crtprx.o $(OBJS) $(MBED_OBJS) -o $(TARGET_ELF) $(LDFLAGS)
OO_PS4_TOOLCHAIN=$(TOOLCHAIN) $(TOOLCHAIN)/bin/$(CDIR)/create-fself$(FSUFFIX) -in=$(TARGET_ELF) -out=$(TARGET_ELF).oelf \
--lib=$(TARGET) --paid 0x3800000000000011
+21 -18
View File
@@ -45,6 +45,8 @@ static void *daemon_thread(void *args){
char name[128];
strncpy(name, (const char *)args, sizeof name - 1);
name[sizeof name - 1] = 0;
FILE *m = fopen("/data/orbisRPC/plugin_boot.log", "a");
if(m){ fprintf(m, "daemon thread up game=%s\n", name); fclose(m); }
daemon_clear_stop();
daemon_run(name);
return NULL;
@@ -54,18 +56,23 @@ int32_t attr_public plugin_load(int32_t argc, const char *argv[]){
(void)argc; (void)argv;
klog("[orbisrpc] <%s\\Ver.0x%08x> %s\n", g_pluginName, g_pluginVersion, __func__);
klog("[orbisrpc] Plugin Author(s): %s\n", g_pluginAuth);
{ FILE *m = fopen("/data/orbisRPC/plugin_boot.log", "a");
if(m){ fprintf(m, "plugin_load enter\n"); fclose(m); } }
if(sys_sdk_proc_info(&procInfo) != 0){
klog("[orbisrpc] sys_sdk_proc_info failed; not starting\n");
return 0;
}
klog("[orbisrpc] loaded into process: pid=%d name=%s titleid=%s\n",
procInfo.pid, procInfo.name, procInfo.titleid);
if(!is_game_titleid(procInfo.titleid)){
/* Validate SDK struct: must be NUL-terminated ASCII, else version mismatch */
procInfo.titleid[sizeof procInfo.titleid - 1] = 0;
procInfo.name[sizeof procInfo.name - 1] = 0;
size_t tlen = strnlen(procInfo.titleid, sizeof procInfo.titleid);
if(tlen != 9 || !is_game_titleid(procInfo.titleid)){
klog("[orbisrpc] not a game title (system app?); not starting daemon\n");
return 0;
}
klog("[orbisrpc] loaded into process: pid=%d name=%s titleid=%s\n",
procInfo.pid, procInfo.name, procInfo.titleid);
/* Resolve a display name for the title we are loaded into. */
static char game_name[128];
@@ -73,23 +80,19 @@ int32_t attr_public plugin_load(int32_t argc, const char *argv[]){
klog("[orbisrpc] game: %s\n", game_name);
/* explicit fat stack: TLS handshakes + JSON buffers overflow the
* small default plugin-thread stacks */
OrbisPthread thread;
* small default plugin-thread stacks. 256KB is mandatory — falling
* back to 64KB crashes inside games, so refuse to start instead. */
OrbisPthreadAttr attr;
memset(&attr, 0, sizeof attr);
if(scePthreadAttrInit(&attr) == 0 &&
scePthreadAttrSetstacksize(&attr, 256*1024) == 0){
if(scePthreadCreate(&s_daemon_thread, &attr, daemon_thread, game_name, "orbisrpc_daemon") == 0)
s_daemon_started = 1;
else
klog("[orbisrpc] daemon thread creation failed\\n");
}else{
klog("[orbisrpc] attr init failed; falling back to default stack\n");
if(scePthreadCreate(&s_daemon_thread, NULL, daemon_thread, game_name, "orbisrpc_daemon2") == 0)
s_daemon_started = 1;
else
klog("[orbisrpc] daemon thread creation failed\\n");
if(scePthreadAttrInit(&attr) != 0 ||
scePthreadAttrSetstacksize(&attr, 256*1024) != 0){
klog("[orbisrpc] attr/stack setup failed; NOT starting (no fallback)\n");
return 0;
}
if(scePthreadCreate(&s_daemon_thread, &attr, daemon_thread, game_name, "orbisrpc_daemon") == 0)
s_daemon_started = 1;
else
klog("[orbisrpc] daemon thread creation failed\\n");
return 0;
}