ONC+ 開発ガイド

RPCSEC_GSS を使用した認証

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

また、GSS-API を使用すると、それがサポートする kerberos V 5、RSA 公開鍵、Diffie-Hellman 公開鍵、CSM や将来サポートされるメカニズムをアプリケーションから使用することができます。 [現在、GSS-API はまだ発表されていません。ただし、特定の GSS-API 機能は RPCSEC_GSS の機能 (この機能は「不透明な」(内部の見えない) 形で扱うことができます) を通じて参照できます。プログラマはこれらの値に直接かかわる必要はありません。]

RPCSEC_GSS セキュリティタイプを使用すると、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 (Quality of Protection) は、保護の質を意味します。QOP により、プライバシまたは完全性サービスとともに使用する暗号化アルゴリズムのタイプが指定されます。各セキュリティメカニズムには、それに関連する 1 つまたは複数の QOP があります。

アプリケーションは、構成ファイル (/etc/gss/qop/etc/gss/mech) またはネームサービスから、有効な QOP とメカニズムを入手できます。開発者は、メカニズムと QOP をハードコード化し、使用するアプリケーション内に埋め込むことは避けてください。そうすれば、新しい、または異なるメカニズムおよび QOP を使用するためにアプリケーションを修正する必要はありません。


注 -

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


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

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

RPCSEC_GSS ルーチン

表 4-8 は、RPCSEC_GSS コマンドを要約したものです。この表では、各関数の個別の説明ではなく、RPCSEC_GSS 関数の全般的な概要を示しています。詳細については、各関数のマニュアルページを参照してください。

表 4-8 RPCSEC_GSS Functions
 関数 目的 入力 出力 注
rpc_gss_seccreate() セキュリティコンテキストの作成 クライアントのハンドル、主体名、メカニズム、QOP、サービスタイプAUTH ハンドル 
rpc_gss_set_defaults() コンテキストの QOP とサービスタイプの変更 古い 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 
rpc_gss_get_principal_name() 固有のパラメータから主体名の RPCSEC_GSS 構造を作成する メカニズム、ユーザー名、マシン名、ドメイン名 RPCSEC_GSS 主体名の構造 
rpc_gss_get_error() RPCSEC_GSS ルーチンが失敗した場合にエラーコードを得る    RPCSEC_GSS エラー番号、該当する場合には errno 
rpc_gss_get_mechanisms() インストールされているメカニズムの文字列を入手する    有効なメカニズムのリスト 
rpc_gss_get_mech_info() 有効な QOP 文字列を入手する メカニズム そのメカニズムの有効な QOP 
rpc_gss_get_versions() サポートされている RPCSEC_GSS の最大および最小のバージョン番号を得る    最大および最小のバージョン番号 
rpc_gss_is_installed() メカニズムが導入されているかどうかをチェックする メカニズム インストールされている場合は TRUE 
rpc_gss_mech_to_oid() ASCII メカニズムを RPC オブジェクト識別子に変換する メカニズム (文字列で) メカニズム (OID で) 
rpc_gss_qop_to_num() ASCII QOP を整数に変換する QOP (文字列で) QOP (整数で) 

コンテキストの作成

コンテキストは、rpc_gss_seccreate() 呼び出しを使用して作成します。この関数では引数として、セッションの、クライアントハンドル (たとえば clnt_create() によって戻されたもの) , サーバーの主体名 (nfs@machine.eng.company.com)、メカニズム、サービスタイプ、および QOPと、使用される場合はほとんどの場合不透明なまま使用される 2 つの GSS-API パラメータをとります。この関数で、AUTH 認証ハンドルを返します。以下のコードフラグメントは、Kerberos v5 セキュリティメカニズムと完全性サービスを使用したコンテキストを作成する場合、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);
 
. . .

この例では、注意する点が数カ所あります。まず、メカニズムは明示的に宣言してありますが (読みやすくするために)、通常は、rpc_gss_get_mechanisms() 用いて、使用できるメカニズムの表から入手します。QOP にも同様のことが言えます。 ここでは、最初の NULL を渡しています。これは、QOP をこのメカニズムのデフォルトに設定するものです。次に、サービスタイプは、RPCSEC_GSS タイプの enum のひとつである rpc_gss_service_t です。最後に、末尾の 2 つの NULL 引数は、不透明な GSS-API オプション用で、プログラマは安全に NULL を値として渡すことができます。

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

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

 
rpc_gss_set_defaults(clnt->clnt_auth, rpc_gss_svc_privacy, qop);
 
