ONC+ 開発ガイド

RPCSEC_GSS を使用した認証

上述の認証タイプ (AUTH_SYS、AUTH_DES、AUTH_KERB) は、1 つの決まった見方で同じように扱うことができます。このため、新しいネットワーキング階層、Generic Security Standard API (汎用セキュリティ規格 API)、すなわち GSS-API が追加されています。GSS-API のフレームワークでは、認証に加え次の 2 つの「サービス」が提供されています。


注 -

現在、GSS-API はまだ発表されていません。ただし、特定の GSS-API 機能は RPCSEC_GSS の機能 (この機能は「不透明な」(opaque 型) で扱うことができる) を通じて参照できます。プログラマはこれらの値に直接かかわる必要はありません。


RPCSEC_GSS API

RPCSEC_GSS API セキュリティタイプを使用すると、ONC RPC アプリケーションは、GSS-API の機能を利用することができます。RPCSEC_GSS は、次の図のように、GSS-API 階層の「最上部」に位置しています。

図 4-1 GSS-API と RPCSEC-GSS のセキュリティ階層

Graphic

RPCSEC-GSS のプログラミングインタフェースを使用する場合は、ONC RPC アプリケーションは以下の項目を指定できます。

メカニズム

セキュリティのパラダイム。各種セキュリティメカニズムでは、1 つまたは複数レベルのデータ保護と同時に、それぞれ異なる種類のデータ保護を提供します。この場合、GSS-API によってサポートされる任意のセキュリティメカニズムを指定します (Kerberos v5、RSA 公開鍵など)。

サービス

プライバシまたは完全性のいずれかを指定します (あるいはどちらも指定しない)。デフォルトは完全性です。この項目はメカニズムに依存しません。

QOP

保護の質。QOP により、プライバシまたは完全性サービスを実現するために使用する暗号化アルゴリズムのタイプが指定されます。各セキュリティメカニズムには、それに関連する 1 つまたは複数の QOP があります。

アプリケーションは、RPCSEC_GSS によって提供される関数により、QOP およびメカニズムのリストを入手できます (「その他の関数」を参照)。開発者は、メカニズムと QOP をハードコード化し、使用するアプリケーション内に埋め込むことは避けてください。そうすれば、新しい、または異なるメカニズムおよび QOP を使用するためにアプリケーションを修正する必要はありません。


注 -

これまでは、「セキュリティタイプ」と「認証タイプ」は同じものを表していました。RPCSEC_GSS の導入によって、「タイプ」は現在、多少異なる意味を持ちます。タイプには、認証とともにサービス (一貫性またはプライバシ) を含むことができますが、現在は RPCSEC_GSS が、これを実行できる唯一のタイプです。


RPCSEC_GSS を使用すると、ONC RPC アプリケーションは、他のタイプを使用して行う場合と同様に、ピアにセキュリティコンテキストを確立し、データを交換してこのコンテキストを破棄します。一度コンテキストが確立されると、アプリケーションは、送信したデータユニットごとに QOP およびサービスを変更できます。

RPCSEC_GSS データタイプを含む RPCSEC_GSS の詳細については、rpcsec_gss(3NSL) のマニュアルページを参照してください。

RPCSEC_GSS ルーチン

表 4-8 は、RPCSEC_GSS コマンドを要約したものです。この表では、各関数の個別の説明ではなく、RPCSEC_GSS 関数の全般的な概要を示しています。各関数の詳細については、該当するマニュアルページを参照するか、RPCSEC_GSS データ構造のリストなどの概要が記載された、rpcsec_gss(3NSL) のマニュアルページを参照してください。

