Xamarin.Mac アプリのサンドボックス化

この記事は、App Store でリリースするための Xamarin.Mac アプリケーションのサンドボックス化について説明しています。 コンテナー ディレクトリ、エンタイトルメント、ユーザーが決定したアクセス許可、特権の分離、カーネルの適用など、サンドボックスに入るすべての要素について説明します。

概要

Xamarin.Mac アプリケーションで C# と .NET を使用する場合、アプリケーションをサンドボックス化する機能は、操作時や Swift の場合と Objective-C 同じです。

An example of the running app

この記事では、Xamarin.Mac アプリケーションでのサンドボックスの操作の基本と、コンテナー ディレクトリ、エンタイトルメント、ユーザーが決定したアクセス許可、特権の分離、カーネルの強制など、サンドボックスに入るすべての要素について説明します。 この記事で使用する 主要な概念と手法については、まず Hello Mac の記事、特 に Xcode とインターフェイス ビルダーアウトレットとアクション の概要に関するセクションを参照することを強くお勧めします。

Xamarin.Mac Internals ドキュメントの「C# クラス/メソッドを Xamarin.Mac Internals のセクションにObjective-C公開する」も参照してください。C# クラスObjective-Cをオブジェクトと UI 要素に結び付けるために使用される属性についてもExport説明Registerしています。

アプリ サンドボックスについて

アプリ サンドボックスは、アプリケーションがシステム リソースに対して持つアクセスを制限することで、悪意のあるアプリケーションが Mac 上で実行されることによって引き起こされる可能性のある損害に対する強力な防御を提供します。

セキュリティで保護されていないアプリケーションは、アプリを実行しているユーザーの完全な権限を持ち、ユーザーができることにアクセスしたり、実行したりできます。 アプリにセキュリティ ホール (または使用しているフレームワーク) が含まれている場合、ハッカーはこれらの弱点を悪用し、アプリを使用して実行されている Mac を制御する可能性があります。

アプリケーションごとにリソースへのアクセスを制限することで、セキュリティで保護されたアプリは、ユーザーのコンピューター上で実行されているアプリケーションの一部で、盗難、破損、または悪意のある意図に対する防御ラインを提供します。

アプリ サンドボックスは、macOS (カーネル レベルで適用) に組み込まれているアクセス制御テクノロジであり、次の 2 つの戦略を提供します。

  1. アプリ サンドボックスを使用すると、開発者はアプリケーションが OS と対話する方法を記述できます。この方法では、ジョブを完了するために必要なアクセス権のみが付与され、それ以上は付与されません。
  2. アプリ サンドボックスを使用すると、ユーザーは、[開く] ダイアログ ボックスと [保存] ダイアログ ボックス、ドラッグ アンド ドロップ操作、その他の一般的なユーザー操作を使用して、システムへのアクセス権をさらにシームレスに付与できます。

アプリ サンドボックスの実装の準備

この記事で詳しく説明するアプリ サンドボックスの要素は次のとおりです。

  • コンテナー ディレクトリ
  • 権利
  • ユーザーが決定したアクセス許可
  • 特権の分離
  • カーネルの適用

これらの詳細を理解したら、Xamarin.Mac アプリケーションでアプリ サンドボックスを導入するための計画を作成できます。

まず、アプリケーションがサンドボックス化に適しているかどうかを判断する必要があります (ほとんどのアプリケーションは適しています)。 次に、API の非互換性を解決し、必要なアプリ サンドボックスの要素を決定する必要があります。 最後に、特権の分離を使用して、アプリケーションの防御レベルを最大化することを確認します。

アプリ サンドボックスを採用する場合、アプリケーションで使用されるファイル システムの場所が異なります。 特に、アプリケーションには、アプリケーション サポート ファイル、データベース、キャッシュ、およびユーザー ドキュメントではないその他のファイルに使用されるコンテナー ディレクトリがあります。 macOS と Xcode はどちらも、これらの種類のファイルを従来の場所からコンテナーに移行するためのサポートを提供します。

サンドボックスのクイック スタート

このセクションでは、アプリ サンドボックスの使用を開始する例として、Web ビュー (特に要求されていない限り、サンドボックスで制限されているネットワーク接続が必要) を使用する単純な Xamarin.Mac アプリを作成します。

アプリケーションが実際にサンドボックス化されていることを確認し、一般的なアプリ サンドボックス エラーのトラブルシューティングと解決方法について説明します。

Xamarin.Mac プロジェクトの作成

サンプル プロジェクトを作成するには、次の手順を実行します。

  1. Visual Studio for Mac を起動し、[新しいソリューション]リンククリックします。

  2. [新しいプロジェクト] ダイアログ ボックスで、Mac>App>Cocoa App を選択します。

    Creating a new Cocoa App

  3. [次へ] ボタンをクリックし、プロジェクト名を入力MacSandboxし、[作成] ボタンをクリックします。

    Entering the app name

  4. Solution Pad で Main.storyboard ファイルをダブルクリックし、Xcode で編集するために開きます。

    Editing the main storyboard

  5. Web ビューウィンドウにドラッグし、コンテンツ領域に合わせてサイズを変更し、ウィンドウで拡大および縮小するように設定します。

    Adding a web view

  6. 次の Web webViewビューのアウトレットを作成します。

    Creating a new outlet

  7. Visual Studio for Mac に戻り、Solution Pad のViewController.cs ファイルをダブルクリックして、編集用に開きます。

  8. 次の using ステートメントを追加します。 using WebKit;

  9. メソッドを ViewDidLoad 次のようにします。

    public override void AwakeFromNib ()
    {
        base.AwakeFromNib ();
        webView.MainFrame.LoadRequest(new NSUrlRequest(new NSUrl("http://www.apple.com")));
    }
    
  10. 変更を保存します。

