2010年08月17日

OAuth は、どう安全なのか?(物語風に)

さてさて、このお話は、どこにあるのかわからない、「ツイット国」のお話です。
実は、この国の人々は、かけ算は得意ですが割り算は苦手……というより、存在すら知りません。
ちょっと変な仮定ですが、物語風 OAuth の説明に必要な仮定ですので。

【はじまりはじまり】

この国に、ツイット太郎という若者がいました。
太郎は、近所のツイット亭というレストランが大のお気に入り。三度の食事をもれなくここで食べていました。
そうなると、面倒なのがお金の支払いです。
そうは言っても、太郎も悪人ではなく、単にお金を持ち歩くのが面倒なだけでした。
そこで、太郎は考えます。
そうだ、ツイット亭の人に、ツイット銀行まで行って、自分の口座から代金を引き落としてもらえば良いんだ。

そうして、太郎は、ツイット亭の人に定期的に銀行まで行くようにお願いし、ツイット亭の人も快く引き受けてくれました。

【Basic 認証の時代】

この時代では、太郎は、お店の人に2つのことを教えます。
1)口座番号(ここでは、12345678 とします)
2)暗証番号(ここでは、7777 とします)
以上です。

お店の人が銀行に行ってお金を引き出すようです。
亭:もしもし、口座番号 12345678 からお金を引き出したいのですが。
銀:では、暗証番号をどうぞ
亭:7777 です。
銀:暗証番号はあっています。では、必要なお金をどうぞ……

こういう会話が交わされます。
……危ないですね?

危ないと言っても、お店の人が太郎の食べてないもののお金まで引き落としてしまうかもしれない……というお話は、今回は、扱いません。
そもそも、そんなおかしなことをするかもしれないお店に、引き落としの代行は依頼しないだろうというのが、基本方針です。

もうひとつの危険性。
もしも、この会話を悪人が聞いたらどうなるでしょう。
早速、ここで聞き耳を立てていた悪人がいたようです。

悪:もしもし、口座番号 12345678 からお金を引き出したいのですが。
銀:では、暗証番号をどうぞ
悪:7777 です。
銀:暗証番号はあっています。では、必要なお金をどうぞ……
悪:しめしめ……。

ただ単に聞いていたことを繰り返すだけですから、簡単なことです。さらに悪いことには、銀行には、「だれがお金を下ろしたか」という記録は一切残りません。
銀行としては、正しい口座番号と暗証番号を知っていたのだから、正しいお客様だと判断するしかないのです。

【OAuth の時代】

さて、Basic 認証はあまりに危険だ……特に、お金を引き出すときの会話を盗み聞きされたどうしようもない。
そこで、時代は、OAuth の時代になりました。
ここでは、ツイット太郎は、ツイット亭と、さらに、ツイット銀行を交えて、4つの情報を決定します。
1)お店の「店舗番号」(ここでは、00110022 とします)
2)お店の「暗証番号」(ここでは、8888 とします)
※ここまでの情報は、「アプリケーションの登録」をしたときに決まります。ユーザーには直接関係ありません。(Twitter が割り当てます)
3)太郎さんの「ツイット亭専用」口座番号(ここでは、11223344 とします)
4)太郎さんの「ツイット亭専用」暗証番号(ここでは、1111とします)
※最後の2つは、「OAuth を承認」したときに決定されます。(Twitter が割り当てます)

さて、今回もお店の人が銀行に向かいお金を下ろします。

亭:店舗番号 00110022 のものですが、11223344 の口座からお金を下ろしたいのですが。
銀:では、最初に、「一回だけ番号」を適当に言ってください。
亭:じゃ、6543 にします。
銀:わかりました。では、「しぐねちゃ」をおしえてください。
亭:えっと〜
  ここで、ツイット亭の人は、「しぐねちゃ」を計算し始めます。
  計算方法は、
  1) 店舗の暗証番号(8888)と、お客様の暗証番号(1111)をくっつけて、88881111 という数字にする。
  2)それに、「一回だけ番号」の、6543 をかける
  3) 結果は、88881111×6543=1728524313
亭:しぐねちゃは、1728524313 です。
銀:正解です。では、必要なお金をどうぞ……。

さてさて、今回も悪人が聞き耳を立ています。

悪:店舗番号 00110022 のものですが、11223344 の口座からお金を下ろしたいのですが。
銀:では、最初に、「一回だけ番号」を適当に言ってください。
悪:じゃ、6543 にします。
銀:その番号はさっき使ったのでだめです。ちゃんと、「一回だけ番号」を言ってください。
悪:困ったなぁ〜 適当に、9876 です。
銀:わかりました。では、しぐねちゃをおしえてください。
悪:しぐねちゃあれ? 暗証番号がわからないから、計算できないよ。