表 4-8 RPCSEC_GSS Functions
 処理 関数 入力 出力
 セキュリティコンテキストの作成rpc_gss_seccreate() クライアントのハンドル、主体名、メカニズム、QOP、サービスタイプAUTH ハンドル
 コンテキストの QOP とサービスタイプの変更rpc_gss_set_defaults() 古い QOP とサービス 新しい QOP とサービス
 セキュリティの変換前に、データの最大サイズを示すrpc_gss_max_data_length() 伝送できる最大データサイズ 変換前の最大データサイズ
 セキュリティの変換前に、データの最大サイズを示すrpc_gss_svc_max_data_length() 伝送できる最大データサイズ 変換前の最大データサイズ
 表示するサーバーの主体名を設定するrpc_gss_set_svc_name() 主体名 , RPC プログラム、バージョン番号 正常に完了した場合は TRUE
 呼び出し元 (クライアント) の資格を得るrpc_gss_getcred()svc_req 構造へのポインタ UNIX 資格、RPCSEC_GSS 資格、cookie
 (ユーザーの作成した) コールバック関数を指定するrpc_gss_set_callback() コールバック関数へのポインタ 正常に完了した場合は TRUE
 固有のパラメータから主体名の RPCSEC_GSS 構造を作成するrpc_gss_get_principal_name() メカニズム、ユーザー名、マシン名、ドメイン名 RPCSEC_GSS 主体名の構造
 RPCSEC_GSS ルーチンが失敗した場合にエラーコードを得るrpc_gss_get_error()    RPCSEC_GSS エラー番号、該当する場合には errno
 インストールされているメカニズムの文字列を入手するrpc_gss_get_mechanisms()    有効なメカニズムのリスト
 有効な QOP 文字列を入手するrpc_gss_get_mech_info() メカニズム そのメカニズムの有効な QOP
 サポートされている RPCSEC_GSS の最大および最小のバージョン番号を得るrpc_gss_get_versions()    最大および最小のバージョン番号
 メカニズムが導入されているかどうかをチェックするrpc_gss_is_installed() メカニズム インストールされている場合は TRUE
 ASCII メカニズムを RPC オブジェクト識別子に変換するrpc_gss_mech_to_oid() メカニズム (文字列で) メカニズム (OID で)
 ASCII QOP を整数に変換するrpc_gss_qop_to_num() QOP (文字列で) QOP (整数で)

コンテキストの作成

コンテキストは、rpc_gss_seccreate() 呼び出しを使用して作成します。この関数では引数として次のものをとります。

この関数で、AUTH 認証ハンドルを返します。例 4-29 は、Kerberos v5 セキュリティメカニズムと完全性サービスを使用したコンテキストを作成する場合、rpc_gss_seccreate() がどのように使用されるかを示しています。


例 4-29 rpc_gss_seccreate()


 
CLIENT *clnt;						/* クライアントハンドル */
char server_host[] = "foo";
char service_name[] = "nfs@machine.eng.company.com";
char mech[] = "kerberosv5";
 
clnt = clnt_create(server_host, SERVER_PROG, SERV_VERS, "netpath");
clnt->clnt_auth = rpc_gss_seccreate(clnt, service_name, mech, ¥
															rpc_gss_svc_integrity, NULL, NULL, NULL);
 
. . .


この例 4-29 では、次の点に注意してください。

値の変更とコンテキストの破棄

コンテキストが設定されると、アプリケーションは伝送される個々のデータユニットの QOP およびサービス値を変更する必要がある場合があります。たとえば、プログラムのパスワードは暗号化したいがログイン名は暗号化したくない場合。これは、次のように rpc_gss_set_defaults() を使用すると実行できます。


例 4-30 rpc_gss_set_defaults()

 
rpc_gss_set_defaults(clnt->clnt_auth, rpc_gss_svc_privacy, qop);
 
. . .

この場合、セキュリティサービスはプライバシに設定されます (「コンテキストの作成」を参照)。

ここで、qop は新しいQOPの名前を表わす文字列へのポインタです。

コンテキストは、通常どおり、auth_destroy() を使用して破棄します。

QOP とサービスの変更に関する詳細は、rpc_gss_set_defaults(3NSL) のマニュアルページを参照してください。

主体名

セキュリティコンテキストを確立し、保持するには、次の 2 つのタイプの主体名が必要です。

サーバー主体名の設定

