Archive for the 'サンドボックス(Sandbox)' Category

2014/05/14 ASOCのアプリをSandbox対応に(Sandbox初心者編)

AppleScriptのアプリケーションをMac App Storeで販売するためには、Xcode上でAppleScriptObjCでプログラムを開発する必要があります。

AppleScriptObjCのプログラムを組むだけであれば、徐々にノウハウもたまってきていますが、2つほど関門があります。

1つは、Mac App Storeのアカウントを取得し、Code Signすること。2つ目は、アプリケーションをSandbox対応にすることです。

前者は単なる作業なので、Apple相手に担当者といろいろモメたとしても解決できないほど難しい問題ではありません。日本のAppleの担当者には非常によくしていただいた(感謝!)のですが、USの担当者とはなぜかケンカをしないと物事が前に進みません。これが、いわゆる開拓者精神というやつなのでしょうか?

sand4.png
▲開発者アカウントを取得してプロファイルをダウンロードするとシステム環境設定で「プロファイル」が有効になる

脱線しましたが……問題は、後者の「Sandbox対応」です。

sand0.png

XcodeプロジェクトのSandbox化設定

AppleScriptObjCのプロジェクトをSandbox化する「だけ」なら、それほど大それた設定が必要なわけではありません。Xcode 5.1.1上だと……Xcode上でプロジェクトの「TARGETS」を選択して、「App Sandbox」をオンにするだけです。

この作業を行うと、「○○.entitlements」ファイルがプロジェクトに追加されるので、必要に応じてこのファイルを編集するだけです。主に、entitlementsファイルの編集が難関というか、この先苦労するんだろうなぁというポイントです(まだ、Sandbox化については自前で調査し始めたところなので)。

コントロール対象のアプリを登録する2つの方法

AppleScriptObjCで作ったアプリをSandbox対応させるのは、前述のとおりXcode上の設定だけで済みます。

ただ、AppleScriptで作ったアプリケーションで「他のアプリケーションをコントロールしない」というケースは少ないものと思われます。そこは、いろんなアプリケーションをこづき回して叩きまくって仕事をさせることでしょう。それこそ、AppleScriptの醍醐味(サディスト味)。

脱線しますが……たとえば、InDesignをコントロールするにしても、JavaScriptからコントロールした場合にはInDesign自体のクラッシュを検知して立ち上げ直すとか、クラッシュからのリカバリを行うこと自体が無理です。AppleScriptなら、そこもすべて対応して夜間回しっぱなしの無人運転まで対応できます。複数のアプリをまたがってのコントロールも重要なポイントです。

話を元に戻しましょう。

WWDC2012のSessionの資料を確認するに、App Sandbox対応したアプリ中で他のアプリをコントロールする場合には、entitlementsファイル中にその旨を宣言する2つの方法があると説明されています。

(1)「com.apple.security.scripting-targets」エントリをentitlementsファイルの中に作成し、操作対象のアプリのオブジェクトとか命令とか属性値を細かく記述(できればやってね、と記載あり)

(2)「さもなければ」「com.apple.security.temporary-exception.apple-events」エントリをentitlementsファイル中に作成し、その中にコントロール対象のアプリケーションのBundle IDを記述

Mac App Storeで購入したアプリやらApple純正アプリやらをこじ開けて、参考になるようなentitlementsファイルがないか探してみたものの……見つかりません。つまり、「ありものを参考にする」という方法が(どういうわけか)とれないので、「とりあえず」ここは簡単な(2)でやってみるしかないでしょう。

ただ……将来的に(2)はすべて禁止で(1)しか受け付けない、という方向に移行したいんだろうなぁ、という意向はひしひしと感じます。

コントロール対象のアプリのBundle IDを登録

とりあえず、(1)のことは忘れて、「com.apple.security.temporary-exception.apple-events」エントリをentitlementsファイル中に作成することにしてみましょう。

sand2.png

なにげに、SafariのBundle IDが「com.apple.safari」ではなく「com.apple.Safari」だったりして引っかけ要素がないでもないですが、とりあえず登録しておけば大丈夫です。

entitlementsに登録していないアプリケーションにASOCプログラム中からコントロールしようとすると、「起動していない」とログにエラーが出力されます。

run scriptでテキストから生成・実行したScriptも監視対象?

Sandbox環境下のAppleScriptの挙動については素朴な疑問がいくつかあるわけですが、「動的にテキストから生成したAppleScriptを実行しても、監視対象になるのか?」というのが最初の疑問。

