LIBRADIUS(3)

名称
libradius - RADIUS クライアントライブラリ

書式
#include <radlib.h> int rad_add_server(struct rad_handle *h, const char *host, int port, const char *secret, int timeout, int max_tries) void rad_close(struct rad_handle *h) int rad_config(struct rad_handle *h, const char *file) int rad_continue_send_request(struct rad_handle *h, int selected, int *fd, struct timeval *tv) int rad_create_request(struct rad_handle *h, int code) struct in_addr rad_cvt_addr(const void *data) u_int32_t rad_cvt_int(const void *data) char * rad_cvt_string(const void *data, size_t len) int rad_get_attr(struct rad_handle *h, const void **data, size_t *len) int rad_init_send_request(struct rad_handle *h, int *fd, struct timeval *tv) struct rad_handle * rad_open(void) int rad_put_addr(struct rad_handle *h, int type, struct in_addr addr) int rad_put_attr(struct rad_handle *h, int type, const void *data, size_t len) int rad_put_int(struct rad_handle *h, int type, u_int32_t value) int rad_put_string(struct rad_handle *h, int type, const char *str) int rad_send_request(struct rad_handle *h) const char * rad_strerror(struct rad_handle *h)

解説
libradius ライブラリは、ユーザサービス遠隔認証ダイアル (RADIUS) の クライアント側を実装しています。 RADIUS は で定義されており、 クライアントはリモート認証サーバへのネットワーク要求により認証を 受けることができます。

初期設定
ライブラリを使用する場合にアプリケーションは、まず rad_open() 呼び出して、次の操作のためのコンテキストを与える struct rad_handle * を取得します。 rad_open() 呼び出しは、仮想メモリが足りない場合を除いて、常に正常終了します。 必要なメモリが割り当てられないとき、 rad_open() は ヌル を返します。

RADIUS への要求を出す前に、ライブラリはコンタクト可能なサーバを 確認しなければなりません。ライブラリの設定をする最も簡単な方法は rad_config() を呼び出すことです。 rad_config() によって、ライブラリは radius.conf(5) でフォーマットが定義されているコンフィグレーションファイルを読み込みます。 コンフィグレーションファイルのパス名は引数 file として rad_config() へ渡されます。この引数には ヌル が 指定されてもかまいません。その場合は標準コンフィグレーションファイル /etc/radius.conf が使われます。 rad_config() は、正常終了時には 0 を返し、エラー終了時には -1 を返します。

ライブラリは rad_add_server() を呼び出すことによって、決まった手順で 設定することもできます。パラメータ host パラメータは、サーバホストを指定し、 完全なドメイン名 (FQDN) でも、またはドット区切りの四つの数字でテキスト形式 で書かれた IP アドレスのどちらで指定してもかまいません。 パラメータ port は、サーバに接続するときの UDP ポート番号を指定します。 port の指定が 0 のとき、ライブラリはネットワークサービスデータベースの ‘radius/udp’ サービスを検索し、見つかったポートを使用します。 エントリが見つからないときには、ライブラリはポート 1812 の標準 RADIUS ポートを使用します。サーバホストに関する共有シークレット情報は、 パラメータ secret として渡されます。パラメータは ヌル で終了するどんな文字列もかまいません。 RADIUS プロトコルでは、共有 シークレット情報の 128 バイトより後は無視されます。サーバからの受信 タイムアウトは、パラメータ timeout により、秒の単位で渡されます。要求をあきらめるまでの 最大繰り返し回数は、パラメータ max_tries で渡されます。 rad_add_server() は 正常終了のときは 0 を返し、エラーが発生したときは -1 を返します。

rad_add_server() は、複数回呼び出しが可能で、 rad_config() と共に使用することができます。 サーバは、10 個まで指定できます。複数サーバが 指定された場合、正しい応答が得られるか、またはサーバの max_tries 制限に達するまで、ラウンドロビン方式で呼び出しを試みます。

RADIUS 要求の生成
RADIUS 要求は、要求の種類を指定するコードと、ゼロあるいは 付加情報を与える複数の属性値で構成されます。新規要求の作成は、まず rad_create_request() 呼び出しから始めます。通常の struct rad_handle * に加えて、 この関数は、パラメータ code を取り、それにより要求タイプを指定します。大抵 RAD_ACCESS_REQUEST が指定されます。 rad_create_request() は正常終了のときは 0 を返し、エラーが発生したときは -1 を返します。

rad_create_request() により要求が生成された後、属性を付加することができます。これは、 rad_put_addr(), rad_put_int(), rad_put_string() 呼び出しにより行われます。これらは、属性を決めるパラメータ type や、インターネットアドレス値、整数値、 ナル文字 で終了する文字列を、それぞれに受け取ります。

ライブラリには、関数 rad_put_attr() も備わっているので、未加工で解釈できない属性も 与えることができます。引数 data は、バイト配列の先頭のポインタで、 引数 len は、その長さを指定します。