ということで、聞き耳をたてていても、失敗に終わるという仕掛けです。

【まとめ】

・OAuth では、暗証番号に相当するものを相手に伝えるかわりに、「それを知らなければできない計算の答」を伝える
 だから、聞き耳をたてていても、暗証番号に相当するものは奪えない。
・OAuth では、「一回だけ番号」に相当するものがあって、毎回送信する情報が変化する。
 だから、聞き耳をたてて、送信されたものを再利用することができない
 (実際には、送信する時点の時刻情報も併せて使います)
・OAuth では、ユーザー情報は、「そのお店専用」になっている。
 だから、直接誰がお金を引き出したか(誰が、ツイートしたか)がはっきり残ってしまう

こんなことをして、承認していない相手に情報が漏れ、不正に使われることを防止しているわけです。

【注意】

このお話の前提となっているのは、「ツイット国の人々は割り算ができない」ということです。
現実の世界では、88881111×6543=1728524313 という計算の答え(しぐねちゃ)と、一回だけ番号(6543)がわかっているのですから、割り算をすることで、88881111 というお店と太郎さんの暗証番号がわかってしまいます。
実際、ここの計算は、単なるかけ算ではなくもう少しややこしい計算が使われています。
ただし、このお話のように、計算するのは(コンピュータなら)簡単だけれど、答えからもとの数字を割り出すのは非常に困難という、そういう計算が使われています。

この例を含めて、技術的には、正しくない内容が含まれています。
また、「4つの情報を決定します」とだけ書いた、決め方の部分もかなり面倒なやりとりがあります。
まあ、そういう点を全部無視していますが、なぜ、OAuth のほうが Basic 認証より安全なんだ? というイメージとしては、大きくは間違っていないと考えています。
posted by 麻野なぎ at 22:12| Comment(0) | TrackBack(0) | Twitter と Bot の周辺

2010年08月06日

月齢と月の形

え、これは、「月齢と月の呼び名」( http://asano-nagi.sblo.jp/article/39959609.html )の続編です。
「月の呼び名」では、
・そもそも、1で始まる旧暦の日付ベースの名前と、0で始まる月齢とが混同されている場面がある。
・しかも、月齢の基準(0になる時点)は、ばらつくから、月齢と月の呼び名はさらにばらつく
という点を指摘したわけですが、では、月齢(すなわち、朔の瞬間からの経過時間)が一定なら、月の形は同じかといえば、これまた、そうでもありません。

これは、端的に言えば、地球からみた月の移動速度がばらつくからなのですが、実際にデータを作成してみました。
これが、2010年から2020年の間の、毎日午前0時の月齢と輝面比の関係をグラフにしたものです。
輝面比というのは、読んで字のごとく、月を円形と見なしたときに光っている部分の割合でして、もちろん、100%が満月。50%が半月。0%は新月です。

moonlog.gif

あと、PDF に加工したデータです。

さて、たとえ直線にならなくても、これ(月齢と輝面比の関係)が、ひとつの線になれば、月齢が同じなら形も同じといえるわけですが、いかんせん、これだけばらついてしまうわけです。
一番ばらつきの大きそうなところを探してみると、
月齢が、7.56 の時に、輝面比 43.4%
月齢が、7.54 の時に、輝面比 59.9%
というのをみつけました。
月齢がほとんど同じでも、輝面比はこれだけばらつくわけです。
ちなみに、この輝面比を、月の形にしてみると、こんな感じになります。

moons.gif

2010年08月05日

OAuth への道 ―― OAuth の危険性にどう対応するか

この記事は、「OAuth の危険性」
http://asano-nagi.sblo.jp/article/39973329.html
の続編である。

そこで、OAuth の危険性にどう対応するかということでまとめようと思うが、最終的に、当たり前の結果しか出てこないであろう事は、いたしかたない。

【(もしかしたら)Twitter サイドの問題】

さて、OAuth の危険性という側面で、Twitter サイドの設定に触れておこう。
実は、OAuth という仕組み全体の中では、OAuth の認証をする際に、「どの程度操作を許可するか」という設定や、「いつまで操作を許可するか」といった設定ができることになっている。
しかしながら、Twitter の設定では、有効期限は「無期限(ただし、ユーザーが「拒否」に設定するまで」。操作権限は、「読み込みのみ or 読み書き」という設定しかできない。
言い換えると、「ポストが可能なサービスなら、あらゆる操作が可能」ということである。

Twitter というサービスの持つ性格、「かなりお気楽にポスト」という事から考えると、せめて「ポストのみ」というレベルの制限はあった方が良いのではないか? というのが、よく言われることである。
(実際にはそうなってない)

【われわれは、かつてどうしてきただろうか?】

この問題を考える際、「ユニクロ行列キャンペーン」(たとえば、http://mainichi.jp/select/biz/it/japan_internet_com/archive/2010/05/31/wmnews_20100531_8.html ) がひとつの参考となる。
ユニクロの仮想店舗にこれまた、仮装行列を作るというもので、行列をするために、Twitter の ID と パスワードが要求されたというものである。
この場合、いくつかの対応が可能だっただろう。

1)なんかおもしろそうだから、何も気にせず、ID と パスワードを入力する
2)ID と パスワードを入力するのは一般的には危険だけど、ユニクロだから信用して入力する
3)おもしろそうだけど、ID とパスワードの入力は断固拒否する(で、参加しない)