サーバーは、起動時に、そのサーバーを表わす主体名を指定する必要があります (1 つのサーバーが複数の主体として機能する場合もあります)。サーバー主体名の設定には、rpc_gss_set_svc_name() を使用します。


例 4-31 rpc_gss_set_svc_name()

char *principal, *mechanism;
u_int req_time;

principal = "nfs@eng.acme.com";
mechanism = "kerberos_v5";
req_time = 10000;		/* 資格の有効時間 */

rpc_gss_set_svc_name(principal, mechanism, req_time, SERV_PROG, SERV_VERS);

Kerberos は、req_time パラメータを無視します。他の認証システムでは、このパラメータを使用する場合があります。

詳細については、rpc_gss_set_svc_name(3NSL) のマニュアルページを参照してください。

クライアント主体名の作成

サーバーは、クライアントの主体名で稼動できなければなりません。たとえば、クライアントの主体名をアクセス制御リストと比較するため、またはクライアントの UNIX 資格を検出するため (このような資格が存在する場合) に必要です。このような主体名は、rpc_gss_principal_t 構造ポインタのフォームで維持されます (rpc_gss_principal_t の詳細については、rpcsec_gss(3NSL) のマニュアルページを参照してください)。サーバーが、受信した主体名を既知のエンティティの名前と比較する必要がある場合、サーバーは、この形式で rpc_gss_principal_t 主体名を生成できなければなりません。

rpc_gss_get_principal_name() 呼び出しでは、ネットワーク上で個人を識別するパラメータをいくつか入力し、rpc_gss_principal_t 構造ポインタとして主体名を生成します。


例 4-32 rpc_gss_get_principal_name()

rpc_gss_principal_t *principal;

rpc_gss_get_principal_name(principal, mechanism, name, node, domain);
. . .

rpc_gss_get_principal_name() への引数は、次のとおりです。

各セキュリティメカニズムには、別々の識別パラメータが必要です。たとえば、Kerberos V5 にはユーザー名が必ず必要です。また、オプションの場合に限り、修飾されたノード名とドメイン名が必要です (Kerberos 用語では、ホスト名と領域名)。

詳細については、rpc_gss_get_principal_name(3NSL) のマニュアルページを参照してください。

主体名の解放

主体名は、free() ライブラリコールを使用して解放します。

サーバーで資格を受信する

サーバーは、クライアントの資格を獲得できなければなりません。 例 4-33 で示すように、rpc_gss_getcred() 関数を使用すると、サーバーは UNIX 資格または RPCSEC_GSS 資格のいずれか (またはこの両方) を検索できます。これは、この関数が正常に終了した場合に設定された 2 つの引数によって実行されます。このうち1つは、呼び出し元の UNIX 資格が組み込まれた rpc_gss_ucred_t 構造 (存在する場合) へのポインタになります。

typedef struct {
    uid_t   uid;          /* ユーザー ID */
    gid_t   gid;          /* グループ ID */
    short   gidlen;       
    git_t   *gidlist;     /* グループのリスト */
} rpc_gss_ucred_t;

もう 1 つの引数は、次のような、rpc_gss_raw_cred_t 構造へのポインタです。

 
typedef struct {
		u_int 					version;															/* RPCSEC_GSS プログラムバージョン */
		char									*mechanism;
		char 								*qop;
		rpc_gss_principal_t		*client_principal;		/* クライアント主体名 */
		char									*svc_principal;			 								/* サーバー主体名 */
		rpc_gss_service_t			service; 											/* プライバシ、完全性 enum */
} rpc_gss_rawcred_t;
 
rpc_gss_principal_t 構造の解説と、作成方法については、「クライアント主体名の作成」を参照してください。 rpc_gss_rawcred_t にはクライアントとサーバーの両方の主体名が組み込まれているため、rpc_gss_getcred() は両方の名前を戻します。

例 4-33 は 1 つのサーバー側のディスパッチ手続きの例です。これにより、サーバーは呼び出し元の資格を入手します。この手続きでは、呼び出し元の UNIX 資格を入手してから、次に rpc_gss_rcred_t 引数内で検出された、メカニズム、QOP、サービスタイプを使用してユーザーの識別情報 (ID) を確認します。


