mirror of
https://github.com/phantomptr/ps5upload.git
synced 2026-10-22 03:42:55 -05:00
Upload, install, convert and manage PS5 game packages over the network. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
192 lines
8.2 KiB
C
192 lines
8.2 KiB
C
#ifndef PS5UPLOAD_AUTHID_H
|
|
#define PS5UPLOAD_AUTHID_H
|
|
|
|
/*
|
|
* Shared authid constants + firmware detection + authid swap helpers.
|
|
*
|
|
* Consolidates the authid/firmware logic that was previously triplicated:
|
|
* - bgft.c: PS5_SHELLCORE_AUTHID, PS5_SYSTEM_INSTALL_AUTHID,
|
|
* authid_acquire(), authid_release_shellcore()
|
|
* - register.c: REG_SHELLCORE_AUTHID, inline restore loop
|
|
* - dpi/the installer daemon (payload/installer/): DPI_JB_AUTHID, DPI_SHELLCORE_AUTHID,
|
|
* dpi_detect_firmware_major()
|
|
*
|
|
* The DPI daemon is a standalone single-file ELF that does NOT link
|
|
* against register.c or bgft.c, so all functions here are `static inline`
|
|
* — each translation unit gets its own copy, but the compiler optimizes
|
|
* them into the same machine code as the old hand-inlined versions.
|
|
*
|
|
* Firmware detection uses the SAFE kern.version sysctl — NOT the faulting
|
|
* kernel_get_fw_version offset read. Two parse tiers (see
|
|
* ps5_parse_firmware_major):
|
|
* 1. "releases/NN" — the canonical build-branch tag on production FWs
|
|
* 2. Bare NN.NN substring — covers sandboxed debug configurations
|
|
* Returns 0 if unknown, which errs toward the proven FW < 11 defaults.
|
|
*/
|
|
|
|
#include <stddef.h>
|
|
#include <sys/types.h>
|
|
#include <sys/sysctl.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
|
|
/* ── Authid constants ───────────────────────────────────────────────────
|
|
*
|
|
* These are ucred auth_id values used by Sony's kernel to gate privileged
|
|
* installer subsystem calls (BGFT, AppInstUtil). */
|
|
|
|
/* ShellCore's authid — required by sceAppInstUtilInstallByPackage and
|
|
* sceAppInstUtilGetInstallStatus on FW < 11. Without it, these calls
|
|
* return 0x80B22404 (HTTP_404 — Sony rejects the URL pre-flight) or
|
|
* 0x80B21106 (parser/parameter rejection for file:// URLs). */
|
|
#define PS5_SHELLCORE_AUTHID 0x3800000000000010ULL
|
|
|
|
/* SYSTEM authid — required for:
|
|
* - sceAppInstUtilInitialize (BGFT init gate)
|
|
* - sceAppInstUtilAppInstallPkg (content-copy gate on FW >= 11)
|
|
* - jb_escalate_pid (the "JB_AUTHID" in elf-arsenal's jb.c)
|
|
* ShellCore is enough to register the title metadata but the content-copy
|
|
* step is gated behind this SYSTEM token; running AppInstallPkg under
|
|
* ShellCore produces the "appmeta present, /user/app empty → dead tile"
|
|
* signature. */
|
|
#define PS5_SYSTEM_INSTALL_AUTHID 0x4801000000000013ULL
|
|
|
|
/* JB (jailbreak) authid — what elf-arsenal's jb_escalate_pid sets as the
|
|
* escalation target. Same value as PS5_SYSTEM_INSTALL_AUTHID; kept as a
|
|
* distinct #define for semantic clarity at call sites that escalate a
|
|
* pid rather than swap for a single Sony call. */
|
|
#define PS5_JB_AUTHID PS5_SYSTEM_INSTALL_AUTHID
|
|
|
|
/* ── Firmware detection ───────────────────────────────────────────────── */
|
|
|
|
/* Parse the kern.version string to extract the PS5 firmware major version.
|
|
*
|
|
* Two parse tiers:
|
|
* 1. "releases/NN" — the canonical build-branch tag on production
|
|
* firmwares. Preferred because it's unambiguous.
|
|
* 2. Bare NN.NN substring — covers firmware strings that omit the
|
|
* "releases/" prefix (some sandboxed debug configurations). We
|
|
* skip any leading "11.0" since FreeBSD's OS major (11) would
|
|
* otherwise be mistaken for PS5 firmware 11.x.
|
|
*
|
|
* Returns 0 if neither matches. */
|
|
static inline int ps5_parse_firmware_major(const char *kv) {
|
|
if (!kv) return 0;
|
|
const char *p = strstr(kv, "releases/");
|
|
if (p) {
|
|
p += strlen("releases/");
|
|
int major = 0;
|
|
int consumed = 0;
|
|
while (*p >= '0' && *p <= '9') {
|
|
major = major * 10 + (*p - '0');
|
|
consumed++;
|
|
p++;
|
|
}
|
|
if (consumed > 0) return major;
|
|
}
|
|
/* Fallback: first NN.NN after the FreeBSD "11.0" prefix. */
|
|
const char *scan = kv;
|
|
if (strncmp(scan, "FreeBSD 11.0", 12) == 0) scan += 12;
|
|
while (*scan) {
|
|
if (scan[0] >= '0' && scan[0] <= '9') {
|
|
int major = 0;
|
|
int consumed = 0;
|
|
const char *q = scan;
|
|
while (*q >= '0' && *q <= '9') {
|
|
major = major * 10 + (*q - '0');
|
|
consumed++;
|
|
q++;
|
|
}
|
|
/* Require NN.NN shape to avoid matching an arbitrary number. */
|
|
if (consumed > 0 && *q == '.' &&
|
|
q[1] >= '0' && q[1] <= '9' && q[2] >= '0' && q[2] <= '9' &&
|
|
(q[3] < '0' || q[3] > '9')) {
|
|
return major;
|
|
}
|
|
scan = q;
|
|
}
|
|
scan++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/* Detect the PS5 firmware major version (9, 10, 11, 12, …) via the SAFE
|
|
* kern.version sysctl. Returns 0 if unknown.
|
|
*
|
|
* Used only to select among hardware- and upstream-observed install contexts.
|
|
* Firmware is not itself a capability guarantee; every accepted install still
|
|
* requires status and on-disk verification. */
|
|
static inline int ps5_detect_firmware_major(void) {
|
|
char buf[256];
|
|
size_t sz = sizeof(buf);
|
|
if (sysctlbyname("kern.version", buf, &sz, NULL, 0) != 0)
|
|
return 0;
|
|
buf[sizeof(buf) - 1] = '\0';
|
|
return ps5_parse_firmware_major(buf);
|
|
}
|
|
|
|
/* ── Authid swap helpers ────────────────────────────────────────────────
|
|
*
|
|
* These require kernel R/W primitives (kernel_get_ucred_authid /
|
|
* kernel_set_ucred_authid). The caller's translation unit must have
|
|
* these symbols visible — either via <ps5/kernel.h> (DPI daemon) or via
|
|
* the extern declarations in runtime.h (main payload). */
|
|
|
|
/* Forward-declare the kernel functions so the helpers below compile without
|
|
* a separate extern block. If <ps5/kernel.h> or runtime.h has already
|
|
* declared them, the declarations must match exactly (same return type
|
|
* and parameter types). These match the signatures in ps5/kernel.h. */
|
|
extern uint64_t kernel_get_ucred_authid(pid_t pid);
|
|
extern int kernel_set_ucred_authid(pid_t pid, uint64_t authid);
|
|
|
|
/* Swap process authid to `target_authid` for one Sony API call.
|
|
* Returns the saved authid on success, or 0 if the swap didn't happen
|
|
* (kernel R/W unavailable or write failure). Pass the return value to
|
|
* ps5_authid_release() to undo the swap.
|
|
*
|
|
* `site_tag` is a short identifier (e.g. "InstallByPackage") used only
|
|
* in the warn log line so multi-call traces are diagnosable.
|
|
*
|
|
* `kernel_get_ucred_authid` and `kernel_set_ucred_authid` must be
|
|
* declared by the including TU (via <ps5/kernel.h> or extern). */
|
|
static inline uint64_t ps5_authid_acquire(const char *site_tag,
|
|
uint64_t target_authid) {
|
|
pid_t mypid = getpid();
|
|
uint64_t saved = kernel_get_ucred_authid(mypid);
|
|
if (saved == 0) {
|
|
/* Kernel R/W unavailable — caller's call will run with whatever
|
|
* authid the process currently has. Better than aborting the
|
|
* install when the only failure mode is "no jailbreak yet." */
|
|
return 0;
|
|
}
|
|
if (kernel_set_ucred_authid(mypid, target_authid) != 0) {
|
|
fprintf(stderr,
|
|
"[%s] WARN: failed to swap to authid 0x%llx; "
|
|
"Sony call will run with current authid (0x%llx)\n",
|
|
site_tag, (unsigned long long)target_authid,
|
|
(unsigned long long)saved);
|
|
return 0;
|
|
}
|
|
return saved;
|
|
}
|
|
|
|
/* Restore prior authid with retry-and-verify (3 attempts). No-op if
|
|
* `saved == 0` (acquire didn't actually swap). On persistent restore
|
|
* failure, the shellui_rpc sensor path's `force_reresolve_locked`
|
|
* re-arms debugger authid as a final safety net. */
|
|
static inline void ps5_authid_release(uint64_t saved, const char *site_tag) {
|
|
if (saved == 0) return;
|
|
pid_t mypid = getpid();
|
|
for (int attempt = 0; attempt < 3; attempt++) {
|
|
(void)kernel_set_ucred_authid(mypid, saved);
|
|
if (kernel_get_ucred_authid(mypid) == saved) return;
|
|
}
|
|
fprintf(stderr,
|
|
"[%s] WARN: failed to restore authid 0x%llx after "
|
|
"Sony call (3 attempts); shellui_rpc will rearm.\n",
|
|
site_tag, (unsigned long long)saved);
|
|
}
|
|
|
|
#endif /* PS5UPLOAD_AUTHID_H */
|