# 通知設計書 64-SSH既知ホストチェックエラー

## 概要

本ドキュメントは、Julia の LibGit2 モジュールにおいて SSH 既知ホストチェックの結果が予期しない値を返した場合に出力されるエラー通知の設計を記述する。

### 本通知の処理概要

SSL/SSH 証明書の検証コールバック `certificate_callback` 内で、SSH の既知ホストチェック結果が `MATCH`、`NOTFOUND`、`MISMATCH` のいずれでもない予期しない値を返した場合に、エラーレベルのログを出力する通知である。

**業務上の目的・背景**：SSH 接続のセキュリティにおいて、既知ホストの検証は中間者攻撃（MITM）を防ぐために重要な機構である。`libssh2` ライブラリの `libssh2_knownhost_checkp` 関数は通常 `MATCH`、`NOTFOUND`、`MISMATCH`、`FAILURE` のいずれかを返すが、それ以外の値が返された場合は内部エラーやライブラリのバージョン不整合を示す可能性がある。このエラーログにより、開発者はセキュリティ検証処理の異常を検知できる。

**通知の送信タイミング**：`certificate_callback` 関数内の SSH 検証分岐において、`ssh_knownhost_check` の戻り値が `MATCH`、`NOTFOUND`、`MISMATCH` のいずれにも該当しない場合に発生する。

**通知の受信者**：LibGit2 経由で SSH 接続を使用する Julia プログラムの開発者。Julia のロギングフレームワークを通じて配信される。

**通知内容の概要**：`"unexpected SSH known host check result"` というメッセージとともに、`check` 変数の値がキーワード引数として出力される。

**期待されるアクション**：開発者は `libssh2` ライブラリのバージョンや既知ホストファイルの状態を確認し、問題の原因を調査することが期待される。

## 通知種別

ログ（Error） - Julia 標準ロギングフレームワーク `@error` マクロによるログ出力

## 送信仕様

### 基本情報

| 項目 | 内容 |
|-----|------|
| 送信方式 | 同期（コールバック関数内で即座にログ出力） |
| 優先度 | 高（Error レベル） |
| リトライ | 無 |

### 送信先決定ロジック

Julia の標準ロギングフレームワークにより、現在アクティブなロガーにメッセージが配信される。デフォルトでは `stderr` に出力される。

## 通知テンプレート

### メール通知の場合

該当なし（ログ出力のみ）

### 本文テンプレート

```
Error: unexpected SSH known host check result
  check = <check_value>
```

### 添付ファイル

該当なし

## テンプレート変数

| 変数名 | 説明 | データ取得元 | 必須 |
|--------|------|-------------|-----|
| check | SSH 既知ホストチェックの結果値 | `ssh_knownhost_check` の戻り値 | Yes |

## 送信トリガー・条件

### トリガー一覧

| トリガー種別 | トリガーイベント | 送信条件 | 説明 |
|------------|----------------|---------|------|
| コールバック | `certificate_callback` の SSH 検証分岐 | `check` が `MATCH`、`NOTFOUND`、`MISMATCH` のいずれでもない場合 | 予期しない既知ホストチェック結果 |

### 送信抑止条件

| 条件 | 説明 |
|-----|------|
| `check == MATCH` | 既知ホストに一致する正常ケース |
| `check == NOTFOUND` | 既知ホストに見つからないケース（別の警告メッセージが表示） |
| `check == MISMATCH` | 既知ホストと不一致のケース（別の警告メッセージが表示） |
| TLS 接続の場合 | SSH ではなく TLS の場合は別の処理パスを通る |
| `valid != 0` の場合 | 既に検証済みの場合は `CERT_ACCEPT` を即座に返す |
| `!NetworkOptions.verify_host(host, transport)` の場合 | ユーザーがホスト検証を無効化している場合 |

## 処理フロー

### 送信フロー

```mermaid
flowchart TD
    A[certificate_callback 呼び出し] --> B{valid != 0?}
    B -->|Yes| C[CERT_ACCEPT 返却]
    B -->|No| D{verify_host 有効?}
    D -->|No| C
    D -->|Yes| E{transport?}
    E -->|TLS| F[TLS 検証失敗処理]
    E -->|SSH| G[ssh_knownhost_check 実行]
    G --> H{check の値?}
    H -->|MATCH| I[valid = true]
    H -->|NOTFOUND| J[ホスト未登録メッセージ表示]
    H -->|MISMATCH| K[ホスト不一致メッセージ表示]
    H -->|その他| L["@error unexpected SSH known host check result"]
    L --> M[CERT_REJECT 返却]
```

## データベース参照・更新仕様

### 参照テーブル一覧

| テーブル名 | 用途 | 備考 |
|-----------|------|------|
| SSH 既知ホストファイル | ホスト鍵の検証 | `NetworkOptions.ssh_known_hosts_files()` で取得 |

### 更新テーブル一覧

該当なし