例 4-33 資格の入手

static void server_prog(struct svc_req *rqstp, SVCXPRT *xprt)
{
		rpc_gss_ucred_t *ucred;
		rpc_gss_rawcred_t *rcred;
 
		if (rqst->rq_proq == NULLPROC) {
			svc_sendreply(xprt, xdr_void, NULL);
			return;
		}
		/*
		 * 他の全ての要求を認証する */
		 */
 
		switch (rqstp->rq_cred.oa_flavor) {
		case RPCSEC_GSS:
			/*
			 * 資格情報を取得する
			 */
			rpc_gss_getcred(rqstp, &rcred, &ucred, NULL);
			/*
			* 設定ファイルを参照してセキュリティパラメータを
			* 使用することでユーザーにアクセスが許可されている
			* ことを確認する
			*/
			if (!authenticate_user(ucred->uid, rcred->mechanism,
				rcred->qop, rcred->service)) {
				svcerr_weakauth(xprt);
				return;
			}
			break; 	/* ユーザーに許可する */
		default:
			svcerr_weakauth(xprt);
			return;
		} /* スイッチの終り */
 
		switch (rqstp->rq_proq) {
		case SERV_PROC1:
			. . .
		}
 
		/* 通常の要求処理 ; 応答を送る ... */
 
		return;
 
}

詳細については、rpc_gss_getcred(3NSL) のマニュアルページを参照してください。

Cookies

例 4-33 では、 rpc_gss_getcred()への最後の引数は、ユーザー定義の cookie です。このコンテキストの作成時にサーバーによってどのような値が指定されていても、このユーザー定義の値が戻されます。この cookie は 4 バイトの値で、そのアプリケーションに適したあらゆる方法で使用されます。RPC はこれを解釈しません。たとえば、 cookie は、コンテキストの起動元を示す構造へのポインタまたはインデックスになることができます。また、各要求ごとにこの値を計算する代わりに、サーバーがコンテキスト作成時にこの値を計算します。このため、要求の処理時間が削減されます。

コールバック

これ以外に cookie が使用される場所は、コールバックです。サーバーは、rpc_gss_set_callback() 関数を使用することにより、(ユーザー定義の) コールバックを指定してコンテキストが最初に使用された時を認知できます。コールバックは、コンテキストが指定されたプログラムとバージョン用に確立されたあとに、そのコンテキストがデータ交換に最初に使用された時に呼び出されます。

ユーザー定義のコールバックルーチンは、以下のような形式になります。

2 番めと 3 番めの引数 deleggss_context は、GSS-API データタイプで、現在はまだ公開されていません。そのため、コールバック関数はこれらを無視します。簡単に説明すると、プログラムが GSS-API オペレーションをこのコンテキスト上で実行する必要がある場合、すなわち受信条件のテストをする場合、deleg は代表されるピアの識別情報になり、一方 gss_context は GSS-API コンテキストへのポインタになります。cookie 引数については、すでに説明しました。

lock 引数は、以下のように rpc_gss_lock_t 構造へのポインタです。

 
typedef struct {
 	bool_t 						locked;
		rpc_gss_rawcred_t		*raw_cred;
} rpc_gss_lock_t;
このパラメータを使用すると、サーバーはセッションに対し強制的に特定の QOP とサービスを実行できます。例 4-33 に記載したように、QOP とサービスは、rpc_gss_rawcred_t 構造内で検出できます。 (サーバーは、サービスと QOP の値を変更する必要はありません。) ユーザー定義のコールバックが呼び出されると、locked フィールドは FALSE に設定されます。サーバーが、lockedTRUE に設定すると、QOP とサービスの値が、rpc_gss_rawcred_t 構造内の値と一致する要求だけが受理されます。

詳細は、 rpc_gss_set_callback(3NSL) のマニュアルページを参照してください。

最大データサイズ