アプリケーションを実行し、Apple Web サイトが次のようにウィンドウに表示されていることを確認します。

Showing an example app run

アプリの署名とプロビジョニング

アプリ サンドボックスを有効にする前に、まず Xamarin.Mac アプリケーションをプロビジョニングして署名する必要があります。

次の操作を行います。

  1. Apple 開発者ポータルにログインします。

    Logging into the Apple Developer Portal

  2. [証明書]、[識別子]、[プロファイル] の順に選択します。

    Selecting Certificates, Identifiers & Profiles

  3. [ Mac アプリ] で、[識別子] を選択 します

    Selecting Identifiers

  4. アプリケーションの新しい ID を作成します。

    Creating a new App ID

  5. [プロビジョニング プロファイル] で、[開発] を選択します

    Selecting Development

  6. 新しいプロファイルを作成し、[Mac アプリ開発] を選択します。

    Creating a new profile

  7. 上記で作成したアプリ ID を選択します。

    Selecting the App ID

  8. このプロファイルの開発者を選択します。

    Adding developers

  9. このプロファイルのコンピューターを選択します。

    Selecting the allowed computers

  10. プロファイルに名前を付けます。

    Giving the profile a name

  11. [完了] ボタンをクリックします。

重要

場合によっては、Apple の開発者ポータルから新しいプロビジョニング プロファイルを直接ダウンロードし、それをダブルクリックしてインストールする必要がある場合があります。 新しいプロファイルにアクセスする前に、Visual Studio for Mac を停止して再起動することが必要になる場合もあります。

次に、開発用コンピューターに新しいアプリ ID とプロファイルを読み込む必要があります。 次の操作を行います。

  1. Xcode を起動し、[Xcode] メニューから [Preferences] を選択します。

    Editing accounts in Xcode

  2. [詳細の表示]... ボタンをクリックします。

    Clicking the View Details button

  3. (左下隅にある ) [更新 ] ボタンをクリックします。

  4. [完了] ボタンをクリックします。