このうち、1)の対応はまずいと思う。しかし、2)は、「自己責任」として、ありだと思う。
他にも、「危険性」の記事で取り上げた、「メールソフトの作者は、(技術的には)すべてのメールにアクセスできる」という話にしても、一般的な危険性を知った上で、それでも、信用できるという判断で、サービスを使用してきたわけである。

なお、「自己責任」というが、たとえば、「煙草には肺がんリスクがある」と明示された上で、「それでも吸う」のは「自己責任」である。肺がんリスクそのものが伏せられていた場合、それで吸うのは自己責任とはいわない。

だから、たとえば、「タイムラインごちゃ混ぜポストBot」が、「あなたにOAuthの許可を求めています」というのが、実は、「タイムラインをごちゃ混ぜにした内容をポストする」ということの許可を求めているのではなく、「そのBotが、目的以外のことはしないだろうと信用して、あなたのアカウント操作を認めるか」ということであるというのを、まず、知って、その上で、あるサービスが有用だったり、おもしろそうだったりで、「承認する」という、自己責任のための情報は提供しなければならないと思う。

【では、どう対応するのか?】

まず、OAuht を承認したアプリケーションに対して、「拒否をする」方法を理解すべきである。
Web 上でログインし、設定 → 連携アプリ で該当するアプリケーションの「許可を取り消す」ことでこれは可能である。
問題が発生した場合、まずは、許可の取り消しが可能であるという状態にしておく必要はある。
※ちなみに、パスワードを変更しても、効果がないので注意。

その上で、そのサービスが信用できるか判断する、判断できなければ使わないと、そういう当たり前の対応しかないのだと思う。
ただ、考えてみれば、Twitterに限らず、各種存在しているサービスを、個人情報を入力した上で利用しているとすれば、それは、「信用できる」という判断があったのだと思う。
Twitter で、OAuth に対して承認を行う場合も、考え方は同じである。
ただ、「単に、(たとえば)タイムラインが読まれてポストされるだけ」ではないよと、そういう意識を持つことは必要なのである。

【本当の脅威は静かにやってくる】

以上述べたとおり、OAuth に対して、何も考えずに承認を与えるというのは危険である。
ただ、今回、通称、「なる四」など、OAuth 周辺の騒動から、OAuth はもしかしたら危険なのかもしれないという話がすこしばかり、一般的になったわけである。

しかし、これは、「なる四」だけが危ないわけでも、OAuth だけが危ないわけでもない。
むしろ、本当に悪意を持ったなら、こんなに大騒ぎをして、「悪巧み」をぶちこわすはずはないと、そういう点は意識すべきである。

そして、数ある(Twitter ではない)Web サービスも、「技術的には」やはり危ないのである。
それを含めて、「どう対応するか」というのを、一度考えるべき時ではあると思う。


【おまけ・ソーシャルクラッキングを考える】

この記事を書いているうちに、

「なるほど4時じゃねーの解除ツール」 ← 嘘ですhttp://spreadsheets.google.com/viewform?formkey=dDJQbVZlZVE0T3BXelh1S004ZWZqZkE6MQ

なるものを見つけることができた。
(この記事を書いている 2010年8月5日の段階では、表示させるだけなら実害はない)

これを見ると、「なるほど4時じゃねーの解除ツール」で、解除をするために、Twitter の ID とパスワードを入力せよというフォームになっている。
この作者は、少なくとも、「凶悪」な方ではなく、「それやっちゃいかんだろう」と、ご自身で指摘してくれる構造になっているわけだが(あ、それでも、最後まで突っ走ると、入力された ID と パスワードを、保存してしまうらしい・作者談)いきなり、このようなフォームを見つけて、「まずい」と、そもそも入力せずに無視することができるだろうか?

また、ここに書いたこと(作者が、「凶悪」ではないとか)も、実際に試してみて(オイ)そこに書かれた文字を信用して書いているだけで、作者が凶悪でないふりをして、実際には、入力された情報をいきなり保存している可能性もある。
また、フォームの作者らしい方のIDも書かれているが、本当に、その方が作者だという保証もない。

と、ようするに、非常に危険(かもしれない)なサイトなのであるが、これは、一瞬で「危険」だと見破らなければならないと、そういうわけである。

