私事ですが、1月末に12年弱勤めた会社を退職しました。
中堅SIerの、名もなき一社員の退職なので「退職しました」的エントリーを書くのもおこがましいのですが、退職を決断するまでに色々な事を考え、自分なりに期すところがあったので、決意表明としてここに書き残しておきたいと思います。
よろしければお付き合い下さい。
続きを読む
2012年03月01日
2011年11月22日
groupに関するエトセトラ
Linuxでユーザの情報を確認しようと思ったらidコマンド。
んじゃグループを確認しようと思ったらどうすんの?/etc/groupをcatするしかないの?と思って調べてみたら、ちゃんと確認方法ありました。
getentコマンド自体はグループを確認するためのコマンドではなく、管理系のデータベース(groupとかpasswdとかhostsとか)から値を引っ張ってくるコマンドなのですが、単なるcatと違うのはネットワーク上の名前解決にも対応している事。なのでLDAP上に登録されてるユーザやグループ、DNSに問い合わせるべきホスト情報とかもgetentで取得できるのです。これは便利!
例えばgoogle.comの名前解決ならこんな感じ。
nslookupでも同じ事出来るのですが、この手の(管理系の)データに同じインターフェースでアクセスできるのは分かりやすくてGood。sudo使った権限管理とかもやりやすそうですし。
で、これを調べているうちに面白いコマンドに出会いました。それがnewgrpコマンド。自分自身のプライマリグループを変えるためのコマンドです。
例えばこんなユーザがいたとしましょう。
このユーザがファイルを作成したら、当然ですが所有者はhogehoge:hogeになります。
ここで、fugaグループにログイン(プライマリグループの変更)します。
プライマリグループがfugaに変更されている事が分かります。
もちろんファイルを作成したら、
と、hogehoge:fugaが所有者になります。
権限を元に戻すには、exitすればOKです。(グループにログインしていたので)
さらに、自分の所属グループ以外であってもログインする事が可能です。
ここではpiyoというグループにログインしてみましょう。
自分が所属していないグループへのログインにはパスワードが必要になります。パスワードの設定されていないグループへのログインは出来ません。
では、この状態でファイルを作成してみましょう。
すごーく当たり前の話ですが、hogehoge:piyoを所有者とするファイルが作成されました。
さて、ここで「グループに対するパスワードって何ぞ?」という疑問が湧いてくるかと思うのですが、これもちゃんとコマンドが用意されていました。
普通はグループへのパスワード設定なんてしないですよね…newgrp知らないと意味分かんないですし。
ここまでグループがユーザと同じように扱えるなら、suのグループ版だってあるんじゃね?と思って調べたらやっぱりありました。
その名もsgコマンド。(超そのまんま)
これはもう解説不要ですね。- をつけると環境の再初期化をするってのもsuと同じなのですが、環境を設定してる.profileなり.bashrcなりってユーザ単位で設定されますよね?グループの場合 - がどう効いてくるのか今ひとつピンと来ていないのですが…まぁいい事にします。
この辺きちんと意識して使うと、ついつい甘くなりがちな管理者権限の局所化ってのがよりうまい感じに出来るのかもしれません。ちょっと色々試してみたいなこれ。
以下のサイトを参考にさせていただきました。(ありがとうございます!)
Linux グループ一覧の確認と/etc/group ファイル
http://kazmax.zpp.jp/linux_beginner/etc_group.html
getentコマンドでユーザ情報を確認
OpenGroove : http://open-groove.net/linux-command/getent/
Studio ODIN - blog風小ネタ集 > newgrp コマンドでグループを変更する
http://www.odin.hyork.net/write/write0311.html
んじゃグループを確認しようと思ったらどうすんの?/etc/groupをcatするしかないの?と思って調べてみたら、ちゃんと確認方法ありました。
getent group hoge
getentコマンド自体はグループを確認するためのコマンドではなく、管理系のデータベース(groupとかpasswdとかhostsとか)から値を引っ張ってくるコマンドなのですが、単なるcatと違うのはネットワーク上の名前解決にも対応している事。なのでLDAP上に登録されてるユーザやグループ、DNSに問い合わせるべきホスト情報とかもgetentで取得できるのです。これは便利!
例えばgoogle.comの名前解決ならこんな感じ。
getent hosts google.com
nslookupでも同じ事出来るのですが、この手の(管理系の)データに同じインターフェースでアクセスできるのは分かりやすくてGood。sudo使った権限管理とかもやりやすそうですし。
で、これを調べているうちに面白いコマンドに出会いました。それがnewgrpコマンド。自分自身のプライマリグループを変えるためのコマンドです。
例えばこんなユーザがいたとしましょう。
$ id
uid=700(hogehoge) gid=700(hoge) 所属グループ=700(hoge),701(fuga)
uid=700(hogehoge) gid=700(hoge) 所属グループ=700(hoge),701(fuga)
このユーザがファイルを作成したら、当然ですが所有者はhogehoge:hogeになります。
$ touch hogefile
$ ls -l hogefile
-rw-r--r-- 1 hogehoge hoge 0 11月 22 10:40 hogefile
$ ls -l hogefile
-rw-r--r-- 1 hogehoge hoge 0 11月 22 10:40 hogefile
ここで、fugaグループにログイン(プライマリグループの変更)します。
$ newgrp fuga
$ id
uid=700(hogehoge) gid=701(fuga) groups=700(hoge),701(fuga)
$ id
uid=700(hogehoge) gid=701(fuga) groups=700(hoge),701(fuga)
プライマリグループがfugaに変更されている事が分かります。
もちろんファイルを作成したら、
$ touch fugafile
$ ls -l fugafile
-rw-r--r-- 1 hogehoge fuga 0 Nov 22 10:42 fugafile
$ ls -l fugafile
-rw-r--r-- 1 hogehoge fuga 0 Nov 22 10:42 fugafile
と、hogehoge:fugaが所有者になります。
権限を元に戻すには、exitすればOKです。(グループにログインしていたので)
さらに、自分の所属グループ以外であってもログインする事が可能です。
ここではpiyoというグループにログインしてみましょう。
$ newgrp piyo
パスワード:
$ id
uid=700(hogehoge) gid=702(piyo) groups=700(hoge),701(fuga),702(piyo)
パスワード:
$ id
uid=700(hogehoge) gid=702(piyo) groups=700(hoge),701(fuga),702(piyo)
自分が所属していないグループへのログインにはパスワードが必要になります。パスワードの設定されていないグループへのログインは出来ません。
では、この状態でファイルを作成してみましょう。
$ touch piyofile
$ ls -l piyofile
-rw-r--r-- 1 hogehoge piyo 0 Nov 22 10:46 piyofile
$ ls -l piyofile
-rw-r--r-- 1 hogehoge piyo 0 Nov 22 10:46 piyofile
すごーく当たり前の話ですが、hogehoge:piyoを所有者とするファイルが作成されました。
さて、ここで「グループに対するパスワードって何ぞ?」という疑問が湧いてくるかと思うのですが、これもちゃんとコマンドが用意されていました。
gpasswd piyo
普通はグループへのパスワード設定なんてしないですよね…newgrp知らないと意味分かんないですし。
ここまでグループがユーザと同じように扱えるなら、suのグループ版だってあるんじゃね?と思って調べたらやっぱりありました。
その名もsgコマンド。(超そのまんま)
$ sg fuga -c "touch sgfugafile"
$ ls -l sgfugafile
-rw-r--r-- 1 hogehoge fuga 0 11月 22 10:59 sgfugafile
$ ls -l sgfugafile
-rw-r--r-- 1 hogehoge fuga 0 11月 22 10:59 sgfugafile
これはもう解説不要ですね。- をつけると環境の再初期化をするってのもsuと同じなのですが、環境を設定してる.profileなり.bashrcなりってユーザ単位で設定されますよね?グループの場合 - がどう効いてくるのか今ひとつピンと来ていないのですが…まぁいい事にします。
この辺きちんと意識して使うと、ついつい甘くなりがちな管理者権限の局所化ってのがよりうまい感じに出来るのかもしれません。ちょっと色々試してみたいなこれ。
以下のサイトを参考にさせていただきました。(ありがとうございます!)
Linux グループ一覧の確認と/etc/group ファイル
http://kazmax.zpp.jp/linux_beginner/etc_group.html
getentコマンドでユーザ情報を確認
OpenGroove : http://open-groove.net/linux-command/getent/
Studio ODIN - blog風小ネタ集 > newgrp コマンドでグループを変更する
http://www.odin.hyork.net/write/write0311.html
2011年05月26日
2011年05月14日
2011年05月10日
フォント置き換え用のupdate.zipを作る (for DHD/CM7)
突然ですが、愛機NexusOneを里子に出して、DesireHDを入手しました。
もちろん毎度お馴染みCyanogenModを入れて使っているわけです。はい。
で、これまたいつもの事ながら、Nightly Buildをがんがん試してしまうわけですが、NexusOneの時に作成したフォント置き換え用のupdate.zipがうまく動きません。これは困った。
DHDの場合解像度も変更したいので、改めてフォント置き換え&解像度変更用のupdate.zipを作ることにしました。
毎度毎度のお約束。以下の内容は全て無保証です。
煉瓦になってもくじけない。転ばぬ先のバックアップ!
続きを読む
もちろん毎度お馴染みCyanogenModを入れて使っているわけです。はい。
で、これまたいつもの事ながら、Nightly Buildをがんがん試してしまうわけですが、NexusOneの時に作成したフォント置き換え用のupdate.zipがうまく動きません。これは困った。
DHDの場合解像度も変更したいので、改めてフォント置き換え&解像度変更用のupdate.zipを作ることにしました。
毎度毎度のお約束。以下の内容は全て無保証です。
煉瓦になってもくじけない。転ばぬ先のバックアップ!
続きを読む
2011年02月10日
HT-03Aでまだまだ戦う (RAM増量編)
ドコモ的にはすっかりなかった事にされているHT-03Aですが、私の手元ではまだまだ最前線で活躍中です。
(と言ってもさすがにメインではなく、ほぼ通話専用のサブ機ですが)
CM6を乗せて、Class10のSDにswap確保して、クロックアップすればまだまだ普通に使えるのですが、やはり一番のネックはメモリの少なさ。96MBはいくら何でも厳しい。swapなしだとまともに動かないし、Class10とは言えSDに対するswap IN/OUTはかなりの重労働。あと5MBでも10MBでもいいから何とか絞り出せないものか…と思ったら、何と大容量15MBも捻出できる事が分かりました。
と言うわけで、久しぶりにこのタイトルで記事を書いてみます。
今さらこの記事読んでうひょうひょするような方は前提知識十分だと思いますので、手順はざっくりと端折って書きます。カスタムROMをそれなりに焼いた事がある方なら問題ないと思いますが、手順読んで疑問点があるようならそっとブラウザを閉じていただくのが吉かと。(hboot/recovery/boot全て書き換えるので派手に手順を間違えると綺麗な文鎮が完成する事請け合いです)
煉瓦を作っても後悔しない方だけ、先の手順に進んで下さい。
続きを読む
(と言ってもさすがにメインではなく、ほぼ通話専用のサブ機ですが)
CM6を乗せて、Class10のSDにswap確保して、クロックアップすればまだまだ普通に使えるのですが、やはり一番のネックはメモリの少なさ。96MBはいくら何でも厳しい。swapなしだとまともに動かないし、Class10とは言えSDに対するswap IN/OUTはかなりの重労働。あと5MBでも10MBでもいいから何とか絞り出せないものか…と思ったら、何と大容量15MBも捻出できる事が分かりました。
と言うわけで、久しぶりにこのタイトルで記事を書いてみます。
今さらこの記事読んでうひょうひょするような方は前提知識十分だと思いますので、手順はざっくりと端折って書きます。カスタムROMをそれなりに焼いた事がある方なら問題ないと思いますが、手順読んで疑問点があるようならそっとブラウザを閉じていただくのが吉かと。(hboot/recovery/boot全て書き換えるので派手に手順を間違えると綺麗な文鎮が完成する事請け合いです)
煉瓦を作っても後悔しない方だけ、先の手順に進んで下さい。
続きを読む
2010年11月12日
Gmailから携帯メールを使う(自前サーバ&iPhone回線持ち限定)
事の発端は、ひとりぶろぐでおなじみmoyashiさんのtwitterでのこんな呟き。
iPhone発売当時、SMS/MMSに対応しないiPhoneへの苦肉の策として導入されたi.softbank.jpというアドレス。私がiPhoneを手にした時はちょうどMMS対応するかしないかくらいのタイミングだったので、私自身はほとんど使っていないし、周りにも使っている人がいない(みんな覚えてもない?)という可哀想な子なのですが、このアドレスには実は他にはないすばらしい特徴があります。
・キャリア回線不要で使えるただのIMAPメール
・携帯各社の中では携帯メールとして認識されている
つまり、回線にも機材(端末)にも全く縛られないメールでありながら、「携帯メールのみ受け取り」と設定している相手にちゃんと届くメールなのです。これを活用しない手はない、とi.softbank.jpとGmailを統合してしまったのが最初の呟きで紹介されていたblog記事でした。
これは私もやってみたい!と思い、記事の通りに設定を始めた(記事の内容が完璧なのでここでは省略…手抜きですいません)のですが、一つ困ったことが。紹介されていた手順では自分のサーバ内にメール送信をしてくれる人(sendmailとかですね)がいることが前提になっているのですが、私はその環境を持っていません。入れて入らないことはないのですが、出来れば送信サーバはGmailとか既存のサービスを使いたい…と思って苦悩していたら、SHIMI.INFOでおなじみ清水さんが「このスクリプト使ってごら〜ん」と助け船を出してくださいました。
str2imap.rb
このスクリプトを/home/hoge(場所はどこでもいいですよ)に配置したら、.fetchmailrcを以下の通り記述します。
.fetchmailrc
あとはfetchmailを起動するだけ。
動きっぱなしになるので完全な裏起動にしましょう。
これでi.softbank.jpに送られたメールは即時にGmailに転送されます。
これならSIMなしの端末からでもメール送れるし、そもそもどの端末、どの回線を使っているかを全く相手に意識させずにこちらが自由に振る舞える。これはある意味真のMNPかも。全キャリア共通でIMAPなメールサーバ作ってくれないかなー。
moyashiさん、清水さん、いのたん♪さん、どうもありがとうございました!
管理人の部屋: i.softbank.jpとGmailの統合
http://gtbleds18.blogspot.com/2010/04/isoftbankjpgmail.html
Togetter - 「i.softbank.jpをGmailに統合するための試行錯誤」
http://togetter.com/li/65323
i.softbank.jp宛メールをfetchmailでGmailにリアルタイム転送 "i.softbank.jpとGmailの統合" http://bit.ly/aDNuRa
(http://twitter.com/hitoriblog/status/28971894276)
(http://twitter.com/hitoriblog/status/28971894276)
iPhone発売当時、SMS/MMSに対応しないiPhoneへの苦肉の策として導入されたi.softbank.jpというアドレス。私がiPhoneを手にした時はちょうどMMS対応するかしないかくらいのタイミングだったので、私自身はほとんど使っていないし、周りにも使っている人がいない(みんな覚えてもない?)という可哀想な子なのですが、このアドレスには実は他にはないすばらしい特徴があります。
・キャリア回線不要で使えるただのIMAPメール
・携帯各社の中では携帯メールとして認識されている
つまり、回線にも機材(端末)にも全く縛られないメールでありながら、「携帯メールのみ受け取り」と設定している相手にちゃんと届くメールなのです。これを活用しない手はない、とi.softbank.jpとGmailを統合してしまったのが最初の呟きで紹介されていたblog記事でした。
これは私もやってみたい!と思い、記事の通りに設定を始めた(記事の内容が完璧なのでここでは省略…手抜きですいません)のですが、一つ困ったことが。紹介されていた手順では自分のサーバ内にメール送信をしてくれる人(sendmailとかですね)がいることが前提になっているのですが、私はその環境を持っていません。入れて入らないことはないのですが、出来れば送信サーバはGmailとか既存のサービスを使いたい…と思って苦悩していたら、SHIMI.INFOでおなじみ清水さんが「このスクリプト使ってごら〜ん」と助け船を出してくださいました。
str2imap.rb
#!/usr/bin/ruby
require 'net/imap'
IMAP_SERV = 'imap.gmail.com'
IMAP_PORT = 993
IMAP_SSL = true
folder = ARGV[0] || 'INBOX'
user = 'Gmailのユーザ名'
pass = 'Gmailのパスワード'
begin
imap = Net::IMAP.new(IMAP_SERV, IMAP_PORT, IMAP_SSL)
imap.login(user, pass)
begin
imap.examine(folder)
rescue
if folder =~ /[^\w]/ then
folder = Net::IMAP.encode_utf7(folder)
end
imap.create(folder)
end
rawmail = ''
STDIN.each { |l|
rawmail << l
}
if rawmail.gsub(/[\n|\r]+/, '').length == 0 then raise 'NO data input.' end
imap.append(folder, rawmail, nil, Time.now)
imap.logout
rescue => err
puts err.to_s
imap.logout
exit 1;
end
exit 0;
require 'net/imap'
IMAP_SERV = 'imap.gmail.com'
IMAP_PORT = 993
IMAP_SSL = true
folder = ARGV[0] || 'INBOX'
user = 'Gmailのユーザ名'
pass = 'Gmailのパスワード'
begin
imap = Net::IMAP.new(IMAP_SERV, IMAP_PORT, IMAP_SSL)
imap.login(user, pass)
begin
imap.examine(folder)
rescue
if folder =~ /[^\w]/ then
folder = Net::IMAP.encode_utf7(folder)
end
imap.create(folder)
end
rawmail = ''
STDIN.each { |l|
rawmail << l
}
if rawmail.gsub(/[\n|\r]+/, '').length == 0 then raise 'NO data input.' end
imap.append(folder, rawmail, nil, Time.now)
imap.logout
rescue => err
puts err.to_s
imap.logout
exit 1;
end
exit 0;
このスクリプトを/home/hoge(場所はどこでもいいですよ)に配置したら、.fetchmailrcを以下の通り記述します。
.fetchmailrc
set postmaster Gmailのユーザ名@gmail.com
set nobouncemail
poll imap.softbank.jp
proto imap
timeout 30
username i.softbankのユーザ名
password i.softbankのパスワード
idle
no mimedecode
keep
mda "/home/hoge/str2imap.rb"
set nobouncemail
poll imap.softbank.jp
proto imap
timeout 30
username i.softbankのユーザ名
password i.softbankのパスワード
idle
no mimedecode
keep
mda "/home/hoge/str2imap.rb"
あとはfetchmailを起動するだけ。
動きっぱなしになるので完全な裏起動にしましょう。
nohup fetchmail > /dev/null 2>&1 &
これでi.softbank.jpに送られたメールは即時にGmailに転送されます。
これならSIMなしの端末からでもメール送れるし、そもそもどの端末、どの回線を使っているかを全く相手に意識させずにこちらが自由に振る舞える。これはある意味真のMNPかも。全キャリア共通でIMAPなメールサーバ作ってくれないかなー。
moyashiさん、清水さん、いのたん♪さん、どうもありがとうございました!
管理人の部屋: i.softbank.jpとGmailの統合
http://gtbleds18.blogspot.com/2010/04/isoftbankjpgmail.html
Togetter - 「i.softbank.jpをGmailに統合するための試行錯誤」
http://togetter.com/li/65323
2010年10月06日
フォント置き換え用のupdate.zipを作る
最近はすっかりNexusOneにCyanogenmod Nightly Buildを入れて暮らしている私。
(そうそう、ずいぶん前ですがNexusOne買いました!)
Nightlyなので日々更新されているわけですが、新しいBuildを入れる度にフォントの置き換えをするのが面倒になってきたので、一念発起してフォント置き換え用のupdate.zipを作ってみました。
以下はその手順のメモ。(それもけっこう雑です…スミマセン)
お約束ですが、以下の内容は全て無保証です。
煉瓦になってもくじけない。転ばぬ先のバックアップ!
続きを読む
(そうそう、ずいぶん前ですがNexusOne買いました!)
Nightlyなので日々更新されているわけですが、新しいBuildを入れる度にフォントの置き換えをするのが面倒になってきたので、一念発起してフォント置き換え用のupdate.zipを作ってみました。
以下はその手順のメモ。(それもけっこう雑です…スミマセン)
お約束ですが、以下の内容は全て無保証です。
煉瓦になってもくじけない。転ばぬ先のバックアップ!
続きを読む
2010年09月11日
HT-03Aでまだまだ戦う (公式1.6からのダイレクトアップグレード編)
2010年08月24日
DevQuiz2010のOAuthをtelnetで倒す
意外にも私以外にtelnetで倒したという話を聞かないので、何となく書いてみる。
Try and Errorでがちゃがちゃとやっていたので、内容的には少し順不同です。
(出来るだけ分かりやすい順序で書いてみました)
問題文は…転載していいのか分からないので省略。
このエントリ見てる方は皆さんご存じですよね、きっと。
まずはOAuthって何ぞ…と思って調べてたどり着いたのがこちらのページ。
(そんな奴がGDDに行こうとするなよ、と言うツッコミは置いといてw)
OAuthプロトコルの中身をざっくり解説してみるよ - ゆろよろ日記
http://d.hatena.ne.jp/yuroyoro/20100506/1273137673
Yahoo!デベロッパーネットワーク - OAuth - OAuthを用いたAPIリクエスト
http://developer.yahoo.co.jp/other/oauth/api.html
なるほど、どうやらAuthorizationヘッダとやらを送りつければいいようです。
各種パラメータについて、とりあえず問題文に以下の4つは指定がありました。
・認証のrealm:devquiz
・Consumer key: 7fded0d291561d16a4b8a651
・Consumer secret: a828fa17fdb32c3cf0956cb3
・署名方式:HMAC-SHA1
これでrealm、oauth_consumer_key、oauth_signature_methodの3つは設定値が分かりました。
で、あとは分からない物を潰していく。
まずはoauth_nonce。これは何でもいいみたいだったので、上記のYahoo!で使っているサンプル値そのままにしてしまいました。
続いてoauth_timestamp。これは所謂UNIX時間を設定するようなのですが、求め方がよく分かりません。んで、ぐぐるさんに調べてもらったら以下のページを見つけました。
エポック秒(UNIX時間)変換マシーン
http://egg-in-oven.hp.infoseek.co.jp/epochsec.html
ボタン一発で計算終了。ありがたい事です。
ただ、ここで指定した時間と現在時刻が600秒以上ずれると認証が通らなくなってしまうようなので、作業はサクサクと進める必要がありました。
最後に残ったのがoauth_signature。これがものすごく複雑なんですが、以下のページに詳細な解説があったのと、間違えた時にDevQuizのサーバが「署名するのはこの文字列のはずだぜ」とご丁寧にも教えてくれたので、署名の方法自体は何とかなりました。
Yahoo!デベロッパーネットワーク - OAuth - リクエストの署名
http://developer.yahoo.co.jp/other/oauth/signinrequest.html
ただ「HMAC-SHA1アルゴリズムを利用して16進のダイジェスト値の生成→Base64エンコード→URLエンコード」という仕組みは分かっても、実際にどうやったら値が求められるのかさっぱり分かりません。前述のエポック秒(UNIX時間)変換マシーンのような一発変換のページを探してみたんですが、残念ながら見つけられず。
ここでうぬぬーと頭を抱えていたのですが、以下のページでPythonで実装されたOAuthのサンプルコードを発見しました。
Twitter API を OAuth で認証するスクリプトを 0 から書いてみた - trial and error
http://techno-st.net/2009/11/26/twitter-api-oauth-0.html
うん、どうやらPythonを使えば何とか出来そう。
とは言えPythonで全てを実装出来るほどのスキルはないので、署名の部分だけ対話型で打ち込んで何とかしてしまいました。
これで最難関の署名が完成。
あとはPOSTメソッドでhello=worldというパラメータを送信するという指定なので、最終的には以下のようなデータを送る事になりました。
これで「200 OK」。
問題の趣旨とはだいぶ解答方法が異なるような気がするのですが、うまく行ったので良しとします。直前にソースコード提出が必須になるという話があった時は正直ビビりまくりでしたw
個人的には、この問題のおかげでOAuthの仕組みをちょっとだけ理解出来たのが一番の収穫でした。今はOAuthを使ったGmail送信用のAndroidアプリを作成中。(いや、まだ一行もコード書けてないんですけど) それが完成したら頑張ってtwitterクライアントを書きたいなと妄想中。twiccaみたいなすごい奴じゃなくて、投稿/Reply専用の俺得クライアントになる予定ですが。
たまに自分を奮い立たせてくれるような宿題とかイベントがあるのはいいですね。
GDDに行けるかどうかは置いといて、おいらもっともっと頑張らないとな。
Try and Errorでがちゃがちゃとやっていたので、内容的には少し順不同です。
(出来るだけ分かりやすい順序で書いてみました)
問題文は…転載していいのか分からないので省略。
このエントリ見てる方は皆さんご存じですよね、きっと。
まずはOAuthって何ぞ…と思って調べてたどり着いたのがこちらのページ。
(そんな奴がGDDに行こうとするなよ、と言うツッコミは置いといてw)
OAuthプロトコルの中身をざっくり解説してみるよ - ゆろよろ日記
http://d.hatena.ne.jp/yuroyoro/20100506/1273137673
Yahoo!デベロッパーネットワーク - OAuth - OAuthを用いたAPIリクエスト
http://developer.yahoo.co.jp/other/oauth/api.html
なるほど、どうやらAuthorizationヘッダとやらを送りつければいいようです。
各種パラメータについて、とりあえず問題文に以下の4つは指定がありました。
・認証のrealm:devquiz
・Consumer key: 7fded0d291561d16a4b8a651
・Consumer secret: a828fa17fdb32c3cf0956cb3
・署名方式:HMAC-SHA1
これでrealm、oauth_consumer_key、oauth_signature_methodの3つは設定値が分かりました。
で、あとは分からない物を潰していく。
まずはoauth_nonce。これは何でもいいみたいだったので、上記のYahoo!で使っているサンプル値そのままにしてしまいました。
続いてoauth_timestamp。これは所謂UNIX時間を設定するようなのですが、求め方がよく分かりません。んで、ぐぐるさんに調べてもらったら以下のページを見つけました。
エポック秒(UNIX時間)変換マシーン
http://egg-in-oven.hp.infoseek.co.jp/epochsec.html
ボタン一発で計算終了。ありがたい事です。
ただ、ここで指定した時間と現在時刻が600秒以上ずれると認証が通らなくなってしまうようなので、作業はサクサクと進める必要がありました。
最後に残ったのがoauth_signature。これがものすごく複雑なんですが、以下のページに詳細な解説があったのと、間違えた時にDevQuizのサーバが「署名するのはこの文字列のはずだぜ」とご丁寧にも教えてくれたので、署名の方法自体は何とかなりました。
Yahoo!デベロッパーネットワーク - OAuth - リクエストの署名
http://developer.yahoo.co.jp/other/oauth/signinrequest.html
ただ「HMAC-SHA1アルゴリズムを利用して16進のダイジェスト値の生成→Base64エンコード→URLエンコード」という仕組みは分かっても、実際にどうやったら値が求められるのかさっぱり分かりません。前述のエポック秒(UNIX時間)変換マシーンのような一発変換のページを探してみたんですが、残念ながら見つけられず。
ここでうぬぬーと頭を抱えていたのですが、以下のページでPythonで実装されたOAuthのサンプルコードを発見しました。
Twitter API を OAuth で認証するスクリプトを 0 から書いてみた - trial and error
http://techno-st.net/2009/11/26/twitter-api-oauth-0.html
うん、どうやらPythonを使えば何とか出来そう。
とは言えPythonで全てを実装出来るほどのスキルはないので、署名の部分だけ対話型で打ち込んで何とかしてしまいました。
import time, random
import urllib, urllib2
import hmac, hashlib
hmac.new("a828fa17fdb32c3cf0956cb3&", "POST&http%3A%2F%2Fgdd-2010-quiz-japan.appspot.com%2Foauth%2F7fded0d291561d16a4b8a651&hello%3Dworld%26oauth_consumer_key%3D7fded0d291561d16a4b8a651%26oauth_nonce%3D24829.2331%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1281716837", hashlib.sha1).digest().encode("base64").strip()
import urllib, urllib2
import hmac, hashlib
hmac.new("a828fa17fdb32c3cf0956cb3&", "POST&http%3A%2F%2Fgdd-2010-quiz-japan.appspot.com%2Foauth%2F7fded0d291561d16a4b8a651&hello%3Dworld%26oauth_consumer_key%3D7fded0d291561d16a4b8a651%26oauth_nonce%3D24829.2331%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1281716837", hashlib.sha1).digest().encode("base64").strip()
これで最難関の署名が完成。
あとはPOSTメソッドでhello=worldというパラメータを送信するという指定なので、最終的には以下のようなデータを送る事になりました。
telnet gdd-2010-quiz-japan.appspot.com 80
POST /oauth/7fded0d291561d16a4b8a651 HTTP/1.0
Host: gdd-2010-quiz-japan.appspot.com
Authorization: OAuth realm="devquiz", oauth_consumer_key="7fded0d291561d16a4b8a651", oauth_signature_method="HMAC-SHA1", oauth_nonce="24829.2331",oauth_timestamp="1281716837",oauth_signature="Guti8N50so36JFGLtKIpC9XmdnI="
Content-length: 11
hello=world
POST /oauth/7fded0d291561d16a4b8a651 HTTP/1.0
Host: gdd-2010-quiz-japan.appspot.com
Authorization: OAuth realm="devquiz", oauth_consumer_key="7fded0d291561d16a4b8a651", oauth_signature_method="HMAC-SHA1", oauth_nonce="24829.2331",oauth_timestamp="1281716837",oauth_signature="Guti8N50so36JFGLtKIpC9XmdnI="
Content-length: 11
hello=world
これで「200 OK」。
問題の趣旨とはだいぶ解答方法が異なるような気がするのですが、うまく行ったので良しとします。直前にソースコード提出が必須になるという話があった時は正直ビビりまくりでしたw
個人的には、この問題のおかげでOAuthの仕組みをちょっとだけ理解出来たのが一番の収穫でした。今はOAuthを使ったGmail送信用のAndroidアプリを作成中。(いや、まだ一行もコード書けてないんですけど) それが完成したら頑張ってtwitterクライアントを書きたいなと妄想中。twiccaみたいなすごい奴じゃなくて、投稿/Reply専用の俺得クライアントになる予定ですが。
たまに自分を奮い立たせてくれるような宿題とかイベントがあるのはいいですね。
GDDに行けるかどうかは置いといて、おいらもっともっと頑張らないとな。