#!/usr/bin/env node import crypto from 'node:crypto' import fs from 'node:fs' import http from 'node:http' import path from 'node:path' import { fileURLToPath } from 'node:url' const MAX_CONTROL_BYTES = 1024 * 1024 export const DEFAULT_PUBLIC_PREFIX = '/hololake/releases' const VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/ const SHA256_PATTERN = /^[a-f0-9]{64}$/ const fail = (code) => { throw new Error(code) } const sha256 = (bytes) => crypto.createHash('sha256').update(bytes).digest('hex') const requireText = (value, code) => { if (typeof value !== 'string' || value.trim() === '') fail(code) return value.trim() } export function normalizePublicPrefix(value) { const prefix = requireText(value, 'HOLOLAKE_RELEASE_PUBLIC_PREFIX_REQUIRED') if (!prefix.startsWith('/') || prefix.endsWith('/') || prefix.includes('//') || prefix.includes('?') || prefix.includes('#')) { fail('HOLOLAKE_RELEASE_PUBLIC_PREFIX_INVALID') } const normalized = path.posix.normalize(prefix) if (normalized !== prefix || normalized === '/' || normalized.split('/').some((segment) => segment === '..')) { fail('HOLOLAKE_RELEASE_PUBLIC_PREFIX_INVALID') } return prefix } function trustedRegularFile(file, { enforceRootOwner, maxBytes = null }) { const info = fs.lstatSync(file) if (!info.isFile() || info.isSymbolicLink()) fail('HOLOLAKE_RELEASE_FILE_NOT_REGULAR') if ((info.mode & 0o022) !== 0) fail('HOLOLAKE_RELEASE_FILE_WRITABLE_BY_NON_OWNER') if (enforceRootOwner && info.uid !== 0) fail('HOLOLAKE_RELEASE_FILE_NOT_ROOT_OWNED') if (maxBytes !== null && info.size > maxBytes) fail('HOLOLAKE_RELEASE_CONTROL_FILE_TOO_LARGE') return info } function safeRelative(root, value, code) { const relative = requireText(value, code) if (path.isAbsolute(relative) || relative.includes('\0')) fail(code) const resolved = path.resolve(root, relative) if (!resolved.startsWith(`${root}${path.sep}`)) fail(code) return resolved } function readTrustedJson(file, options) { trustedRegularFile(file, { ...options, maxBytes: MAX_CONTROL_BYTES }) return { bytes: fs.readFileSync(file), value: JSON.parse(fs.readFileSync(file, 'utf8')) } } function validatePlatform(platform, releaseDirectory, enforceRootOwner, sourceCommit, publicPrefix) { const url = new URL(requireText(platform?.url, 'HOLOLAKE_RELEASE_PACKAGE_URL_REQUIRED')) if (url.protocol !== 'https:' || url.username || url.password || url.search || url.hash) { fail('HOLOLAKE_RELEASE_PACKAGE_URL_INVALID') } const packageName = decodeURIComponent(path.posix.basename(url.pathname)) if (!packageName || packageName === '.' || packageName === '..') fail('HOLOLAKE_RELEASE_PACKAGE_NAME_INVALID') if (!url.pathname.startsWith(`${publicPrefix}/`) || url.pathname === `${publicPrefix}/latest.json` || url.pathname === `${publicPrefix}/health`) { fail('HOLOLAKE_RELEASE_PACKAGE_PUBLIC_PREFIX_MISMATCH') } const packagePath = safeRelative(releaseDirectory, packageName, 'HOLOLAKE_RELEASE_PACKAGE_PATH_INVALID') const packageInfo = trustedRegularFile(packagePath, { enforceRootOwner }) if (!Number.isSafeInteger(platform.size) || platform.size <= 0 || platform.size !== packageInfo.size) { fail('HOLOLAKE_RELEASE_PACKAGE_SIZE_MISMATCH') } if (!SHA256_PATTERN.test(platform.sha256 || '') || sha256(fs.readFileSync(packagePath)) !== platform.sha256) { fail('HOLOLAKE_RELEASE_PACKAGE_SHA256_MISMATCH') } requireText(platform.signature, 'HOLOLAKE_RELEASE_PACKAGE_SIGNATURE_REQUIRED') const codeReceiptId = requireText(platform.platformCodeSignatureReceipt, 'HOLOLAKE_RELEASE_CODESIGN_RECEIPT_REQUIRED') const notarizationReceiptId = requireText(platform.notarizationReceipt, 'HOLOLAKE_RELEASE_NOTARIZATION_RECEIPT_REQUIRED') const codeReceipt = readTrustedJson( safeRelative(releaseDirectory, `${codeReceiptId}.json`, 'HOLOLAKE_RELEASE_CODESIGN_RECEIPT_PATH_INVALID'), { enforceRootOwner }, ).value const notarizationReceipt = readTrustedJson( safeRelative(releaseDirectory, `${notarizationReceiptId}.json`, 'HOLOLAKE_RELEASE_NOTARIZATION_RECEIPT_PATH_INVALID'), { enforceRootOwner }, ).value if ( codeReceipt?.schema !== 'hololake.platform-code-signature-receipt/v1' || codeReceipt?.state !== 'DEVELOPER_ID_SIGNATURE_STRICT_AND_GATEKEEPER_ACCEPTED' || codeReceipt?.sourceCommit !== sourceCommit ) fail('HOLOLAKE_RELEASE_CODESIGN_RECEIPT_INVALID') if ( notarizationReceipt?.schema !== 'hololake.apple-notarization-receipt/v1' || notarizationReceipt?.state !== 'APPLE_NOTARIZATION_ACCEPTED_AND_STAPLED' || notarizationReceipt?.sourceCommit !== sourceCommit ) fail('HOLOLAKE_RELEASE_NOTARIZATION_RECEIPT_INVALID') return { pathname: url.pathname, file: packagePath, size: packageInfo.size } } function loadActiveRelease(stateRoot, enforceRootOwner, publicPrefix) { const activationPath = path.join(stateRoot, 'ACTIVE.json') if (!fs.existsSync(activationPath)) { return { state: 'EMPTY_FAIL_CLOSED', release: null, reasonCode: null, publicPrefix } } const activation = readTrustedJson(activationPath, { enforceRootOwner }).value if ( activation?.schema !== 'hololake.release-broadcast-activation/v1' || activation?.state !== 'HUMAN_APPROVED_SIGNED_NOTARIZED_RELEASE_ACTIVE' ) fail('HOLOLAKE_RELEASE_ACTIVATION_INVALID') const releaseId = requireText(activation.releaseId, 'HOLOLAKE_RELEASE_ID_REQUIRED') const version = requireText(activation.version, 'HOLOLAKE_RELEASE_VERSION_REQUIRED') if (!VERSION_PATTERN.test(version)) fail('HOLOLAKE_RELEASE_VERSION_INVALID') if (!SHA256_PATTERN.test(activation.broadcastSha256 || '')) fail('HOLOLAKE_RELEASE_BROADCAST_SHA256_INVALID') requireText(activation.humanApprovalReceipt, 'HOLOLAKE_RELEASE_HUMAN_APPROVAL_REQUIRED') const broadcastPath = safeRelative(stateRoot, activation.broadcastRelativePath, 'HOLOLAKE_RELEASE_BROADCAST_PATH_INVALID') const pipelinePath = safeRelative(stateRoot, activation.pipelineReceiptRelativePath, 'HOLOLAKE_RELEASE_PIPELINE_PATH_INVALID') const approvalPath = safeRelative(stateRoot, activation.humanApprovalReceiptRelativePath, 'HOLOLAKE_RELEASE_HUMAN_APPROVAL_PATH_INVALID') const broadcastDocument = readTrustedJson(broadcastPath, { enforceRootOwner }) const pipelineReceipt = readTrustedJson(pipelinePath, { enforceRootOwner }).value const approvalReceipt = readTrustedJson(approvalPath, { enforceRootOwner }).value if (sha256(broadcastDocument.bytes) !== activation.broadcastSha256) fail('HOLOLAKE_RELEASE_BROADCAST_SHA256_MISMATCH') if ( pipelineReceipt?.schema !== 'hololake.signed-release-pipeline-receipt/v1' || pipelineReceipt?.state !== 'SIGNED_NOTARIZED_RELEASE_BROADCAST_READY_FOR_JD_CONTROLLER_UPLOAD' || pipelineReceipt?.broadcastSha256 !== activation.broadcastSha256 || !/^[a-f0-9]{40}$/.test(pipelineReceipt?.sourceCommit || '') || pipelineReceipt?.automaticUpload !== false || pipelineReceipt?.automaticActivation !== false ) fail('HOLOLAKE_RELEASE_PIPELINE_RECEIPT_INVALID') if ( approvalReceipt?.schema !== 'hololake.release-broadcast-human-approval/v1' || approvalReceipt?.state !== 'HUMAN_APPROVED_EXACT_SIGNED_NOTARIZED_RELEASE' || approvalReceipt?.approvalId !== activation.humanApprovalReceipt || approvalReceipt?.releaseId !== releaseId || approvalReceipt?.version !== version || approvalReceipt?.broadcastSha256 !== activation.broadcastSha256 ) fail('HOLOLAKE_RELEASE_HUMAN_APPROVAL_INVALID') const broadcast = broadcastDocument.value if ( broadcast?.schema !== 'hololake.release-broadcast/v1' || broadcast?.releaseId !== releaseId || broadcast?.version !== version || broadcast?.hololake?.restart?.required !== true || broadcast?.hololake?.restart?.automaticAllowed !== false || broadcast?.hololake?.rollback?.supported !== true || broadcast?.hololake?.rollback?.healthReceiptRequired !== true || !broadcast.platforms || typeof broadcast.platforms !== 'object' || Array.isArray(broadcast.platforms) || Object.keys(broadcast.platforms).length === 0 ) fail('HOLOLAKE_RELEASE_BROADCAST_INVALID') const releaseDirectory = path.dirname(broadcastPath) const packages = new Map() for (const platform of Object.values(broadcast.platforms)) { const accepted = validatePlatform(platform, releaseDirectory, enforceRootOwner, pipelineReceipt.sourceCommit, publicPrefix) if (packages.has(accepted.pathname)) fail('HOLOLAKE_RELEASE_PACKAGE_ROUTE_COLLISION') packages.set(accepted.pathname, accepted) } return { state: 'READY_SIGNED_NOTARIZED_BROADCAST', release: { releaseId, version, broadcastBytes: broadcastDocument.bytes, packages }, reasonCode: null, publicPrefix, } } export function loadRuntimeState(stateRoot, { enforceRootOwner = false, publicPrefix = DEFAULT_PUBLIC_PREFIX } = {}) { const resolvedRoot = path.resolve(stateRoot) try { const normalizedPrefix = normalizePublicPrefix(publicPrefix) return loadActiveRelease(resolvedRoot, enforceRootOwner, normalizedPrefix) } catch (error) { return { state: 'LOCKED_INVALID_RELEASE_EVIDENCE', release: null, reasonCode: error instanceof Error ? error.message : 'HOLOLAKE_RELEASE_UNKNOWN_FAILURE', publicPrefix: null, } } } function jsonResponse(response, status, value) { const body = Buffer.from(`${JSON.stringify(value)}\n`) response.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8', 'Content-Length': body.length, 'Cache-Control': 'no-store', 'X-Content-Type-Options': 'nosniff', }) response.end(body) } export function createReleaseServer(runtimeState) { return http.createServer((request, response) => { response.setHeader('X-Content-Type-Options', 'nosniff') if (!['GET', 'HEAD'].includes(request.method || '')) { response.writeHead(405, { Allow: 'GET, HEAD', 'Cache-Control': 'no-store' }) return response.end() } const pathname = new URL(request.url || '/', 'http://127.0.0.1').pathname const publicHealthPath = runtimeState.publicPrefix ? `${runtimeState.publicPrefix}/health` : null const publicLatestPath = runtimeState.publicPrefix ? `${runtimeState.publicPrefix}/latest.json` : null if (pathname === '/health' || pathname === publicHealthPath) { const status = runtimeState.state === 'LOCKED_INVALID_RELEASE_EVIDENCE' ? 503 : 200 return jsonResponse(response, status, { schema: 'hololake.release-broadcast-health/v1', state: runtimeState.state, updateAvailable: runtimeState.release !== null, automaticUpload: false, automaticActivation: false, upstreamUpdateSources: [], ...(runtimeState.publicPrefix ? { publicPathPrefix: runtimeState.publicPrefix, releaseEndpointPath: `${runtimeState.publicPrefix}/latest.json`, } : {}), ...(runtimeState.release ? { releaseId: runtimeState.release.releaseId, version: runtimeState.release.version } : {}), ...(runtimeState.reasonCode ? { reasonCode: runtimeState.reasonCode } : {}), }) } if (pathname === '/latest.json' || pathname === publicLatestPath) { if (runtimeState.state === 'EMPTY_FAIL_CLOSED') { response.writeHead(204, { 'Cache-Control': 'no-store' }) return response.end() } if (!runtimeState.release) { response.writeHead(503, { 'Cache-Control': 'no-store' }) return response.end() } response.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8', 'Content-Length': runtimeState.release.broadcastBytes.length, 'Cache-Control': 'no-store', 'X-Content-Type-Options': 'nosniff', }) return response.end(request.method === 'HEAD' ? undefined : runtimeState.release.broadcastBytes) } const packageFile = runtimeState.release?.packages.get(pathname) if (packageFile) { response.writeHead(200, { 'Content-Type': 'application/octet-stream', 'Content-Length': packageFile.size, 'Cache-Control': 'public, max-age=31536000, immutable', 'X-Content-Type-Options': 'nosniff', }) if (request.method === 'HEAD') return response.end() return fs.createReadStream(packageFile.file).on('error', () => response.destroy()).pipe(response) } response.writeHead(404, { 'Cache-Control': 'no-store' }) response.end() }) } export function main(env = process.env) { const host = env.HOLOLAKE_RELEASE_HOST || '127.0.0.1' if (host !== '127.0.0.1') fail('HOLOLAKE_RELEASE_LOOPBACK_BIND_REQUIRED') const port = Number(env.HOLOLAKE_RELEASE_PORT || 3940) if (!Number.isInteger(port) || port < 1024 || port > 65535) fail('HOLOLAKE_RELEASE_PORT_INVALID') const stateRoot = path.resolve(env.HOLOLAKE_RELEASE_STATE_ROOT || '/var/lib/guanghu/hololake-release-broadcast') const publicPrefix = env.HOLOLAKE_RELEASE_PUBLIC_PREFIX || DEFAULT_PUBLIC_PREFIX const runtimeState = loadRuntimeState(stateRoot, { enforceRootOwner: env.HOLOLAKE_RELEASE_ENFORCE_ROOT_OWNER === '1', publicPrefix, }) const server = createReleaseServer(runtimeState) server.on('clientError', (_error, socket) => socket.end('HTTP/1.1 400 Bad Request\r\nConnection: close\r\n\r\n')) server.listen(port, host, () => { process.stdout.write(`${JSON.stringify({ schema: 'hololake.release-broadcast-startup/v1', host, port, state: runtimeState.state })}\n`) }) return server } export function isMainModule(argvPath, moduleUrl) { return Boolean(argvPath) && fs.realpathSync(path.resolve(argvPath)) === fs.realpathSync(fileURLToPath(moduleUrl)) } if (isMainModule(process.argv[1], import.meta.url)) { try { main() } catch (error) { process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`) process.exitCode = 1 } }