macOSにはSecure Keyboard Entryという機能があり、有効化されている間はフォーカスの当たっていないアプリにキー入力が渡らなくなる。パスワード入力欄にフォーカスした際などに自動的に有効化されるが、無効化し忘れたプロセスが残っていると、テキスト展開ツールやIMEなど他のアプリのキー入力監視が効かなくなる。ここではSecure Keyboard Entryを有効にしているプロセスをkCGSSessionSecureInputPIDから特定する方法をまとめる。
Secure Keyboard Entryとは
Secure Keyboard Entryは、キー入力を現在フォーカスのあるプロセスにのみ配送し、他のプロセスによるキーイベントの監視・傍受を防ぐ機能である。パスワードマネージャーやテキスト展開ツールなど、キー入力を監視することで機能するアプリからパスワードなどの機密情報を保護する目的で存在する。
Terminal.appやパスワード入力を扱うアプリは、機密情報を入力するフィールドにフォーカスが移るとEnableSecureEventInput()を呼び出してSecure Keyboard Entryを有効化し、フォーカスが外れるとDisableSecureEventInput()で無効化する。有効化と無効化は内部的にネストしたカウンタで管理されており、複数のプロセスが同時に有効化していても、すべてのプロセスが無効化するまで機能はオンのままになる。
Terminal.appは「ターミナル」メニューの「セキュアキーボード入力」からも手動でオン・オフを切り替えられる。
有効化されたままになる問題
アプリの実装によっては、無効化を呼び忘れたり、クラッシュによってDisableSecureEventInput()が呼ばれないまま終了したりすることがある。有効化されたままの状態になると、システム全体でキー入力の監視が効かなくなり、テキスト展開ツールやオートメーションツール、サードパーティ製IMEの変換候補などが動作しなくなる。
ログアウト・ログインし直せば強制的に解除されるが、原因のプロセスを特定できれば、そのプロセスを終了するだけで直る場合がある。
kCGSSessionSecureInputPIDで有効化しているプロセスを調べる
現在Secure Keyboard Entryを有効にしているプロセスのPIDは、I/O Kit RegistryのIOConsoleUsersプロパティ内のkCGSSessionSecureInputPIDに記録されている。ioregコマンドで確認できる。
$ ioreg -l -w 0 | grep -i secureinput
Secure Keyboard Entryが有効な状態では、次のようにIOConsoleUsers全体を含む行が出力される。
| "IOConsoleUsers" = ({"kCGSSessionOnConsoleKey"=Yes,"kSCSecuritySessionID"=102744,(中略),"kCGSSessionSecureInputPID"=45346,(中略)})
無効な状態ではkCGSSessionSecureInputPIDキー自体が辞書に含まれないため、何も出力されない。
grep -oでPIDの値だけを抜き出すと確認しやすい。
$ ioreg -l -w 0 | grep -o 'kCGSSessionSecureInputPID"=[0-9]*'
kCGSSessionSecureInputPID"=45346
該当プロセスを特定する
取得したPIDをpsに渡すと、プロセスを特定できる。
$ ps -c -o pid=,comm= -p 45346
45346 Dia
-cオプションを付けると実行ファイル名のみが表示され、フルパスのcommand列より読みやすい。手元の環境では、Webブラウザがパスワード入力欄でフォーカスを受け取った際に有効化していたケースを実際に観測できた。
特定したプロセスが正規のパスワード入力中でないことを確認できれば、そのプロセスを終了することでSecure Keyboard Entryの有効化状態を解除できる場合がある。