実際に試してみたら、「監視対象になる」ことが分りました。テキストから生成・実行するAppleScript内でコントロールするアプリケーションのbundle idをあらかじめ登録しておけば大丈夫です。ただ、事前に対象アプリケーションが分らないとか(choose applicationで選択)いう場合には……ダメだと思います。Bundle ID指定にワイルドカードは効かないでしょうから(後述)。

choose fileとかできるの?

ただ単にSandbox化しただけでは禁止されます。「App Sandbox」の「File Access:」で「User Selected File」を「Read Only」ないし「Read/Write」に設定すればchoose fileやchoose folderが有効になります。

Bundle内のAppleScriptをload scriptできるの?

AppleScriptObjCのプログラム内で外部のプログラムをコントロールする場合には、コントロール部分を別ファイルに分離して、AppleScriptObjCのプログラム内からload scriptで呼び出すのが安全です。AppleScriptObjCプログラム内では通常のAppleScriptの挙動が変わったり、エラーになるケースが多々あるためです(このあたりは、AppleScript Studioの時もそうでした)。

2013年10月の段階(OS X 10.9のリリースから間もない時期)では、サンドボックス化したAppleScriptObjCプログラム内でload scriptを行うとエラーになっていたようです(MacScripter.netの議論にそのような痕跡が残っています)。現在、OS X 10.9.2上でload scriptを行ってもエラーにはなりませんでした。

ただし、一応念のためにバンドル内に同梱する(Xcode Projectに追加する)AppleScriptについては、(AppleScriptエディタで)保存時にも念のためにCode Signし、保存形式も「実行専用」を指定し、保存後にFinder上で「読み出しのみ」にパーミッションを設定しておきました。

アクティビティモニタで見てもサンドボックス有効になっていないみたいだけど?

Sandboxの配下で動いているはずなのに、アクティビティモニタでプロセスを確認して見ても(画面上では)サンドボックス内で動作しているように見えない、というケースに多々遭遇しました。

sand1.png

かなり不思議に思っていたのですが、sandboxd(デーモン)(なりアクティビティモニタ)がアプリケーションの判定結果をキャッシュしている(普通、初回起動後にsandbox対応状態が変わるアプリなどないはず)ものと見て、entitlementsの内容をGUI側からいじくって項目を増やしてみた(無意味に「ピクチャ」フォルダへのアクセス権を付加したり)ところ、AppleScriptObjCプログラムをビルドして実行すると「サンドボックス=はい」に表示が変わりました。

追記1:choose applicationによる事前指定のない任意アプリの制御

テストのために、

  –choose applicationによるアプリの任意選択制御(多分だめ)
  tell current application
    set anApp to choose application
  end tell

  tell anApp to activate

というコードを書いてSandbox対応したAppleScriptObjCアプリの中で実行してみたら……

sandtest[31876:303] *** -[AppDelegate clicked:]: Adobe Photoshop CS3 got an error: Application isn’t running. (error -600)

と、コンソールにエラーは出るものの、操作対象として指定したアプリケーションが起動することはしますね。

追記2:Finder経由でBundle IDを指定してアプリケーションを起動

パスやアプリケーション名称を指定した場合には、Sandboxに阻まれて起動ができなかったりしますが、FinderにはBundle IDを指定して特定のデータを指定のアプリケーションでオープンするという(AppleScript向けの)機能があります。

つまり、事前に宣言していなくても……Finder(com.apple.finder)の制御についてentitlementsに記述しておけば、指定ファイルを任意のアプリケーションでオープンさせるとか……Finder経由でアプリケーションの起動だけならできてしまうのでは? という疑問を持って実験してみました。

  –Finder経由でアプリケーションのオープン
  tell application “Finder”
    open application file id “com.apple.addressbook”–「コンタクト」を起動
  end tell

