EN JA
krb5_introduction(3)
krb5_introduction(3) HeimdalKerberos5library krb5_introduction(3)

名称

krb5_introduction - Kerberos 5 API の紹介

Kerberos 5 API 概説

すべての関数は、マニュアルページに文書化されています。このセクションは、Kerberos ライブラリで使用される主要な構成要素の概説と特定の関数を検索する場所へのポイントに到達しようとするものです。

Kerberos コンテキスト

kerberos コンテキスト (krb5_context) は、すべてのスレッドごとの状態を保持しています。コンテキスト特有であるすべてのグローバル変数は、デフォルト暗号化タイプ、資格証明キャッシュ (例えば、チケットファイル) とデフォルトのレルム (realm) を含んで、この構造体に格納されます。

構造体の内部は、関数が情報の抽出のために存在するので、直接アクセスされるべきではありません。

コンテキストとモジュールを作成する方法については、 krb5_init_context() のマニュアルページ、関数に関する詳細については、 Heimdal Kerberos 5 ライブラリを参照してください。

Kerberos 認証コンテキスト

Kerberos認証コンテキスト (krb5_auth_context) は、スレッドまたはプロセスのためのコンテキストを保持する kerberos コンテキストと同様の方法で、確証されたコンテキストに関連するすべてのコンテキストを保持しています。

krb5_auth_context は、サーバ/クライアントの間の認証に直接関連する様々な関数によって使用されます。この構造体が含んでいるデータの例は、様々なフラグ、クライアントとサーバのアドレス、ポート番号、キーブロック (またサブキー)、シーケンス番号、再生キャッシュとチェックサムのタイプです。

Kerberos プリンシパル

Kerberos プリンシパルは、Kerberos のユーザまたはサービスを識別する構造です。プリンシパルを保持する構造体は、krb5_principal です。レルムとプリンシパルの要素を抽出するための関数がありますが、ほとんどのアプリケーションには、構造体の内容を検査する理由はありません。

(移植性のさまざまな度合で) プリンシパルを作成するいくつかの方法とそれを解放する 1 つの方法があります。

また、詳細については、 プリンシパル操作関数とモジュール Heimdal Kerberos 5 プリンシパル関数も参照してください。

資格証明キャッシュ

資格証明キャッシュは、ユーザのためのチケットを保持しています。与えられたユーザは、ユーザが、最初のチケット (最初の krbtgt) を持っているところで、各レルムに対して 1 つの、いくつかの資格証明キャッシュを持つことができます。

資格証明キャッシュデータを、異なる提案に対して、それらの各々に、異なった方法で内部に保存することができます。ファイル資格証明 (FILE) キャッシュとプロセスに基づいた (KCM) キャッシュは、永久的な記憶域のためです。一方、メモリキャッシュ (MEMORY) は、ローカルプロセスへのローカルキャッシュです。

キャッシュは、 krb5_cc_resolve() でオープンされるか、または krb5_cc_new_unique() で作成されます。

キャッシュが再び ( krb5_cc_resolve() を使用して) オープンする必要があるなら、 krb5_cc_close() は、ハンドルをクローズしますが、キャッシュは、削除しません。 krb5_cc_destroy() は、キャッシュを 0 に設定し、キャッシュを削除するので、もはやそれを参照することはできません。

また、 資格証明キャッシュ関数Heimdal Kerberos 5 資格証明キャッシュ関数を参照してください。

Kerberos エラー

Kerberos エラーは、com_err ライブラリに基づいています。すべてのエラーコードは、32 ビットの符号付きの数値で、最初の 24 ビットは、エラーがどのサブシステムが起源であるかを定義し、最後の 8 ビットは、ライブラリ内の 255 のエラーコードです。各エラーコードには、それに関連した固定の文字列があります。例えば、エラーコード -1765328383 には、シンボリック名 KRB5KDC_ERR_NAME_EXP があり、エラー文字列 ``Client's entry in database has expired'' (データベースのクライアントのエントリは、期限が切れました) に関連しています。

これは、単に unix のエラーコードの 1 つを戻すことに比較して大きな改良です。しかしながら、Heimdal には、カスタマイズされたエラーメッセージを戻すための拡張があります。 ``Key table entry not found'' (キーテーブルのエントリが見つからない) を取得する代わりに、ユーザは、 ``failed to find host/host.example.com@EXAMLE.COM(kvno 3) in keytab /etc/krb5.keytab (des-cbc-crc)'' を戻すでしょう。これは、ユーザが、エラーの原因を見つける機会を改善するので、利用者は、それが利用可能なときはいつでもカスタマイズされたエラーメッセージを使用するべきです。