関数 rad_put_X() は、正常終了時には 0 返し、エラー発生時には -1 を返します。

要求の送信と応答の受信
RADIUS 要求は生成された後、 rad_send_request() または rad_init_send_request() と rad_continue_send_request() 呼び出しの組み 合わせにより、送信されます。

関数 rad_send_request() は、要求を送信し、必要ならば定義されたサーバに対して ラウンドロビン方式で接続を試み、正しい応答がを待ちます。 正しい応答があった場合、 rad_send_request() は応答のタイプを指定する RADIUS コードを返します。 戻り値は、一般に RAD_ACCESS_ACCEPT, RAD_ACCESS_REJECT, RAD_ACCESS_CHALLENGE です。正しくない応答を受信したとき、 rad_send_request() は -1 を返します。

応答待ちをブロックしたくない場合は、代わりに rad_init_send_request() および rad_continue_send_request() を使えます。 RADIUS サーバからの返答を受信するか、 またはタイムアウトになった場合、これらの関数は rad_send_request() の項で挙げた値を返します。それ以外では、ゼロが返され、 fd および tv での指す値が select(2) に渡されるディスクリプタとタイムアウトに設定されます。

rad_init_send_request() は最初に呼び出す必要があり、続いて、戻り値が 0 でなくなるまで rad_continue_send_request() 呼び出しを繰り返します。 それぞれの呼び出しの間に、アプリケーションは、 select(2) を呼び出す必要があり、その際 *fd を読み出しディスクリプタとして渡し、 tv で定義される時間経過の後、タイムアウトします。 select から制御が戻ったとき、 select(2) でディスクリプタが読み出し可能である場合は、引数 selected に 0 でない値を設定して rad_continue_send_request() を呼び出す必要があります。

RADIUS への要求と同じように、各応答は 0 または、 それ以上の属性を持っています。応答が rad_send_request() または rad_continue_send_request() により正常に受信された後、属性は rad_get_attr() によって、1 つずつ取り出すことができます。 rad_get_attr() 呼び出しが呼ばれるたびに、現在の応答から次の属性を 取得し、参照パラメータ data および len を介して、データへのポインタとデータ長をそれぞれ保管します。 データは応答それ自身の中に存在し、 変更してはいけないということに注意して下さい。 rad_get_attr() 呼び出しは、正常終了すると RADIUS 属性タイプを返します。 現在の応答内に属性が無くなると rad_get_attr() は 0 を返します。不正な属性のようなエラーが検出されると、 -1 を返します。

属性の共通タイプは、 rad_cvt_addr(), rad_cvt_int(), rad_cvt_string() によりデコードすることができます。これらの関数は、 rad_get_attr() により取得される属性データへのポインタを受け取ります。 rad_cvt_string() の 場合は、 len で長さも指定する必要があります。これらの関数は、属性を インターネットアドレスや整数値、文字列などとして解釈し、得られた値を 戻り値として返します。 rad_cvt_string() はメモリを動的に割り当て、 ヌル で終了した文字列を返します。アプリケーションは、不要な文字列を free(3) を使って解放しなければなりません。

十分な仮想メモリがない場合、 rad_cvt_string() は ヌル を返します。 rad_cvt_addr() および rad_cvt_int() がエラー終了することはありません。

エラーメッセージ取得
引数 struct rad_handle * を受け取る関数は、異常終了の場合にエラーメッセージを記録します。 このエラーメッセージは rad_strerror() 呼び出しで取り出すことができます。メッセージテキストは、得られた struct rad_handle * により、新しいエラーで上書きされます。 そのため、メッセージを保存しておくべきなら、 同一のハンドルを使って引き続きライブラリ呼び出しを行うことで、 複写しておかなければなりません。

クリーンアップ
RADIUS ライブラリで使用したリソースは、 rad_close() を呼び出しで解放できます。

戻り値
以下の関数は、処理が正常に終了時、負でない値を返します。エラーを 検出したときは、 -1 を返し、 rad_strerror() を使用して取出した エラーメッセージを記録します。

rad_add_server()
rad_config()
rad_create_request()
rad_get_attr()
rad_put_addr()
rad_put_attr()
rad_put_int()
rad_put_string()
rad_init_send_request()
rad_continue_send_request()
rad_send_request()

以下の関数は、処理が正常に終了した時、 ヌル でないポインタを返します。 十分な仮想メモリの割り当てができないとき、 ヌル を返しますが、 エラーメッセージは記録されません。

rad_cvt_string()
rad_open()

関連ファイル
/etc/radius.conf

関連項目
radius.conf(5) C. Rigney, et al, Remote Authentication Dial In User Service (RADIUS), RFC 2138.

作者
このソフトウェアの作成者は John Polstra であり、Juniper Networks, Inc により FreeBSD プロジェクトに寄贈されました。