次に、Xamarin.Mac プロジェクトで新しいアプリ ID とプロビジョニング プロファイルを選択する必要があります。 次の操作を行います。

  1. Solution Pad で Info.plist ファイルをダブルクリックして、編集用に開きます。

  2. バンドル識別子が、上記で作成したアプリ ID と一致していることを確認します (例: com.appracatappra.MacSandbox

    Editing the Bundle Identifier

  3. 次に、Entitlements.plist ファイルをダブルクリックし、iCloud Key-Value StoreiCloud コンテナーがすべて、上記で作成したアプリ ID と一致していることを確認します (例: com.appracatappra.MacSandbox

    Editing the Entitlements.plist file

  4. 変更を保存します。

  5. ソリューション パッド、プロジェクト ファイルをダブルクリックして、編集用のオプションを開きます。

    Editign the solution's options

  6. [Mac 署名] を選択し、[アプリケーション バンドルに署名] をチェックしてインストーラー パッケージに署名します。 [ プロビジョニング プロファイル] で、上記で作成したプロファイルを選択します。

    Setting the provisioning profile

  7. [完了] ボタンをクリックします。

重要

Xcode によってインストールされた新しいアプリ ID とプロビジョニング プロファイルを認識するには、Visual Studio for Mac を終了して再起動する必要がある場合があります。

プロビジョニングに関する問題のトラブルシューティング

この時点で、アプリケーションを実行し、すべてが正しく署名され、プロビジョニングされていることを確認する必要があります。 アプリが以前と同じように実行されている場合は、すべて問題ありません。 エラーが発生した場合は、次のようなダイアログ ボックスが表示されることがあります。

An example provisioning issue dialog

プロビジョニングと署名の問題の最も一般的な原因を次に示します。

  • アプリ バンドル ID が、選択したプロファイルのアプリ ID と一致しません。
  • 開発者 ID が、選択したプロファイルの開発者 ID と一致しません。
  • テスト対象の Mac の UUID は、選択したプロファイルの一部として登録されていません。

問題が発生した場合は、Apple 開発者ポータルで問題を修正し、Xcode でプロファイルを更新し、Visual Studio for Mac で クリーン ビルドを実行します。

アプリ サンドボックスを有効にする

アプリ サンドボックスを有効にするには、プロジェクト オプションでチェックボックスを選択します。 次の操作を行います。

  1. Solution Pad で Entitlements.plist ファイルをダブルクリックして、編集用に開きます。

  2. [エンタイトルメントを有効にする] と [アプリのサンドボックスを有効にする] の両方確認します。

    Editing entitlements and enabling sandboxing

  3. 変更を保存します。

この時点で、アプリ サンドボックスを有効にしましたが、Web ビューに必要なネットワーク アクセスを提供していません。 ここでアプリケーションを実行すると、空のウィンドウが表示されます。

Showing the web access being blocked

アプリがサンドボックス化されていることを確認する

リソースのブロック動作とは別に、Xamarin.Mac アプリケーションが正常にサンドボックス化されたかどうかを確認する 3 つのメイン方法があります。

  1. Finder で、フォルダーの~/Library/Containers/内容をチェックします。アプリがサンドボックス化されている場合は、アプリのバンドル識別子のような名前のフォルダーがあります (例: com.appracatappra.MacSandbox

    Opening the app's bundle

  2. システムでは、アクティビティ モニターでアプリがサンドボックスとして表示されます。

    • アクティビティ モニターを起動します (下 /Applications/Utilities)。
    • [列の表示>] を選択し、[サンドボックス] メニュー項目がチェックされていることを確認します。
    • アプリケーションの [サンドボックス] 列が読み取 Yes られるようにします。

    Checking the app in the Activity Monitor

  3. アプリ バイナリがサンドボックス化されていることを確認します。

    • ターミナル アプリを起動します。
    • applications bin ディレクトリに移動します。
    • 次のコマンドを発行します codesign -dvvv --entitlements :- executable_path (アプリケーションへのパスは次 executable_path のとおりです)。

    Checking the app on the command line

サンドボックス アプリのデバッグ

デバッガーは TCP 経由で Xamarin.Mac アプリに接続します。つまり、既定ではサンドボックスを有効にするとアプリに接続できないため、適切なアクセス許可を有効にせずにアプリを実行しようとすると、"デバッガーに接続できません" というエラーが表示されます。

Setting the required options

[ 発信ネットワーク接続を許可する (クライアント)] アクセス許可はデバッガーに必要なアクセス許可であり、これを有効にすると通常どおりデバッグできます。 それなしではデバッグできないため、デバッグ ビルド専用のサンドボックス化されたアプリのエンタイトルメントにそのアクセス許可を自動的に追加するようにターゲットmsbuildを更新CompileEntitlementsしました。 リリース ビルドでは、変更されていないエンタイトルメント ファイルで指定されたエンタイトルメントを使用する必要があります。

アプリ サンドボックス違反の解決

アプリ サンドボックス違反は、サンドボックス化された Xamarin.Mac アプリケーションが、明示的に許可されていないリソースにアクセスしようとした場合に発生します。 たとえば、Web ビューでは Apple Web サイトを表示できなくなりました。

アプリ サンドボックス違反の最も一般的な原因は、Visual Studio for Mac で指定されたエンタイトルメント設定がアプリケーションの要件と一致しない場合に発生します。 ここでも、この例に戻ると、Web ビューが機能し続けるネットワーク接続の権利がありません。

アプリ サンドボックス違反の検出

Xamarin.Mac アプリケーションでアプリ サンドボックス違反が発生していると思われる場合、問題を検出する最も簡単な方法は、コンソール アプリを使用することです。

次の操作を行います。

  1. 問題のアプリをコンパイルし、Visual Studio for Mac から実行します。

  2. コンソール アプリケーション (from/Applications/Utilties/) を開きます。

  3. サイドバーで[すべてのメッセージ]を選択し、検索に入力sandboxします。

    An example of a sandboxing issue in the console

上記のアプリの例では、Kernal がその権利を network-outbound 要求していないため、アプリ サンドボックスのためにトラフィックをブロックしていることがわかります。

権利を使用したアプリ サンドボックス違反の修正

これで、アプリサンドボックス違反を見つける方法を見つけたので、アプリケーションの権利を調整することでどのように解決できるかを見てみましょう。

次の操作を行います。

  1. Solution Pad で Entitlements.plist ファイルをダブルクリックして、編集用に開きます。

  2. [エンタイトルメント] セクションで、[発信ネットワーク接続を許可する (クライアント)] チェック ボックスをチェックします。

    Editing the entitlements

  3. 変更をアプリケーションに保存します。

サンプル アプリに対して上記の操作を行い、それをビルドして実行すると、Web コンテンツが期待どおりに表示されるようになります。

アプリ サンドボックスの詳細

アプリ サンドボックスによって提供されるアクセス制御メカニズムは、ほとんどなく、理解しやすいです。 ただし、アプリサンドボックスが各アプリで採用される方法は、アプリの要件に基づいて一意です。

Xamarin.Mac アプリケーションが悪意のあるコードによって悪用されるのを防ぎ、アプリ (または使用するライブラリまたはフレームワークのいずれか) に脆弱性が 1 つだけ存在し、アプリとシステムとの対話を制御する必要があります。

アプリ サンドボックスは、アプリケーションの意図したシステムとの対話を指定できるようにすることで、引き継ぎを防ぐ (または引き起こす可能性のある損害を制限する) よう設計されています。 システムは、アプリケーションがジョブを完了するために必要なリソースへのアクセスのみを許可し、それ以上のアクセス権を付与しません。

アプリ サンドボックス用に設計する場合は、最悪のシナリオを想定して設計します。 アプリケーションが悪意のあるコードによって侵害された場合、アプリのサンドボックス内のファイルとリソースにのみアクセスすることに限定されます。

エンタイトルメントとシステム リソース アクセス

前述のように、サンドボックス化されていない Xamarin.Mac アプリケーションには、アプリを実行しているユーザーの完全な権限とアクセス権が付与されます。 悪意のあるコードによって侵害された場合、保護されていないアプリは敵対的な動作のエージェントとして機能し、損害を与える可能性は広範囲に及びます。

アプリ サンドボックスを有効にすると、最小限の特権セットを除くすべての権限が削除されます。その後、Xamarin.Mac アプリの権利を使用して、必要に応じて再度有効にします。

アプリケーションの App Sandbox リソースを変更するには、Entitlements.plist ファイルを編集し、エディターのドロップダウン ボックスから必要な権限をチェックまたは選択します。

Editing the entitlements

コンテナー ディレクトリとファイル システム アクセス

Xamarin.Mac アプリケーションがアプリ サンドボックスを採用すると、次の場所にアクセスできます。

  • アプリ コンテナー ディレクトリ - 最初の実行時に、OS は、すべてのリソースがアクセスできる特別な コンテナー ディレクトリを作成します 。 アプリには、このディレクトリへの完全な読み取り/書き込みアクセス権が付与されます。
  • アプリ グループ コンテナー ディレクトリ - 同じグループ内のアプリ間で共有される 1 つ以上 のグループ コンテナー へのアクセス権をアプリに付与できます。
  • ユーザー指定のファイル - アプリケーションは、ユーザーが明示的に開いたりドラッグ アンド ドロップしたりしたファイルへのアクセスを自動的に取得します。
  • 関連項目 - 適切な権利を持つアプリケーションは、同じ名前で拡張子が異なるファイルにアクセスできます。 たとえば、 .txt ファイルと .pdf.
  • 一時ディレクトリ、コマンド ライン ツール ディレクトリ、および世界で読み取り可能な特定の場所 - アプリは、システムで指定されている他の適切に定義された場所にあるファイルにさまざまな程度アクセスできます。

アプリ コンテナー ディレクトリ

Xamarin.Mac アプリケーションの App Container Directory には、次の特性があります。

  • これはユーザーのホーム ディレクトリ (通常 ~Library/Containers) 内の非表示の場所にあり、アプリケーション内の NSHomeDirectory 関数 (下記参照) を使用してアクセスできます。 ホーム ディレクトリ内にあるため、各ユーザーはアプリ用の独自のコンテナーを取得します。
  • アプリには、コンテナー ディレクトリとその中のすべてのサブディレクトリとファイルへの無制限の読み取り/書き込みアクセス権があります。
  • macOS のパス検索 API のほとんどは、アプリのコンテナーに対して相対的です。 たとえば、コンテナーには独自のライブラリ (経由でNSLibraryDirectoryアクセス)、Application Support、Preferences サブディレクトリがあります。
  • macOS は、コード署名を使用して、アプリとそのコンテナー間の接続を確立し、適用します。 別のアプリがバンドル識別子を使用してアプリのスプーフィングを試みる場合でも、コード署名のためにコンテナーにアクセスできなくなります。
  • コンテナーは、ユーザーが生成したファイル用ではありません。 代わりに、データベース、キャッシュ、その他の特定の種類のデータなど、アプリケーションで使用されるファイル用です。
  • 靴箱の種類のアプリ (Apple の写真アプリなど) の場合、ユーザーのコンテンツはコンテナーに入ります。

重要

残念ながら、Xamarin.Mac には (Xamarin.iOS とは異なり) NSHomeDirectory まだ 100% の API カバレッジがないため、API は Xamarin.Mac の現在のバージョンでマップされていません。

一時的な回避策として、次のコードを使用できます。

[System.Runtime.InteropServices.DllImport("/System/Library/Frameworks/Foundation.framework/Foundation")]
public static extern IntPtr NSHomeDirectory();

public static string ContainerDirectory {
    get {
        return ((NSString)ObjCRuntime.Runtime.GetNSObject(NSHomeDirectory())).ToString ();
        }
}

アプリ グループ コンテナー ディレクトリ

Mac macOS 10.7.5 以降では、アプリケーションは権利を com.apple.security.application-groups 使用して、グループ内のすべてのアプリケーションに共通する共有コンテナーにアクセスできます。 この共有コンテナーは、データベースや他の種類のサポート ファイル (キャッシュなど) などのユーザー向けではないコンテンツに使用できます。

グループ コンテナーは、各アプリのサンドボックス コンテナー (グループの一部である場合) に自動的に追加され、次の位置に ~/Library/Group Containers/<application-group-id>格納されます。 グループ ID は、開発チーム ID と期間で始まる必要があります 。次に例を示します。

<team-id>.com.company.<group-name>

詳細については、「エンタイトルメント キー リファレンス」の「アプリケーション グループへのアプリケーションの追加」を参照してください

アプリ コンテナーの外部にある Powerbox とファイル システムへのアクセス

サンドボックス化された Xamarin.Mac アプリケーションは、次の方法でコンテナーの外部にあるファイル システムの場所にアクセスできます。

  • ユーザーの特定の方向に移動します (ダイアログを開いて保存するか、ドラッグ アンド ドロップなどのその他の方法を使用)。
  • 特定のファイル システムの場所 (または/usr/libなど/bin) に対して権利を使用する。
  • ファイル システムの場所が、世界で読み取り可能な特定のディレクトリ (共有など) にある場合。

Powerbox は、サンドボックス Xamarin.Mac アプリのファイル アクセス権を拡張するためにユーザーと対話する macOS セキュリティ テクノロジです。 Powerbox には API はありませんが、アプリが呼び出 NSOpenPanel すときに NSSavePanel透過的にアクティブ化されます。 Powerbox アクセスは、Xamarin.Mac アプリケーションに設定したエンタイトルメントを使用して有効になります。

サンドボックス アプリに [開く] または [保存] ダイアログが表示されると、ウィンドウは Powerbox (AppKit ではなく) によって表示されるため、ユーザーがアクセスできるファイルまたはディレクトリにアクセスできます。

ユーザーが [開く] または [保存] ダイアログからファイルまたはディレクトリを選択 (またはアプリのアイコンにドラッグ) すると、Powerbox はアプリのサンドボックスに関連付けられたパスを追加します。

さらに、システムは、サンドボックス アプリに対して以下を自動的に許可します。

  • システム入力メソッドへの接続。
  • [サービス] メニューからユーザーが選択したサービスを呼び出します (サービス プロバイダーによってサンドボックス アプリに対して安全としてマークされたサービスの場合のみ)。
  • [最近使ったファイルを開く] メニューからユーザーが選択したファイルを開きます。
  • 他のアプリケーション間でコピーと貼り付けを使用します。
  • 次の世界で読み取り可能な場所からファイルを読み取ります。
    • /bin
    • /sbin
    • /usr/bin
    • /usr/lib
    • /usr/sbin
    • /usr/share
    • /System
  • によって NSTemporaryDirectory作成されたディレクトリ内のファイルの読み取りと書き込み。

既定では、サンドボックス Xamarin.Mac アプリによって開かれたファイルまたは保存されたファイルはメインアプリが終了するまでアクセスできます (アプリの終了時にファイルがまだ開かれていた場合を除く)。 開いているファイルは、次にアプリを起動したときに、macOS Resume 機能を使用してアプリのサンドボックスに自動的に復元されます。

Xamarin.Mac アプリのコンテナーの外部にあるファイルに永続化を提供するには、セキュリティ スコープブックマーク (下記参照) を使用します。

アプリ サンドボックスを使用すると、同じファイル名を持ち、拡張子が異なる関連アイテムにアプリがアクセスできます。 この機能には、a) アプリ Info.plst のファイル内の関連する拡張機能の一覧、b) アプリがこれらのファイルで何を行うかをサンドボックスに伝えるコードという 2 つの部分があります。

これが理にかなっているシナリオは 2 つあります。

  1. アプリは、(新しい拡張子を持つ) 別のバージョンのファイルを保存できる必要があります。 たとえば、ファイルを .txt ファイルにエクスポートします .pdf 。 この状況を処理するには、a NSFileCoordinator を使用してファイルにアクセスする必要があります。 最初にメソッドを WillMove(fromURL, toURL) 呼び出し、ファイルを新しい拡張機能に移動してから呼び出 ItemMoved(fromURL, toURL)します。
  2. アプリは、1つの拡張子を持つメインファイルと異なる拡張子を持つ複数のサポートファイルを開く必要があります。 たとえば、ムービーファイルやサブタイトルファイルなどです。 an を NSFilePresenter 使用して、セカンダリ ファイルにアクセスします。 メイン ファイルをプロパティにPrimaryPresentedItemURL、セカンダリ ファイルをプロパティにPresentedItemURL指定します。 メイン ファイルを開いたら、クラスのメソッドをAddFilePresenterNSFileCoordinator呼び出してセカンダリ ファイルを登録します。

どちらのシナリオでも、アプリの Info.plist ファイルで、アプリが開くことができるドキュメントの種類を宣言する必要があります。 任意のファイルの種類の場合は、配列内の NSIsRelatedItemType エントリに (値を YES持つ) を CFBundleDocumentTypes 追加します。

サンドボックス アプリを使用してダイアログの動作を開いて保存する

次の制限は、サンドボックス Xamarin.Mac アプリから呼び出すときとNSSavePanel呼び出すときに適用NSOpenPanelされます。

  • プログラムで [OK] ボタンを呼び出すことはできません。
  • でユーザーの選択内容をプログラムで NSOpenSavePanelDelegate変更することはできません。

さらに、次の継承の変更が行われます。

  • セキュリティで保護されていないアプリ - NSOpenPanelNSSavePanel``NSPanel``NSWindow``NSResponder``NSObject``NSOpenPanel``NSSavePanel``NSObject``NSOpenPanel``NSSavePanel

セキュリティ スコープのブックマークと永続的なリソース アクセス

前述のように、サンドボックス Xamarin.Mac アプリケーションは、(PowerBox によって提供される) 直接ユーザー操作を使用して、コンテナーの外部にあるファイルまたはリソースにアクセスできます。 ただし、これらのリソースへのアクセスは、アプリの起動またはシステムの再起動間で自動的に保持されることはありません。

セキュリティ スコープのブックマークを使用すると、サンドボックス Xamarin.Mac アプリケーションはユーザーの意図を保持し、アプリの再起動後に特定のリソースへのアクセスを保持メイン。

セキュリティ スコープのブックマークの種類

セキュリティ スコープのブックマークと永続的なリソース アクセスを使用する場合、次の 2 つのユース ケースがあります。

  • アプリ スコープブックマークは、ユーザー指定のファイルまたはフォルダーへの永続的なアクセスを提供します。

    たとえば、サンドボックス化された Xamarin.Mac アプリケーションで編集用の外部ドキュメントを開くことを許可している場合、 NSOpenPanelアプリはアプリ スコープブックマークを作成して、今後同じファイルに再度アクセスできるようにします。

  • ドキュメント スコープブックマークは、サブファイルへの特定のドキュメント永続的アクセスを提供します。

たとえば、後で 1 つのムービーに結合される個々の画像、ビデオ クリップ、サウンド ファイルにアクセスできるプロジェクト ファイルを作成するビデオ編集アプリです。

ユーザーが (a を介して NSOpenPanel) リソース ファイルをプロジェクトにインポートすると、アプリはプロジェクトに格納されているアイテムのドキュメント スコープブックマークを作成し、ファイルに常にアクセスできるようにします。

ドキュメント スコープのブックマークは、ブックマーク データとドキュメント自体を開くことができる任意のアプリケーションで解決できます。 これにより、移植性がサポートされ、ユーザーはプロジェクト ファイルを別のユーザーに送信でき、すべてのブックマークも機能します。

重要

ドキュメント スコープのブックマークは、フォルダーではなく 1 つのファイルのみを指すことができます。また、そのファイルはシステムで使用される場所 (たとえば/Library/private

セキュリティ スコープのブックマークの使用

いずれかの種類のセキュリティ スコープ ブックマークを使用するには、次の手順を実行する必要があります。

  1. セキュリティ スコープのブックマークを使用する必要がある Xamarin.Mac アプリで適切な権利を設定する - アプリ スコープブックマーク の場合は、エンタイトルメント キーを com.apple.security.files.bookmarks.app-scopetrue設定します。 ドキュメント スコープのブックマークの場合、エンタイトルメント キーを com.apple.security.files.bookmarks.document-scope > に true設定します。
  2. セキュリティ スコープのブックマーク を作成する - ユーザーがアクセス権を付与した (たとえば)、アプリに永続的なアクセス権が必要なファイルまたはフォルダーに対して NSOpenPanel これを行います。 クラスの public virtual NSData CreateBookmarkData (NSUrlBookmarkCreationOptions options, string[] resourceValues, NSUrl relativeUrl, out NSError error) メソッドを NSUrl 使用してブックマークを作成します。
  3. セキュリティ スコープのブックマーク を解決する - アプリがリソースに再度アクセスする必要がある場合 (再起動後など)、ブックマークをセキュリティ スコープの URL に解決する必要があります。 クラスのメソッドをpublic static NSUrl FromBookmarkData (NSData data, NSUrlBookmarkResolutionOptions options, NSUrl relativeToUrl, out bool isStale, out NSError error)NSUrl使用してブックマークを解決します。
  4. セキュリティ スコープ URL からファイルにアクセスすることをシステムに明示的に通知します。この手順は、上記のセキュリティ スコープ URL を取得した直後、またはリソースへのアクセスを放棄した後でリソースへのアクセスを回復する場合に実行する必要があります。 クラスの StartAccessingSecurityScopedResource () メソッドを NSUrl 呼び出して、セキュリティ スコープ URL へのアクセスを開始します。
  5. セキュリティ スコープ URL からファイルへのアクセスが完了したことをシステムに明示的に通知します。できるだけ早く、アプリがファイルにアクセスする必要がなくなったときにシステムに通知する必要があります (ユーザーがファイルを閉じた場合など)。 クラスのメソッドをStopAccessingSecurityScopedResource ()NSUrl呼び出して、セキュリティ スコープ URL へのアクセスを停止します。

リソースへのアクセスを放棄したら、もう一度手順 4 に戻ってアクセスを再確立する必要があります。 Xamarin.Mac アプリが再起動された場合は、手順 3 に戻り、ブックマークを再解決する必要があります。

重要

セキュリティ スコープ URL リソースへのアクセスを解放できないと、Xamarin.Mac アプリがカーネル リソースをリークします。 その結果、アプリは再起動されるまで、コンテナーにファイル システムの場所を追加できなくなります。

アプリ サンドボックスとコード署名

アプリ サンドボックスを有効にし、Xamarin.Mac アプリの特定の要件を有効にした後 (エンタイトルメントを介して)、サンドボックスを有効にするにはプロジェクトにコード署名する必要があります。 アプリサンドボックスに必要なエンタイトルメントがアプリの署名にリンクされているため、コード署名を実行する必要があります。

macOS では、アプリのコンテナーとそのコード署名の間にリンクが適用されます。この方法では、アプリバンドル ID をスプーフィングしている場合でも、他のアプリケーションがそのコンテナーにアクセスすることはできません。 このメカニズムは次のように機能します。

  1. システムは、アプリのコンテナーを作成するときに、そのコンテナーに アクセス制御リスト (ACL) を設定します。 一覧の最初のアクセス制御エントリには、アプリの 指定された要件 (DR) が含まれています。アプリの将来のバージョンを認識する方法 (アップグレードされたとき) について説明します。
  2. 同じバンドル ID を持つアプリが起動するたびに、システムは、アプリのコード署名がコンテナーの ACL のエントリのいずれかで指定された指定された要件と一致することをチェックします。 システムが一致するものを見つけられない場合は、アプリの起動を妨げます。

コード署名は次の方法で動作します。

  1. Xamarin.Mac プロジェクトを作成する前に、Apple 開発者ポータルから開発証明書、配布証明書、および開発者 ID 証明書を取得します。
  2. Mac App Store が Xamarin.Mac アプリを配布すると、Apple コード署名で署名されます。

テストとデバッグを行うときは、署名した Xamarin.Mac アプリケーションのバージョンを使用します (これはアプリ コンテナーの作成に使用されます)。 後で、Apple App Store からバージョンをテストまたはインストールする場合、そのバージョンは Apple 署名で署名され、起動に失敗します (元のアプリ コンテナーと同じコード署名がないため)。 この状況では、次のようなクラッシュ レポートが表示されます。

Exception Type:  EXC_BAD_INSTRUCTION (SIGILL)

これを修正するには、アプリの Apple 署名付きバージョンを指す ACL エントリを調整する必要があります。

サンドボックス化に必要なプロビジョニング プロファイルの作成とダウンロードの詳細については、上記の「アプリ署名とプロビジョニング」セクションを参照してください。

ACL エントリの調整

Xamarin.Mac アプリの Apple 署名済みバージョンの実行を許可するには、次の操作を行います。

  1. ターミナル アプリ (in /Applications/Utilities) を開きます。
  2. Xamarin.Mac アプリの Apple 署名済みバージョンの Finder ウィンドウを開きます。
  3. ターミナル ウィンドウに入力 asctl container acl add -file します。
  4. Xamarin.Mac アプリのアイコンを Finder ウィンドウからドラッグし、[ターミナル] ウィンドウにドロップします。
  5. ファイルへの完全なパスがターミナルのコマンドに追加されます。
  6. Enter キーを押してコマンドを実行します。

コンテナーの ACL に、Xamarin.Mac アプリと macOS の両方のバージョンで指定されたコード要件が含まれるようになり、どちらのバージョンの実行も許可されるようになりました。

ACL コード要件の一覧を表示する

次の手順を実行して、コンテナーの ACL のコード要件の一覧を表示できます。

  1. ターミナル アプリ (in /Applications/Utilities) を開きます。
  2. asctl container acl list -bundle <container-name>」と入力します。
  3. Enter キーを押してコマンドを実行します。

<container-name>通常は、Xamarin.Mac アプリケーションのバンドル識別子です。

アプリ サンドボックス用の Xamarin.Mac アプリの設計

アプリ サンドボックス用の Xamarin.Mac アプリを設計するときは、一般的なワークフローに従う必要があります。 つまり、アプリにサンドボックスを実装する詳細は、特定のアプリの機能に固有になります。

アプリ サンドボックスを採用するための 6 つの手順

アプリ サンドボックス用の Xamarin.Mac アプリの設計は、通常、次の手順で構成されます。

  1. アプリがサンドボックスに適しているかどうかを判断します。
  2. 開発と配布の戦略を設計する。
  3. API の非互換性を解決します。
  4. 必要なアプリ サンドボックスエンタイトルメントを Xamarin.Mac プロジェクトに適用します。
  5. XPC を使用して特権の分離を追加します。
  6. 移行戦略を実装します。

重要

アプリ バンドル内の メイン 実行可能ファイルをサンドボックス化するだけでなく、そのバンドルに含まれるすべてのヘルパー アプリまたはツールもサンドボックス化する必要があります。 これは、Mac App Store から配布されるすべてのアプリに必要であり、可能であれば、他の形式のアプリ配布に対して行う必要があります。

Xamarin.Mac アプリのバンドル内のすべての実行可能バイナリの一覧については、ターミナルで次のコマンドを入力します。

find -H [Your-App-Bundle].app -print0 | xargs -0 file | grep "Mach-O .*executable"

アプリケーションのバンドルの名前とパスを指定 [Your-App-Bundle] します。

Xamarin.Mac アプリがサンドボックスに適しているかどうかを判断する

ほとんどの Xamarin.Mac アプリはアプリ サンドボックスと完全に互換性があるため、サンドボックスに適しています。 アプリサンドボックスで許可されていない動作がアプリに必要な場合は、別の方法を検討する必要があります。

アプリで次のいずれかの動作が必要な場合、アプリ サンドボックスと互換性がありません。

  • Authorization Services - アプリ サンドボックスでは、「Authorization Services C リファレンス」で説明されている関数を操作することはできません。
  • アクセシビリティ API - スクリーン リーダーなどの支援アプリや、他のアプリケーションを制御するアプリをサンドボックス化することはできません。
  • Apple イベントを任意のアプリ に送信する - アプリが不明な任意のアプリに Apple イベントを送信する必要がある場合は、サンドボックス化できません。 呼び出されたアプリの既知の一覧については、引き続きアプリをサンドボックス化できます。エンタイトルメントには、呼び出されたアプリの一覧を含める必要があります。
  • 分散通知のユーザー情報辞書を他のタスクに送信する - アプリ サンドボックスでは、他のタスクをメッセージングするためにオブジェクトにNSDistributedNotificationCenter投稿するときにディクショナリを含userInfoめることはできません。
  • カーネル拡張機能 の読み込み - カーネル拡張機能の読み込みは、アプリ サンドボックスで禁止されています。
  • [開く] ダイアログと [保存] ダイアログ でユーザー入力をシミュレートする - プログラムによって開くダイアログまたは保存ダイアログを操作して、ユーザー入力をシミュレートまたは変更することは、アプリ サンドボックスでは禁止されています。
  • 他のアプリの環境設定へのアクセスまたは設定 - 他のアプリ の設定を操作することは、アプリサンドボックスでは禁止されています。
  • ネットワーク 設定の構成 - ネットワーク 設定の操作は、アプリ サンドボックスでは禁止されています。
  • 他のアプリ の終了 - アプリ サンドボックスでは、他のアプリの終了を禁止 NSRunningApplication します。

API の非互換性の解決

アプリ サンドボックス用の Xamarin.Mac アプリを設計するときに、一部の macOS API の使用に非互換性が発生する可能性があります。

いくつかの一般的な問題とその解決方法を次に示します。

  • ドキュメント を開く、保存する、追跡する - 以外 NSDocumentのテクノロジを使用してドキュメントを管理する場合は、アプリ サンドボックスのサポートが組み込まれているため、ドキュメントに切り替える必要があります。 NSDocument は自動的に PowerBox と連携し、ユーザーが Finder でドキュメントを移動した場合にサンドボックス内にドキュメントを保持するためのサポートを提供します。
  • ファイル システム リソースへのアクセスを保持する - Xamarin.Mac アプリがコンテナー外のリソースへの永続的なアクセスに依存している場合は、セキュリティ スコープのブックマークを使用してアクセスメイン保持します。
  • アプリ のログイン 項目を作成する - アプリ サンドボックスでは、起動サービスの状態を使用してログイン 項目を LSSharedFileList 作成したり、起動サービスの状態を LSRegisterURL操作したりすることはできません。 「Service Management FrameworkSMLoginItemSetEnabled使用したログイン項目の追加」の説明に従って、この関数を使用します。
  • ユーザー データ へのアクセス - ディレクトリ サービスからユーザーのホーム ディレクトリを取得するなどの getpwuid POSIX 関数を使用している場合は、Cocoa や Core Foundation などの NSHomeDirectoryシンボルを使用することを検討してください。
  • 他のアプリ の基本設定へのアクセス - アプリ サンドボックスはパス検索 API をアプリのコンテナーに転送するため、そのコンテナー内で基本設定を変更し、別のアプリの基本設定にアクセスすることは許可されません。
  • Web ビュー での HTML5 埋め込みビデオの使用 - Xamarin.Mac アプリで WebKit を使用して埋め込み HTML5 ビデオを再生する場合は、AV Foundation フレームワークに対してアプリをリンクする必要もあります。 アプリ サンドボックスは、CoreMedia がこれらのビデオを再生できないようにします。

必要なアプリ サンドボックスエンタイトルメントの適用

アプリ サンドボックスで実行する Xamarin.Mac アプリケーションのエンタイトルメントを編集し、[アプリサンドボックスの有効化] チェックボックスをチェックする必要があります。

アプリの機能に基づいて、OS の機能やリソースにアクセスするために他の権利を有効にする必要がある場合があります。 アプリのサンドボックス化は、アプリの実行に必要な最小限の権利に要求する権利を最小限に抑える場合に最適に機能するため、エンタイトルメントをランダムに有効にするだけです。

Xamarin.Mac アプリに必要なエンタイトルメントを特定するには、次の操作を行います。

  1. アプリ サンドボックスを有効にして、Xamarin.Mac アプリを実行します。
  2. アプリの機能を実行します。
  3. コンソール アプリ (使用可能) /Applications/Utilitiesを開き、[すべてのメッセージ] ログで違反をsandboxdします。
  4. 違反ごとに sandboxd 、他のファイル システムの場所ではなくアプリ コンテナーを使用して問題を解決するか、アプリ サンドボックスの権利を適用して制限付き OS 機能へのアクセスを有効にします。
  5. Xamarin.Mac アプリのすべての機能をもう一度再実行してテストします。
  6. すべての sandboxd 違反が解決されるまで繰り返します。

XPC を使用して特権の分離を追加する

アプリ サンドボックス用の Xamarin.Mac アプリを開発する場合は、特権とアクセスの観点からアプリの動作を確認し、リスクの高い操作を独自の XPC サービスに分離することを検討してください。

詳細については、「Apple の XPC サービスおよびデーモンおよびサービスの作成プログラミング ガイド」を参照してください。

移行戦略を実装する

以前サンドボックス化されていない Xamarin.Mac アプリケーションの新しいサンドボックス バージョンをリリースする場合は、現在のユーザーがスムーズなアップグレード パスを持っていることを確認する必要があります。

コンテナー移行マニフェストを実装する方法の詳細については、Apple のサンドボックスへのアプリの移行に関するドキュメントを参照してください。

まとめ

この記事では、Xamarin.Mac アプリケーションのサンドボックス化について詳しく説明しました。 まず、単純な Xamarin.Mac アプリを作成して、アプリ サンドボックスの基本を示しました。 次に、サンドボックス違反を解決する方法を示しました。 次に、アプリ サンドボックスを詳しく見て、最後に、アプリ サンドボックス用の Xamarin.Mac アプリの設計について説明しました。