## エラー処理

### エラーケース一覧

| エラー種別 | 発生条件 | 対処方法 |
|----------|---------|---------|
| 予期しないチェック結果 | `ssh_knownhost_check` が想定外の値を返した場合 | `@error` を出力し `CERT_REJECT` を返す |

### リトライ仕様

| 項目 | 内容 |
|-----|------|
| リトライ回数 | 0（リトライなし） |
| リトライ間隔 | - |
| リトライ対象エラー | - |

## 配信設定

### レート制限

| 項目 | 内容 |
|-----|------|
| 1分あたり上限 | 制限なし |
| 1日あたり上限 | 制限なし |

### 配信時間帯

制限なし

## セキュリティ考慮事項

- `check` 変数の値が出力されるが、ホスト名や鍵情報は含まれない。
- このエラーが発生した場合、`CERT_REJECT` が返されるため、接続は拒否される。セキュリティ上安全側に倒す設計となっている。

## 備考

- `certificate_callback` は C 関数ポインタとして libgit2 に登録される（callbacks.jl 行518）。
- SSH 検証は `libssh2` ライブラリの `libssh2_knownhost_checkp` 関数に依存している。

---

## コードリーディングガイド

本通知を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | callbacks.jl | `stdlib/LibGit2/src/callbacks.jl` | `CertHostKey` 構造体（行366-375）。証明書ホスト鍵情報 |
| 1-2 | callbacks.jl | `stdlib/LibGit2/src/callbacks.jl` | `KnownHost` 構造体（行427-433） |

**読解のコツ**: C 構造体とのメモリレイアウト互換性が必要なため、フィールドの型と順序は libgit2/libssh2 のヘッダファイルと一致させている。

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | callbacks.jl | `stdlib/LibGit2/src/callbacks.jl` | `certificate_callback` 関数（行381-425）。**本通知の発生箇所（行419）** |

**主要処理フロー**:
1. **行387**: `valid != 0` チェック - 既に検証済みなら ACCEPT
2. **行388-391**: ホスト名とトランスポート種別の判定
3. **行392-395**: `NetworkOptions.verify_host` でユーザー設定確認
4. **行401-421**: SSH 検証分岐
5. **行403-405**: 既知ホストファイルの取得と `ssh_knownhost_check` 実行
6. **行407-418**: MATCH/NOTFOUND/MISMATCH の各ケース処理
7. **行419**: `@error("unexpected SSH known host check result", check)` - **本通知**

#### Step 3: SSH 既知ホストチェック処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | callbacks.jl | `stdlib/LibGit2/src/callbacks.jl` | `ssh_knownhost_check` 関数（行444-504）。libssh2 を使用した既知ホストチェック |

**主要処理フロー**:
- **行449-454**: ホストとポートの解析
- **行458-463**: libssh2 セッション初期化
- **行464-500**: 各既知ホストファイルを順に検査
- **行479-487**: `libssh2_knownhost_checkp` 呼び出し

### プログラム呼び出し階層図

```
certificate_callback(cert_p, valid, host_p, data_p)   [callbacks.jl:381]
    |
    +-- NetworkOptions.verify_host(host, "SSH")         [NetworkOptions]
    |
    +-- NetworkOptions.ssh_known_hosts_files()           [NetworkOptions]
    |
    +-- ssh_knownhost_check(files, host, cert)          [callbacks.jl:435]
    |       |
    |       +-- libssh2_session_init_ex                 [libssh2]
    |       +-- libssh2_knownhost_init                  [libssh2]
    |       +-- libssh2_knownhost_readfile              [libssh2]
    |       +-- libssh2_knownhost_checkp                [libssh2]
    |
    +-- (check が想定外の値)
            |
            +-- @error "unexpected SSH known host check result" [callbacks.jl:419]
            +-- return CERT_REJECT
```

### データフロー図

```
[入力]                         [処理]                              [出力]

CertHostKey (cert_p)  ------>  certificate_callback
host_p (Ptr{Cchar})   ------>    |
valid (Cint)          ------>    +-- SSH 分岐
                                 |
SSH known hosts files  ------>   +-- ssh_knownhost_check      ---->  check (Cint)
                                 |       |
                                 |       +-- libssh2_knownhost_checkp
                                 |
                                 +-- check 判定
                                         |
                                         +-- (想定外) @error  ---->  エラーログ (stderr)
                                                                     CERT_REJECT
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| callbacks.jl | `stdlib/LibGit2/src/callbacks.jl` | ソース | `certificate_callback` と `ssh_knownhost_check`。本通知の発生元（行419） |
| types.jl | `stdlib/LibGit2/src/types.jl` | ソース | RemoteCallbacks 構造体（certificate_check フィールド） |
| consts.jl | `stdlib/LibGit2/src/consts.jl` | ソース | CERT_ACCEPT/REJECT、LIBSSH2_KNOWNHOST_CHECK_* 定数 |
