Constant OPENCODE_CLOUD_BOOTSTRAP_SH
Source pub const OPENCODE_CLOUD_BOOTSTRAP_SH: &[u8] = b"#!/bin/bash\nset -euo pipefail\n\nSTATE_DIR=\"/var/lib/opencode-users\"\nSTATE_FILE=\"${STATE_DIR}/.initial-otp.json\"\nSECRET_FILE=\"${STATE_DIR}/.initial-otp.secret\"\nLOCK_FILE=\"${STATE_DIR}/.initial-otp.lock\"\nCOMPLETE_MARKER_FILE=\"${STATE_DIR}/.bootstrap-complete.json\"\nPROTECTED_USER=\"opencoder\"\nBUILTIN_USERS_FILE=\"/etc/opencode-cloud/builtin-home-users.txt\"\nFALLBACK_BUILTIN_HOME_USERS=(\"opencoder\" \"ubuntu\")\nBUILTIN_HOME_USERS=()\n\njson_ok() {\n jq -cn \"$@\"\n}\n\njson_error() {\n local code=\"$1\"\n local message=\"$2\"\n local status=\"$3\"\n jq -cn --arg code \"${code}\" --arg message \"${message}\" --argjson status \"${status}\" \\\n \'{ok:false,code:$code,message:$message,status:$status}\'\n}\n\nensure_state_dir() {\n install -d -m 0700 \"${STATE_DIR}\"\n load_builtin_home_users\n}\n\nacquire_lock() {\n exec 9>\"${LOCK_FILE}\"\n flock -x 9\n}\n\ngenerate_random_hex() {\n local byte_count=\"$1\"\n od -An -N \"${byte_count}\" -tx1 /dev/urandom | tr -d \' \\n\'\n}\n\nutc_now() {\n date -u +\"%Y-%m-%dT%H:%M:%SZ\"\n}\n\nhash_salted_otp() {\n local salt=\"$1\"\n local otp=\"$2\"\n printf \"%s\" \"${salt}:${otp}\" | sha256sum | awk \'{print $1}\'\n}\n\nstate_is_active() {\n [ -f \"${STATE_FILE}\" ] && [ -f \"${SECRET_FILE}\" ]\n}\n\nremove_state_files() {\n rm -f \"${STATE_FILE}\" \"${SECRET_FILE}\"\n}\n\nbootstrap_is_completed() {\n [ -f \"${COMPLETE_MARKER_FILE}\" ]\n}\n\nmark_bootstrap_completed() {\n local completed_at\n completed_at=\"$(utc_now)\"\n umask 077\n jq -cn --arg completed_at \"${completed_at}\" --arg username \"${PROTECTED_USER}\" \\\n \'{completed:true,completed_at:$completed_at,username:$username}\' > \"${COMPLETE_MARKER_FILE}\"\n chmod 600 \"${COMPLETE_MARKER_FILE}\"\n}\n\nget_completed_at() {\n jq -r \'.completed_at // empty\' \"${COMPLETE_MARKER_FILE}\" 2>/dev/null || true\n}\n\nload_builtin_home_users() {\n BUILTIN_HOME_USERS=(\"${FALLBACK_BUILTIN_HOME_USERS[@]}\")\n\n if [ ! -r \"${BUILTIN_USERS_FILE}\" ]; then\n return 0\n fi\n\n local username\n while IFS= read -r username; do\n username=\"$(printf \"%s\" \"${username}\" | tr -d \'\\r\\n\')\"\n if [ -n \"${username}\" ]; then\n BUILTIN_HOME_USERS+=(\"${username}\")\n fi\n done < \"${BUILTIN_USERS_FILE}\"\n}\n\nis_builtin_home_user() {\n local username=\"$1\"\n local builtin\n for builtin in \"${BUILTIN_HOME_USERS[@]}\"; do\n if [ \"${username}\" = \"${builtin}\" ]; then\n return 0\n fi\n done\n return 1\n}\n\nhas_non_protected_user_record() {\n # Managed user records are the canonical source of configured users.\n # Ignore image-default users so base-image accounts do not disable IOTP.\n shopt -s nullglob\n local record username\n for record in \"${STATE_DIR}\"/*.json; do\n username=\"$(jq -r \'.username // empty\' \"${record}\" 2>/dev/null || true)\"\n if [ -z \"${username}\" ]; then\n continue\n fi\n if is_builtin_home_user \"${username}\"; then\n continue\n fi\n if [ \"${username}\" != \"${PROTECTED_USER}\" ]; then\n return 0\n fi\n done\n return 1\n}\n\nhas_non_protected_system_user() {\n # Secondary safety net for unmanaged runtime-created users with /home entries.\n local line username home\n while IFS= read -r line; do\n username=\"$(cut -d: -f1 <<< \"${line}\")\"\n home=\"$(cut -d: -f6 <<< \"${line}\")\"\n if [[ \"${home}\" != /home/* ]]; then\n continue\n fi\n if is_builtin_home_user \"${username}\"; then\n continue\n fi\n return 0\n done < <(getent passwd)\n\n return 1\n}\n\nhas_non_protected_configured_user() {\n has_non_protected_user_record || has_non_protected_system_user\n}\n\nread_input_json() {\n cat\n}\n\nread_input_field() {\n local payload=\"$1\"\n local key=\"$2\"\n jq -r --arg key \"${key}\" \'.[$key] // empty\' <<< \"${payload}\" 2>/dev/null || true\n}\n\nvalidate_username() {\n local username=\"$1\"\n if [[ ! \"${username}\" =~ ^[a-z_][a-z0-9_-]{0,31}$ ]]; then\n return 1\n fi\n if [ \"${username}\" = \"${PROTECTED_USER}\" ]; then\n return 1\n fi\n return 0\n}\n\npassword_meets_policy() {\n local password=\"$1\"\n if [ \"${#password}\" -lt 12 ]; then\n return 1\n fi\n\n local classes=0\n [[ \"${password}\" =~ [[:upper:]] ]] && classes=$((classes + 1))\n [[ \"${password}\" =~ [[:lower:]] ]] && classes=$((classes + 1))\n [[ \"${password}\" =~ [[:digit:]] ]] && classes=$((classes + 1))\n [[ \"${password}\" =~ [^[:alnum:]] ]] && classes=$((classes + 1))\n\n [ \"${classes}\" -ge 3 ]\n}\n\nverify_ubuntu_platform() {\n local distro=\"\"\n if [ -r /etc/os-release ]; then\n # shellcheck disable=SC1091\n distro=\"$(. /etc/os-release && printf \"%s\" \"${ID:-}\")\"\n fi\n [ \"${distro}\" = \"ubuntu\" ]\n}\n\nemit_inactive_and_cleanup() {\n remove_state_files\n json_ok \'{ok:true,active:false,reason:\"user_exists\"}\'\n}\n\nemit_status() {\n local include_secret=\"$1\"\n if has_non_protected_configured_user; then\n emit_inactive_and_cleanup\n return 0\n fi\n\n if bootstrap_is_completed; then\n local completed_at\n completed_at=\"$(get_completed_at)\"\n remove_state_files\n if [ -n \"${completed_at}\" ]; then\n jq -cn --arg completed_at \"${completed_at}\" \\\n \'{ok:true,active:false,reason:\"completed\",completed_at:$completed_at}\'\n else\n json_ok \'{ok:true,active:false,reason:\"completed\"}\'\n fi\n return 0\n fi\n\n if ! state_is_active; then\n json_ok \'{ok:true,active:false,reason:\"not_initialized\"}\'\n return 0\n fi\n\n local created_at otp\n created_at=\"$(jq -r \'.created_at // empty\' \"${STATE_FILE}\" 2>/dev/null || true)\"\n if [ -z \"${created_at}\" ]; then\n remove_state_files\n json_ok \'{ok:true,active:false,reason:\"invalid_state\"}\'\n return 0\n fi\n\n if [ \"${include_secret}\" = \"1\" ]; then\n otp=\"$(tr -d \'\\r\\n\' < \"${SECRET_FILE}\" 2>/dev/null || true)\"\n if [ -z \"${otp}\" ]; then\n remove_state_files\n json_ok \'{ok:true,active:false,reason:\"invalid_secret\"}\'\n return 0\n fi\n jq -cn --arg created_at \"${created_at}\" --arg otp \"${otp}\" \\\n \'{ok:true,active:true,created_at:$created_at,otp:$otp}\'\n return 0\n fi\n\n jq -cn --arg created_at \"${created_at}\" \'{ok:true,active:true,created_at:$created_at}\'\n}\n\ncmd_init_internal() {\n if has_non_protected_configured_user; then\n emit_inactive_and_cleanup\n return 0\n fi\n\n if bootstrap_is_completed; then\n emit_status \"0\"\n return 0\n fi\n\n if state_is_active; then\n emit_status \"1\"\n return 0\n fi\n\n remove_state_files\n\n local otp salt created_at otp_hash\n otp=\"$(generate_random_hex 48)\"\n salt=\"$(generate_random_hex 16)\"\n created_at=\"$(utc_now)\"\n otp_hash=\"$(hash_salted_otp \"${salt}\" \"${otp}\")\"\n\n jq -cn \\\n --arg created_at \"${created_at}\" \\\n --arg salt \"${salt}\" \\\n --arg otp_hash \"${otp_hash}\" \\\n \'{version:1,active:true,created_at:$created_at,salt:$salt,otp_hash:$otp_hash}\' > \"${STATE_FILE}\"\n\n umask 077\n printf \"%s\" \"${otp}\" > \"${SECRET_FILE}\"\n chmod 600 \"${STATE_FILE}\" \"${SECRET_FILE}\"\n\n jq -cn --arg created_at \"${created_at}\" --arg otp \"${otp}\" \'{ok:true,active:true,created_at:$created_at,otp:$otp}\'\n}\n\ncmd_init() {\n ensure_state_dir\n acquire_lock\n cmd_init_internal\n}\n\ncmd_reset() {\n ensure_state_dir\n acquire_lock\n\n rm -f \"${COMPLETE_MARKER_FILE}\"\n remove_state_files\n\n cmd_init_internal\n}\n\ncmd_status() {\n local include_secret=\"0\"\n if [ \"${1:-}\" = \"--include-secret\" ]; then\n include_secret=\"1\"\n fi\n\n ensure_state_dir\n acquire_lock\n emit_status \"${include_secret}\"\n}\n\nverify_otp_internal() {\n local otp=\"$1\"\n local salt expected_hash actual_hash\n\n if ! state_is_active; then\n json_error \"inactive\" \"Bootstrap one-time password is not active.\" 403\n return 0\n fi\n\n salt=\"$(jq -r \'.salt // empty\' \"${STATE_FILE}\" 2>/dev/null || true)\"\n expected_hash=\"$(jq -r \'.otp_hash // empty\' \"${STATE_FILE}\" 2>/dev/null || true)\"\n if [ -z \"${salt}\" ] || [ -z \"${expected_hash}\" ]; then\n remove_state_files\n json_error \"inactive\" \"Bootstrap state is invalid.\" 403\n return 0\n fi\n\n actual_hash=\"$(hash_salted_otp \"${salt}\" \"${otp}\")\"\n if [ \"${actual_hash}\" != \"${expected_hash}\" ]; then\n json_error \"otp_invalid\" \"Initial one-time password is invalid.\" 401\n return 0\n fi\n\n json_ok \'{ok:true,active:true}\'\n}\n\ncmd_verify() {\n local payload otp\n payload=\"$(read_input_json)\"\n otp=\"$(read_input_field \"${payload}\" \"otp\")\"\n\n if [ -z \"${otp}\" ]; then\n json_error \"invalid_request\" \"Missing one-time password.\" 400\n return 0\n fi\n\n ensure_state_dir\n acquire_lock\n\n if has_non_protected_configured_user; then\n emit_inactive_and_cleanup\n return 0\n fi\n\n verify_otp_internal \"${otp}\"\n}\n\ncmd_complete() {\n local payload otp verify_json verify_code\n payload=\"$(read_input_json)\"\n otp=\"$(read_input_field \"${payload}\" \"otp\")\"\n\n if [ -z \"${otp}\" ]; then\n json_error \"invalid_request\" \"Missing one-time password.\" 400\n return 0\n fi\n\n ensure_state_dir\n acquire_lock\n\n if has_non_protected_configured_user; then\n emit_inactive_and_cleanup\n return 0\n fi\n\n verify_json=\"$(verify_otp_internal \"${otp}\")\"\n verify_code=\"$(jq -r \'.code // empty\' <<< \"${verify_json}\" 2>/dev/null || true)\"\n if [ -n \"${verify_code}\" ]; then\n printf \"%s\\n\" \"${verify_json}\"\n return 0\n fi\n\n remove_state_files\n mark_bootstrap_completed\n\n jq -cn --arg username \"${PROTECTED_USER}\" \'{ok:true,completed:true,active:false,username:$username}\'\n}\n\ncmd_create_user() {\n local payload otp username password\n payload=\"$(read_input_json)\"\n otp=\"$(read_input_field \"${payload}\" \"otp\")\"\n username=\"$(read_input_field \"${payload}\" \"username\")\"\n password=\"$(read_input_field \"${payload}\" \"password\")\"\n\n if [ -z \"${otp}\" ] || [ -z \"${username}\" ] || [ -z \"${password}\" ]; then\n json_error \"invalid_request\" \"otp, username, and password are required.\" 400\n return 0\n fi\n\n ensure_state_dir\n acquire_lock\n\n if has_non_protected_configured_user; then\n emit_inactive_and_cleanup\n return 0\n fi\n\n local verify_json verify_code\n verify_json=\"$(verify_otp_internal \"${otp}\")\"\n verify_code=\"$(jq -r \'.code // empty\' <<< \"${verify_json}\" 2>/dev/null || true)\"\n if [ -n \"${verify_code}\" ]; then\n printf \"%s\\n\" \"${verify_json}\"\n return 0\n fi\n\n if ! verify_ubuntu_platform; then\n json_error \"unsupported_platform\" \"Initial signup is currently supported only on Ubuntu containers.\" 400\n return 0\n fi\n\n if ! validate_username \"${username}\"; then\n json_error \"invalid_username\" \"Username must match ^[a-z_][a-z0-9_-]{0,31}$ and cannot be reserved.\" 400\n return 0\n fi\n\n if ! password_meets_policy \"${password}\"; then\n json_error \"invalid_password\" \"Password must be at least 12 characters and include 3 of 4 classes.\" 400\n return 0\n fi\n\n if id -u \"${username}\" >/dev/null 2>&1; then\n json_error \"username_exists\" \"Username already exists.\" 409\n return 0\n fi\n\n if ! useradd -m -s /bin/bash \"${username}\" >/dev/null 2>&1; then\n json_error \"create_failed\" \"Failed to create the Linux user account.\" 500\n return 0\n fi\n\n if ! printf \"%s:%s\\n\" \"${username}\" \"${password}\" | chpasswd >/dev/null 2>&1; then\n userdel -r \"${username}\" >/dev/null 2>&1 || true\n json_error \"create_failed\" \"Failed to set password for the new user.\" 500\n return 0\n fi\n\n local shadow_hash status locked record_path\n shadow_hash=\"$(getent shadow \"${username}\" | cut -d: -f2)\"\n if [ -z \"${shadow_hash}\" ]; then\n json_error \"create_failed\" \"Failed to read password hash for the new user.\" 500\n return 0\n fi\n\n status=\"$(passwd -S \"${username}\" | tr -s \' \' | cut -d\' \' -f2)\"\n locked=\"false\"\n if [ \"${status}\" = \"L\" ]; then\n locked=\"true\"\n fi\n\n record_path=\"${STATE_DIR}/${username}.json\"\n umask 077\n jq -cn --arg username \"${username}\" --arg hash \"${shadow_hash}\" --argjson locked \"${locked}\" \\\n \'{username:$username,password_hash:$hash,locked:$locked}\' > \"${record_path}\"\n chmod 600 \"${record_path}\"\n\n remove_state_files\n mark_bootstrap_completed\n\n jq -cn --arg username \"${username}\" \'{ok:true,created:true,username:$username}\'\n}\n\nusage() {\n cat <<\'EOF\'\nUsage: opencode-cloud-bootstrap <command>\n\nCommands:\n init Initialize bootstrap OTP if needed\n reset Reset bootstrap completion and reinitialize OTP\n status [--include-secret]\n Show bootstrap status\n verify Verify OTP (expects JSON stdin: {\"otp\":\"...\"})\n complete Complete bootstrap after verified OTP (expects JSON stdin: {\"otp\":\"...\"})\n create-user Create first user (expects JSON stdin: {\"otp\":\"...\",\"username\":\"...\",\"password\":\"...\"})\nEOF\n}\n\nmain() {\n local command=\"${1:-}\"\n shift || true\n\n case \"${command}\" in\n init)\n cmd_init \"$@\"\n ;;\n reset)\n cmd_reset \"$@\"\n ;;\n status)\n cmd_status \"$@\"\n ;;\n verify)\n cmd_verify \"$@\"\n ;;\n complete)\n cmd_complete \"$@\"\n ;;\n create-user)\n cmd_create_user \"$@\"\n ;;\n *)\n usage >&2\n exit 1\n ;;\n esac\n}\n\nmain \"$@\"\n";