こういう、人間の特性を悪用したクラッキングは、「ソーシャルクラッキング」と呼ばれている。
たとえば、「システム管理課の××です。アカウント管理サーバーがクラッシュしたので、確認のため、パスワードを教えてください」とか、「××銀行の○○です。あなたの口座に入金があったのですが、機械のトラブルで入金ができていません。確認のために暗証番号を教えてください」とか。

冒頭の例に似たものには、「パスワード評価サイト」を見かけたことがある。
「パスワードの安全性を判定します。パスワードを入力してください」
その結果は……こんな得体の知れないサイトでパスワードを入力すると悪用されますよ。

いずれにしても、情報の入力には気をつけましょう……と、そういうことである。
posted by 麻野なぎ at 17:27| Comment(0) | TrackBack(0) | Twitter と Bot の周辺

2010年08月04日

OAuth への道 ―― OAuth の危険性

この記事を書こうとしているとき、Twitter 界隈では、"OAuth の危険性・悪用" に関連した話題がささやかれている。
そこで、本当に、OAuth は危険なのかということについて書いてみることにする。

今、OAuth の危険性として話題になっているのは、いくつかの側面がある。
何かが、危険であるとか、安全であるとかを話題にするとき、「どういう面が危険とされているのか?」という切り分けは重要である。

【機能的な側面】

OAuth は、もととも、「当人が通常の操作を行うところを、代行する」ために準備された機能である。Titter の場合、通常の動作とは、Web 上でログインした後、タイムラインを読んだり、ポストを行ったり、それこそ、ダイレクトメールを読んだり書いたりというそういう操作を意味する。

これ以外の操作は、すべて、「代行されたもの」だと考えて良い。
たとえば、Twitter のクライアントを使用するのも、「代行されたもの」である。
とすれば、OAuth を承認することで、「代行可能な操作」は、クライアントで実行可能な全操作であり、言い換えれば、ユーザーが実行可能なほとんどすべての操作ということになる。
当然、ダイレクトメールの送受信、お気に入りの設定なども可能である。

しかも、これらの機能を「自動的に」実行可能な点に注意しなければならない。
ポストすべきメッセージはキーボードから入力し、読むべきメッセージは画面に表示されるというケースが多いと思われる。
けれど、何も、メッセージはユーザー自身がキーボードから入力しなくても、クライアントなり、第三者サービスが、勝手に生成して送信することもできる。
読み込まれたタイムラインは、表示しないまま、どこかにデータとして送信することもできる。

さらにいえば、「公開されていない」メッセージも、自分がフォローしている場合には「読める」というのも注意しておきたい。
多くのクライアントでは、公開されていないメッセージは、ReTweet できないようになっているが、これも、「公開されていない」という目印を認識して、対応しているに過ぎない。
「公開されていない」メッセージであっても、読むことができる以上、(技術的には)送信できるわけである。

【危険性が周知されていないという危険性】

さて、上述したのは、多くの場合において、「大げさ」ではある。
確かに技術的に可能ではある(しかも、OAuth 認証に対応しているアプリケーションとしては、技術的には難しいものではない)
ただ、それは、「メールソフトの作者は、(技術的には)ユーザーのメールを自由に読むことができる」というのと、同じ指摘であるに過ぎない。

特に、いわゆる Web メールで、「他のメールサーバーのメールも読めるような設定が可能です」という場合、(技術的には)ユーザーのメールを自由に読むことができて、なおかつ、ユーザーはそれに気づかないというのも、そんなに難しいものではない。

ただし、メールソフトに関しては、この説明で多くの人が「確かに、技術的にはそうなのだろう」と納得はできると思う。
メールソフトとして、メールの読み書きをしているのだから、そのメールをたとえば、谷転送したりすることは技術的には可能だというのは、十分想像できることである。

ところが、Twitter の場合、もう少し別の側面が存在する。

たとえば、「あなたのアカウントのタイムラインの発言を、適当に混ぜ合わせて、一日に一回あなたのアカウントからポストします」という、ちょっとお手軽なアプリケーションがあったとしよう。
おそらく、Twitterで、OAuth の認証が求められる。

「あなたのタイムライン、ぐちゃぐちゃまとめますサービス」が、認証を求めています。
・許可する ・拒否する。

ここで、このサービス(多分Bot)が、タイムラインを読んで、適当な言葉を混ぜ合わせて、それをポストするだけの機能だったら、そんなに難しいことを考えずに、許可しても良いだろうと思う。
しかし、このBotもまた、「技術的には」あらゆる操作が可能なのだ。

だから、許可すべきではない……とはいわない。
いわないが、少なくとも、このサービスがそこそこ使われているか? 少なくとも現時点では、問題を起こしてないか? そして、何かあったときに、改めて拒否するにはどうしたらいいか、そういうところまでを、確認した上で、許可するのが良いのではないだろうか?

