Files
rustdesk-custom/scripts/preconfigure.sh
T
gusadmin 1b3c3496c5 Приватность публичного репо + выкл. проверку обновлений + релиз latest
- Убраны все машинно/инфра-специфичные данные из README/CODEMAP/скриптов/
  workflows (хосты, IP, домен gitea -> github.server_url).
- preconfigure: enable-check-update=N (выкл. проверку обновлений); подсказка
  «set up your own server» и так гаснет с override-сервером.
- CI публикует exe/apk в Gitea Release `latest` (обновляется каждый прогон,
  стабильная ссылка) + версионный релиз на теге v*.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 19:13:54 +03:00

161 lines
8.5 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# Вшивает адрес сервера и публичный ключ в клон RustDesk перед сборкой.
# Патчит две константы в сабмодуле hbb_common:
# pub const RENDEZVOUS_SERVERS: &[&str] = &["rs-ny.rustdesk.com"];
# pub const RS_PUB_KEY: &str = "OeVu...";
#
# Значения берутся из окружения (см. config/server.env.example):
# RUSTDESK_SERVER — хост(ы) hbbs. Несколько — через запятую. Порт по умолчанию 21116,
# нестандартный указывать как host:port.
# RUSTDESK_PUB_KEY — публичный ключ сервера (содержимое id_ed25519.pub, base64).
# RUSTDESK_API_SERVER — (опц.) URL API-сервера (RustDesk Server Pro). Пусто — пропустить.
#
# Использование: RUSTDESK_SERVER=... RUSTDESK_PUB_KEY=... ./scripts/preconfigure.sh <путь-к-клону-rustdesk>
set -euo pipefail
SRC="${1:?укажи путь к клону rustdesk первым аргументом}"
CFG="$SRC/libs/hbb_common/src/config.rs"
[ -f "$CFG" ] || { echo "ОШИБКА: не найден $CFG — сабмодуль hbb_common не инициализирован?" >&2; exit 1; }
: "${RUSTDESK_SERVER:?не задан RUSTDESK_SERVER}"
: "${RUSTDESK_PUB_KEY:?не задан RUSTDESK_PUB_KEY}"
# Собираем Rust-массив &["a", "b"] из запятой-разделённого списка серверов.
IFS=',' read -ra SRV <<< "$RUSTDESK_SERVER"
ARR=""
for s in "${SRV[@]}"; do
s="$(echo -n "$s" | tr -d '[:space:]')"
[ -n "$s" ] && ARR="${ARR}\"${s}\", "
done
ARR="&[${ARR%, }]"
# Экранируем спецсимволы sed-замены (& | \) в подставляемых значениях.
esc() { printf '%s' "$1" | sed -e 's/[\\&|]/\\&/g'; }
ARR_ESC="$(esc "$ARR")"
KEY_ESC="$(esc "$RUSTDESK_PUB_KEY")"
# Патч RENDEZVOUS_SERVERS
sed -i -E "s|^pub const RENDEZVOUS_SERVERS: &\[&str\] = .*;|pub const RENDEZVOUS_SERVERS: \&[\&str] = ${ARR_ESC};|" "$CFG"
# Патч RS_PUB_KEY
sed -i -E "s|^pub const RS_PUB_KEY: &str = .*;|pub const RS_PUB_KEY: \&str = \"${KEY_ESC}\";|" "$CFG"
# Проверяем, что патч применился (значения не печатаем целиком — только факт).
grep -q "^pub const RENDEZVOUS_SERVERS: &\[&str\] = &\[\"" "$CFG" || { echo "ОШИБКА: не удалось пропатчить RENDEZVOUS_SERVERS" >&2; exit 1; }
if grep -q "OeVuKk5nlHiXp" "$CFG"; then
echo "ОШИБКА: RS_PUB_KEY остался дефолтным RustDesk" >&2; exit 1
fi
echo "[preconfigure] RENDEZVOUS_SERVERS -> ${#SRV[@]} сервер(ов), RS_PUB_KEY вшит."
# ─────────────────────────────────────────────────────────────────────────────
# Custom-client: сервер/ключ ВИДНЫ и ЗАЛОЧЕНЫ в настройках (override-settings) +
# опц. preset (постоянный) пароль в HARD_SETTINGS. Механизм RustDesk load_custom_client()
# читает ПОДПИСАННЫЙ custom.txt (приватного ключа их генератора у нас нет) -> патчим
# загрузчик под встроенный НЕподписанный конфиг (src/custom_client.json, include_str!),
# что работает и на Windows, и на Android. Отключить: RUSTDESK_NO_CUSTOM_CLIENT=1.
# ─────────────────────────────────────────────────────────────────────────────
if [ "${RUSTDESK_NO_CUSTOM_CLIENT:-}" != "1" ]; then
# Рабочий python (на Windows git-bash python3 = Store-заглушка -> берём python).
PY=""; for p in python3 python; do "$p" -c 'import hashlib,base64,json,secrets' 2>/dev/null && { PY="$p"; break; }; done
[ -n "$PY" ] || { echo "ОШИБКА: не найден рабочий python для custom-client" >&2; exit 1; }
FIRST_SRV="$(echo -n "${SRV[0]}" | tr -d '[:space:]')"
LOCK_PW="${RUSTDESK_LOCK_PASSWORD:-Y}" # залочить смену preset-пароля (по умолчанию да)
"$PY" - "$SRC/src/custom_client.json" "$FIRST_SRV" "$RUSTDESK_PUB_KEY" "${RUSTDESK_API_SERVER:-}" "${RUSTDESK_PRESET_PASSWORD:-}" "$LOCK_PW" <<'PYEOF'
import sys, json, hashlib, base64, secrets
out, server, key, api, preset_pw, lock_pw = sys.argv[1:7]
override = {
"custom-rendezvous-server": server,
"relay-server": server,
"key": key,
"enable-check-update": "N", # выключить проверку обновлений
}
# Подсказка «set up your own server» гаснет сама: using_public_server()=пуст ли custom-rendezvous-server,
# а он у нас в override -> непуст -> подсказки нет.
if api:
override["api-server"] = api
cfg = {"override-settings": override}
if preset_pw:
override["verification-method"] = "use-both-passwords" # постоянный + временный пароль
if lock_pw == "Y":
override["disable-change-permanent-password"] = "Y"
salt = secrets.token_hex(16)
h1 = hashlib.sha256(preset_pw.encode() + salt.encode()).digest() # = compute_permanent_password_h1
cfg["password"] = "00" + base64.b64encode(h1).decode() # HBBS preset storage: "00"+b64(h1)
cfg["salt"] = salt
with open(out, "w", encoding="utf-8") as f:
json.dump(cfg, f, ensure_ascii=False)
print("[preconfigure] custom_client.json: сервер виден+залочен, preset-пароль=" + ("да" if preset_pw else "нет"))
PYEOF
# Патч common.rs: встроенный неподписанный загрузчик (идемпотентно; клон сбрасывается перед каждой сборкой).
CM="$SRC/src/common.rs"
if ! grep -q "read_custom_client_unsigned" "$CM"; then
sed -i 's|pub fn load_custom_client() {|pub fn load_custom_client() {\n read_custom_client_unsigned(include_str!("custom_client.json"));|' "$CM"
grep -q 'read_custom_client_unsigned(include_str' "$CM" || { echo "ОШИБКА: не удалось внедрить вызов в load_custom_client" >&2; exit 1; }
cat >> "$CM" <<'RUSTEOF'
// [rustdesk-custom] Встроенный НЕподписанный custom-client конфиг (src/custom_client.json).
pub fn read_custom_client_unsigned(json: &str) {
let json = json.trim();
if json.is_empty() || json == "{}" {
return;
}
let Ok(mut data) =
serde_json::from_str::<std::collections::HashMap<String, serde_json::Value>>(json)
else {
log::error!("Failed to parse embedded custom client config");
return;
};
if let Some(app_name) = data.remove("app-name") {
if let Some(app_name) = app_name.as_str() {
*config::APP_NAME.write().unwrap() = app_name.to_owned();
}
}
let mut map_display_settings = HashMap::new();
for s in keys::KEYS_DISPLAY_SETTINGS {
map_display_settings.insert(s.replace("_", "-"), s);
}
let mut map_local_settings = HashMap::new();
for s in keys::KEYS_LOCAL_SETTINGS {
map_local_settings.insert(s.replace("_", "-"), s);
}
let mut map_settings = HashMap::new();
for s in keys::KEYS_SETTINGS {
map_settings.insert(s.replace("_", "-"), s);
}
let mut buildin_settings = HashMap::new();
for s in keys::KEYS_BUILDIN_SETTINGS {
buildin_settings.insert(s.replace("_", "-"), s);
}
if let Some(default_settings) = data.remove("default-settings") {
read_custom_client_advanced_settings(
default_settings,
&map_display_settings,
&map_local_settings,
&map_settings,
&buildin_settings,
false,
);
}
if let Some(overwrite_settings) = data.remove("override-settings") {
read_custom_client_advanced_settings(
overwrite_settings,
&map_display_settings,
&map_local_settings,
&map_settings,
&buildin_settings,
true,
);
}
for (k, v) in data {
if let Some(v) = v.as_str() {
config::HARD_SETTINGS.write().unwrap().insert(k, v.to_owned());
};
}
}
RUSTEOF
echo "[preconfigure] common.rs пропатчен (встроенный custom-client загрузчик)."
fi
fi