Ключ: датчик случайных чисел Валидаты инициализируется из мастера — человек водит мышью в браузере

На сервере без экрана окно Валидаты «Пожалуйста, двигайте мышью» никто не видел, ключ в тихом режиме
падал с 0x80090022 (ИШ: «Не найден ключ ЭП (E0700009)»), пересборка справочника — тоже.
bj-validata-rng: тихая проверка датчика (testcsp -silent -random), сеанс на виртуальном экране,
движения из поля мастера повторяются в окне Валидаты (XTEST), прогресс — по полосе её окна.
Установщик ключа проверяет датчик до записи на флешку. zpki.ini: Count = числу профилей, блоки подряд.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014FsEKyJrYF69Cj9ZXzFLRi
This commit is contained in:
zuevav
2026-10-06 19:53:18 +03:00
parent d9b8af2c0a
commit cf1da4a0a9
7 changed files with 559 additions and 7 deletions
+18 -7
View File
@@ -186,6 +186,12 @@ if [ "$ACTION" = "inspect" ]; then
fi
[ "$ACTION" = "install" ] || err "неизвестное действие"
# датчик случайных чисел Валидаты: пока он не инициализирован (окно «двигайте мышью» на сервере без экрана никто
# не видит), ключ в тихом режиме не работает — ни пересборка справочника, ни подпись ИШ. Проверяем до записи на флешку.
if [ -x /usr/local/sbin/bj-validata-rng ] && /usr/local/sbin/bj-validata-rng status 2>/dev/null | grep -q '"ready":false'; then
err "датчик случайных чисел Валидаты не инициализирован — сначала пройдите «Датчик случайных чисел» на этом шаге (поводить мышью в поле)"
fi
# ---- целевая точка монтирования (флешка) ----
TMP_MNT=""; UMOUNT_AFTER=0
if [ "$NOWRITE" = 1 ]; then
@@ -286,16 +292,21 @@ for l in L:
try: idx=max(idx,int(s[len("[Profile_"):-1]))
except: pass
n=idx+1
# нарастить Count в секции верхнеуровневых профилей (последний 'Count = K' до первого Profile_)
firstp=next((k for k,l in enumerate(L) if l.strip().startswith("[Profile_")), len(L))
for k in range(firstp-1,-1,-1):
if L[k].strip().startswith("Count = "):
try: L[k]=f"Count = {int(L[k].split('=')[1])+1}"
except: pass
break
L+=[f"[Profile_{n}]",f"Name = {name}","Count = 2",
f"store_0 = pse://signed//{igp}/local.pse",
f"store_1 = file://{igp}/local.gdbm"]
# Count в секции [Profile] — число блоков [Profile_N] (раньше прибавлялась единица при каждой установке,
# и после переустановки того же профиля Count расходился с числом профилей)
# блоки — подряд с нуля: Валидата читает Profile_0…Profile_{Count-1}, дыра после удалённого блока прятала профиль
cnt=0
for k,l in enumerate(L):
if l.strip().startswith("[Profile_") and l.strip().endswith("]"):
L[k]=f"[Profile_{cnt}]"; cnt+=1
firstp=next((k for k,l in enumerate(L) if l.strip().startswith("[Profile_")), len(L))
for k in range(firstp-1,-1,-1):
if L[k].strip().startswith("Count = "):
L[k]=f"Count = {cnt}"
break
open(ini,"w").write("\n".join(L))
PY
fi