OAuth の認証は、見かけ上、「かくかくしかじかのサービスを許可するか」という質問に見える。
しかしながら、実際は、「こういうことを言っているサービスがあるが、このサービスを信用して、あなたのアクセス権を譲渡しても良いか?」と尋ねているのである。

時間である。
続きは、また、近いうちに……。(オイ)
posted by 麻野なぎ at 12:44| Comment(0) | TrackBack(0) | Twitter と Bot の周辺

2010年08月03日

月齢と月の呼び名

Twitter の Bot、「節気さんシリーズ」で、月の名前を表示している。
そのときにいろいろと調査をして、節気さんでは、(旧暦)一日からの月の出現回数で、月の名前を決定している。
このほかにも、旧暦の日付を以て月の名前としている場面もよく見かける。
この場合、「その日の夜に上る(上っている)月」と解釈すれば、概ね節気さんシリーズの呼び名と一致する。また、その日固有の名前としては、二十三夜(下弦の月)くらいまでしか使われておらず、これも、実質的には、月の出現回数であっても旧暦の日付であっても、差異を生じさせない一因となっている。

ただ、時々、月齢の数字=月の名前(の数字)と理解されているケースがあって、これは、少々間違っている。
これは、気がついてみれば簡単なことで、旧暦の日付は1(一日)から始まるが、月齢は0から始まるということなのだ。
しかも、不思議なことに、月齢を以て月の名前を決めるという立場でも、なぜか、三日月は、旧暦3日(つまり、月齢は概ね2)としているケースが多い。
同じように数えれば、旧暦13日は、概ね月齢12で、これが十三夜。以下、月齢13で小望月、月齢14で十五夜、月齢15で十六夜、以降、旧暦20日(月齢は概ね19)の更待月まで、一連の名前が続くことになる。

ここまで書いてきたが、本質的な意味では月齢と月の名前の関係には誤差が含まれるということを、そもそも注意する必要がある。
月齢の定義に立ち返ると、月齢=0となるのは、朔の瞬間(太陽と月が同じ向きになった瞬間)である。そして、旧暦の一日は、「朔の瞬間を含む日」と定義される。
つまり、月齢が0になる瞬間は、旧暦一日の 0:01 かもしれないし、23:59 かもしれないという、そういう意味である。言い換えると、「その日の月齢が、ほぼ全日に渡って0」だったとして、その日は、旧暦の一日かもしれないし(朔が 0:01 のとき)、旧暦の二日かもしれない(朔が 23:59のとき)。

しかしながら、月の名前は、あくまでも旧暦の日付(または、旧暦一日から数えた、月の出現回数)で決定するわけだから、これは言い換えると、その日の月齢が0だったとしても、「朔月(旧暦一日の月)」かもしれないし、「既朔(旧暦二日の月)」かもしれないと、そういう意味である。
もちろん、そのいずれかによって、その後一月の間、最大1日分の誤差が生じるというわけである。

一方で、月齢を整数で表現する流儀もある。この場合は、「朔を含む日の月齢を0、その後1日ごとに1加算」というわけで、こちらの流儀であれば、月齢+1=旧暦の日付であるといえる。

ちなみに、2010年〜2020年の間で計算してみると、
最も早い時刻に朔となる日:2012-06-20 00:02:27
最も遅い時刻に朔となる日:2017-02-26 23:58:56
である。

それぞれの日を起点として、月齢・旧暦の日付・月の名前を図示すると以下のようになる。

moonpost.gif

※ちなみに、2010年〜2020年の範囲で、0時台、23時台に朔となるのは、以下の日々です。

※朔の時刻が0時台の日
2012-06-20 00:02:27
2012-08-18 00:53:50
2013-06-09 00:55:57
2019-11-27 00:05:03
2020-02-24 00:32:17

※朔の時刻が23時台の日
2011-04-03 23:31:53
2012-03-22 23:36:51
2014-08-25 23:13:04
2015-06-16 23:05:10
2015-08-14 23:53:03
2016-02-08 23:39:18
2017-02-26 23:58:56

著作権の自動発生と、著作権登録制度

2010年現在、日本では(そして他の多くの国でも)著作権は著作と同時に「自然発生する」と考えられている。
一方で、「ちゃんとした」著作権の登録制度も存在している。ついでに言えば、ちゃんとしていない著作権の登録も、一部の団体で勝手に行われている。

では、自然発生するという著作権に、登録制度が存在するのはなぜだろうか?
それは、著作権が「譲渡可能」なものであることを最大の理由としている。
しばらく前、「著作権の保護期間延長」が問題になったことがある。これを書いている時点では、ひとまず、延長しないという方向にはなったが、このときに、「著作者と著作権者は異なるということを意識して議論しなければならない」という話を聞いたことがある。