また、モジュール Heimdal Kerberos 5 エラー報告関数を参照してください。

キータブ (keytab) 管理

キータブは、ローカルに格納されたキーのための記憶域です。 Heimdal は、Kerberos 5 キータブ、Kerberos 4 srvtab、AFS-KeyFile のため、とメモリのキーを格納するためのキータブのサポートを含んでいます。

キータブは、サーバと長期間のサービスのために使用されます。

また、 キータブ操作関数Heimdal Kerberos 5 キータブ操作関数 を参照してください。

Kerberos の暗号

Heimdal は、Kerberos の暗号のフレームワーク、すべての暗号の操作の実装を含んでいます。暗号のコンテキストを作成するためには、 krb5_crypto_init() を呼び出します。

または、モジュール Heimdal Kerberos 5 暗号化関数を参照してください。

Kerberos 5 クライアントのサンプルのウォークスルー

この例は、サンプルの TCP Kerberos 5 クライアントの部分を含んでいます、実際の動作するクライアントを必要とするなら、Heimdal 配布の appl/test ディレクトリを調べてください。

このプログラム中の kerberos 関数から返されるすべての Kerberos エラーコードは、エラーコードの説明文を印刷して、終了する、krb5_err に渡されます。グラフィカルなプログラムは、エラーコードを krb5_get_error_message() 関数で人間に読み込み可能なエラー文字列に変換することができます。

krb5_init_context() が成功して完了する前に、どんな Kerberos 関数を使用するべきでないことに注意してください。それは、 krb5_init_context() が失敗するとき、err() を使用するためです。

最初に、クライアントは、Kerberos 5 ライブラリを初期化するために krb5_init_context を呼び出す必要があります。これは、プログラム中の 1 つのスレッドごとに一度だけ必要です。関数が 0 以外の値を返すなら、それは、Kerberos の実装が失敗しているか、またはこのホストで無効にされていることを示します。


#include <krb5.h>