. . .
ここで、 qop は新しい QOP の名前を表わす文字列へのポインタです。

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

主体名

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

サーバー主体名の設定

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

char *principal, *mechanism;
u_int req_time;
 
principal = "nfs@engineering.company.com";
mechanism = "kerberosv5";
req_time = 10000;		/* 資格の有効時間 */
 
rpc_gss_set_svc_name(principal, mechanism, req_time, SERV_PROG, SERV_VERS);

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

サーバーは、クライアントの主体名で稼動できなければなりません。たとえば、クライアントの主体名をアクセス制御リストと比較するため、またはクライアントの UNIX 資格を検出するため (このような資格が存在する場合) に必要です。サーバーが、受信した主体名を既知のエンティティの名前と比較する必要がある場合、サーバーは、既知のエンティティ用に rpc_gss_principal_t 主体名を生成できなければなりません。 rpc_gss_get_principal_name() 呼び出しでは、ネットワーク上で個人を識別するパラメータをいくつか入力し、rpc_gss_principal_t 構造ポインタの形式で主体名を設定します。

 
rpc_gss_principal_t *principal;
 
rpc_gss_get_principal_name(principal, mechanism, name, node, domain);
. . .
最初に設定される引数は、rpc_gss_principal_t です。次の引数は、使用するセキュリティメカニズムです。生成される主体名はメカニズムに依存します。最後の 3 つの引数は、ネットワーク外の個人を識別するために使用されるパラメータです。 「name」には、joeh または nfs などの、個人名またはサービス名が入ります。「node」には UNIX マシン名、「domain」には DNS、NIS、または NIS+ ドメイン名が入ります。各セキュリティメカニズムには、別々の識別パラメータが必要です。たとえば、Kerberos v5 には、ユーザー名を必ず指定します。それに加えて修飾されたノード名とドメイン名を指定することができます。 (Kerberos 用語では、ホスト名と領域名)。

主体名の解放

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

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

サーバーは、クライアントの資格を獲得できなければなりません。 rpc_gss_getcred() 関数を使用すると、サーバーは UNIX 資格または RPCSEC_GSS 資格のいずれか (またはこの両方) を検索できます。これは、この関数が正常に終了した場合に設定された 2 つの引数によって実行されます。最初の引数は、呼び出し元の UNIX 資格 (uidgid) が組み込まれた rpc_gss_ucred_t 構造 (存在する場合) へのポインタになります。2 番めの引数は 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_gss_principal_t 構造が表示されます。) rpc_gss_rawcred_t にはクライアントとサーバーの両方の主体名が組み込まれているため、rpc_gss_getcred() は両方の名前を戻します。

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


例 4-29 資格の入手

 
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;
 
}

Cookies

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

コールバック

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

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

2 番めと 3 番めの引数は、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 とサービスを実行できます。QOP とサービスは、rpc_gss_rawcred_t 構造内で検出できます。サーバーはこれらの値は変更できません。ユーザー定義のコールバックが呼び出されると、locked パラメータは FALSE に設定されます。サーバーは、コンテキストをロックするために、これを TRUE に設定する必要があります。コンテキストがロックされると、QOP とサービスの値と一致する要求だけが受理されます。

最大データサイズ

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

その他の関数

関数の中には、導入されたセキュリティシステムに関する情報を入手する場合に使用できるものもあります。rpc_gss_get_mechanisms() は、導入されたセキュリティメカニズムのリストを戻します。一方、rpc_gss_is_installed() は、指定したメカニズムがインストールされているかどうかを検査します。rpc_gss_get_mech_info() は、指定されたメカニズムの有効な QOP を戻します。これらの関数を使用することによって、プログラマは、アプリケーション内のセキュリティパラメータのハードコード化を避けることができます。RPCSEC_GSS 関数については、表 4-8rpcsec_gss(3N) マニュアルページを参照してください。

関連ファイル

gsscred テーブル

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


注 -

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


gsscred ファイルには、クライアントの UNIX 資格とネットワーク資格の両方が入っています。後者は、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、サービスを実現する共有ライブラリとカーネルモジュールが格納されます。次に例を示します。


 kerberosv5		1.2.840.113554.1.2.2		mech_krb5.so 	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() 関数を使用してこれらのパラメータと同等の文字列にない値を入手します。