rpc_gss_max_data_length()rpc_gss_svc_max_data_length() の 2 つの関数は、1 つのデータが、セキュリティ測度によって変換され「ワイヤを通じて」送信される前に、そのデータの大きさを判別する場合に便利です。つまり、暗号化などのセキュリティ変換により、通常、伝送される 1 つのデータのサイズは変更されます (通常は、大きくなる)。データが使用できるサイズ以上に大きくならないように、これら 2 つの関数 (前者はクライアント側バージョンで、後者はサーバー側バージョン) により、指定されたトランスポートの変換前の最大サイズが戻されます。

詳細については、rpc_gss_max_data_length(3NSL)rpc_gss_svc_max_data_length(3NSL) のマニュアルページを参照してください。

その他の関数

関数の中には、導入されたセキュリティシステムに関する情報を入手する場合に使用できるものもあります。

これらの関数を使用することによって、プログラマは、アプリケーション内のセキュリティパラメータのハードコード化を避けることができます (RPCSEC_GSS 関数については、表 4-8rpcsec_gss(3NSL) のマニュアルページを参照)。

関連ファイル

RPCSEC_GSS は各種のファイルを使用して情報を保存します。

gsscred テーブル

サーバーが要求に関連するクライアントの資格を検索すると、サーバーはクライアントの主体名 (rpc_gss_principal_t 構造ポインタの形式)、またはクライアントのローカル UNIX 資格 (UID) のいずれかを入手できます。NFS 要求などのサービス では、アクセス検査に必要なローカル UNIX 資格が必要ですが、他の資格は必要ありません。つまり、これらのサービスでは、たとえば主体名は、rpc_gss_principal_t 構造として直接、独自のアクセス制御リスト内に格納できるからです。


注 -

クライアントのネットワーク資格 (その主体名) とローカル UNIX 資格間の対応は自動的に行われません。これは、ローカルのセキュリティ管理者が明示的に設定する必要があります。


gsscred ファイルには、クライアントの UNIX 資格とネットワーク(たとえば、Kerberos V5) 資格の両方が入っています。後者は、rpc_gss_principal_t 構造の Hex-ASCII 表示です。これには、XFN を通じてアクセスするため、このテーブルは、ファイル、NIS、NIS+、あるいは XFN によってサポートされる将来のネームサービス上に導入できます。XFN 階層では、このテーブルは this_org_unit/service/gsscred として表示されます。 gsscred テーブルは、gsscred ユーティリティとともに保持されます。このユーティリティを使用すると、管理者はユーザーやメカニズムの追加および削除が行えます。

/etc/gss/qop と /etc/gss/mech

便宜上、RPCSEC_GSS では、メカニズムと保護の質 (QOP) パラメータを表示するためにリテラルの文字列を使用します。ただし、基本的なメカニズム自体では、メカニズムをオブジェクト識別子として、QOP は 32 ビット整数として表示する必要があります。また、各メカニズムごとに、そのメカニズムのサービスを実現する共有ライブラリを指定する必要があります。

/etc/gss/mech ファイルには、システム上に導入されたすべてのメカニズムに関する情報、メカニズム名 (ASCII 形式)、メカニズムの ODI、このメカニズムによって使用できるサービスを実現する共有ライブラリ、サービスを実現するカーネルモジュールが格納されます。次に例を示します。


kerberos_v5   1.2.840.113554.1.2.2    gl/mech_krb5.so gl_kmech_krb5

/etc/gss/qop ファイルには、導入されたすべてのメカニズム用に、各メカニズムがサポートするすべての QOP が、ASCII 文字列とそれに対応する 32 ビット整数の両方で格納されます。

/etc/gss/mech/etc/gss/qop は、両方とも指定されたシステムにセキュリティメカニズムが最初に導入されたときに作成されます。

カーネル内 RPC ルーチンは、通常、文字列にない値を使用してメカニズムと QOP を表すため、アプリケーションは、これらのカーネル内ルーチンを利用したい場合には、rpc_gss_mech_to_oid()rpc_gss_qop_to_num() 関数を使用してこれらのパラメータと同等の文字列にない値を入手します。