int
main(int argc, char **argv)
{
krb5_context context;


if (krb5_init_context(&context))
errx (1, 'krb5_context');

今、クライアントは、別の終りでホストに接続したい。これを行う好ましい方法は、getaddrinfo がアドレスタイプに中立で、利用可能なあらゆるプロトコルを使用することができるので、 (この実装された関数があるオペレーティングシステムのために) getaddrinfo を使用しています。


struct addrinfo *ai, *a;
struct addrinfo hints;
int error;


memset (&hints, 0, sizeof(hints));
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;


error = getaddrinfo (hostname, 'pop3', &hints, &ai);
if (error)
errx (1, '%s: %s', hostname, gai_strerror(error));


for (a = ai; a != NULL; a = a->ai_next) {
int s;


s = socket (a->ai_family, a->ai_socktype, a->ai_protocol);
if (s < 0)
continue;
if (connect (s, a->ai_addr, a->ai_addrlen) < 0) {
warn ('connect(%s)', hostname);
close (s);
continue;
}
freeaddrinfo (ai);
ai = NULL;
}
if (ai) {
freeaddrinfo (ai);
errx ('failed to contact %s', hostname);
}

確証の前に、認証コンテキストを作成する必要があります。このコンテキストは、1 つの確証された (認証予定の) 接続のためにすべての情報を保持しています (krb5_auth_context を参照)。


status = krb5_auth_con_init (context, &auth_context);
if (status)
krb5_err (context, 1, status, 'krb5_auth_con_init');

認証でアドレスを設定するために、ソケットに接続されるファイル記述子を与えられるとき、必要とされるものすべてを行うヘルプ関数 krb5_auth_con_setaddrs_from_fd() があります。


status = krb5_auth_con_setaddrs_from_fd (context,
auth_context,
&sock);
if (status)
krb5_err (context, 1, status,
'krb5_auth_con_setaddrs_from_fd');

次のステップは、私たちが接続したいサービスのためのサーバのプリンシパルを構築することです。 (また、 krb5_sname_to_principal() を参照。)


status = krb5_sname_to_principal (context,
hostname,
service,
KRB5_NT_SRV_HST,
&server);
if (status)
krb5_err (context, 1, status, 'krb5_sname_to_principal');

クライアントのプリンシパルは、krb5_sendauth() 関数に渡されず、これによって、 krb5_sendauth() 関数は、それ自体を解明しようと試みます。

サーバプログラムは、Kerberos 5 認証コードを受信するために関数 krb5_recvauth() を使用しています。

この場合、相互認証が試みられます。ということは、サーバがクライアントに確証することです。相互認証を使用することは、正しいサーバ (キーを知っているサーバ) に通信していることを検証するユーザを有効にするので、よいことです。

ブロックされないソケットを使用しているなら、 krb5_sendauth() のすべての仕事を利用者自体が行う必要があります。基本的に、相互認証の場合には、 krb5_rd_rep() があるサーバからの結果を検証して、 krb5_mk_req() から認証コードを送信する必要があります。


status = krb5_sendauth (context,
&auth_context,
&sock,
VERSION,
NULL,
server,
AP_OPTS_MUTUAL_REQUIRED,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL);
if (status)
krb5_err (context, 1, status, 'krb5_sendauth');

いったん認証が行なわれたならば、それは、いくらかのデータを送信する時間です。最初に、krb5_data 構造体を作成し、次に、krb5_sendauth()/krb5_recvauth() 認証シーケンスで交換されたセッションキーを含んでいる auth_context を使用して、 krb5_mk_safe() でそれに署名します。


data.data = 'hej';
data.length = 3;


krb5_data_zero (&packet);


status = krb5_mk_safe (context,
auth_context,
&data,
&packet,
NULL);
if (status)
krb5_err (context, 1, status, 'krb5_mk_safe');

そして、ネットワークを越えてそれを送信します。


len = packet.length;
net_len = htonl(len);


if (krb5_net_write (context, &sock, &net_len, 4) != 4)
err (1, 'krb5_net_write');
if (krb5_net_write (context, &sock, packet.data, len) != len)
err (1, 'krb5_net_write');

暗号化された (そして、署名された) データを送信するために、 krb5_mk_priv() が代わりに使用されるべきです。 krb5_mk_priv() は、それを署名することに加えて、データを暗号化するということを除いて、krb5_mk_safe() と同じように動作します。


data.data = 'hemligt';
data.length = 7;


krb5_data_free (&packet);


status = krb5_mk_priv (context,
auth_context,
&data,
&packet,
NULL);
if (status)
krb5_err (context, 1, status, 'krb5_mk_priv');

そして、ネットワークを越えてそれを送信します。


len = packet.length;
net_len = htonl(len);


if (krb5_net_write (context, &sock, &net_len, 4) != 4)
err (1, 'krb5_net_write');
if (krb5_net_write (context, &sock, packet.data, len) != len)
err (1, 'krb5_net_write');

サーバは、署名を検証し、パケットを復号化するために krb5_rd_safe() と krb5_rd_priv() を使用しています。

アプリケーションでパスワードを確認する

krb5_verify_user() については、マニュアルページを参照してください。

MIT Kerberos との API の相違点

このセクションは、少し整理されていませんが、これまでのところ、全体的な構造の違いはありません、しかしながら、それらのいくつかは、Heimdal が ASN.1 コンパイラと MIT を使用しない、 root があります。訳注: 原文がおかしくて、翻訳できません。

プリンシパルとレルム (アドレス体系)

Heimdal は、krb5_realm (すなわち、char *) としてレルムを格納します MIT Kerberos は、レルムを格納するために krb5_data を使用します。

Heimdal で、krb5_principal は、構成要素の name_type を含んでいません。代りに、構成要素の name.name_type に格納されます。 Heimdal の nametype を取得して、設定するためには、 krb5_principal_get_type()krb5_principal_set_type() を使用します。

プリンシパルとレルムに関する詳細については、krb5_principal を参照してください。

エラーメッセージ

エラー文字列を取得するために、Heimdal は、krb5_get_error_message() を使用します。これは、(error_message を返す ``Key table entry not found'' の代わりに、 ``Can't find host/datan.example.com@CODE.COM in /etc/krb5.conf.'' のように) カスタムのエラーメッセージを返すことです。

Heimdal は、com_err インタフェースのスレッドセーフバージョンを使用します。グローバルな com_err テーブルは、初期化されません。次に、error_message は、全くつまらないエラー文字列 (単なるエラーコード自体) を返します。

11 Jan 2012 Version 1.5.2