実際、「お金になる」ような著作権は、多くは、何とか事務所に譲渡されており、著作者といえども自由に複製できない(著作権者ではないから)という状況だったりする。
この場合、「誰が著作権者か」を明示するために、(ちゃんとした)著作権の登録制度は有用なのである。

さて、問題になるのは、一部民間で行われている、「ちゃんとしていない」著作権登録である。
セールスポイントは、「著作権登録であなたのアイディアを保護しましょう」ということらしいけれど、どうやら、自分が書いた図面やら(アイディアの)説明文やらを、「登録」して、「保護しよう」ということらしい。
しかしながら、著作権ではアイディアは保護されない。確かに、その図面や説明文と「全く同じもの」を作れば、著作権の侵害になる場合もある。けれど、アイディアを表現するのに、全く同じ文面は不要であろう。

これだけの話であれば、単に、「役に立たない」というレベルで終わるのだが、著作権として考えれば、もうひとつ別の問題がある。
要するに著作権の侵害とは、「勝手に複製を作ってはいけない」ということである。
だから、オリジナルの存在を知らずにたまたま同じものを(または類似のものを)作ってしまった……という場合、著作権の侵害とはならないのである。

これは、「依拠性」という概念であり、ちょっと探すと、「ワン・レイニー・ナイト・イン・トーキョー 事件(昭和53年9月7日・最高裁)」が判例として出てきたりする。
だから、アイディアを保護するために、著作権の登録をしてみたところで、もしも、その図面なり説明文なりを、公開せずに後生大事にしまっておけば、たとえ類似のアイディアが出現しても、「そんなもの(=オリジナル)は、見る機会などなかった。それにアクセスすることなどできなかった」と言われてしまえば、少なくとも、著作権の侵害はいえなくなってしまう。

たとえ、著作権登録を行ったとして、「盗まれないように誰にも見せずにしまっておく」という運用を勧めていたとしたら、それは、著作権侵害という主張を不可能にしてしまうという、ことでもあるのだ。
つまり、著作権の侵害(=無断複製)を主張するためには、逆説的ではあるが、「誰もが見ようと思えば見られる」という状況に置くということが必要なのである。

著作権の場合、たとえ、同じものができたとしても、「知らなかった(それを見る手段がなかった)」と証明できれば、著作権の侵害には当たらない。
一方で、特許の場合、特許は必ず公開されるので、「知らなかった」が通用しない世界ではある。
posted by 麻野なぎ at 12:28| Comment(0) | TrackBack(0) | 著作権の周辺

2010年08月02日

Turbo C++ (というか、BCB というか、C++ Builder)で、DLL の「共有セグメント」を使う安直な方法

【結論】

・共有セグメントに置きたい変数は、グローバルレベルで、「初期化せずに」宣言
・以下の記述のみの .def ファイルを、プロジェクトに追加する。

----------------- from here ------------
SECTIONS
_BSS READ WRITE SHARED
----------------- to here ------------

さて、先日、突然一日のキーストローク数をカウントしてみたくなりました。
公開するわけでも、販売するわけでもない、そういう目的なので、まあ、なんとか動かせばいいか……というレベルでいろいろ情報を探すと、

・システムフックというのを使えばいいらしい。
・システムフックは、dll として作成する必要があるらしい。
・この場合、dll は、各スレッドごとに作成されるので、グローバル変数(たとえば、キーストロークの総数)は、共有セグメントに持たなければならい。

ということ。
そして、共有セグメントを使う方法としては、

#pragma data_seg("セグメント名")
ここで、変数を宣言+初期化
#pragma data_seg()

としたあと、.def ファイルで、このセグメントを共有指定すればOKという情報が。

以上の情報を頼りに、dll を作り始めましたが、#pragma data_seg が変?
あ、これ、Visual C++ の独自拡張なのですね。BCB ではそのままでは使えません。

ではどうすればいいのか?
「メモリマップトファイルを使用してください」
あ、確かに、とっても正しい回答であります。

といいつつも、さらに、メモリマップトファイルまで理解するのはちょっとおっくう。
そこで、「何が本質的なのか?」と自問。

別に、変数に「任意のセグメント名をつける」ことが必要なのではなく、「その変数が存在するセグメントを、共有セグメントとして定義する」ことが必要なのです。

そう、「その変数が存在するセグメント」さえわかれば、(さらに、副作用さえなければ)、そのセグメント名を共有セグメントとして指定すれば良いわけです。

そこで、とりあえず作成したキーフックするソースをアセンブルしてみると、問題の変数は、BSS というセグメントに存在している。あとは、BSS というセグメントを共有セグメントにすればいいわけで……
※冒頭で、「初期化せずに」と書いたのは、たまたまこの条件の変数が BSS に存在していたというだけです。

