次の図に、SASL ライフサイクル内に含まれる各種ステップを示します。クライアントの動作は図の左側に、サーバーの動作は右側に、それぞれ示してあります。その間に描かれた矢印は、外部接続経由でのクライアントとサーバー間の相互作用を示しています。
次からの節で、このライフサイクル内のステップについて説明します。
クライアントは sasl_client_init() を呼び出すことで libsasl をクライアント用に初期化します。サーバーは、sasl_server_init() を呼び出すことで libsasl をサーバー用に初期化します。
sasl_client_init() の実行時には、SASL クライアントプラグイン、クライアントの機構プラグイン、およびクライアントの標準化プラグインが読み込まれます。同様に、sasl_server_init() の呼び出し時には、SASL サーバープラグイン、サーバーの機構プラグイン、サーバーの標準化プラグイン、およびサーバーの auxprop プラグインが読み込まれます。sasl_client_init() の呼び出し後、追加のクライアントプラグインは、sasl_client_add_plugin() と sasl_canonuser_add_plugin() を使用して追加できます。サーバー側では、sasl_server_init() の呼び出し後、追加のサーバープラグインは、sasl_server_add_plugin()、sasl_canonuser_add_plugin()、および sasl_auxprop_add_plugin() を使用して追加できます。SASL 機構は Solaris ソフトウェアの次のディレクトリに格納されます。
32 ビット SPARC アーキテクチャー: /usr/lib/sasl
32 ビット x86 アーキテクチャー: /usr/lib/sasl
64 ビット SPARC アーキテクチャー: /usr/lib/sasl/sparcv9
x64 アーキテクチャー: /usr/lib/sasl/amd64
ただし、SASL_CB_GETPATH コールバックを使えば、このデフォルトの場所を変更できます。
この時点で、必要な大域コールバックのすべてが設定されています。SASL クライアントと SASL サーバーには、次のコールバックを含めることができます。
SASL_CB_GETOPT
SASL_CB_LOG
SASL_CB_GETPATH
SASL_CB_VERIFYFILE
さらに SASL サーバーには、SASL_CB_GETCONF コールバックも含めることができます。
サーバーとクライアントはプロトコル経由で接続を確立します。SASL による認証を行う場合、サーバーとクライアントは SASL 接続コンテキストを作成します。それには、sasl_server_new() と sasl_client_new() をそれぞれ使用します。SASL クライアントと SASL サーバーは、sasl_setprop() を使って機構に対するセキュリティー制約プロパティーを設定できます。これにより、SASL コンシューマアプリケーションは、指定された SASL 接続コンテキストの最小 SSF、最大 SSF、およびセキュリティープロパティーを決定できます。
#define SASL_SEC_NOPLAINTEXT 0x0001 #define SASL_SEC_NOACTIVE 0x0002 #define SASL_SEC_NODICTIONARY 0x0004 #define SASL_SEC_FORWARD_SECRECY 0x0008 #define SASL_SEC_NOANONYMOUS 0x0010 #define SASL_SEC_PASS_CREDENTIALS 0x0020 #define SASL_SEC_MUTUAL_AUTH 0x0040
認証とセキュリティー層は、クライアント/サーバー間のプロトコルや libsasl 以外の機構を使って提供してもかまいません。そうした場合、sasl_setprop() 経由で外部認証 ID や外部 SSF を設定できます。たとえば、プロトコルが SSL を使用してサーバーに対するクライアント認証を行う場合を考えます。この場合、外部認証 ID をクライアントの被認証者名として、外部 SSF を鍵のサイズとして、それぞれ使用できます。
サーバー側では、libsasl が、セキュリティープロパティーと外部 SSF に従って利用可能な SASL 機構を決定します。クライアントは、その利用可能な SASL 機構を SASL サーバーからプロトコル経由で取得します。
SASL サーバー側で SASL 接続コンテキストを作成するには、sasl_server_new() を呼び出す必要があります。すでに使われていない既存の SASL 接続コンテキストを再利用することも可能です。ただし、その場合は次のパラメータをリセットする必要があります。
#define SASL_DEFUSERREALM 3 /* default realm passed to server_new or set with setprop */ #define SASL_IPLOCALPORT 8 /* iplocalport string passed to server_new */ #define SASL_IPREMOTEPORT 9 /* ipremoteport string passed to server_new */ #define SASL_SERVICE 12 /* service passed to sasl_*_new */ #define SASL_SERVERFQDN 13 /* serverFQDN passed to sasl_*_new */
sasl_client_new() と sasl_server_new() に対するパラメータは、コールバックとプロトコルフラグ以外はすべて変更可能です。
また、サーバーとクライアントは、セキュリティーポリシーの確立や接続固有パラメータの設定も行えます。それには、sasl_setprop() を使って次のプロパティーを指定します。
#define SASL_SSF_EXTERNAL 100 /* external SSF active (sasl_ssf_t *) */ #define SASL_SEC_PROPS 101 /* sasl_security_properties_t */ #define SASL_AUTH_EXTERNAL 102 /* external authentication ID (const char *) */
SASL_SSF_EXTERNAL – 強度係数 (鍵のビット数) の設定用
SASL_SEC_PROPS – セキュリティーポリシーの定義用
SASL_AUTH_EXTERNAL – 外部認証 ID
サーバーは、sasl_listmech() を呼び出すことで、セキュリティーポリシーを満たす利用可能な SASL 機構のリストを取得できます。クライアントは通常、利用可能な機構リストをプロトコルに依存した方法でサーバーから取得できます。
SASL セッションの初期化を図示したのが、次の図です。この図と後続の図では、プロトコル経由でデータを転送した後の検査処理は、図を単純化する目的で省略しています。
認証時にクライアントとサーバーで実行されるステップの数は、使用されるセキュリティー機構ごとに異なります。SASL クライアントは、使用すべきセキュリティー機構のリストを指定して sasl_client_start() を呼び出します。このリストは通常、サーバーから送られてきます。libsasl は、利用可能な機構とクライアントのセキュリティーポリシーに基づいて、この SASL セッションに最適な機構を選択します。クライアントのセキュリティーポリシーは、許可される機構を制御します。そして、選択された機構が sasl_client_start() から返されます。クライアントのセキュリティー機構は、認証時に追加情報を必要とする場合があります。登録されたコールバック関数が NULL でない限り、libsasl はその指定されたコールバックを呼び出します。コールバック関数が NULL である場合、libsasl は、SASL_INTERACT と必要情報の要求を返します。SASL_INTERACT が返された場合、要求された情報を指定して sasl_client_start() を呼び出す必要があります。
sasl_client_start() から SASL_CONTINUE または SASL_OK が返された場合、クライアントは、選択された機構と結果の認証データを、サーバーに送信する必要があります。その他の値が返された場合、何らかのエラーが発生しています。たとえば、利用可能な機構が存在しない、などです。
サーバーは、クライアントによって選択された機構と、認証データを受信します。続いてサーバーは、sasl_server_start() を使ってこのセッション用に機構データを初期化します。また、sasl_server_start() は認証データの処理も行います。sasl_server_start() から SASL_CONTINUE または SASL_OK が返された場合、サーバーは認証データを送信します。sasl_server_start() からその他の値が返された場合、機構の受け入れに失敗した、認証に失敗した、など、何らかのエラーが発生しています。その認証は中止する必要があります。その SASL コンテキストは、解放するか、または再利用する必要があります。
認証プロセスのうち、以上の部分を図示したのが、次の図です。
サーバー側の sasl_server_start() 呼び出しから SASL_CONTINUE が返された場合、サーバーは必要な認証情報をすべて取得するために、クライアントとの通信を継続します。後続のステップ数は機構ごとに異なります。必要に応じて、クライアントは sasl_client_step() を呼び出すことで、サーバーからの認証データを処理し、応答を生成します。同様に、サーバーは sasl_server_step() を呼び出すことで、クライアントからの認証データを処理し、応答を生成できます。この交換は、認証が完了するか、エラーが発生するまで継続されます。SASL_OK が返された場合、それはクライアント側またはサーバー側での認証が正常に完了したことを意味します。他方の認証を完了させるために他方に送信すべき追加データが、SASL 機構内にまだ残っている可能性があります。サーバー側とクライアント側の両方で認証が完了すると、サーバーとクライアントは、互いのプロパティーを照会できるようになります。
次の図は、追加認証データを転送する際の、サーバーとクライアント間における相互作用を示したものです。
セキュリティー層の有無を検査するには、sasl_getprop(3SASL) 関数を使ってセキュリティー強度係数 (SSF) の値が 0 よりも大きいかどうかを確認します。セキュリティー層の折衝が行われていた場合、クライアントとサーバーは認証成功後に結果の SSF を使用する必要があります。クライアントとサーバー間のデータ交換は、認証の場合と似た方法で行われます。プロトコルによってクライアントまたはサーバーにデータが送信される前に、データに sasl_encode() が適用されます。受信側では、最後に、sasl_decode() によってデータが復号化されます。セキュリティー層の折衝がなされていなかった場合、その SASL 接続コンテキストは必要ありません。したがって、このコンテキストは破棄または再利用してかまいません。
SASL 接続コンテキストを解放する必要があるのは、そのセッションを再利用しない場合だけです。sasl_dispose() は、SASL 接続コンテキストと関連するすべてのリソースおよび機構を解放します。sasl_done() を呼び出す場合、その前に SASL 接続コンテキストを破棄しておく必要があります。SASL 接続に対するコンテキストリソースを解放することは、sasl_done() の責任ではありません。「libsasl のクリーンアップ」を参照してください。
SASL セッションが解放される際、すべての状態が解放される可能性がある旨が、関連する機構に通知されます。SASL セッションを解放する必要があるのは、そのセッションを再利用しない場合だけです。それ以外の場合、別のセッションがその SASL 状態を再利用できます。クライアントとサーバーのどちらも、sasl_dispose() を使って SASL 接続コンテキストを解放します。
このステップでは、SASL ライブラリとプラグインのすべてのリソースを解放します。クライアントとサーバーは sasl_done() を呼び出すことで、libsasl() のリソースを解放し、すべての SASL プラグインを読み込み解除します。sasl_done() は SASL 接続コンテキストを解放しません。アプリケーションが SASL クライアントでもあり、かつ SASL サーバーでもある場合、sasl_done() によって SASL クライアントと SASL サーバー双方のリソースが解放される点に注意してください。クライアント、サーバーのいずれかのリソースのみを解放することはできません。
ライブラリ内で sasl_done() を呼び出すべきではありません。アプリケーション内で sasl_done() を呼び出す際には、libsasl を使用している可能性のあるすべてのライブラリとの干渉を回避できるように、細心の注意を払う必要があります。