code wiki / _hdl_build / nx_galx_authz.nx
nx_galx_authz.nx source
↩ module page · 90 lines · 4360 B
1// nx_galx_authz.nx -- maps the EXISTING gallery catalog categories (galx_vid_rules.tsv) to ACCESS LEVELS, per
2// the operator's model (2026-06-17): the gallery holds the OWNER-ONLY stuff (cam recordings + NSFW reddit/tumblr/
3// redgifs); the SFW media library (Zatoichi, Mr Bean) is a different area served family-level. Categories
4// (from galx_vid_rules, first-substring-match, default 'r'): m=Media(SFW) r=Recordings(cam) v=Videos(NSFW).
5// Mapping: m -> FAMILY (1, watch anywhere); r + v (+ any default) -> OWNER (3, ONLY elder, nobody else).
6// galx_cat_of mirrors nx_gallery_serve's gs_path_cat so the gate can prove path->category->level WITHOUT
7// importing the daemon. The gallery daemon composes: nx_sa_validate_handle -> level -> galx_can_view per item +
8// filter the listing (owner-only items never even listed below owner). license_tier: ORIGINAL
9import "nx_syscalls.nx"
10
11const GALX_FAMILY: i64 = 1
12const GALX_OWNER: i64 = 3
13
14// categorize a path b[ls..le) via the rules buffer rb[0..rsz) (substring<TAB>cat lines, first match wins).
15// returns the category char: 'm'(109) / 'r'(114) / 'v'(118). default 'r'(114). (mirror of gs_path_cat)
16func galx_cat_of(b: *u8, ls: i64, le: i64, rb: *u8, rsz: i64) -> i64 {
17 if (rb as i64) == 0 { return 114 }
18 var i: i64 = 0
19 var lstart: i64 = 0
20 while i <= rsz {
21 var nl: i64 = 0
22 if i == rsz { nl = 1 } else { if rb[i] == (10 as u8) { nl = 1 } }
23 if nl == 1 {
24 var tab: i64 = 0 - 1
25 var p: i64 = lstart
26 while p < i { if rb[p] == (9 as u8) { if tab < 0 { tab = p } } p = p + 1 }
27 if tab > lstart { if tab + 1 < i {
28 let slen: i64 = tab - lstart
29 var q: i64 = ls
30 var found: i64 = 0
31 while q + slen <= le {
32 var j: i64 = 0
33 var ok: i64 = 1
34 while j < slen { if b[q+j] != rb[lstart+j] { ok = 0; j = slen } else { j = j + 1 } }
35 if ok == 1 { found = 1; q = le } else { q = q + 1 }
36 }
37 if found == 1 { return rb[tab+1] as i64 }
38 } }
39 lstart = i + 1
40 }
41 i = i + 1
42 }
43 return 114
44}
45
46// category char -> required access level. m=SFW media -> family; r=recordings + v=NSFW (+ unknown) -> owner-only.
47func galx_cat_level(cat: i64) -> i64 {
48 if cat == 109 { return GALX_FAMILY }
49 return GALX_OWNER
50}
51
52// may a viewer at `level` see this gallery item? ALLOW iff level >= the item's category level (deny-by-default:
53// an uncategorized item is treated as a recording = owner-only, the safe floor).
54func galx_can_view(level: i64, b: *u8, ls: i64, le: i64, rb: *u8, rsz: i64) -> i64 {
55 let cat: i64 = galx_cat_of(b, ls, le, rb, rsz)
56 if level >= galx_cat_level(cat) { return 1 }
57 return 0
58}
59
60func galx_starts(p: *u8, plen: i64, pre: *u8) -> i64 {
61 var m: i64 = 0
62 while pre[m] != (0 as u8) { m = m + 1 }
63 if m > plen { return 0 }
64 var i: i64 = 0
65 while i < m { if (p[i] as i64) != (pre[i] as i64) { return 0 } i = i + 1 }
66 return 1
67}
68func galx_has(hay: *u8, hn: i64, needle: *u8) -> i64 {
69 var nl: i64 = 0
70 while needle[nl] != (0 as u8) { nl = nl + 1 }
71 if nl == 0 { return 1 }
72 if nl > hn { return 0 }
73 let last: i64 = hn - nl
74 var i: i64 = 0
75 while i <= last { var j: i64 = 0; var hit: i64 = 1; while j < nl { if (hay[i+j] as i64) != (needle[j] as i64) { hit = 0; j = nl } if hit == 1 { j = j + 1 } } if hit == 1 { return 1 } i = i + 1 }
76 return 0
77}
78// the /media (everyone/family) file allowlist: a NAS path, EXCEPT the OWNER-ONLY recordings/NSFW area
79// (/mnt/nas_logging -- cam recordings + reddit/tumblr). /media is SFW-for-everyone; the owner-only stuff is
80// served ONLY by /gallery (the other thread). So /media must NEVER serve a nas_logging path, even by direct
81// request. Returns 1 = allowed, 0 = deny. (operator 2026-06-17: /media for everyone, /gallery for just me)
82func galx_media_path_ok(path: *u8, plen: i64) -> i64 {
83 var base: i64 = 0
84 if galx_starts(path, plen, "/mnt/nas_" as *u8) == 1 { base = 1 }
85 if galx_starts(path, plen, "/volume1/" as *u8) == 1 { base = 1 }
86 if base == 0 { return 0 }
87 if galx_has(path, plen, "nas_logging" as *u8) == 1 { return 0 }
88 if galx_has(path, plen, "/logging/" as *u8) == 1 { return 0 }
89 return 1
90}