上述の認証タイプ (AUTH_SYS、AUTH_DES、AUTH_KERB) は、1 つの決まった見方で同じように扱うことができます。このため、新しいネットワーキング階層、Generic Security Standard API (汎用セキュリティ規格 API)、すなわち GSS-API が追加されています。GSS-API のフレームワークでは、認証に加え次の 2 つの「サービス」が提供されています。
「完全性」
一貫性サービスでは、GSS-API は下位層のメカニズムを使用してプログラム間で交換されるメッセージを認証します。暗号化チェックサムによって、以下が確立されます。
データの発信側から受信側への識別情報 (ID)
受信側から発信側への識別情報 (ID) (相互の認証が要求された場合)
伝送されたデータそのものの認証
「プライバシ」
プライバシサービスには、完全性サービスが含まれています。これに加えて、伝送データも「暗号化」され傍受者から保護されます。
米国の輸出の規約により、プライバシサービスはすべてのユーザーが利用できるわけではありません。
現在、GSS-API はまだ発表されていません。ただし、特定の GSS-API 機能は RPCSEC_GSS の機能 (この機能は「不透明な」(opaque 型) で扱うことができる) を通じて参照できます。プログラマはこれらの値に直接かかわる必要はありません。
RPCSEC_GSS API セキュリティタイプを使用すると、ONC RPC アプリケーションは、GSS-API の機能を利用することができます。RPCSEC_GSS は、次の図のように、GSS-API 階層の「最上部」に位置しています。
RPCSEC-GSS のプログラミングインタフェースを使用する場合は、ONC RPC アプリケーションは以下の項目を指定できます。
セキュリティのパラダイム。各種セキュリティメカニズムでは、1 つまたは複数レベルのデータ保護と同時に、それぞれ異なる種類のデータ保護を提供します。この場合、GSS-API によってサポートされる任意のセキュリティメカニズムを指定します (Kerberos v5、RSA 公開鍵など)。
プライバシまたは完全性のいずれかを指定します (あるいはどちらも指定しない)。デフォルトは完全性です。この項目はメカニズムに依存しません。
保護の質。QOP により、プライバシまたは完全性サービスを実現するために使用する暗号化アルゴリズムのタイプが指定されます。各セキュリティメカニズムには、それに関連する 1 つまたは複数の QOP があります。
アプリケーションは、RPCSEC_GSS によって提供される関数により、QOP およびメカニズムのリストを入手できます (「その他の関数」を参照)。開発者は、メカニズムと QOP をハードコード化し、使用するアプリケーション内に埋め込むことは避けてください。そうすれば、新しい、または異なるメカニズムおよび QOP を使用するためにアプリケーションを修正する必要はありません。
これまでは、「セキュリティタイプ」と「認証タイプ」は同じものを表していました。RPCSEC_GSS の導入によって、「タイプ」は現在、多少異なる意味を持ちます。タイプには、認証とともにサービス (一貫性またはプライバシ) を含むことができますが、現在は RPCSEC_GSS が、これを実行できる唯一のタイプです。
RPCSEC_GSS を使用すると、ONC RPC アプリケーションは、他のタイプを使用して行う場合と同様に、ピアにセキュリティコンテキストを確立し、データを交換してこのコンテキストを破棄します。一度コンテキストが確立されると、アプリケーションは、送信したデータユニットごとに QOP およびサービスを変更できます。
RPCSEC_GSS データタイプを含む RPCSEC_GSS の詳細については、rpcsec_gss(3NSL) のマニュアルページを参照してください。
表 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() 呼び出しを使用して作成します。この関数では引数として次のものをとります。
クライアントハンドル(たとえば、clnt_create()によって戻されたもの)
サーバーの主体名 ( nfs@acme.com)
セッションのメカニズム (Kerberos V5 など)
セキュリティサービスタイプ (プライバシなど)
セッションの QOP
使用される場合は、ほとんど不透明( opaque )なまま使用される (つまり、プログラマが NULL 値を入れることができる) 2 つの GSS-API パラメータ
この関数で、AUTH 認証ハンドルを返します。例 4-29 は、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); . . . |
この例 4-29 では、次の点に注意してください。
メカニズムは明示的に宣言してありますが (読みやすくするために)、通常は、rpc_gss_get_mechanisms() 用いて、使用できるメカニズムの表から入手します。
QOP は、NULL として渡されます。これにより、QOP はこのメカニズムのデフォルトに設定されます。これ以外の場合は、このメカニズムを使用して、rpc_gss_get_mechanisms() を指定したプログラムで有効な値を入手できます。詳細については、マニュアルページの rpc_gss_get_mechanisms(3NSL) を参照してください。
セキュリティサービスタイプ、rpc_gss_svc_integrity は、RPCSEC_GSS タイプの enum のひとつである rpc_gss_service_t です。rpc_gss_service_t のフォーマットは、次のようになります。
typedef enum { rpc_gss_svc_default = 0, rpc_gss_svc_none = 1, rpc_gss_svc_integrity = 2, rpc_gss_svc_privacy = 3 } rpc_gss_service_t; |
デフォルトのセキュリティサービスは、完全性をマップするため、プログラマは指定された rpc_gss_svc_default を入手し、同じ結果を獲得することができます。
詳細については、rpc_gss_seccreate(3NSL) のマニュアルページを参照してください。
コンテキストが設定されると、アプリケーションは伝送される個々のデータユニットの QOP およびサービス値を変更する必要がある場合があります。たとえば、プログラムのパスワードは暗号化したいがログイン名は暗号化したくない場合。これは、次のように 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 つのタイプの主体名が必要です。
サーバーの主体名は、通常、「service@host」の形式の NULL で終わる ASCII 文字列で指定します。たとえば、 nfs@eng.acme.com のように指定します。
クライアントが rpc_gss_seccreate() でセキュリティコンテキストを作成する時に、このフォーマットでサーバーの主体名を指定します (「コンテキストの作成」を参照)。同様にサーバーは、表示する主体名を設定する必要がある場合は、引数としてこのフォーマットの主体名をとる rpc_gss_set_svc_name() を使用します。
サーバーが受信するクライアントの主体名は、rpc_gss_principal_t 構造の形式 (使用するメカニズムによって決定される、不透明に長さを暗示したバイト列) をとります。この構造については、rpcsec_gss(3NSL) のマニュアルページを参照してください 。
サーバーは、起動時に、そのサーバーを表わす主体名を指定する必要があります (1 つのサーバーが複数の主体として機能する場合もあります)。サーバー主体名の設定には、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 構造ポインタとして主体名を生成します。
rpc_gss_principal_t *principal; rpc_gss_get_principal_name(principal, mechanism, name, node, domain); . . .
rpc_gss_get_principal_name() への引数は、次のとおりです。
「 principal 」には、設定された rpc_gss_principal_t 構造へのポインタが入ります。
「 mechanism 」には、使用されるセキュリティメカニズムです (生成される主体名は、メカニズムに依存することに注意してください)。
「 name 」には joeh または nfs などの個人名、またはサービス名が入ります。
「 node 」には、UNIX マシン名などが入ります。
「 domain 」には、たとえば、DNS、NIS、または NIS+ドメイン名、あるいは Kerberos の領域が入ります。
各セキュリティメカニズムには、別々の識別パラメータが必要です。たとえば、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; |
例 4-33 は 1 つのサーバー側のディスパッチ手続きの例です。これにより、サーバーは呼び出し元の資格を入手します。この手続きでは、呼び出し元の UNIX 資格を入手してから、次に rpc_gss_rcred_t 引数内で検出された、メカニズム、QOP、サービスタイプを使用してユーザーの識別情報 (ID) を確認します。
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) のマニュアルページを参照してください。
例 4-33 では、 rpc_gss_getcred()への最後の引数は、ユーザー定義の cookie です。このコンテキストの作成時にサーバーによってどのような値が指定されていても、このユーザー定義の値が戻されます。この cookie は 4 バイトの値で、そのアプリケーションに適したあらゆる方法で使用されます。RPC はこれを解釈しません。たとえば、 cookie は、コンテキストの起動元を示す構造へのポインタまたはインデックスになることができます。また、各要求ごとにこの値を計算する代わりに、サーバーがコンテキスト作成時にこの値を計算します。このため、要求の処理時間が削減されます。
これ以外に cookie が使用される場所は、コールバックです。サーバーは、rpc_gss_set_callback() 関数を使用することにより、(ユーザー定義の) コールバックを指定してコンテキストが最初に使用された時を認知できます。コールバックは、コンテキストが指定されたプログラムとバージョン用に確立されたあとに、そのコンテキストがデータ交換に最初に使用された時に呼び出されます。
ユーザー定義のコールバックルーチンは、以下のような形式になります。
2 番めと 3 番めの引数 deleg と gss_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; |
詳細は、 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) のマニュアルページを参照してください。
関数の中には、導入されたセキュリティシステムに関する情報を入手する場合に使用できるものもあります。
rpc_gss_get_mechanisms() は、導入されたセキュリティメカニズムのリストを戻します。
rpc_gss_is_installed() は、指定したメカニズムがインストールされているかどうかを検査します。
rpc_gss_get_mech_info() は、指定されたメカニズムの有効な QOP を戻します。
これらの関数を使用することによって、プログラマは、アプリケーション内のセキュリティパラメータのハードコード化を避けることができます (RPCSEC_GSS 関数については、表 4-8 と rpcsec_gss(3NSL) のマニュアルページを参照)。
RPCSEC_GSS は各種のファイルを使用して情報を保存します。
サーバーが要求に関連するクライアントの資格を検索すると、サーバーはクライアントの主体名 (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 ユーティリティとともに保持されます。このユーティリティを使用すると、管理者はユーザーやメカニズムの追加および削除が行えます。
便宜上、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() 関数を使用してこれらのパラメータと同等の文字列にない値を入手します。