Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .github/ISSUE_TEMPLATE/beta-report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ body:
id: version
attributes:
label: W-Fix version / Версия W-Fix
placeholder: v3.0.0-beta.1
placeholder: v3.1.0-beta.1
validations:
required: true
- type: dropdown
Expand All @@ -35,6 +35,8 @@ body:
- Local repair / Локальный ремонт
- Active Directory domain
- Workgroup / Одноранговая сеть
- Pair Repair live / Парный ремонт по сети
- Pair Repair offline / Парный ремонт через файлы
validations:
required: true
- type: textarea
Expand Down
20 changes: 20 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,23 @@ jobs:

- name: NuGet vulnerability report
run: dotnet list W-Fix.sln package --vulnerable --include-transitive

- name: Publish portable win-x64 executable
run: >-
dotnet publish src/W-Fix.App/W-Fix.App.csproj
--configuration Release
--runtime win-x64
--self-contained true
--no-restore
-p:PublishSingleFile=true
-p:IncludeAllContentForSelfExtract=true
-p:EnableCompressionInSingleFile=true
-o artifacts/publish/win-x64

- name: Upload beta test artifact
uses: actions/upload-artifact@v7
with:
name: W-Fix-${{ github.sha }}-win-x64
path: artifacts/publish/win-x64/W-Fix.exe
if-no-files-found: error
retention-days: 14
15 changes: 15 additions & 0 deletions CODE_SIGNING_POLICY.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,18 @@ Free code signing provided by [SignPath.io](https://signpath.io/), certificate b
Until SignPath approval, public beta releases remain explicitly marked unsigned and include SHA-256 checksums. For internal testing, a separately documented self-signed certificate may be trusted manually on managed test computers; it is never presented as publicly trusted.

See also [Privacy Policy](PRIVACY.md) and [Security Policy](SECURITY.md).

## One-time catalog key bootstrap / Первичная настройка ключа каталога

Владелец релиза выполняет это локально один раз. Закрытый файл не коммитится и удаляется сразу после записи секрета:

```powershell
dotnet run --project tools/W-Fix.CatalogSigner -- generate private.pem public.pem
Get-Content private.pem -Raw | gh secret set KNOWN_ISSUES_PRIVATE_KEY_PEM --repo OneDeadMachine-Dev/W-FIX
Copy-Item public.pem src/W-Fix.Core/Catalog/known-issues-public.pem
Remove-Item private.pem, public.pem -Force
```

После обновления публичного ключа требуется обычный PR и проверка `verify` на тестовой подписи. SignPath identifiers добавляются как repository variables, а `SIGNPATH_API_TOKEN` — только как Environment secret `release`. Окружение `release` требует ручного подтверждения владельца и принимает только теги `v*`.

The release owner performs this once on a trusted local machine. The private file is never committed and is deleted immediately after the secret is stored. Updating the public key requires a normal PR and a test `verify` run. SignPath identifiers are repository variables; `SIGNPATH_API_TOKEN` is restricted to the `release` Environment secret. The `release` environment requires manual owner approval and accepts only `v*` tags.
2 changes: 2 additions & 0 deletions PRIVACY.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ W-Fix не содержит телеметрии, рекламы и автома
- Альтернативные учётные данные сохраняются только после явного согласия в Windows Credential Manager. Пароли не записываются в конфигурацию, аргументы процессов, логи и отчёты.
- При диагностике W-Fix может загрузить декларативный каталог известных проблем с официального GitHub Release проекта. Загруженный каталог проверяется цифровой подписью и не может содержать исполняемый код.
- W-Fix не передаёт сведения третьим лицам, если пользователь сам не экспортировал и не отправил отчёт или support bundle.
- Pair Repair обменивается данными только между двумя явно выбранными ПК. Приглашение и offline-снимок не содержат паролей; live-listener и временное правило Firewall удаляются после сессии.

Сообщить о проблеме конфиденциальности можно через [Private vulnerability reporting](https://github.com/OneDeadMachine-Dev/W-FIX/security/advisories/new).

Expand All @@ -23,5 +24,6 @@ W-Fix contains no telemetry, advertising, or automatic report uploads. It operat
- Alternate credentials are saved only with explicit consent in Windows Credential Manager. Passwords are never written to configuration, process arguments, logs, or reports.
- During diagnostics W-Fix may download a declarative known-issues catalog from the project's official GitHub Release. The catalog is signature-verified and cannot contain executable code.
- W-Fix sends no information to third parties unless the user explicitly exports and shares a report or support bundle.
- Pair Repair exchanges data only between two explicitly selected PCs. Invitations and offline snapshots contain no passwords; the live listener and temporary Firewall rule are removed after the session.

Report a privacy concern through [Private vulnerability reporting](https://github.com/OneDeadMachine-Dev/W-FIX/security/advisories/new).
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

[![Platform](https://img.shields.io/badge/platform-Windows%2010%2F11-blue?logo=windows)](https://www.microsoft.com/windows)
[![.NET](https://img.shields.io/badge/.NET-8.0-purple?logo=dotnet)](https://dotnet.microsoft.com/)
[![Release](https://img.shields.io/badge/version-3.0.0--beta.1-blue)](https://github.com/OneDeadMachine-Dev/W-FIX/releases)
[![Release](https://img.shields.io/badge/version-3.1.0--beta.1-blue)](https://github.com/OneDeadMachine-Dev/W-FIX/releases)
[![License](https://img.shields.io/badge/license-MIT-orange)](LICENSE)
[![Author](https://img.shields.io/badge/author-OneDeadMachine-red)](https://github.com/OneDeadMachine)

Expand Down Expand Up @@ -45,6 +45,7 @@

### Плюс:
- 🌐 **Remote Repair Center v3** — несколько доменных ПК, preflight, инвентаризация, автоматический план, проверка и изолированный rollback
- 🔗 **Pair Repair Wizard v3.1** — ремонт общего принтера между двумя ПК: TLS pairing, общий диагноз, двусторонний rollback и offline fallback
- 🧠 **Диагностические правила** — вывод по наблюдаемым фактам, уверенность и официальный источник известной проблемы
- 🔐 **Credential Manager** — альтернативная доменная учётная запись без пароля в конфигурации, CLI или логах
- 📊 **Отчёты** — JSON/HTML для каждого запуска и обезличенный ZIP support bundle
Expand All @@ -70,6 +71,8 @@
3. Запусти **Диагностику**, проверь факты и сформированный план.
4. Подтверди пакетный ремонт. Сбой одной машины не останавливает остальные; обратимые шаги неуспешной цели откатываются.

Если общий принтер подключён к другому ПК, открой **Pair Repair** на обеих машинах. Хост создаёт одноразовый `.wfixpair`, оба пользователя сверяют код, а клиент формирует и выполняет общий план. Подробная инструкция: [Pair Repair на русском](docs/pair-repair.md) / [English guide](docs/pair-repair.en.md).

> ⚠️ Права администратора обязательны — фиксеры изменяют реестр и службы Windows.

---
Expand Down Expand Up @@ -111,6 +114,7 @@ W-Fix/
│ │ ├── Remote/ # WinRM preflight и инвентаризация
│ │ ├── Diagnostics/ # Evidence-based правила
│ │ ├── Repair/ # Планировщик, legacy-адаптер и batch executor
│ │ ├── Pairing/ # TLS pairing, SMB/RPC diagnostics и двухузловая saga
│ │ ├── Catalog/ # Подписанный каталог Windows known issues
│ │ ├── Fixers/ # 12 фиксеров (FixerBase → IFixer)
│ │ ├── Services/
Expand All @@ -123,6 +127,7 @@ W-Fix/
│ └── W-Fix.App/ # WPF UI (MVVM + CommunityToolkit)
│ ├── ViewModels/
│ ├── RemoteCenterWindow.xaml
│ ├── PairRepairWindow.xaml
│ ├── Views/
│ └── Assets/icon.ico
└── publish/W-Fix.exe # Готовый портативный файл
Expand Down
2 changes: 2 additions & 0 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,7 @@ Include the W-Fix version, Windows version, expected and actual behavior, and mi

- W-Fix требует административных прав, потому что изменяет службы, реестр, политики печати и драйверы.
- Remote Center выполняет действия только на явно выбранных целях.
- Pair Repair использует TLS 1.2+, временный ECDSA-ключ, pinning, одинаковый код и подтверждение на обоих ПК. По каналу разрешены только типизированные DTO и встроенные `pair.*` действия.
- Pair listener не открывается на Public-профиле; SMB1 не поддерживается.
- Загружаемый known-issues catalog декларативен, подписан ECDSA и ссылается только на встроенные действия.
- Private keys, GitHub tokens and SignPath tokens must never be committed to the repository.
16 changes: 16 additions & 0 deletions docs/architecture.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,19 @@ short-lived `PSCredential`; it is never embedded in a PowerShell script, process
The known-issues catalog is declarative. A valid ECDSA signature does not grant code execution: catalog entries can
only reference action IDs compiled into W-Fix. Microsoft source URLs are restricted to `learn.microsoft.com` and
`support.microsoft.com`.

## Pair Repair v3.1 pipeline

`IPairSessionTransport` creates a one-time TLS session with a temporary ECDSA P-256 certificate. The client checks
the public-key pin from `.wfixpair`; both windows show the derived six-digit code, and application messages remain
blocked until both users approve. The protocol accepts only versioned DTOs and built-in `pair.*` identifiers. It
cannot carry PowerShell source or passwords.

`IPairInventoryService` checks only the explicitly named peer. `IPairRepairExecutor` runs the shared plan as a
two-node saga: remote host steps go through `PairAgentCommandLoop`, while client steps use the local dispatcher.
Every mutation has a checkpoint. Failure, cancellation, timeout, or connection loss triggers reverse rollback and
an explicit `abort`; `commit` is sent only after every verification passes.

The host Firewall lease is scoped to the current executable, exact port, `LocalSubnet`, and Private/Domain profiles.
Offline ECDSA-signed snapshots detect tampering, but each side repairs independently and therefore cannot offer
cross-machine automatic rollback. A `HOST\\User` password is written directly to Windows Credential Manager.
17 changes: 17 additions & 0 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
- `W-Fix.Core.Diagnostics` — правила, формирующие находки только из наблюдаемых фактов.
- `W-Fix.Core.Repair` — планирование, адаптер двенадцати v2-фиксеров и ограниченное пакетное выполнение.
- `W-Fix.Core.Catalog` — встроенный и подписанный онлайн-каталог известных проблем Windows.
- `W-Fix.Core.Pairing` — TLS-транспорт, подписанный offline-обмен, парная диагностика и двухузловая saga.

UI не должен самостоятельно определять успешность системной команды. Источником истины является
`PowerShellExecutionResult`, а итог многошагового фиксера вычисляется из результатов всех выполненных шагов.
Expand Down Expand Up @@ -95,6 +96,22 @@ PowerShell Remoting выполняет команды в сервисном ко
Каталог известных проблем декларативен и не содержит скриптов. Даже корректно подписанная запись может выбрать
только действие, уже скомпилированное и зарегистрированное в W-Fix.

## Конвейер Pair Repair v3.1

`IPairSessionTransport` создаёт одноразовую TLS-сессию с временным ECDSA P-256 сертификатом. Клиент проверяет
pin публичного ключа из `.wfixpair`, оба окна показывают вычисленный шестизначный код, а прикладные сообщения
разрешаются только после двух подтверждений. Протокол принимает только версионированные DTO и встроенные
идентификаторы `pair.*`; строки PowerShell и пароли через него не передаются.

`IPairInventoryService` проверяет только явно названного соседа. `IPairRepairExecutor` выполняет общий план как
двухузловую saga: remote host-side шаги проходят через `PairAgentCommandLoop`, local client-side шаги выполняются
локальным dispatcher. До каждого изменения создаётся checkpoint. Ошибка, отмена, timeout или потеря соединения
вызывают обратный rollback и явный `abort`; `commit` отправляется только после повторной проверки всех шагов.

На хосте действует временное Firewall-правило для текущего EXE, точного порта, `LocalSubnet` и Private/Domain.
В offline-режиме ECDSA-подписанный снимок защищён от изменения, но обе стороны ремонтируются раздельно, поэтому
общий автоматический rollback недоступен. Пароль `HOST\\User` сохраняется напрямую в Windows Credential Manager.

## Риски и подтверждения

- `Reversible` — обычное подтверждение плана и обязательный снимок.
Expand Down
39 changes: 39 additions & 0 deletions docs/pair-repair.en.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Pair Repair Wizard v3.1

Pair Repair fixes a shared printer between two explicitly selected PCs. It is neither a network scanner nor a persistent agent: W-Fix checks only the named peer and removes its temporary listener after the PairRun.

In a domain, Host and Client can be entered in one window. W-Fix uses the current Kerberos identity and existing WinRM transport. Queue connection and test-page operations run in the signed-in Client user's session through a temporary Task Scheduler job instead of the administrator service account's HKCU.

## Live mode

1. Run W-Fix as administrator on both PCs.
2. On the PC physically hosting the printer, open **Pair Repair**, choose **Host**, and enter the client name and exact local printer name.
3. Create and save a `.wfixpair` invitation. It expires after 15 minutes and is accepted once.
4. Select **Wait for client**. On the other PC choose **Client** and open the invitation.
5. Compare the six-digit code in both windows and approve on both PCs. Mutations remain disabled until dual approval succeeds.
6. The client gathers both snapshots and displays evidence plus the shared repair plan. Expert actions are excluded by default.
7. Execute the plan. Snapshots precede every mutation, verification determines success, and reversible steps roll back on both endpoints after a failure.
8. Send a Windows test page and confirm the physical output.

The live session uses TLS 1.2/1.3, a temporary ECDSA P-256 certificate, and public-key pinning. Its temporary Firewall rule is restricted to the current executable, exact port, Private/Domain profiles, and `LocalSubnet`. A listener is never opened on a Public profile.

## Workgroup credentials

When Windows requires authentication, the client can save an existing `HOST\User` credential scoped to that host. The password goes directly to Windows Credential Manager and is excluded from PairRun, invitations, support bundles, and W-Fix logs.

W-Fix never synchronizes primary-user passwords. SMB1 cannot be enabled. Insecure guest, disabled SMB signing, and reduced RPC protection remain expert-only actions with separate warnings and rollback.

## Offline fallback

If the live port is blocked, export a signed snapshot on one side and import it on the other. Each PC runs only its local plan. The file contains no credentials, but cross-machine automatic rollback is unavailable in offline mode.

## Collected diagnostics

- Windows version, domain/workgroup, and network profile;
- DNS for the selected peer, SMB 445, and RPC 135;
- Function Discovery, Spooler, and narrow Firewall rules;
- SMB signing, guest restrictions, and conflicting SMB sessions;
- shared queue, ShareName, driver, Point and Print, and RPC policies;
- PrintService/SMBClient errors without document names or content.

PairRun reports are stored under `%ProgramData%\W-Fix\Runs\pair-<RunId>`.
Loading