keyHookdef.def というファイルを作って、その中に、上記の
SECTIONS
_BSS READ WRITE SHARED
を書き込み。

これをプロジェクトに追加すると、どうやら、所定の動作をしてくれたようです。
めでたしめでたし。

ちなみに、ソース全体は以下のようになります。

---------------- keyHookUnit1.cpp ------------------------
#include
#include
#include
#pragma hdrstop

// この下にある、グローバル変数が、BSS に存在するようです。
HINSTANCE hInst;
HHOOK hHook;
int pressCount;

static void save()
{
std::ofstream otf("c:\\user\\keyCount_LL.txt");
otf << pressCount;
otf.close();
}

static void load()
{
std::ifstream inf("c:\\user\\keyCount_LL.txt");

if (inf)
{
inf >> pressCount;
inf.close();
}
else
pressCount = 0;
}

LRESULT CALLBACK HookProc(int nCode, WPARAM wp, LPARAM lp)
{
if ((nCode == HC_ACTION) && (wp == WM_KEYDOWN)) // キー押下時
{
pressCount++;
if ((pressCount % 1000) == 0) save();
}
return CallNextHookEx(hHook, nCode, wp, lp);
}

extern "C" __declspec(dllexport) void HookStart()
{
load();
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, (HOOKPROC)HookProc, hInst, 0);
}

extern "C" __declspec(dllexport) void HookEnd()
{
UnhookWindowsHookEx(hHook);
save();
}

extern "C" __declspec(dllexport) int get()
{
return pressCount;
}

extern "C" __declspec(dllexport) void clear()
{
pressCount = 0;
save();
}

#pragma argsused
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
hInst = hinst;
return 1;
}
---------------- keyHook.h --------------------------------
#include

extern "C" __declspec(dllexport) void HookStart();
extern "C" __declspec(dllexport) void HookEnd();
extern "C" __declspec(dllexport) int get();
extern "C" __declspec(dllexport) void clear();

---------------- keyHookDef.def ---------------------------
SECTIONS
_BSS READ WRITE SHARED
---------------- to here ----------------------------------
posted by 麻野なぎ at 12:28| Comment(1) | TrackBack(0) | Twitter と Bot の周辺

2010年07月27日

節気さんBotと、「中秋の名月」

【2010年8月29日に追記】

実は、「月の名前」の切り替え時刻を考え直しました。
詳細は、「月の異名」再び( http://asano-nagi.sblo.jp/article/38733291.html )への追記としましたが、これにより、中秋の名月の切り替えも、普通の感覚にかなり近づいたと思います。

実際には、


始まり:2010年9月22日 5:22 (高知の明六ツ)
終わり:2010年9月23日 6:00 (月齢君の定時ツイート)

と言うことになります。

--------------------- 追記、ここまで。


今年も、秋になると、「中秋の名月」がやってきます。
節気さんシリーズBotでも、中秋の名月に反応します。(世界の……、は除く)
ただ、当日になると、「節気さんシリーズ、違うんじゃないか」と思われそうなので、早めにちょっとした解説です。

内容は、「月の異名(というか、月の呼び名)」さらに……。( http://asano-nagi.sblo.jp/article/38759410.html ) で書いたものではあるのですが。
さて、節気さんシリーズでは、月の名前は「(旧暦)何日の月はどういう名前」という立場ではなく、「(旧暦)1日から数えて、何回目の月はどういう名前」という立場をとっています。
たとえば、今年(2010年)の中秋の名月付近は、

9/21 16:21 月の出 〜 9/22 4:12 月の入り(小望月)
9/22 16:47 月の出 〜 9/23 5:08 月の入り(十五夜)
9/23 17:13 月の出 〜 9/24 6:04 月の入り(十六夜)

として、取り扱っています。(月の出・月の入時刻は東京のもの)
「何日の月が」という規定をしてしまうと、月が出ている間に(日付をまたぐので)月の名前が変わったり、未明の月(月の入り前)と夕刻の月(月の出後)のどちらの名前なのかとか、そういう問題が発生するためです。

さて、このようなわけで、月の名前が変化するタイミングは月の入りと月の出の中間としています。
ですから、節気さんシリーズが、「十五夜(特に、中秋の名月)」とつぶやくのは、

開始:小望月の月の入りと、十五夜の月の出の中間 = 9/22 10:29
終了:十五夜の月の入りと、十六夜の月の出の中間 = 9/23 11:10

となります。

一般的には、「(2010年は)9月22日が中秋の名月」と言われることになりますが、節気さんシリーズは、9/22になっても、10:30 頃までは、「小望月」と言ってますし、翌日(9/23)になっても、昼前まで、「中秋の名月」とつぶやくことになります。

それは、こういう事情によるわけです。

2010年06月11日

OAuth への道 ―― OAuth gate 作ってみました

もしかして、Basic 認証の Bot の出力をそのまま、OAuth に置き換えられるんではないか……と、
ちょっと作ってみました。

非常に限定的な用途になりますが、もしかして、どこかに需要があるかも……しれないと。

【特徴】

・Bot と 同じパソコンの中で動きます(ネットワーク経由でも動かないことはない)
・故に、外部に、パスワードなどを送信しません
・ただし、パソコンの中に、OAuth 用のシークレットコードを保存します
・Twitter のパスワードは、(OAuth gate では)保存しません。

【対象】

・Windwos で動作します。(一応、OAuth gate が Windows 上で動けば、ネットワーク上の他のパソコンでBotが動くのも可です)
・POST にしか対応していません(Twitter API では、statsues/update のみです)
・何かを投稿する毎に、Twitter に「接続」と「切断」をするタイプのBotにしか対応しません。
・それ以外の機能が使われていたりすると、良くないことが怒ると思います。
・プロクシにも対応していません。
・ひとつの Bot に対してしか(というか、一組の、OAuth キーに対してしか)対応していません。

詳しくはこちらで → http://www.axis.blue/tec/oauth_gate.html
posted by 麻野なぎ at 12:31| Comment(0) | TrackBack(0) | Twitter と Bot の周辺

2010年06月10日

OAuth への道 ―― OAuth gate というのを考えてみた。

OAuth gate の動きを少々修正しました。
いや、修正したと言っても、まだ作ってませんが。
さて……。


Basic 認証で動く Bot と同じパソコンの中で動いて、OAuth 認証にして Twitter に投げるという発想で。

もともとが安易な性格なので

・Windows で動いて
・Bot のみ対応
・そもそも、POST のみ対応
・一回ごとに(認証だけではなく)接続と、切断を行うBotのみ対応

というパターですが。
こんなのでできるのかな?
とりあえず、○つけたのは、コードを書いたつもり。



○ 1)[SYSTEM] port の値(デフォルトは 80)で、サーバーとして待機する
○ 2)クライアントからの接続要求を受け入れる
○ 3)クライアントから切断が要求されたら、接続を切断する(自動)
×   ・その際、Twitter 側に接続中であれば、その接続を切断する

