POSA_LEAKSMS/firmware/scripts/build.ps1
cw2007 73e49fd528 feat: RPi4 누수+온습도 2-모듈 단일 서버 통합 + 보안 하드닝
2번 모듈 신규(raspberry_pi4_sht30/): SHT30 온습도 → cafe24, raw-body X-Signature HMAC, 폐쇄망 오프라인 설치(vendor/install), systemd, CRC/포맷 자가점검. firmware sht30_fw wire 포맷과 byte-parity 검증.

1번 모듈 통합(raspberry_pi4/): 누수+카메라를 동일 서버로. 레거시 sha256(key+json) body-sig → X-Signature HMAC 전환, 사진 canonical=device_id|sensor_id|log_id|timestamp.

서버 통합(php/): api/sensor_data.php 누수 이벤트 수신, api/photo_upload.php 신규(HMAC·finfo·서버생성 파일명·nonce 멱등·sensor 결속), photo.php 인증 사진서빙, dashboard.php 누수 패널+사진, sms_send.php 누수 SMS, config.php 태그/요약.

DB: sql/migration_add_leak.sql(가산·멱등), schema_sht30.sql 통합 스키마.

보안 하드닝(외부 펜테스트 대비, 확정 CRITICAL/HIGH 0): cron_heartbeat api_key fail-closed, setup_mfa 부트스트랩 토큰 post-enrollment 잠금, var/ PHP 실행차단, HSTS.

문서/테스트: SYSTEM_OVERVIEW.md, security_hardening_test.php 갱신. 참고: 사용자 요청으로 세션 외 기존 미커밋 변경도 함께 포함.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-23 16:21:11 +09:00

137 lines
6.4 KiB
PowerShell