……できます(^ー^; 予想どおり、できてしまいます。ただ、sandboxdが許してもMac App Storeへの申請が通るかどうかは定かではありません。

まだまだ苦難は続く

entitlementsファイルの記述については、前述のとおり、(2)の操作対象アプリケーションのBundle IDを書く方法とは別に、(1)の「com.apple.security.scripting-targets」エントリを作成して、アプリケーション内のオブジェクトやら命令やらを書く、という(よりまっとうな)やり方があり、もしかしたらMac App Storeへの申請時に(1)を求められる可能性もあります。

ただ、いろいろ調べてみた上で書きますが、「ちょっと無理じゃないの?」というのが(1)についての正直な感想です。

最初に、WWDCのビデオを見たときに感じたのは「じゃあ、GUI Scriptingで動的にGUI elementを検出してコントロールするような場合には全滅じゃないか!」(事前にすべて調査して書いておくなんて無理?)ということでした。

昨今の動向としては明らかに「有用性」よりも「セキュリティ」にAppleの重視するポイントが変わりつつあり、1デベロッパーがUS Appleの担当者に噛み付いたり吼えたりしても影響力が及ばないところでしょうか。ぜひ、USのデベロッパーのUS Apple担当者への噛み付きや乱闘に期待したいところです。

2013/06/29 OSX 10.7, 10.8のAppleScriptリリースノートがやっと掲載される(2/2)

OS X 10.9のリリースを秋に控えたこの時期になって、ノコノコ掲載されたAppleScriptリリースノートの続編(10.8)です。機能追加やバグ修正などは、リリースノートを読まないと分らないので、OSのリリースと同時に掲載されることが望ましいのですが……Cupertinoには世間とは別の謎の常識が存在しているようです。

自分はOS X 10.7を海外のScripterの評判から「パスすべきOS」と判断し、メイン環境としてはほとんど使いませんでした。そのため、10.6からいきなり10.8に移行して、環境の激変に目を回していましたが……それ以前のバージョンのOSをいまだに使っている人は、次の10.9に乗り損なうと、取り返しのつかない状態になると思います。

OS X 10.8機能追加

・AppleScript Editor
10.8のAppleScriptエディタは書類の取扱いに関して数多くの機能追加が行われている。
「Auto Save」書類への変更は自動的に保存される。コンパイル(構文確認)前の入力であっても同様。
「Versions」書類の以前のバージョンに簡単に戻れる。書類のタイトルバーから前バージョンへの移行が行える。
「Exporting」ファイルメニューから選択可能な「書き出す…」コマンドによって、現在編集中のScript/Scriptアプリケーション(アプレット)の配布用コピーを保存可能になった。「書き出す…」コマンドは実行専用のScriptを書き出す唯一の方法になった。編集可能なオリジナルScriptを上書き保存してしまう危険を減らすことになる。
「Bundle Identifier」アプレット(Script Application)時のバンドルの内容設定用ドロワーにて、あらたにバンドルID設定用フィールドを設けた。AppleScriptエディタはデフォルト値をフィールドに用意しておくが、ユーザーには配布用Scriptアプリケーションの識別用にカスタマイズすることが推奨される。バンドルIDを設定することが推奨されるものの、以前のバージョンまではInfo.plistを直接書き換える作業が必要とされてきた。

OS X 10.8 バグ修正

・AppleScript

リスト型変数(list)を文字(string)に変換する際、リスト中のアイテムが1つでも変換不可であればエラーにするようにした。従来はこれが、一部分のみ変換成功すると主張していた

「div」および「mod」演算子でIEEE754の演算ルーチンを使って結果を出すようにした。これは、OS X上の他のプログラミング言語との整合性のための修正。従来バージョンでは、正しくない答を正しくするように演算結果をごまかしていた。

・Standard Additions
「time to GMT」(グリニッジ標準時との時差)コマンドはタイムゾーンの変化とサマータイム時間の施行を考慮するようになった

「open for access」コマンドはスラッシュ(/)入りのファイル名のファイルを作成可能になった

互換性に関する注意点

Sandbox化したアプリケーション(Mountain Lion上のテキストエディットなど)にコマンドを送信する場合、パラメーターでファイル参照を行っているものは、ファイル記述、POSIXパス記述である必要がある。単なるパスの文字列で指定すると、ファイルにアクセスできない。たとえば、file “Macintosh HD:Users:me:sample.txt”やchoose fileの実行結果(aliasが得られる)は受け付けられるが、”/Users/me/sample.txt”では受け付けられない。

(以下、Developper NoteとしてAppleScript AppletへのCode Siginingの仕方と、AppleScript対応のアプリケーションのSandbox化の留意点、AppleScript対応機能がSandbox化により影響を受けないことが記載されている)

2012/03/04 Macworld Web、OS X 10.8の新セキュリティ基準がAppleScriptに与えるインパクトについて掲載

MacWorld Webにおいて、「How new Mac security measures will impact AppleScript」と題して「新しいセキュリティ基準がAppleScriptに与える衝撃」という記事を掲載しています。

要約すると……

・ユーザーがアプリ操作のために作ったScriptには、影響はないだろう

・アプリ内部で(ユーザーに見えないところで)AppleScriptを利用している箇所もあり、Sandbox化する場合には通信するアプリのIDをplistに登録しておく必要があり、リストにないアプリと新たに通信する必要がある場合には影響が出るだろう

・各アプリの専用Scriptメニューから呼び出すScriptについては、Scriptの保存先フォルダが厳密に規定されているので、好き勝手な場所には置けない(所定の場所に置けば大丈夫だろう)

・GateKeeperは、ユーザー自身が作ったScriptはともかく、オンラインで配布されているAppleScriptアプレットでAppleのデジタル署名のないものについてはアラートを表示するだろう。10.8で新たに採用される「XIP」形式のアーカイブにはデジタル署名が可能なので、これを利用するべき

といったところですが、残念ながら内容が「浅い」です。

これまで実際にPiyomaru Softwareが作成したAppleScriptやAppleScriptベースのアプリケーション、システムを「複雑さ」と「技術的なレベル」の2軸にもとづいてマッピングしてみると、下図のようになります。

chart1.jpg

そして、実際に影響が出そうなジャンルのものをピックアップしてみると、上図の黄色のボックスのあたりになります。

とくに、アプレットを動的に生成するようなタイプのAppleScriptは、ちょっと困ったことになりそうです。アプレットを自動生成するアプリケーション(FTP Droplet Toasterとか)や、並列処理を行うために動的にアプレットを作成するAppleScriptは、影響が出そうです。

ただ、さすがにそこまで凝ったことをやる場合にはユーザーが手動でGateKeeperのセキュリティポリシーを一時的にゆるめる設定を行うなど、まったく対処できないわけではありません。

問題は……AppleScriptに対して肝心の(平均的な)Appleのエンジニアの理解度が低いことであり、ユーザー側でさまざまなソリューションを開発しても、Appleのせいで問題に直面する可能性も否定できません。これは、Appleに対して文句を言っていくしかありません。

2012/02/19 AppleriptObjCベースのCocoaアプリケーションのSandbox化は可能か?

Sadbox化(Sandboxing)とは、アプリケーションを実行する際に、「保護された環境下でプログラムを実行し不正処理を防ぐセキュリティモデルの一種」

2011年末に「2012年3月以降、Mac AppStoreではSandbox対応したアプリケーションでないとリジェクト(却下)する」らしいよ、という噂が流れました。

Sandbox対応すると、ファイルの読み書きについて指定フォルダ以下のみに限定されたり、AppleEventによる通信も(開発時に)指定されたアプリケーションに限られるなど、アプリケーションが「できること」が制限されます。また、実行コードの同一性を保証するための「コード署名」の機構が用意され、コードの書き換えを禁止しています。

AppleScript業界的にいえば、AppleScriptのアプレットについては……プロパティを書き換えただけで実行ファイルが変更されてしまうわけで、Sandbox対応になじみません。AppleScript Studioアプリもモデルが古いのでMac AppStoreに提出しても通らないだろうというところ。

AppleScriptObjCアプリになって、はじめてMac AppStore上で流通できるアプリケーションを作成し得るだろう、という見方があったわけですが……ちょっと待て、そもそもAppleScriptObjCアプリってSandbox化できるのか? といった議論がありました。

実際、2011年末のTwitter界隈では一種パニック状態に陥っているんだか、声高に騒いでいる人が大勢(海外に)いました。この騒ぎについてはリアルタイムにキャッチしていたのですが、事実関係が把握できないと、怒っていいのか安心していいのか分りません。まずは、情報の収集と分析を行っていました。

そんな中、実際にBEN WALDIEによって検証記事が掲載され、これを1か月ほど後になって見つけました。

「Sandboxing a Cocoa-AppleScript (AppleScriptObjC) Application」 2011/10/13

結論をいえば、AppleScriptObjCアプリのSandbox化はできるということで、ひとまずは安心してよいということになります。ただ、いろいろ試行錯誤は必要なんだろうなと思われるところです。BEN WALDIEの記事にはSandbox化したAppleScriptObjCのXcodeプロジェクトのアーカイブがリンクされており、参考になると思います。