ワイルド過ぎる realm のワイルドカードを何とかしたい - 前編 -
openid.realm の値が例えば、
- *.org
- *.co.jp
みたいなケース。これだと大多数のドメインを許可する事になってしまうので、これを避けたいと言う話。
どうすれば良いか
ではサンプルとして、openid.example.co.jp を取り上げて考えて見ましょう。
ドメイン部ですけど、カンマ区切りで右端にある物を TLD (top level domain) と言います。例えば .jp だとか .org だとか。
Top-level domain - Wikipedia によれば、主要なTLDとして
と言った物が挙げられます。*1
でちょっと脇道にそれてしまったけども、まずドメインの右端が TLD にマッチする事が必須条件。ここでは .jp がそれに当たるので残りは openid.example.co となります。
ここで次の右端である .co ですが SLD (second level domain) と言います。www.example.org ならば example がそれに当たります。
SLD までで、特定の所有者に紐づくのかそうでないかでワイルドな realm なのか、そうでないのかを判断して良いかと思います。なので、
- *.co.jp は複数の所有者が考えられるので NG
- *.example.org は特定の所有者だと考えられるので OK
って事になります。SLD でも ccTLD に紐づく SLD の事を ccSLD (country code SLD) と言うようです。
さて、wikipedia (en) の当該ページにあるリンクには Mozilla の Wiki へのリンクがあります。
ただこれはどの程度、メンテナンスされてる情報かがイマイチ分からないのですよねぇ。とか思ってググってたら Mozilla がちゃんとメンテナンスしている事が分かりました。
- Public Suffix List - MozillaWiki
- Gecko:Effective TLD Service - MozillaWiki
- Public Suffix List
- effective_tld_names.dat
nsIEffectiveTLDService ってのがあるらしく、元データは effective_tld_names.dat と言うファイルに集約されているみたいです。ここに ccSLD も含めた有効なドメインのパターンが存在し、結構ちゃんとメンテナンスされているみたいです。
ただ最近話題になっていた .me と言う ccTLD なんかはまだ無いみたい。Mozilla++ ですね。
さて Perl で書いてみよう
まず TLD ですが、Net::Domain::TLD と言うモジュールがありまして、ここから TLD のリストを得る事が出来ます。
#!/usr/bin/perl use strict; use warnings; use Perl6::Say; use Data::Dump qw(dump); use Net::Domain::TLD qw(tlds tld_exists); say '[tld types] ' . join(', ', Net::Domain::TLD::TLD_TYPES); say '-' x 50; say '[' . $_ . '] ' . join(', ', tlds($_)) for (Net::Domain::TLD::TLD_TYPES);
TLD の種別の出力と、TLD の種別ごとに TLD 一覧を出力します。
- new_open
- new_restricted
- gtld_open
- gtld_restricted
- cc
と言うのが種別になります。
tld_exists は、
と言うのを調べられます。
#!/usr/bin/perl use strict; use warnings; use Perl6::Say; use Data::Dump qw(dump); use Net::Domain::TLD qw(tlds tld_exists); say dump(tld_exists('org')); # org は TLD かどうか -> 1 say dump(tld_exists('hoge')); # hoge は TLD かどうか -> 0 say dump(tld_exists('jp', 'cc')); # jp は ccTLD かどうか -> 1 say dump(tld_exists('com', 'cc')); # com は ccTLD かどうか -> 0
TLD は調べられますが、SLD まではどうにもならないので、effective_tld_names.dat を利用してみます。
Gecko:Effective TLD Service - MozillaWiki によるとこのファイルの記述ルールは、
と言うルールのようです。
まずこれらのルールを考慮して TLD がどれだけ網羅されているか、Net::Domain::TLD と比較してみます。
#!/usr/bin/perl use strict; use warnings; use Data::Dump qw(dump); use LWP::UserAgent; use Net::Domain::TLD qw(tlds); use Perl6::Say; my $tld_names = 'http://mxr.mozilla.org/mozilla/source//netwerk/dns/src/effective_tld_names.dat?raw=1'; my $ua = LWP::UserAgent->new; my $res = $ua->get($tld_names); unless ($res->is_success) { die; } my %tlds = (); for (split "\n" => $res->content) { s|(//.*)||g; s|\s+||g; next if (/^\n*$/); my $tld = ((split(/\./, $_))[-1]); $tlds{$tld}++; } say dump(scalar keys %tlds); say dump(scalar (my @tlds = tlds)); say "-" x 50; say dump(grep { !exists $tlds{$_} } @tlds);
結果は、
256 272 -------------------------------------------------- ( "sj", "bv", "gb", "wf", "um", "me", "pm", "rs", "mf", "eh", "tp", "yt", "kp", "so", "bl", "tel", )
なるほどなるほど。16個の TLD が Mozilla のリストからは漏れてるみたいです。
この未調査の TLD の事は別途何とかするかするとして、このデータを上手く使えば、ccSLD まで考慮に入れて realm の検証が出来そうです。
という訳で
次回、ccSLD も考慮に入れたモジュールを作ってみちゃったりする予定です。