<#
.SYNOPSIS
SHT30 온습도 STM32F407 펌웨어 빌드 (sht30_fw) — Ninja + arm-none-eabi.
.DESCRIPTION
firmware/ 를 소스 루트로, firmware/build 를 빌드 디렉터리로 CMake(Ninja)
구성/빌드한다. 크로스 툴체인 파일(cmake/arm-none-eabi-toolchain.cmake)을
사용하며, sht30_fw 실행 타깃을 산출한다.
폐쇄망(air-gapped): 이 스크립트는 네트워크에 접속하지 않는다. 모든 의존성은
firmware/third_party 에 사전 벤더링되어 있어야 한다(scripts/vendor.ps1 참조).
third_party 가 없으면 CMake configure 단계에서 즉시 실패한다.
.PARAMETER BuildType
CMAKE_BUILD_TYPE (Release | RelWithDebInfo | Debug). 기본 Release.
.PARAMETER Clean
빌드 디렉터리를 먼저 삭제하고 새로 구성한다(클린 빌드).
.PARAMETER ToolchainPrefix
arm-none-eabi 접두 경로 override (PATH 에 없을 때).
예) "C:/Program Files (x86)/Arm/GNU Toolchain mingw-w64-i686-arm-none-eabi/bin/arm-none-eabi-"
.EXAMPLE
pwsh firmware/scripts/build.ps1
pwsh firmware/scripts/build.ps1 -Clean -BuildType RelWithDebInfo
#>
[CmdletBinding()]
param(
[ValidateSet('Release', 'RelWithDebInfo', 'Debug')]
[string]$BuildType = 'Release',
[switch]$Clean,
[string]$ToolchainPrefix,
# 자리표시자(PLACEHOLDER) 서버 CA 상태로도 빌드를 강행한다(테스트 전용).
[switch]$AllowPlaceholderCA
)
$ErrorActionPreference = 'Stop'
# 빌드 타깃은 SHT30 단일 보드(sht30_fw).
$Target = 'sht30_fw'
# ── 경로 산출 (스크립트 위치 기준, cwd 무관) ─────────────────────────────────
$ScriptDir = Split-Path -Parent $MyInvocation.MyCommand.Path
$FwRoot = Split-Path -Parent $ScriptDir # .../firmware
$BuildDir = Join-Path $FwRoot 'build'
$Toolchain = Join-Path $FwRoot 'cmake/arm-none-eabi-toolchain.cmake'
Write-Host "==== SHT30 STM32F407 펌웨어 빌드 ====" -ForegroundColor Cyan
Write-Host " firmware root : $FwRoot"
Write-Host " build dir : $BuildDir"
Write-Host " build type : $BuildType"
Write-Host " target : $Target"
# ── 사전 점검: 필수 도구 ─────────────────────────────────────────────────────
function Assert-Tool([string]$name) {
if (-not (Get-Command $name -ErrorAction SilentlyContinue)) {
throw "필수 도구를 찾을 수 없습니다: $name (PATH 확인)"
}
}
Assert-Tool 'cmake'
Assert-Tool 'ninja'
# 툴체인 컴파일러 존재 확인(접두 override 미지정 시 PATH 에서 arm-none-eabi-gcc).
if (-not $ToolchainPrefix) {
if (-not (Get-Command 'arm-none-eabi-gcc' -ErrorAction SilentlyContinue)) {
throw "arm-none-eabi-gcc 를 PATH 에서 찾을 수 없습니다. -ToolchainPrefix 로 지정하세요."
}
}
# ── 폐쇄망 가드: third_party 벤더링 확인 ─────────────────────────────────────
$ThirdParty = Join-Path $FwRoot 'third_party'
if (-not (Test-Path $ThirdParty)) {
throw @"
third_party 가 없습니다(폐쇄망 빌드 전 벤더링 필요).
networked 빌드 머신에서 먼저 실행하세요:
pwsh firmware/scripts/vendor.ps1
"@
}
# ── 배포 가드: 자리표시자(PLACEHOLDER) 서버 CA 검출 ──────────────────────────
# server_ca.c 가 자리표시자면 부팅 시 tls_init() 의 X.509 파싱이 실패해 bsp_fatal()
# 로 안전 정지한다(데이터 유출은 없으나 동작 불가). "조용한 부팅 실패"를 피하려고
# 빌드 단계에서 미리 차단한다. 실제 Cafe24 루트 CA 로 교체해야 한다(certs/README.md).
$ServerCa = Join-Path $FwRoot 'certs/server_ca.c'
if ((Test-Path $ServerCa) -and (Select-String -Path $ServerCa -SimpleMatch 'PLACEHOLDER' -Quiet)) {
if ($AllowPlaceholderCA) {
Write-Warning "server_ca.c 가 자리표시자(PLACEHOLDER) 입니다 — 이 펌웨어는 부팅 시 TLS 초기화 실패로 정지합니다(-AllowPlaceholderCA 로 강행)."
} else {
throw @"
server_ca.c 가 자리표시자(PLACEHOLDER) 상태입니다 — 실제 Cafe24 루트 CA 로 교체해야 합니다.
이 상태로 빌드한 펌웨어는 부팅 시 tls_init() 이 bsp_fatal() 로 정지합니다(동작 불가).
교체: firmware/certs/README.md 및 certs/gen_ca_header.ps1 참고.
(테스트 목적 강행: build.ps1 ... -AllowPlaceholderCA)
"@
}
}
# ── 클린 빌드 ────────────────────────────────────────────────────────────────
if ($Clean -and (Test-Path $BuildDir)) {
Write-Host " (clean) 기존 빌드 디렉터리 삭제: $BuildDir" -ForegroundColor Yellow
Remove-Item -Recurse -Force $BuildDir
}
# ── Configure (Ninja + 툴체인) ───────────────────────────────────────────────
$cfgArgs = @(
'-S', $FwRoot
'-B', $BuildDir
'-G', 'Ninja'
"-DCMAKE_TOOLCHAIN_FILE=$Toolchain"
"-DCMAKE_BUILD_TYPE=$BuildType"
)
if ($ToolchainPrefix) {
$cfgArgs += "-DTOOLCHAIN_PREFIX=$ToolchainPrefix"
}
Write-Host "`n[1/2] cmake configure …" -ForegroundColor Green
& cmake @cfgArgs
if ($LASTEXITCODE -ne 0) { throw "cmake configure 실패 (exit $LASTEXITCODE)" }
# ── Build ────────────────────────────────────────────────────────────────────
$buildArgs = @('--build', $BuildDir, '--target', $Target)
Write-Host "`n[2/2] cmake build ($Target) …" -ForegroundColor Green
& cmake @buildArgs
if ($LASTEXITCODE -ne 0) { throw "빌드 실패 (exit $LASTEXITCODE)" }
# ── 산출물 요약 ──────────────────────────────────────────────────────────────
Write-Host "`n==== 빌드 완료. 산출물 ====" -ForegroundColor Cyan
Get-ChildItem -Path $BuildDir -Recurse -Include '*.elf', '*.bin', '*.hex', '*.map' `
-ErrorAction SilentlyContinue |
ForEach-Object {
'{0,12:N0} {1}' -f $_.Length, $_.FullName
} | Write-Host