Apacheのダイジェスト認証DB(いわゆる.htdigest)のエントリを生成するスクリ プトを書いた。
-
kanatouserid.rb:
日本語仮名表記の名前を与えると、ユーザIDの案を出力する。 -
tohtdigest.rb:
ユーザIDとパスワードとrealmを与えると、htdigest向けの エントリを出力する。
使い方
% echo "やまだ たろう\nすずき はなこ" | kanatouserid.rb
tyamada
hsuzuki
% echo -n "userid PASSWORD" | tohtdigest.rb --realm=realm
userid:realm:3c5849e99abf53956919e822fd3c6f32
% apg
...
% cat | kanatouserid.rb | tohtdigest.rb --realm=foo
やまだ たろう
すずき はなこ
^D
...
tyamada:foo:6cd6ad4e982e880951edf09b93677793
hsuzuki:foo:3ea0703da39fdd92b9c7d00e9df67d74
%
kanatouserid.rb
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
# usage:
# % echo "やまだ たろう\nすずき はなこ" | kanatouserid.rb
# tyamada
# hsuzuki
# requirements: ruby, kakasi
# license: public domain
require 'nkf'
kana_names = ARGF.readlines
roman_names = kana_names.map{|n|
if /./.match(n)
IO.popen("kakasi -Ha -Ka -Ja -Ea -ka", "rb+"){|k|
k.puts NKF.nkf("--unix", n)
k.close_write
k.gets
}
else
$stderr.print "Warn: cannot convert to roman: #{n.inspect}\n"
end
}
userids = roman_names.map{|n|
if /[^\s]+?\s+?[^\s]+?/.match(n)
family, given = n.split(/\s+/)
given.split(//).first + family # jdoe
else
$stderr.print "Warn: invalid name (order family given):
#{n.inspect}\n"
end
}
userids.map{|u|
puts u
}
tohtdigest.rb
#!/usr/bin/ruby
# -*- coding: utf-8 -*-
# htdigest helper
# usage:
# % echo -n "userid PASSWORD" \
# | tohtdigest.rb --realm=realm \
# >> /path/to/apache2/.htdigest
# % tail -n 1 /path/to/apache2/.htdigest
# userid:realm:3c5849e99abf53956919e822fd3c6f32
# requirements: ruby, openssl
# license: public domain
module HTDigest
def htdigest(userid, realm, password)
src = [userid, realm, password].join(":")
hash = ` echo -n #{src} | openssl dgst -md5`.chomp
[userid, realm, hash].join(":")
end
module_function :htdigest
end
def main(lines, config)
entries = lines.map{|l|
userid, password = l.split(/\s+/)
HTDigest.htdigest(userid, config[:realm], password)
}
puts entries
end
if $0 == __FILE__
# handle options
require 'optparse'
default_config = {
:realm => nil,
:test => false
}
clo = command_line_options = {}
ARGV.options {|o|
o.def_option('--realm=REALM',
'specify realm (mandatory)',
String){|s| clo[:realm] = s}
o.def_option('--test', 'run test'){clo[:test] = true}
o.def_option('--help', 'show this message'){puts o; exit(0)}
o.parse!
} or exit(1)
unless clo[:realm]
raise OptionParser::MissingArgument, "--realm option required"
end
config = default_config.update(clo)
if config[:test]
# run test
require 'test/unit'
class TC_HTDigest < Test::Unit::TestCase
def setup
@srcs = [["userid", "realm", "PASSWORD"],
["jdoe", "realm", "sesame"]]
end
def test_htdigest
expected = ["userid:realm:3c5849e99abf53956919e822fd3c6f32",
"jdoe:realm:92c75fce053b3dc40e3571ecd4c2822f"]
result = @srcs.map{|s| HTDigest.htdigest(s[0], s[1], s[2])}
assert_equal(expected, result)
end
end
else
# run main
lines = ARGF.readlines
main(lines, config)
end
end
Other Articles
- 13 Oct 2017: 『テスト駆動開発』
- 19 Oct 2016: 『新装版 達人プログラマー 職人から名匠への道』
- 19 Aug 2016: 『プログラミングElixir』
- 20 Oct 2015: Migrating from git-media to git-lfs
- 04 Oct 2015: Git Large File Storageクライアントのインストール
- 12 Aug 2015: isbn.rb
- 22 Apr 2015: 「なるのか、なすのか?」(To Be Or To Do?)