Files
knutwurst--ps5-patchdl/src/patchdl_scan.h
T
Knutwurst 73c75ddd83 Medium hardening: JSON escapes, policy whitelist, scan lock, EVP check
json_get_str now decodes the common JSON escapes (\" \\ \/ \n \r \t \b
\f) and collapses \uXXXX to '?'. Previously \" terminated the value
early and \\ was copied literal, so a body containing escapes turned
into garbage at the install backend.

default_policy is constrained to "allow" or "deny" before being stored,
so a malformed POST can't write an arbitrary string into config.json
and round-trip it back out of /api/config as broken JSON.

/api/manifest/<tid>, /api/pkgverify/<tid>, /api/pkgmeta/<tid> now run
path_segment_safe(tid) explicitly. The lookup gate they relied on
(get_title_action_info) is defense-by-coincidence — a future refactor
that populates g_titles via another path would lose the check.

patchdl_scan and patchdl_scan_debug_json perform a process-wide vnode
swap that is only safe single-threaded. patchdl_scan_lock() is now
called once right after MHD_start_daemon; subsequent calls return -1 /
NULL instead of racing the worker threads.

EVP_DigestFinal_ex return code is now checked. A failed final left dig
uninitialized; hex_encode would have produced empty hex and a silent
-2 with no diagnostic. patchdl_sha256_fd_region switches its inner
sprintf to snprintf — same effect, no -Wformat-security warning.
2026-06-24 20:39:43 +02:00

49 lines
2.1 KiB
C

#pragma once
#include <stddef.h>
#include <stdint.h>
typedef enum {
PATCHDL_SOURCE_OFFICIAL = 0,
PATCHDL_SOURCE_EXTERNAL = 1,
PATCHDL_SOURCE_SHADOWMOUNT = 2,
PATCHDL_SOURCE_UNKNOWN = 3,
} patchdl_source_t;
typedef struct {
char title_id[32];
char content_id[64];
char name[128];
char installed_version[16];
char source_path[256];
char mount_from[256];
char version_file_uri[256]; /* from app.db, for version.xml */
patchdl_source_t source_type;
/* populated by background verxml fetch — guarded by websrv mutex */
char compatible_version[16];
char latest_version[16];
char latest_required_fw[16];
char patch_url[512]; /* manifest_url if present, otherwise pkg URL */
char delta_url[512]; /* DP.pkg bootstrap URL (always a PKG) */
char patch_title_id[16]; /* target title id from version.xml */
char patch_storage_title_id[16]; /* title id embedded in delta_url */
int verxml_done;
int enabled; /* user policy, persisted in config.json */
int resumable; /* a partial download is on disk */
long long partial_bytes; /* size of that partial, for the UI */
} patchdl_title_t;
int patchdl_scan(patchdl_title_t **titles_out, size_t *count_out);
void patchdl_scan_free(patchdl_title_t *titles, size_t count);
const char *patchdl_source_str(patchdl_source_t src);
/* Diagnostic: malloc'd JSON dump of the mount table + scan-base directory
listings. Caller frees. */
char *patchdl_scan_debug_json(void);
/* Mark scan/debug as no longer safe to call (must be set after MHD worker
threads come up — patchdl_scan performs a process-wide vnode swap that
would race any concurrent thread). After this is set, both entry points
return immediately. Call once during startup, after MHD_start_daemon. */
void patchdl_scan_lock(void);