○ 4)接続完了後、クライアントからのデータを受信する
○ 5)クライアントからのデータは CRLF で1行ごとに区切る
○ 6)2個の空行(CRLF のみの行)を受信したら、次の処理に移行する

○ 7)最初の空行の直前までをヘッダとする。
○ 6)最初の空行の次の行をボディとする(ボディは1行のみ)
○   ・以上の結果を、Memo_server_recv に順次書き込む

8)ヘッダの処理
○   ・POST で始まり、.json を含む行 → POST http://api.twitter.com/1/statuses/update.json HTTP/1.1 に差し替える
○   ・POST で始まり、.json を「含まない」行 → POST http://api.twitter.com/1/statuses/update.xml HTTP/1.1 に差し替える
○   ・Authorization: で始まる行
×     Basic 以降、行末までの文字列を取得する
×     文頭・文末のスペースをトリミングする
×     得られた文字列のハッシュを算出する(MD5)
×     算出されたハッシュが、[USER] ID_Pass と一致することを確認する
×    ・一致しない場合、Twitter 側への送信は行わない
×      クライアントへは、とりあえず、エラーの旨を返す。
○     OAuth ヘッダを算出し、これに差し替える
○   ・Host: で始まる行 → Host: api.twitter.com に差し替える
○ ・その他の行 → そのまま
×   ・POST で始まる行、Authorization: で始まる行のいずれかが存在しない場合、Twitter 側への送信は行わない
      クライアントへは、とりあえず、エラーの旨を返す。

○   ・以上の変換処理(そのままの行を含む)結果を、Memo_twitter_send に順次書き込む

9)ボディの処理
○   ・ボディの内容を、そのまま、Memo_twitter_send に書き込む

× 10)api.twitter.com に接続要求を行う
× 11)接続を待つ → 60秒以内に接続できないとき、Memo_twitter_recv に、「接続エラー」を書き込み、サーバーとしての接続を遮断する
× 12)api.twitter.com に対して、Memo_twitter_send の内容を順次送信する
× 13)api.twitter.com に対して、読み込みを行い、読み込み内容を、Memo_twitter_recv に順次書き込むとともに、クライアントに送信する
× 14)受信終了文字列を受信したら( とか)Twitter への接続を切断する

○ 15)クライアントからの切断要求を受けて、接続を切断する。(3)と同じ
posted by 麻野なぎ at 12:20| Comment(0) | TrackBack(0) | Twitter と Bot の周辺