モジュール
標準構成でユーザ認証をするためには,auth.so, auth_db.so, mysql.soと言ったモジュールが必要で,マニュアルによると,auth.so, auth_db.soを使うためにはmysql.soが必要だと書いてあります.ところが実際に試してみたところ,auth.soをはmysql.soを必要としませんでした.そこで,設定ファイルの認証部分,
if (!www_authorize("iptel.org", "subscriber")) { www_challenge("iptel.org", "0"); break; }; save("location"); break;
で使っている関数のうち,www_authorizeはauth_db.soをwww_challengeはauth.soを使っていたので,この部分を,
if(!exec_msg("/usr/local/sbin/ser_acc.pl")){ www_challenge("iptel.org", "0"); break; }; save("location"); break; };
と変更して認証できることを確認しました.このとき使ったser_scc.plスクリプトは以下のようになります.
#!/bin/perl # ser_acc.pl use Digest::MD5 qw(md5_hex); use strict; my ($auth, $userid, $realm, $nonce, $uri, $response); my $pass; my ($a1, $a2, $digest); $auth = $ENV{SIP_HF_AUTHORIZATION}; $pass = "def" # テスト用 exit 1 unless ($auth); if($auth =~ m{userid=\"([0-9a-zA-Z]+)\"}){ $userid = $1; } if($auth =~ m{realm=\"([0-9a-zA-Z.]+)\"}){ $realm = $1; } if($auth =~ m{nonce=\"([0-9a-zA-Z]+)\"}){ $nonce = $1; } if($auth =~ m{uri=\"([0-9a-zA-Z.:]+)\"}){ $uri = $1; } if($auth =~ m{response=\"([0-9a-zA-Z]+)\"}){ $response = $1; } exit 1 unless ($userid && $realm && $nonce && $uri && $response); $a1 = md5_hex( $userid . ':' . $realm . ':' . $pass ); $a2 = md5_hex( 'REGISTER' . ':' . $uri ); $digest = md5_hex ($a1 . ':' . $nonce . ':' . $a2 ); exit 1 if ($response ne $digest); }
このスクリプトはREGISTERパケットのヘッダからAUTHORIZATIONフィールドを抜き出し,ダイジェスト認証を使って認証を行います.正常であればexit 0 を問題があればexit 1を最終的に実行します.exitしたときの値がexec_msgの返値になるので,これを使えばwww_authorizeの代わりになるというわけです.
このときのser.cfgは以下のようになります.
# # SER config script # # ----------- global configuration parameters ------------------------ check_via=no dns=no rev_dns=no fifo="/tmp/ser_fifo" # ------------------ module loading ---------------------------------- loadmodule "/usr/local/lib/ser/modules/sl.so" loadmodule "/usr/local/lib/ser/modules/tm.so" loadmodule "/usr/local/lib/ser/modules/rr.so" loadmodule "/usr/local/lib/ser/modules/maxfwd.so" loadmodule "/usr/local/lib/ser/modules/usrloc.so" loadmodule "/usr/local/lib/ser/modules/registrar.so" loadmodule "/usr/local/lib/ser/modules/exec.so" loadmodule "/usr/local/lib/ser/modules/auth.so" # ----------------- setting module-specific parameters --------------- # -- usrloc params -- modparam("usrloc", "db_mode", 0) # -- rr params -- modparam("rr", "enable_full_lr", 1) # ------------------------- request routing logic ------------------- # main routing logic route{ if (!mf_process_maxfwd_header("10")) { sl_send_reply("483","Too Many Hops"); break; }; if ( msg:len > max_len ) { sl_send_reply("513", "Message too big"); break; }; record_route(); if (loose_route()) { t_relay(); break; }; if (uri==myself) { if (method=="REGISTER") { if(!exec_msg("/usr/local/sbin/ser_acc.pl")){ www_challenge("iptel.org", "0"); break; }; save("location"); break; }; if (!lookup("location")) { sl_send_reply("404", "Not Found"); break; }; }; if (!t_relay()) { sl_reply_error(); }; }
これを使って何か面白いことできないかな. (^^;