macOSの sudo で TouchID が使えるようにする（tmuxやscreen内での利用も対応）

# pam_tid.so と pam_reattach.so

- `pam_tid.so` は TouchID 認証を利用するための macOS 付属の PAM モジュール。
- `pam_reattach.so` は `pam_tid.so` が tmux 内だと利用できない問題を解決してくれる PAM モジュール。

これら２つの設定を `/etc/pam.d/sudo` ないし `/etc/pam.d/sudo_local` に追記してやることで、sudo で TouchID が使い放題になります。

## /etc/pam.d/sudo_local に sudo の設定が書けるようになりました！
2024年9月16日リリースの macOS Sequoia から `/etc/pam.d/sudo` の頭に `auth include sudo_local` という設定が追加されました。これにより今後はユーザが追加でsudoのpam設定を行いたい場合は `/etc/pam.d/sudo_local` に書く事が推奨されるようになりました。
これにより何が嬉しいかというと、今までは macOS がアップデートされる度に `/etc/pam.d/sudo` がデフォルトに戻されてしまいその度に TouchID が使えなくなってしまっていましたが、今後は sudo_local に一度 TouchID の設定をしてしまえば macOS がアップデートされても sudo で TouchID が使い続けられるようになったということです。

Appleのサイト上でもその旨がアナウンスされてました。

https://support.apple.com/ja-jp/109030#:~:text=/etc/pam.d/sudo_local



# 設定スクリプト
新しい Macbook のセットアップの際に手順書だと面倒なのでワンライナーでセットアップできるようにした。
元コードを修正した際に Qiita に再貼り付けするのは面倒なのでソース確認したい人は [Gist: macOSの sudo で TouchID が使えるようにする（tmux内の利用も対応）](https://gist.github.com/kawaz/d95fb3b547351e01f0f3f99783180b9f) を参照。

```
curl -sL https://gist.githubusercontent.com/kawaz/d95fb3b547351e01f0f3f99783180b9f/raw/10c9e17e62dd3f08d3e564cad69324f6f2297380/install-pam_tid-and-pam_reattach.sh | bash
```

こいつは以下のことをやってくれる。
- `/etc/pam.d/sudo` に `auth include sudo_local` が無ければ追記する。(macOS Sonomaからこのスタイルがデフォルトになったので、より古い場合もその同じ形に揃えることにした)
- `pam_tid.so` が未設定なら `/etc/pam.d/sudo_local` に追記する。
- `pam_reattach.so` が未インストールなら brew install を使ってインストールする。
- `pam_reattach.so` が未設定なら `/etc/pam.d/sudo_local` に追記する。

# Before/After
`/etc/pam.d は以下のように変わる

```diff
diff --git a/pam.d.old/sudo b/pam.d/sudo
index 1869df8..8e27c88 100644
--- a/pam.d.old/sudo
+++ b/pam.d/sudo
@@ -1,4 +1,5 @@
 # sudo: auth account password session
+auth       include        sudo_local
 auth       sufficient     pam_smartcard.so
 auth       required       pam_opendirectory.so
 account    required       pam_permit.so
diff --git a/pam.d/sudo_local b/pam.d/sudo_local
new file mode 100644
index 0000000..bba1591
--- /dev/null
+++ b/pam.d/sudo_local
@@ -0,0 +1,4 @@
+# sudo_local: local config file which survives system update and is included for sudo
+# uncomment following line to enable Touch ID for sudo
+auth       optional       /opt/homebrew/lib/pam/pam_reattach.so
+auth       sufficient     pam_tid.so
```

- macOS Sequoia 以降の場合は sudo_local の include はデフォルトになってるので `/etc/pam.d/sudo` は変化しません。
- `pam_reattach.so` のパスについて
    - このファイルのパスは Mac のアーキテクチャによって変わります。
        - Intel Mac なら /usr/local/lib/pam/
        - Apple Silicon Mac なら /opt/homebrew/lib/pam/
    - pamの設定ファイルにファイル名のみで書くと /usr/local/lib/pam/ は探してくれるが /opt/homebrew/lib/pam/ は探してくれないので、アーキテクチャに寄らず利用出来るようフルパスで書くようにします。


# 問題が起きたら
もし何か問題が発生し `/etc/pam.d/sudo` または `/etc/pam.d/sudo_local` が壊れて `sudo` が利用出来なくなると、sudo を利用して /etc/pam.d/sudo を編集する事も出来なくなってしまい困ります。万が一の際に備えて、sudo 以外の手段でこのファイルを編集する方法を知っておくことは重要です。

以下は実際に自分が試して上手くいった、__Finder__ を使って回復する手順です。

1. Finder で /etc/pam.d/ を開く（`open -R /etc/pam.d/sudo`）
2. sudo ファイルを選択してコンテキストメニューの「情報を見る」を開く
3. 情報ダイアログの下の方にある「共有とアクセス」の + ボタンを押して自分のユーザで書き込み可能になるようアクセス権を追加する（アクセス権の変更の為には情報ダイアログの右下に表示された鍵マークをクリックして解除する必要があります）
4. アクセス権を付けたら適当なエディタで編集出来るようになるので問題が起きる前の内容に書き換えて保存する
5. sudo が無事使えるようになった事を確認し、問題なければ 3 の手順で追加した不要なアクセス権を削除しておく