Skip to content

AMT と RDP のパスワードをブラウザに保存できるようにし、電源オンを 1 回押しにする - #120

Merged
5ym merged 1 commit into
mainfrom
save-passwords
Nov 11, 2026
Merged

5ym merged 1 commit into
mainfrom
save-passwords

Conversation

@5ym

@5ym 5ym commented Nov 11, 2026

Copy link
Copy Markdown
Contributor

パスワードの保存(AMT・RDP)

  • つなぐ前の画面のパスワードの欄の下に「パスワードをこの端末に保存する」(既定はオフ)と「保存を消去」を足した。Talos の先と、保存が使えないブラウザでは出さない
  • 保存するのは、チェックを入れて つながったあと(AMT は電源の状態を読めたとき、RDP は CredSSP を通って接続シーケンスが終わったとき)。断られたパスワードは保存しない
  • つなぐ先と種類(AMT / RDP)ごとに、ユーザー名とパスワードを持つ(RDP のドメインはユーザー名の中)
  • 置くのはブラウザの中だけで、mado には送らない(mado がパスワードを受け取らない作りは変えていない。サーバーの変更は無い)。WebCrypto の取り出せない(extractable: false)AES-GCM 256 の鍵を IndexedDB に置き、その鍵で暗号化したもの(保存ごとに新しい IV、追加の認証データに「種類:つなぐ先」)を IndexedDB に置く(web/saved-login.ts)。localStorage には置かない
  • 保存があれば、その先を選んだときに欄に入れてチェックを入れる。自動ではつながない(今までどおり「開く」「接続」を押したときだけ。AMT は続けて間違えると締め出すため)
  • 保存したもので認証を断られたら、欄に入れ直さず「保存したパスワードでは認証できませんでした。入力し直すか、保存を消去してください」と出す。入力し直してつながれば上書きする。回線などの失敗では入れ直す。RDP は CredSSP でサーバーが NTSTATUS を返したとき(LogonError)だけ見分ける
  • 消し方: 「保存を消去」/ チェックを外してつなぐ / 画面のログアウト(保存と鍵を全部消してから /logout へ)/ 一覧から無くなった先は次に開いたときに消す
  • 守れるのは「プロファイルのファイルを読まれても平文は出ない」まで。同じブラウザでページを開ける人と、ページに入り込んだスクリプトからは使える。docs/amt.md の「ユーザー名とパスワードの保存」に書いた(docs/rdp-client.md と README からも)

電源オンは 1 回押し

  • AMT の「電源オン」だけ、1 回押しで実行する(two-press.ts に once)。シャットダウン・再起動・強制再起動・強制電源オフと、Talos の電源の操作は 2 回押しのまま

試験

  • web/saved-login.test.ts(保存・読み出し・上書き・消去・先と種類ごとの分離・平文が無いこと・鍵を取り出せないこと・2 つのタブの同時の保存・使えない環境)。IndexedDB の偽物に fake-indexeddb を devDependencies に足した(比べた結果は docs/amt.md の「IndexedDB の偽物を選んだ理由」)
  • web/two-press.test.ts(2 回押しと、1 回押しの once)
  • tools/amt-e2e/ui.cjs: 電源オンの 1 回押し、保存の一連(違うパスワードは保存しない、つながると保存、開き直しても入る、自動ではつながない、IndexedDB に平文が無い、断られたら 1 度でやめる、上書き、消去、ログアウトで消える)、保存が使えないブラウザ
  • wslc のコンテナで bun run lint・bunx tsc --noEmit・bun test web(369 件)・bun run build:web・dotnet run --project tests/Mado.Tests.csproj(159 件、Windows だけの 3 件はスキップ)・tools/amt-e2e の e2e.ts と ui.cjs を通した

本物の AMT・Windows の RDP・実機のブラウザでは確かめていない。

🤖 Generated with Claude Code

https://claude.ai/code/session_01T8TqVdo6LUrWKdVQgbScVU

パスワードの保存
- つなぐ前の画面に「パスワードをこの端末に保存する」(既定はオフ)。チェックを入れて
  つながったあとに、つなぐ先と種類(AMT / RDP)ごとにユーザー名とパスワードを保存する
- 置くのはブラウザの中だけ。WebCrypto の取り出せない AES-GCM の鍵を IndexedDB に置き、
  その鍵で暗号化したものを IndexedDB に置く(web/saved-login.ts)。mado には送らない
- 保存があれば欄に入れる。自動ではつながない。保存したもので認証を断られたら入れ直さず、
  入力し直す(上書き)か「保存を消去」で消せる
- 画面のログアウトで、保存と鍵を消す。一覧に無くなった先の保存も消す
- IndexedDB か WebCrypto が使えないブラウザではチェックを出さない

電源
- AMT の「電源オン」だけ 1 回押しで実行する(two-press.ts の once)。
  動いている PC に影響する操作は 2 回押しのまま

試験は bun(fake-indexeddb を devDependencies に追加)と tools/amt-e2e/ui.cjs。

Co-Authored-By: Claude Fable 5.2 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01T8TqVdo6LUrWKdVQgbScVU
@claude

claude Bot commented Nov 11, 2026 •

Copy link
Copy Markdown

Claude finished @5ym's task in 23s —— View job


レビュー結果

変更を読み、web/saved-login.ts、web/app.ts、web/rdp/credssp.ts、web/two-press.ts、web/amt/view.ts を中心に確認しました。ビルドやテストは実行していません。ブロッカーになる不具合は見つかりませんでした。

良い点

  • 保存のタイミングは「つながったあと 1 回だけ」で、keeper の done ??= が RDP の方式フォールバックによる二重保存を防いでいます。
  • 認証を断られたときは、保存したものを入れ直さず、AMT は 1 度で止めます。AMT のロックアウト対策として妥当です。
  • extractable: false の鍵、保存ごとに新しい IV、AAD に kind:target を入れる設計は適切です。複数タブで鍵を同時に作る競合も key() の再読込で対処されています。
  • 威力の限界(同一ブラウザで開ける人やページ内スクリプトからは使える)が docs/amt.md に正直に書かれています。
  • 試験は、競合・平文が無いこと・鍵を取り出せないこと・使えない環境まで押さえています。

要確認・軽微な点(いずれも修正必須ではありません)

  1. LogonError の判定範囲(web/rdp/credssp.ts)
    LogonError になるのは readTsRequest で errorCode を受けたときだけです。CredSSP の途中で別の例外(たとえば connect 側でラップされた例外)に変わっていると、instanceof が外れて「保存したもので断られた」扱いになりません。そのときは同じ保存済みパスワードが毎回入り直します。実際に errorCode が LogonError のまま runSession の catch まで届くか、実機かモックで確認してください。
  2. prune と save の競合(web/app.ts)
    prune は起動時に走ります。getAllKeys のあとに別タブが保存すると、その新しい保存が一覧外として消える可能性があります。ただし対象は一覧にある先だけなので、実害は小さいです。
  3. onversionchange が無い(web/saved-login.ts)
    将来スキーマを上げたとき、古いタブが DB を握って onblocked になります。現状は v1 だけなので影響はありません。
  4. ログアウト時のクリア(web/app.ts)
    ログアウトのリンクを通らない終了(タブを閉じる、セッション切れ)では、保存は残ります。仕様としては文書化されているので、問題とはしていません。

まとめ

設計と実装は一貫していて、テストも十分です。上の 1 の確認だけお願いします。
/ branch: save-passwords

@5ym
5ym merged commit 27d2ae7 into main Nov 11, 2026
7 checks passed
@5ym
5ym deleted the save-passwords branch November 11, 2026 04:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant