polish: UTF-8 batch scripts, drop redundant set-vnc-password, robust vnc password probe
- run.bat / open-firewall.bat: UTF-8 (no BOM) + chcp 65001 instead of cp866/chcp 866. - scripts/set-vnc-password.bat: removed (run.bat syncs the UltraVNC password via ensure-vnc-password.ps1). - scripts/ensure-vnc-password.ps1: use a real RFB VNC-Auth probe to 127.0.0.1:5900 to decide if the password already matches (no UAC when it does); set via createpassword/setpasswd + service restart only when it differs. Works for any password length (no stored-password encoding assumptions). - AGENTS.md: .bat encoding convention updated to UTF-8/chcp 65001; drop set-vnc-password refs.
This commit is contained in:
@@ -63,17 +63,18 @@ scripts/get-novnc.{ps1,sh} скачать noVNC
|
|||||||
scripts/get-vnc.ps1 скачать портативный UltraVNC в vnc/ (с верификацией zip)
|
scripts/get-vnc.ps1 скачать портативный UltraVNC в vnc/ (с верификацией zip)
|
||||||
scripts/list-ips.ps1 список IPv4 машины (используется run.bat)
|
scripts/list-ips.ps1 список IPv4 машины (используется run.bat)
|
||||||
scripts/open-firewall.bat открыть порт 8080 в Windows Firewall (от админа)
|
scripts/open-firewall.bat открыть порт 8080 в Windows Firewall (от админа)
|
||||||
scripts/set-vnc-password.bat задать VNC-пароль сервису UltraVNC (от админа; без него noVNC получает authentication rejected)
|
|
||||||
scripts/ensure-vnc-password.ps1 синхронизирует VNC-пароль UltraVNC с паролем из run.bat (пишет только при несовпадении; UAC только при смене) — вызывается из run.bat
|
scripts/ensure-vnc-password.ps1 синхронизирует VNC-пароль UltraVNC с паролем из run.bat (пишет только при несовпадении; UAC только при смене) — вызывается из run.bat
|
||||||
run.bat запуск в один клик (спрашивает только пароль); синхронизирует VNC-пароль UltraVNC с введённым (см. ensure-vnc-password.ps1); если 5900 уже занят (сервис UltraVNC) — не порождает второй VNC-сервер, а подключается к существующему
|
run.bat запуск в один клик (спрашивает только пароль); синхронизирует VNC-пароль UltraVNC с введённым (см. ensure-vnc-password.ps1); если 5900 уже занят (сервис UltraVNC) — не порождает второй VNC-сервер, а подключается к существующему
|
||||||
```
|
```
|
||||||
|
|
||||||
## Соглашения и подводные камни
|
## Соглашения и подводные камни
|
||||||
|
|
||||||
- **Кодировка файлов `.bat`:** сохранять в кодировке **cp866** с окончаниями строк
|
- **Кодировка файлов `.bat`:** **UTF-8 без BOM**, окончания строк **CRLF**, и первой
|
||||||
**CRLF**. PowerShell `Set-Content -Encoding UTF8` добавляет BOM и пишет LF —
|
командой после `@echo off` — `chcp 65001 >nul` (консоль в UTF-8, иначе кириллица
|
||||||
не использовать для `.bat`. Пиши через
|
в echo/set/for превратится в мусор). Проверено: `echo`, `set /p`, `for /f` и
|
||||||
`[System.IO.File]::WriteAllText(path, content -replace "(?<!\r)\n","`r`n", [Text.Encoding]::GetEncoding(866))`.
|
перенаправление в файл корректно работают с кириллицей под `chcp 65001`.
|
||||||
|
Пиши через `[System.IO.File]::WriteAllText(path, content -replace "(?<!\r)\n","`r`n", [Text.UTF8Encoding]::new($false))`.
|
||||||
|
(BOM не ставить — ломает первую строку `@echo off` на старых Windows.)
|
||||||
- **Go-файлы:** UTF-8 **без BOM**, LF. То же самое правило — не использовать
|
- **Go-файлы:** UTF-8 **без BOM**, LF. То же самое правило — не использовать
|
||||||
`Set-Content -Encoding UTF8` (ставит BOM). Используй
|
`Set-Content -Encoding UTF8` (ставит BOM). Используй
|
||||||
`[System.IO.File]::WriteAllText(path, content, [Text.UTF8Encoding]::new($false))`.
|
`[System.IO.File]::WriteAllText(path, content, [Text.UTF8Encoding]::new($false))`.
|
||||||
@@ -102,5 +103,5 @@ run.bat запуск в один клик (спрашивае
|
|||||||
`%ProgramData%\UltraVNC\ultravnc.ini`; задать его обычным пользователем через
|
`%ProgramData%\UltraVNC\ultravnc.ini`; задать его обычным пользователем через
|
||||||
tray-иконку молча не получается (нет прав на запись).
|
tray-иконку молча не получается (нет прав на запись).
|
||||||
`run.bat` синхронизирует этот пароль сам через `scripts/ensure-vnc-password.ps1`
|
`run.bat` синхронизирует этот пароль сам через `scripts/ensure-vnc-password.ps1`
|
||||||
(пишет только при несовпадении, UAC только при смене; вручную — `scripts/set-vnc-password.bat` от админа). VNC-пароль = первые 8 байт,
|
(пишет только при несовпадении; UAC только при смене пароля). VNC-пароль = первые 8 байт,
|
||||||
поэтому используй ASCII-пароль <= 8 символов и там, и в `run.bat`.
|
поэтому используй ASCII-пароль <= 8 символов и там, и в `run.bat`.
|
||||||
|
|||||||
@@ -1,44 +1,44 @@
|
|||||||
@echo off
|
@echo off
|
||||||
REM ============================================================
|
REM ============================================================
|
||||||
REM web-vnc launcher - § ¯ã᪠¢ ®¤¨ ª«¨ª. ‘¯à 訢 ¥â ⮫쪮 ¯ ஫ì.
|
REM web-vnc launcher - запуск в один клик. Спрашивает только пароль.
|
||||||
REM ============================================================
|
REM ============================================================
|
||||||
chcp 866 >nul
|
chcp 65001 >nul
|
||||||
cd /d "%~dp0"
|
cd /d "%~dp0"
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo === web-vnc: VNC ¢ ¡à 㧥ॠ===
|
echo === web-vnc: VNC в браузере ===
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
REM --- 1. �¨ ਪ ---
|
REM --- 1. Бинарник ---
|
||||||
if exist "web-vnc.exe" goto havebin
|
if exist "web-vnc.exe" goto havebin
|
||||||
where go >nul 2>nul
|
where go >nul 2>nul
|
||||||
if not errorlevel 1 goto dogobuild
|
if not errorlevel 1 goto dogobuild
|
||||||
echo [®è¨¡ª ] web-vnc.exe ¥ ©¤¥, Go ¥ ãáâ ®¢«¥.
|
echo [ошибка] web-vnc.exe не найден, а Go не установлен.
|
||||||
echo “áâ ®¢¨â¥ Go á https://go.dev/dl/ «¨¡® ¯®«®¦¨â¥ ᮡà ë© web-vnc.exe à冷¬.
|
echo Установите Go с https://go.dev/dl/ либо положите собранный web-vnc.exe рядом.
|
||||||
echo.
|
echo.
|
||||||
pause
|
pause
|
||||||
exit /b 1
|
exit /b 1
|
||||||
:dogobuild
|
:dogobuild
|
||||||
echo ‘®¡¨à î web-vnc.exe ...
|
echo Собираю web-vnc.exe ...
|
||||||
go build -o web-vnc.exe .\cmd\web-vnc
|
go build -o web-vnc.exe .\cmd\web-vnc
|
||||||
if errorlevel 1 goto buildfail
|
if errorlevel 1 goto buildfail
|
||||||
:havebin
|
:havebin
|
||||||
|
|
||||||
REM --- 2. noVNC-ª«¨¥â ---
|
REM --- 2. noVNC-клиент ---
|
||||||
if exist "internal\server\static\core\rfb.js" goto havenovnc
|
if exist "internal\server\static\core\rfb.js" goto havenovnc
|
||||||
echo noVNC-ª«¨¥â ¥éñ ¥ ¢áâ஥. �ëâ îáì ᪠ç âì ...
|
echo noVNC-клиент ещё не встроен. Пытаюсь скачать ...
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-novnc.ps1"
|
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-novnc.ps1"
|
||||||
if errorlevel 1 goto novncfail
|
if errorlevel 1 goto novncfail
|
||||||
echo �¥à¥á®¡¨à î á noVNC ...
|
echo Пересобираю с noVNC ...
|
||||||
go build -o web-vnc.exe .\cmd\web-vnc
|
go build -o web-vnc.exe .\cmd\web-vnc
|
||||||
goto havenovnc
|
goto havenovnc
|
||||||
:novncfail
|
:novncfail
|
||||||
echo [¯à¥¤ã¯à¥¦¤¥¨¥] �¥ 㤠«®áì ᪠ç âì noVNC (¥â ¨â¥à¥â ?).
|
echo [предупреждение] Не удалось скачать noVNC (нет интернета?).
|
||||||
echo ‚ ¡à 㧥ॠ®âªà®¥âáï áâà ¨æ á ¯®¤áª §ª®©. �®¢â®à¨â¥ ¯®§¦¥: scripts\get-novnc.ps1
|
echo В браузере откроется страница с подсказкой. Повторите позже: scripts\get-novnc.ps1
|
||||||
echo.
|
echo.
|
||||||
:havenovnc
|
:havenovnc
|
||||||
|
|
||||||
REM --- 3. VNC-á¥à¢¥à (¯®¨áª/§ £à㧪 ) ---
|
REM --- 3. VNC-сервер (поиск/загрузка) ---
|
||||||
set "SPAWNARGS="
|
set "SPAWNARGS="
|
||||||
set "SPAWN_CMD="
|
set "SPAWN_CMD="
|
||||||
if exist "vnc\winvnc.exe" goto uselocalvnc
|
if exist "vnc\winvnc.exe" goto uselocalvnc
|
||||||
@@ -49,7 +49,7 @@ if exist "C:\Program Files\uvnc bvba\UltraVNC\winvnc.exe" goto autodetectvnc
|
|||||||
if exist "C:\Program Files (x86)\uvnc bvba\UltraVNC\winvnc.exe" goto autodetectvnc
|
if exist "C:\Program Files (x86)\uvnc bvba\UltraVNC\winvnc.exe" goto autodetectvnc
|
||||||
if exist "C:\Program Files\TightVNC\tvnserver.exe" goto autodetectvnc
|
if exist "C:\Program Files\TightVNC\tvnserver.exe" goto autodetectvnc
|
||||||
if exist "C:\Program Files (x86)\TightVNC\tvnserver.exe" goto autodetectvnc
|
if exist "C:\Program Files (x86)\TightVNC\tvnserver.exe" goto autodetectvnc
|
||||||
echo VNC-á¥à¢¥à ¥ ©¤¥. �ëâ îáì ᪠ç âì ¯®àâ â¨¢ë© UltraVNC ...
|
echo VNC-сервер не найден. Пытаюсь скачать портативный UltraVNC ...
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-vnc.ps1"
|
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\get-vnc.ps1"
|
||||||
if errorlevel 1 goto novncserver
|
if errorlevel 1 goto novncserver
|
||||||
if exist "vnc\winvnc.exe" goto uselocalvnc
|
if exist "vnc\winvnc.exe" goto uselocalvnc
|
||||||
@@ -59,75 +59,75 @@ goto novncserver
|
|||||||
if exist "vnc\winvnc.exe" set "SPAWN_CMD=vnc\winvnc.exe -run"
|
if exist "vnc\winvnc.exe" set "SPAWN_CMD=vnc\winvnc.exe -run"
|
||||||
if exist "vnc\tvnserver.exe" if not defined SPAWN_CMD set "SPAWN_CMD=vnc\tvnserver.exe -run"
|
if exist "vnc\tvnserver.exe" if not defined SPAWN_CMD set "SPAWN_CMD=vnc\tvnserver.exe -run"
|
||||||
set "SPAWNARGS=--spawn-command "%SPAWN_CMD%""
|
set "SPAWNARGS=--spawn-command "%SPAWN_CMD%""
|
||||||
echo � ©¤¥ «®ª «ìë© VNC-á¥à¢¥à: %SPAWN_CMD%
|
echo Найден локальный VNC-сервер: %SPAWN_CMD%
|
||||||
goto vncdone
|
goto vncdone
|
||||||
:autodetectvnc
|
:autodetectvnc
|
||||||
echo VNC-á¥à¢¥à ©¤¥ ¢ á¨á⥬¥ ( ¢â®-®¯à¥¤¥«¥¨¥ ¯à¨ § ¯ã᪥).
|
echo VNC-сервер найден в системе (авто-определение при запуске).
|
||||||
goto vncdone
|
goto vncdone
|
||||||
:novncserver
|
:novncserver
|
||||||
echo [¯à¥¤ã¯à¥¦¤¥¨¥] VNC-á¥à¢¥à ¥ 㤠«®áì ¯®«ãç¨âì.
|
echo [предупреждение] VNC-сервер не удалось получить.
|
||||||
echo �¥§ VNC-á¥à¢¥à à ¡®ç¨© á⮫ ¥ ¡ã¤¥â âà ᫨஢ âìáï.
|
echo Без VNC-сервера рабочий стол не будет транслироваться.
|
||||||
echo “áâ ®¢¨â¥ UltraVNC/TightVNC ¢àãçãî ¨«¨ ¯®¢â®à¨â¥: scripts\get-vnc.ps1
|
echo Установите UltraVNC/TightVNC вручную или повторите: scripts\get-vnc.ps1
|
||||||
echo.
|
echo.
|
||||||
:vncdone
|
:vncdone
|
||||||
|
|
||||||
REM --- 4. � ஫ì ---
|
REM --- 4. Пароль ---
|
||||||
:getpw
|
:getpw
|
||||||
set "PW="
|
set "PW="
|
||||||
set /p "PW=‚¢¥¤¨â¥ ¯ à®«ì ¤®áâ㯠: "
|
set /p "PW=Введите пароль доступа: "
|
||||||
if "%PW%"=="" goto emptypw
|
if "%PW%"=="" goto emptypw
|
||||||
goto gotpw
|
goto gotpw
|
||||||
:emptypw
|
:emptypw
|
||||||
echo � à®«ì ¥ ¬®¦¥â ¡ëâì ¯ãáâë¬.
|
echo Пароль не может быть пустым.
|
||||||
goto getpw
|
goto getpw
|
||||||
:gotpw
|
:gotpw
|
||||||
|
|
||||||
REM --- 4b. Sync UltraVNC password with the one entered (only when it differs) ---
|
REM --- 4b. Sync UltraVNC password with the one entered (only when it differs) ---
|
||||||
echo ‘¨åந§¨àãî ¯ ஫ì UltraVNC á ¢¢¥¤ñë¬. �ਠ¥á®¢¯ ¤¥¨¨ § ¯à®á¨â ¯à ¢ ¤¬¨¨áâà â®à ...
|
echo Синхронизирую пароль UltraVNC с введённым. При несовпадении запросит права администратора...
|
||||||
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\ensure-vnc-password.ps1" -Password "%PW%"
|
powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\ensure-vnc-password.ps1" -Password "%PW%"
|
||||||
if errorlevel 1 echo [¯à¥¤ã¯à¥¦¤¥¨¥] �¥ 㤠«®áì á¨åந§¨à®¢ âì ¯ ஫ì UltraVNC - ¯à®¤®«¦ î.
|
if errorlevel 1 echo [предупреждение] Не удалось синхронизировать пароль UltraVNC - продолжаю.
|
||||||
|
|
||||||
REM --- 5. •íè ¯ ஫ï + â®â ¦¥ ¯ à®«ì ¤«ï VNC-á¥à¢¥à ---
|
REM --- 5. Хэш пароля + тот же пароль для VNC-сервера ---
|
||||||
echo ƒ¥¥à¨àãî åíè ¯ ஫ï ...
|
echo Генерирую хэш пароля ...
|
||||||
for /f "delims=" %%i in ('web-vnc.exe --gen-hash "%PW%"') do set "HASH=%%i"
|
for /f "delims=" %%i in ('web-vnc.exe --gen-hash "%PW%"') do set "HASH=%%i"
|
||||||
if "%HASH%"=="" goto hashfail
|
if "%HASH%"=="" goto hashfail
|
||||||
REM ’®â ¦¥ ¯ à®«ì ¡ã¤¥â ¢â®¬ â¨ç¥áª¨ ¯¥à¥¤ noVNC ¤«ï ¢â®à¨§ 樨 VNC-á¥à¢¥à¥.
|
REM Тот же пароль будет автоматически передан noVNC для авторизации на VNC-сервере.
|
||||||
set "WEBVNC_VNC_PASSWORD=%PW%"
|
set "WEBVNC_VNC_PASSWORD=%PW%"
|
||||||
set "PW="
|
set "PW="
|
||||||
|
|
||||||
REM --- 6. „®áâã¯ë¥ ¤à¥á ---
|
REM --- 6. Доступные адреса ---
|
||||||
echo.
|
echo.
|
||||||
echo === €¤à¥á ¤«ï ¯®¤ª«î票ï (¯®àâ 8080) ===
|
echo === Адреса для подключения (порт 8080) ===
|
||||||
echo http://localhost:8080
|
echo http://localhost:8080
|
||||||
for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\list-ips.ps1"') do echo http://%%a:8080
|
for /f "delims=" %%a in ('powershell -NoProfile -ExecutionPolicy Bypass -File "%~dp0scripts\list-ips.ps1"') do echo http://%%a:8080
|
||||||
echo.
|
echo.
|
||||||
echo …᫨ á ¤à㣮© ¬ è¨ë ¥ ®âªàë¢ ¥âáï - ®¤¨ à § ¢ë¯®«¨â¥ ®â ¨¬¥¨
|
echo Если с другой машины не открывается - один раз выполните от имени
|
||||||
echo ¤¬¨¨áâà â®à : scripts\open-firewall.bat
|
echo администратора: scripts\open-firewall.bat
|
||||||
echo.
|
echo.
|
||||||
|
|
||||||
REM --- 7. ‡ ¯ã᪠---
|
REM --- 7. Запуск ---
|
||||||
echo ‡ ¯ã᪠î web-vnc http://localhost:8080
|
echo Запускаю web-vnc на http://localhost:8080
|
||||||
echo Žáâ ®¢¨âì: Ctrl+C
|
echo Остановить: Ctrl+C
|
||||||
echo.
|
echo.
|
||||||
REM --- 6b. 5900 already listening? -> do NOT spawn a 2nd VNC server (avoid conflict with the UltraVNC service) ---
|
REM --- 6b. 5900 already listening? -> do NOT spawn a 2nd VNC server (avoid conflict with the UltraVNC service) ---
|
||||||
set "SPAWNFLAG=--spawn"
|
set "SPAWNFLAG=--spawn"
|
||||||
powershell -NoProfile -Command "try{$c=New-Object Net.Sockets.TcpClient('127.0.0.1',5900);$c.Close();exit 0}catch{exit 1}"
|
powershell -NoProfile -Command "try{$c=New-Object Net.Sockets.TcpClient('127.0.0.1',5900);$c.Close();exit 0}catch{exit 1}"
|
||||||
if not errorlevel 1 (
|
if not errorlevel 1 (
|
||||||
echo VNC-á¥à¢¥à 㦥 á«ãè ¥â 127.0.0.1:5900 - ¯®¤ª«îç îáì ª ¥¬ã ¡¥§ --spawn.
|
echo VNC-сервер уже слушает 127.0.0.1:5900 - подключаюсь к нему без --spawn.
|
||||||
set "SPAWNFLAG="
|
set "SPAWNFLAG="
|
||||||
)
|
)
|
||||||
web-vnc.exe --password-hash "%HASH%" %SPAWNARGS% %SPAWNFLAG% --listen :8080
|
web-vnc.exe --password-hash "%HASH%" %SPAWNARGS% %SPAWNFLAG% --listen :8080
|
||||||
echo.
|
echo.
|
||||||
echo ‘¥à¢¥à ®áâ ®¢«¥.
|
echo Сервер остановлен.
|
||||||
pause
|
pause
|
||||||
exit /b
|
exit /b
|
||||||
|
|
||||||
:buildfail
|
:buildfail
|
||||||
echo ‘¡®àª ¥ 㤠« áì.
|
echo Сборка не удалась.
|
||||||
pause
|
pause
|
||||||
exit /b 1
|
exit /b 1
|
||||||
|
|
||||||
:hashfail
|
:hashfail
|
||||||
echo [®è¨¡ª ] �¥ 㤠«®áì ᣥ¥à¨à®¢ âì åíè ¯ ஫ï.
|
echo [ошибка] Не удалось сгенерировать хэш пароля.
|
||||||
pause
|
pause
|
||||||
exit /b 1
|
exit /b 1
|
||||||
@@ -1,59 +1,71 @@
|
|||||||
# ensure-vnc-password.ps1 - keep the UltraVNC service VNC password in sync
|
# ensure-vnc-password.ps1 - keep the UltraVNC VNC password in sync with the
|
||||||
# with the password the user types in run.bat. Called from run.bat.
|
# password the user types in run.bat. Called from run.bat.
|
||||||
#
|
#
|
||||||
# It only WRITES when the password actually differs (so a normal launch with
|
# It checks whether the running VNC server already ACCEPTS the given password
|
||||||
# the same password does nothing and asks for NO admin rights). When it must
|
# (a real RFB VNC-Auth handshake against 127.0.0.1:5900 - the same mechanism
|
||||||
# change the password it re-launches itself elevated (one UAC prompt) and
|
# noVNC uses). If it does, nothing happens and NO admin rights are needed.
|
||||||
# restarts the uvnc_service so the new password takes effect.
|
# If it does not (or no server is up), it sets the UltraVNC service password
|
||||||
|
# to the given value (one UAC prompt) and restarts uvnc_service so it reloads.
|
||||||
#
|
#
|
||||||
# Usage: powershell -NoProfile -ExecutionPolicy Bypass -File ensure-vnc-password.ps1 -Password "<pw>"
|
# Usage: powershell -NoProfile -ExecutionPolicy Bypass -File ensure-vnc-password.ps1 -Password "<pw>"
|
||||||
# Exit codes: 0 = password matches (or was set OK); 1 = could not set it.
|
# Exit codes: 0 = password already accepted (or set OK); 1 = could not set it.
|
||||||
|
|
||||||
param([Parameter(Mandatory=$true)][string]$Password)
|
param([Parameter(Mandatory=$true)][string]$Password)
|
||||||
|
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
$ini = Join-Path $env:ProgramData "UltraVNC\ultravnc.ini"
|
$ini = Join-Path $env:ProgramData "UltraVNC\ultravnc.ini"
|
||||||
|
|
||||||
function Write-Info($m){ Write-Host "ensure-vnc-password: $m" }
|
function Write-Info($m){ Write-Host "ensure-vnc-password: $m" }
|
||||||
|
|
||||||
if (-not (Test-Path $ini)) {
|
if (-not (Test-Path $ini)) {
|
||||||
# No installed UltraVNC service config (e.g. portable copy / TightVNC) - nothing to sync.
|
|
||||||
Write-Info "no %ProgramData%\UltraVNC\ultravnc.ini - nothing to sync."
|
Write-Info "no %ProgramData%\UltraVNC\ultravnc.ini - nothing to sync."
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- VNC password obfuscation: DES-ECB(key=bitrev([23,82,107,6,35,78,88,7]), pw8) + 1-byte checksum ---
|
# ---- bit-reverse a byte (VNC key bytes are bit-reversed) ----
|
||||||
function Invoke-BitRev([byte]$b){ $r=0; for($i=0;$i -lt 8;$i++){ $r = $r -bor ((($b -shr $i) -band 1) -shl (7-$i)) }; return [byte]$r }
|
function Invoke-BitRev([byte]$b){ $r=0; for($i=0;$i -lt 8;$i++){ $r = $r -bor ((($b -shr $i) -band 1) -shl (7-$i)) }; return [byte]$r }
|
||||||
function Get-ExpectedPasswd([string]$pw){
|
|
||||||
$fixedkey = [byte[]](23,82,107,6,35,78,88,7)
|
# ---- real RFB VNC-Auth probe. Returns 'ok','rejected','unreachable','noserver' ----
|
||||||
$kr = New-Object byte[] 8; for($i=0;$i -lt 8;$i++){ $kr[$i] = Invoke-BitRev $fixedkey[$i] }
|
function Test-VncAuth([string]$pw,[string]$target,[int]$port){
|
||||||
|
$c = New-Object System.Net.Sockets.TcpClient
|
||||||
|
try { $c.Connect($target,$port) } catch { return 'unreachable' }
|
||||||
|
try {
|
||||||
|
$s = $c.GetStream(); $s.ReadTimeout = 8000; $s.WriteTimeout = 8000
|
||||||
|
$rb = New-Object byte[] 64
|
||||||
|
$got = 0
|
||||||
|
while($got -lt 12){ $n = $s.Read($rb,$got,12-$got); if($n -le 0){ return 'unreachable' }; $got += $n }
|
||||||
|
if (-not ([System.Text.Encoding]::ASCII.GetString($rb,0,12).StartsWith("RFB "))) { return 'noserver' }
|
||||||
|
$s.Write([System.Text.Encoding]::ASCII.GetBytes("RFB 003.008`n"),0,12)
|
||||||
|
$n = $s.Read($rb,0,64); if($n -lt 1){ return 'unreachable' }
|
||||||
|
$numTypes = $rb[0]
|
||||||
|
if($numTypes -eq 0 -or $n -lt (1+$numTypes)){ return 'noserver' }
|
||||||
|
$types = $rb[1..($numTypes)]
|
||||||
|
if(-not ($types -contains 2)){ return 'noserver' } # VNC-Auth not offered (e.g. MS-Logon only)
|
||||||
|
$s.Write([byte[]](2),0,1) # choose VNC-Auth
|
||||||
|
$got = 0
|
||||||
|
while($got -lt 16){ $n = $s.Read($rb,$got,16-$got); if($n -le 0){ return 'unreachable' }; $got += $n }
|
||||||
|
$challenge = $rb[0..15]
|
||||||
$pb = [System.Text.Encoding]::ASCII.GetBytes($pw)
|
$pb = [System.Text.Encoding]::ASCII.GetBytes($pw)
|
||||||
if($pb.Length -gt 8){ $pb = $pb[0..7] }
|
if($pb.Length -gt 8){ $pb = $pb[0..7] }
|
||||||
$plain = New-Object byte[] 8; for($i=0;$i -lt 8;$i++){ if($i -lt $pb.Length){ $plain[$i] = $pb[$i] } }
|
$key = New-Object byte[] 8
|
||||||
|
for($i=0;$i -lt 8;$i++){ $kb = if($i -lt $pb.Length){[int]$pb[$i]}else{0}; $key[$i] = Invoke-BitRev ([byte]$kb) }
|
||||||
$des = New-Object System.Security.Cryptography.DESCryptoServiceProvider
|
$des = New-Object System.Security.Cryptography.DESCryptoServiceProvider
|
||||||
$des.Mode = [System.Security.Cryptography.CipherMode]::ECB
|
$des.Mode = [System.Security.Cryptography.CipherMode]::ECB
|
||||||
$des.Padding = [System.Security.Cryptography.PaddingMode]::None
|
$des.Padding = [System.Security.Cryptography.PaddingMode]::None
|
||||||
$des.Key = $kr
|
$des.Key = $key
|
||||||
$cipher = $des.CreateEncryptor().TransformFinalBlock($plain,0,8)
|
$resp = $des.CreateEncryptor().TransformFinalBlock($challenge,0,16)
|
||||||
$sum = 0; foreach($b in $cipher){ $sum = ($sum + $b) -band 0xFF }
|
$s.Write($resp,0,16)
|
||||||
$h = ($cipher | ForEach-Object { $_.ToString("X2") }) -join ""
|
$n = $s.Read($rb,0,4); if($n -lt 4){ return 'rejected' }
|
||||||
return $h + $sum.ToString("X2")
|
$status = ($rb[0]*16777216)+($rb[1]*65536)+($rb[2]*256)+$rb[3]
|
||||||
|
if($status -eq 0){ return 'ok' } else { return 'rejected' }
|
||||||
|
} finally { $c.Close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
function Get-CurrentPasswd{
|
$probe = Test-VncAuth $Password "127.0.0.1" 5900
|
||||||
$line = Get-Content $ini -ErrorAction SilentlyContinue | Where-Object { $_ -match '^\s*passwd\s*=' -and $_ -notmatch 'passwd2' } | Select-Object -First 1
|
if($probe -eq 'ok'){
|
||||||
if (-not $line) { return "" }
|
Write-Info "UltraVNC already accepts this password - nothing to do."
|
||||||
return ($line -split '=',2)[1].Trim()
|
|
||||||
}
|
|
||||||
|
|
||||||
$expected = Get-ExpectedPasswd $Password
|
|
||||||
$current = Get-CurrentPasswd
|
|
||||||
if ($current -ieq $expected) {
|
|
||||||
Write-Info "UltraVNC password already matches - nothing to do."
|
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
Write-Info "UltraVNC password needs setting (probe=$probe). Need admin."
|
||||||
Write-Info "UltraVNC password differs (ini=$current, expected=$expected). Need to set it (admin required)."
|
|
||||||
|
|
||||||
# Locate UltraVNC install + password tools.
|
# Locate UltraVNC install + password tools.
|
||||||
$uvncDirs = @(
|
$uvncDirs = @(
|
||||||
@@ -65,62 +77,54 @@ $uvncDirs = @(
|
|||||||
$uvnc = $uvncDirs | Where-Object { Test-Path "$_\winvnc.exe" } | Select-Object -First 1
|
$uvnc = $uvncDirs | Where-Object { Test-Path "$_\winvnc.exe" } | Select-Object -First 1
|
||||||
if(-not $uvnc){ Write-Info "UltraVNC install not found - cannot set password."; exit 1 }
|
if(-not $uvnc){ Write-Info "UltraVNC install not found - cannot set password."; exit 1 }
|
||||||
|
|
||||||
# Are we admin?
|
function Get-IniPasswd{
|
||||||
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
$line = Get-Content $ini -ErrorAction SilentlyContinue | Where-Object { $_ -match '^\s*passwd\s*=' -and $_ -notmatch 'passwd2' } | Select-Object -First 1
|
||||||
|
if(-not $line){ return "" }
|
||||||
if (-not $isAdmin) {
|
return ($line -split '=',2)[1].Trim()
|
||||||
Write-Info "re-launching elevated to set the password..."
|
|
||||||
$p = Start-Process -FilePath "powershell.exe" -Verb RunAs -Wait -PassThru -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","`"$PSCommandPath`"","-Password","`"$Password`"")
|
|
||||||
if ($p.ExitCode -ne 0) { Write-Info "elevated run failed (exit $($p.ExitCode))."; exit 1 }
|
|
||||||
$now = Get-CurrentPasswd
|
|
||||||
if ($now -ieq $expected) { Write-Info "password set OK."; exit 0 }
|
|
||||||
Write-Info "password still not updated after elevated run (ini=$now)."; exit 1
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# --- admin path: actually set the password ---
|
function Invoke-SetTool([string]$exe,[string]$pw){
|
||||||
function Set-Tool{
|
|
||||||
param([string]$exe)
|
|
||||||
if(-not (Test-Path $exe)){ return $false }
|
if(-not (Test-Path $exe)){ return $false }
|
||||||
try {
|
try {
|
||||||
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
||||||
$psi.FileName = $exe
|
$psi.FileName = $exe; $psi.Arguments = "`"$pw`""; $psi.UseShellExecute = $false
|
||||||
$psi.Arguments = "`"$Password`""
|
|
||||||
$psi.UseShellExecute = $false
|
|
||||||
$p = [System.Diagnostics.Process]::Start($psi)
|
$p = [System.Diagnostics.Process]::Start($psi)
|
||||||
if(-not $p.WaitForExit(5000)){ $p.Kill() }
|
if(-not $p.WaitForExit(5000)){ $p.Kill() }
|
||||||
return ($p.ExitCode -eq 0)
|
return ($p.ExitCode -eq 0)
|
||||||
} catch { return $false }
|
} catch { return $false }
|
||||||
}
|
}
|
||||||
|
|
||||||
$ok = $false
|
function Do-Set([string]$pw){
|
||||||
if (Set-Tool (Join-Path $uvnc "createpassword.exe")) { $ok = $true }
|
$before = Get-IniPasswd
|
||||||
$now = Get-CurrentPasswd
|
[void](Invoke-SetTool (Join-Path $uvnc "createpassword.exe") $pw)
|
||||||
if ($now -ine $expected -and (Test-Path (Join-Path $uvnc "setpasswd.exe"))) {
|
$after = Get-IniPasswd
|
||||||
# fallback to setpasswd.exe "<pw>"
|
if($after -ieq $before){
|
||||||
try {
|
[void](Invoke-SetTool (Join-Path $uvnc "setpasswd.exe") $pw)
|
||||||
$psi = New-Object System.Diagnostics.ProcessStartInfo
|
$after = Get-IniPasswd
|
||||||
$psi.FileName = Join-Path $uvnc "setpasswd.exe"
|
}
|
||||||
$psi.Arguments = "`"$Password`""
|
if($after -ieq $before){ Write-Info "password tools did not change $ini (still $after)."; return $false }
|
||||||
$psi.UseShellExecute = $false
|
# restart the service so the running server reloads (only if it was running)
|
||||||
$p = [System.Diagnostics.Process]::Start($psi)
|
try { $q = (& sc.exe query uvnc_service 2>$null); $running = ($q -match 'RUNNING') } catch { $running = $false }
|
||||||
if (-not $p.WaitForExit(5000)) { $p.Kill() }
|
if($running){
|
||||||
} catch {}
|
Write-Info "restarting uvnc_service ..."
|
||||||
$now = Get-CurrentPasswd
|
& net.exe stop uvnc_service 2>$null | Out-Null
|
||||||
|
& net.exe start uvnc_service 2>$null | Out-Null
|
||||||
|
}
|
||||||
|
return $true
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($now -ine $expected) {
|
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||||
Write-Info "tools did not update the password (ini=$now). Set it manually via UltraVNC Admin Properties as admin."
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
Write-Info "password updated in $ini."
|
|
||||||
|
|
||||||
# Restart the service so it reloads the new password.
|
if(-not $isAdmin){
|
||||||
$svc = "uvnc_service"
|
Write-Info "re-launching elevated to set the password..."
|
||||||
$svcExists = $false
|
$p = Start-Process -FilePath "powershell.exe" -Verb RunAs -Wait -PassThru -ArgumentList @("-NoProfile","-ExecutionPolicy","Bypass","-File","`"$PSCommandPath`"","-Password","`"$Password`"")
|
||||||
try { $null = (& sc.exe query $svc 2>$null); $svcExists = ($LASTEXITCODE -eq 0) } catch {}
|
if($p.ExitCode -ne 0){ Write-Info "elevated run failed (exit $($p.ExitCode))."; exit 1 }
|
||||||
if ($svcExists) {
|
# confirm by re-probing (if a server is up now)
|
||||||
Write-Info "restarting service $svc ..."
|
$again = Test-VncAuth $Password "127.0.0.1" 5900
|
||||||
& net.exe stop $svc 2>$null | Out-Null
|
if($again -eq 'ok'){ Write-Info "password set OK."; exit 0 }
|
||||||
& net.exe start $svc 2>$null | Out-Null
|
if($again -eq 'unreachable'){ Write-Info "password written; no server up to verify (will be used on next start)."; exit 0 }
|
||||||
|
Write-Info "password set but server still rejects it (probe=$again)."; exit 1
|
||||||
}
|
}
|
||||||
exit 0
|
|
||||||
|
# admin path
|
||||||
|
if(Do-Set $Password){ Write-Info "password set OK."; exit 0 } else { exit 1 }
|
||||||
+12
-12
@@ -1,16 +1,16 @@
|
|||||||
@echo off
|
@echo off
|
||||||
REM ============================================================
|
REM ============================================================
|
||||||
REM open-firewall.bat - ®âªàë¢ ¥â ¯®àâ 8080 ¢ Windows Firewall.
|
REM open-firewall.bat - открывает порт 8080 в Windows Firewall.
|
||||||
REM ‡ ¯ã᪠âì ®â ¨¬¥¨ ¤¬¨¨áâà â®à (®¤¨ à §).
|
REM Запускать от имени администратора (один раз).
|
||||||
REM ‹¨¡® § ¯ãáâ¨â¥ ¤¢ ¦¤ë: ä ©« á ¬ § ¯à®á¨â ¯à ¢ ¤¬¨¨áâà â®à .
|
REM Либо запустите дважды: файл сам запросит права администратора.
|
||||||
REM ============================================================
|
REM ============================================================
|
||||||
chcp 866 >nul
|
chcp 65001 >nul
|
||||||
cd /d "%~dp0"
|
cd /d "%~dp0"
|
||||||
|
|
||||||
REM �஢¥àª ¯à ¢ ¤¬¨¨áâà â®à ¨ ¢â®-¯®¢ë襨¥.
|
REM Проверка прав администратора и авто-повышение.
|
||||||
net session >nul 2>nul
|
net session >nul 2>nul
|
||||||
if errorlevel 1 (
|
if errorlevel 1 (
|
||||||
echo ‡ ¯à®á ¯à ¢ ¤¬¨¨áâà â®à ...
|
echo Запрос прав администратора ...
|
||||||
powershell -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
|
powershell -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
|
||||||
exit /b
|
exit /b
|
||||||
)
|
)
|
||||||
@@ -18,20 +18,20 @@ if errorlevel 1 (
|
|||||||
set PORT=8080
|
set PORT=8080
|
||||||
set RULE=web-vnc
|
set RULE=web-vnc
|
||||||
|
|
||||||
echo “¤ «ïî áâ ஥ ¯à ¢¨«® (¥á«¨ ¥áâì) ...
|
echo Удаляю старое правило (если есть) ...
|
||||||
netsh advfirewall firewall delete rule name="%RULE%" >nul 2>nul
|
netsh advfirewall firewall delete rule name="%RULE%" >nul 2>nul
|
||||||
|
|
||||||
echo „®¡ ¢«ïî à §à¥è î饥 ¯à ¢¨«® ¤«ï ¢å®¤ï饣® TCP-âà 䨪 ¯®àâ %PORT% ...
|
echo Добавляю разрешающее правило для входящего TCP-трафика на порт %PORT% ...
|
||||||
netsh advfirewall firewall add rule name="%RULE%" dir=in action=allow protocol=TCP localport=%PORT%
|
netsh advfirewall firewall add rule name="%RULE%" dir=in action=allow protocol=TCP localport=%PORT%
|
||||||
if errorlevel 1 (
|
if errorlevel 1 (
|
||||||
echo [®è¨¡ª ] �¥ 㤠«®áì ¤®¡ ¢¨âì ¯à ¢¨«®.
|
echo [ошибка] Не удалось добавить правило.
|
||||||
pause
|
pause
|
||||||
exit /b 1
|
exit /b 1
|
||||||
)
|
)
|
||||||
|
|
||||||
echo.
|
echo.
|
||||||
echo ƒ®â®¢®. �®àâ %PORT% ®âªàëâ ¤«ï ¢å®¤ïé¨å ¯®¤ª«î票©.
|
echo Готово. Порт %PORT% открыт для входящих подключений.
|
||||||
echo ’¥¯¥àì ª web-vnc ¬®¦® ¯®¤ª«îç âìáï á ¤àã£¨å ¬ è¨ á¥â¨ ¯® ¤à¥áã:
|
echo Теперь к web-vnc можно подключаться с других машин сети по адресу:
|
||||||
echo http://IP_�’މ_Œ€˜ˆ�›:%PORT%
|
echo http://IP_ЭТОЙ_МАШИНЫ:%PORT%
|
||||||
echo.
|
echo.
|
||||||
pause
|
pause
|
||||||
@@ -1,109 +0,0 @@
|
|||||||
@echo off
|
|
||||||
REM ============================================================
|
|
||||||
REM set-vnc-password.bat - reliably set the UltraVNC VNC password
|
|
||||||
REM for the running service (uvnc_service / LocalSystem), which
|
|
||||||
REM reads %ProgramData%\UltraVNC\ultravnc.ini.
|
|
||||||
REM
|
|
||||||
REM Runs AS ADMINISTRATOR (auto-elevates). It first tries the
|
|
||||||
REM UltraVNC CLI helpers (createpassword.exe / setpasswd.exe) and
|
|
||||||
REM VERIFIES the password actually changed in ultravnc.ini; if they
|
|
||||||
REM fail silently (as they can), it opens the UltraVNC settings GUI
|
|
||||||
REM so you can set "VNC Password" there. Then it restarts the
|
|
||||||
REM service. Use the SAME password in run.bat (ASCII, max 8 chars).
|
|
||||||
REM ============================================================
|
|
||||||
chcp 866 >nul
|
|
||||||
cd /d "%~dp0"
|
|
||||||
|
|
||||||
net session >nul 2>nul
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo Requesting administrator rights ...
|
|
||||||
powershell -Command "Start-Process -FilePath '%~f0' -Verb RunAs"
|
|
||||||
exit /b
|
|
||||||
)
|
|
||||||
|
|
||||||
set "UVNC="
|
|
||||||
for %%P in (
|
|
||||||
"C:\Program Files\uvnc bvba\UltraVNC"
|
|
||||||
"C:\Program Files\UltraVNC"
|
|
||||||
"C:\Program Files (x86)\uvnc bvba\UltraVNC"
|
|
||||||
"C:\Program Files (x86)\UltraVNC"
|
|
||||||
) do (
|
|
||||||
if exist "%%~P\winvnc.exe" if not defined UVNC set "UVNC=%%~P"
|
|
||||||
)
|
|
||||||
if not defined UVNC (
|
|
||||||
echo [error] UltraVNC installation not found.
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
echo UltraVNC: %UVNC%
|
|
||||||
set "INI=%ProgramData%\UltraVNC\ultravnc.ini"
|
|
||||||
|
|
||||||
:getpw
|
|
||||||
set "PW="
|
|
||||||
set /p "PW=Enter VNC password (ASCII, max 8 chars): "
|
|
||||||
if "%PW%"=="" ( echo Password cannot be empty. & goto getpw )
|
|
||||||
|
|
||||||
REM record old passwd
|
|
||||||
set "OLDPW="
|
|
||||||
if exist "%INI%" for /f "tokens=2 delims==" %%a in ('findstr /b /i "passwd=" "%INI%" 2^>nul ^| findstr /v /i "passwd2"') do set "OLDPW=%%a"
|
|
||||||
echo Old passwd=%OLDPW%
|
|
||||||
|
|
||||||
REM try CLI helpers, verify after each
|
|
||||||
set "DONE=0"
|
|
||||||
if exist "%UVNC%\createpassword.exe" (
|
|
||||||
echo Trying createpassword.exe ...
|
|
||||||
"%UVNC%\createpassword.exe" "%PW%" >nul 2>nul
|
|
||||||
call :checkchanged
|
|
||||||
)
|
|
||||||
if "%DONE%"=="0" if exist "%UVNC%\setpasswd.exe" (
|
|
||||||
echo Trying setpasswd.exe ...
|
|
||||||
"%UVNC%\setpasswd.exe" "%PW%" "%PW%" >nul 2>nul
|
|
||||||
call :checkchanged
|
|
||||||
)
|
|
||||||
if "%DONE%"=="0" (
|
|
||||||
echo.
|
|
||||||
echo CLI helpers did not change the password file. Opening UltraVNC settings...
|
|
||||||
echo -> right-click the UltraVNC tray icon, choose Admin Properties,
|
|
||||||
echo set the "VNC Password" to: %PW%
|
|
||||||
echo -> close the settings/tray app, then come back here and press a key.
|
|
||||||
echo.
|
|
||||||
start "" "%UVNC%\winvnc.exe"
|
|
||||||
pause
|
|
||||||
call :checkchanged
|
|
||||||
)
|
|
||||||
set "PW="
|
|
||||||
if "%DONE%"=="0" (
|
|
||||||
echo [warn] Password still not changed in %INI%.
|
|
||||||
echo Set it manually in UltraVNC Admin Properties as administrator.
|
|
||||||
pause
|
|
||||||
exit /b 1
|
|
||||||
)
|
|
||||||
|
|
||||||
REM restart the service so it reloads the password
|
|
||||||
set "SVC=uvnc_service"
|
|
||||||
sc query %SVC% >nul 2>nul
|
|
||||||
if errorlevel 1 (
|
|
||||||
echo [warn] Service '%SVC%' not found; restart winvnc manually if it runs in app mode.
|
|
||||||
goto showini
|
|
||||||
)
|
|
||||||
echo Restarting service %SVC% ...
|
|
||||||
net stop %SVC% >nul 2>nul
|
|
||||||
net start %SVC%
|
|
||||||
|
|
||||||
:showini
|
|
||||||
echo.
|
|
||||||
echo --- %INI% ---
|
|
||||||
if exist "%INI%" type "%INI%"
|
|
||||||
echo.
|
|
||||||
echo Done. Use the SAME password in run.bat, then reconnect in the browser.
|
|
||||||
pause
|
|
||||||
exit /b
|
|
||||||
|
|
||||||
:checkchanged
|
|
||||||
set "NEWPW="
|
|
||||||
if exist "%INI%" for /f "tokens=2 delims==" %%a in ('findstr /b /i "passwd=" "%INI%" 2^>nul ^| findstr /v /i "passwd2"') do set "NEWPW=%%a"
|
|
||||||
if not "%NEWPW%"=="%OLDPW%" (
|
|
||||||
echo Password file updated. New passwd=%NEWPW%
|
|
||||||
set "DONE=1"
|
|
||||||
)
|
|
||||||
goto :eof
|
|
||||||
Reference in New Issue
Block a user