POSIX原理主義でOAuthも侵略「火を吹くTwitter怪人“小鳥男”」

この記事は、POSIX原理主義の思想で世界征服を目論む**[秘密結社シェルショッカー日本支部](https://github.com/ShellShoccar-jpn/)**がお送りします。
物語に登場する名称は一部を除き架空のものであり、実在する人名・団体名等とは一切関係ありません。

![ShellShoccar_title.png](https://qiita-image-store.s3.amazonaws.com/0/9113/8d1687e2-3c17-b312-6150-6fc3eca7d3fa.png)

# Twitterリア充祭、絶賛開催中

全世界70𥝱人(70𥝱人=70,000,000,000,000,000,000,000,000人)のプログラマーどもよ、メリークリスマス。私こそ秘密結社シェルショッカー日本支部のリッチー大佐である。

こんな時間に、しかもクリスマスの夜にQittaを訪れているお前たちなら当然、ひとりでネットと戯れているはずだな！しかし、ネットの向こうには、カノジョやデートスポット、高級な料理の写真とともに自分がいかに勝ち組であるかをTwitterでひけらかすリア充どもが、今まさに増殖している。しばらくの間、Twitterを開けばそんな奴らのツイートが洪水のように押し寄せる。お前たちには閲覧を拒否する権利も無く、そのダメージは計り知れない。

どうだ、訳も無く腹が立つか？反撃したいとは思わぬか？……フッフッフ、そうかそうか、ならばいい方法を教えてやろう。なぁに簡単なことだ、**リア充が行きそうなスポットに対し、爆破予告や殺人予告を一言ツイートするだけ**だ。ターゲット店の厨房の冷蔵庫に入り込んでの記念撮影写真や、ターゲット店内で醤油差しを鼻に突っ込んでの記念写真付きのツイートをするのもよいな。リア充どもは悲鳴を上げて逃げだずぞ。ワッハッハ！

まぁしかし、丸腰でやったらあっという間に捕まるだろう。そこでだ、今日はお前たちに我々が開発した秘密兵器を与えてやろう。**さぁ、姿を見せろ！怪人「小鳥男」よ！**

# [Twitterクライアント怪人「小鳥男」](https://github.com/ShellShoccar-jpn/kotoriotoko)

この怪人はな、かつて仮面○イダーに倒され、死んだ「ドクガ○ダー」という怪人をベースにしておる。当時の戦闘の現場から怪人のDNAを採取し、我らの**POSIX原理主義シェルスクリプトテクノロジー**により、Twitterバード（API）と融合させて造ったのだ。シェルスクリプトの姿をしておるが、飽くまで怪人だ！

![Kotoriotoko_spec.png](https://qiita-image-store.s3.amazonaws.com/0/9113/1e3ed0b7-b1f3-f796-170a-ef22a0b6d746.png)

Twitterバードが小鳥であるせいで、こいつらを融合させたら小柄で小太りの男になってしまったがな……。しかし、なぜそんな無様な死にざまを晒した怪人をわざわざ復活させたのか気になるか？それはな、奴には**炎を吹く能力があったから**だ。どうだ、Twitter民どもを炎上させるにはうってつけであろう。ワッハッハッ！

## Twitterの日常操作を、コマンド化する

小鳥男の使命は、普段お前たちがWebブラウザー上でGUI的にやっているTwitterの各種操作を、コマンドでCUI的に行えるようにすることだ。次に列挙する操作がすべてコマンドでできるようになるのだ。

* 投稿系
  * 投稿（画像・動画付も可）、リツイート、それらの取消
  * お気に入り登録、取消
* ツイート閲覧系
  * タイムライン表示
  * 検索
* フォロー系
  * フォロー、解除、フォロー先・フォロワー表示

## 小鳥男の恐るべき戦闘能力

だが小鳥男の真の恐ろしさそこではない。こいつはPOSIX原理主義シェルスクリプトで書かれているから、**世の中のほとんどのUNIXホスト上にコピーするだけで動く。**これこそが小鳥男の恐ろしさだ！

フッフッフッ……気付いたか！あとはお前たちがハッキング能力さえ身に付ければ、世界中のUNIXホストにいとも簡単にこの小鳥男を仕掛けることができ、世界中のホストからアブナいツイートをしまくって、Twitter民どもを炎上、そして混乱に陥れることができるというわけだ。世界征服も実に捗るな。ワッハッハッ！

# さぁ、使ってみろ！

小鳥男が何者かわかったら早速使ってみて驚け。そのためにまず小鳥男のインストール方法を教えてやる。手順は大きく分けて3つある。アカウントとアプリの登録、プログラムのインストール、そして設定だ。インストールはアッと言う間だが、Twitterのこざかしいセキュリティー対策のせいでアカウントの登録が少々面倒だが……、まぁやってみるがよい。

## 1) アカウント&アプリケーション登録

このサイトを見にくるお前達なら詳しい説明は不要だな。Twitterのアカウント登録と、アプリケーション登録をするのだ。なに、どうやればいいのかわからないだと？仕方のない奴め。[Twitter APIの使い方まとめ](https://syncer.jp/twitter-api-matome#sec-1)あたりを見て済ませてくるがいい！

アカウント登録にあたっては、携帯電話の登録を済ませておくのを忘れんようにな。WebブラウザーからではなくTwitter APIから使うためには、今年からそれなりの審査をパスしなければならないようになった。その審査に使われるのが携帯電話（**SMSが受信できる機種でなければならない**）であり、こいつで身元確認をしようという腹らしい。恐らく我々のような秘密結社を排除するためであろうな。フッ、こざかしい真似をしおって……。だがな、そんなもの我々には無力だ!!

## 2) 小鳥男のインストール

インストールは物凄く簡単だ。gitコマンドが使えるなら、適当なディレクトリーに移動して次のとおりに打ち込むだけで一発完了だ！コマンドの起動に必要な実行パーミッションの設定もgitコマンドがもうやり終えている。本当にコマンド一発だ、どうだ凄いだろう。この勢いで世界中のサーバーに小鳥男を次々インストールしていけばいいのだ。

```sh:gitコマンドで一発インストール完了
$ git clone https://github.com/ShellShoccar-jpn/kotoriotoko.git
```

gitコマンドが使えないホストでは一発とはいかぬが、もちろんインストールは可能だ。適当なディレクトリーに移動して次の通りに打ち込めばよい。やっていることは小鳥男のリポジトリーにあるzipファイルをダウンロード・展開し、その中の"BIN"と"TOOL"と"UTL"ディレクトリー内の各ファイルに実行パーミッションを与えているだけだ。難しいことは何もないな。

```sh:gitコマンドが無いならこうやってインストールするのだ
$ wget https://github.com/ShellShoccar-jpn/kotoriotoko/archive/master.zip
$ unzip master.zip
$ chmod +x kotoriotoko/BIN/* kotoriotoko/TOOL/* kotoriotoko/UTL/*
```

## 3) アカウント情報を設定する

最後は設定作業だ。まずは小鳥男インストールディレクトリー直下の“CONFIG”ディレクトリーの中にある“COMMON.SHLIB.SAMPLE”というファイルを、同じ場所に“COMMON.SHLIB”という名前でコピーし、普段使っているテキストエディターでそれを開け。

```sh:設定ファイルのテンプレートをコピーして開け！
$ cd ./kotoriotoko/CONFIG
$ cp COMMON.SHLIB.SAMPLE COMMON.SHLIB
$ vi COMMON.SHLIB
```

そこに次のようにして取得した各種アカウント情報を書き込むだけだ。

```text:
            :
            :
######################################################################
# アカウント情報
######################################################################

readonly MY_scname='hogehoge'
readonly MY_apikey='1234567890123456789012345'
readonly MY_apisec='12345678901234567890123456789012345678901234567890'
readonly MY_atoken='1234567890-123456789012345678901234567890123456789'
readonly MY_atksec='123456789012345678901234567890123456789012345'
```


## 4) Enjoy! 炎上in'!（動作確認）

これで準備は全て整った。あとはコマンドを好きに実行するだけだ。“BIN”ディレクトリーの中にあるものが実行コマンドだ。“BIN”へ移動し、試しに次のようにしてツイートしてみるがいい。

```sh:れっつ炎上in'
$ cd ./kotoriotoko/BIN
$ ./tweet.sh "【爆破予告】今からハド○ン本社にボンバ○マンを仕掛けます。【拡散希望】"
```

![Kotoriotoko_ScreenShot.png](https://qiita-image-store.s3.amazonaws.com/0/9113/0bd45a4c-d617-b9ca-7f01-9ccd61d22c34.png)

あぁ言い忘れたが、アカウントを普通に取得した限り、丸腰ツイートだからな。ツイート文には気を付けろよ。

# 何、動かんだと？

どうだ使い心地は……。何、エラーメッセージが表示されて動かない、だと？それは140文字を超えるツイートをしているとかそんなところではないのか。ん、エラーメッセージを見てほしいだと。よし、見せてみろ。

```
$ ./tweet.sh '世界征服だ！わっはっは'
tweet.sh: OpenSSL command is not found.
$ 
```

それは読んで字の如く、OpenSSLコマンドが見つからんということだ。[OpenSSL](https://www.openssl.org/)または[LibreSSL](http://www.libressl.org/)のどちらかをインストールすればよいだけだ。

何、また別のメッセージが出ただと？どれ、もう一度見せてみろ。

```
$ ./tweet.sh 'お前もPOSIX原理主義者になれ！'
tweet.sh: No HTTP-GET/POST command found.
$ 
```

小鳥男はWebアクセスに[cURLコマンド](http://curl.haxx.se/)または[GNU Wgetコマンド](http://www.gnu.org/software/wget/)を必要としているのだ。だからそのどちらかをインストールすれば治まるぞ。

わかっておる……。POSIX原理主義集団の秘密結社シェルショッカーが、なぜPOSIXの範囲でないコマンドに当たり前のように依存しているのかと言いたいのだな。せくな、その理由は今から説明してやる。

# 新解釈・POSIX原理主義

OpenSSLやcURL/Wgetに依存するなどという、POSIX原理主義に反するようなことをなぜやったのか。特にOpenSSLなどは、2014年に[Heartbleed](https://ja.wikipedia.org/wiki/%E3%83%8F%E3%83%BC%E3%83%88%E3%83%96%E3%83%AA%E3%83%BC%E3%83%89)という超特大のセキュリティーホールを出したプログラムだ。なぜそんなものに頼ったのか。理由は簡単だ。**POSIXの範囲では理論的に不可能な処理があるからだ。「できないものはできない」と認めざるを得ない。**

だが心配するな。これでPOSIX原理主義が破綻するわけではない！我々の野望がついえるわけでは決しないぞ！

## 交換可能性の確保こそが真の目的

POSIX原理主義という思想はなぜ生まれたのか、よく考えてみるのだ。

OSや言語、依存ソフトウェア等で行われるバージョンアップ。下位互換性があると言いながら実は細かなところで失われていたり、酷い時はあえて切り捨てられたり……。しかもそれが年に何度も何度も繰り返される。予告のうえで行われることもあれば、脆弱性の発見などによってある日突然通告されて実施されることもある。我々は散々そういう目に遭い、苦しめられてきたのではないか。

そこでPOSIXという理想郷に辿り着いた……。POSIXとは1つのベンダーの思惑を超えて、「皆でこの仕様を守りましょう」という国際規格だ。だから、1つのベンダーの気まぐれで仕様がコロコロ変わるということがない。かつ、複数のベンダーが互換性のあるコマンドをそれぞれ独自に実装している。だからPOSIXの範囲でプログラムを組んでいれば、例え1つのOS（実装）が脆弱性やサポート終了で使えなくなっても、別のものに簡単に乗り換えられるのだ。そうすれば10年20年の長きに渡り、使い続けられるプログラムになる。この簡単に乗り換えられるという性質、つまり**依存ソフトを簡単に交換できるという「交換可能性」こそがPOSIX原理主義の本質だ。**

よく「bashやPHPなどの主要なシェルや言語は、どのOSでも大抵用意されているから実質的にPOSIXみたいなものだ」などと言う輩がおる。愚か者めが！全然違う。それらを作っている開発団体はいくつある？bashは[FSF](http://www.fsf.org/)だけが、PHPは[The PHP Group](http://www.php.net/)だけが作っていて、互換性のある別実装というものが存在せん。だから、それら唯一の実装が使えなくなったら逃げ道は無いのだよ。bashには去年[Shell Shock](https://ja.wikipedia.org/wiki/2014%E5%B9%B4%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B7%E3%83%A7%E3%83%83%E3%82%AF%E8%84%86%E5%BC%B1%E6%80%A7)という巨大なセキュリティーホールが見つかって大騒ぎになったな。同時に修正バージョンが公開されたからいいが、もし無かったら……。普及率の高さにあぐらをかいてbash依存のシェルスクリプトを書いていた者は泣きながら別シェルへの移植作業をしなければならなかったはずだ。

ゆえに、10年20年の長きに渡ってメンテナンス地獄から解放されたければ、**普及率の高さではなく、互換実装の多さを担保することが重要**なのだ！だから我々はPOSIXにこだわってきたのだよ。

## ではOpenSSLやcURL/Wgetはどうか？

OpenSSLやcURL/Wgetで交換可能性は果たして確保できるのか？

まずOpenSSL。こいつはさっきも触れたように2014年、Heartbleedという超特大のセキュリティーホールをひけらかしてしまった。だが逆にその反省から、LibreSSLという別の実装が生み出されることになった。しかも都合がよいことに、OpenSSLと基本的に同じコマンド引数が通用するような完全互換コマンドまで同梱されたのだ。ゆえに、今度またOpenSSLで何らかの致命的セキュリティーホールが見つかったらLibreSSLに乗り換えるだけで済む。依存アプリケーションには一切手を加えずにな。もちろんLibreSSL側に致命的セキュリティーホールが見つかればOpenSSLに乗り換えればよい。

次にWebアクセスコマンドであるcURLやWgetだ。これは残念ながらOpenSSLとLibreSSLのように完全互換ではない。コマンド引数も全く違う。しかもcURLの方が多機能で、例えばcURLならCGI変数のPOSTやファイルアップロードなども非常に簡単にできる。問題はここだ。ここでcURLに合わせ、cURL独自のファイルアップロード機能を使ってしまえば、POSIX原理主義は本当に破綻する。普通のプログラマー達は、こういう場面で何の躊躇もなく利用できる機能を利用してしまうからその後にメンテナンス地獄に堕ちるのだ。まったく愚かなことだ……。

## 新解釈・POSIX原理主義の実践

POSIXの範囲ではできないことがありながらも、POSIX原理主義の本質は貫く。これを**新解釈・POSIX原理主義**、略して「新POSIX原理主義」あるいは「POSIX原理主義2.0」と呼ぶ。

小鳥男のコマンドの一つ“twmediup.sh”を見てみよ。これはTwitterに投稿用の画像ファイルをアップロードするためのコマンド[^1]だ。インストールした小鳥男のファイルを開いてもよいし、[GitHub上のコード](https://github.com/ShellShoccar-jpn/kotoriotoko/blob/master/BIN/twmediup.sh)をブラウザーで眺めてもよいぞ。

[^1]: 通常のツイートコマンド“tweet.sh”で、画像付きツイートをすると内部的に呼び出されるので通常直接実行する必要はない。

このコードで新POSIX原理主義的に注目すべき箇所は2つある。まず1箇所目は54〜61行目だ。

```sh:twmediup.sh(54-61)
# --- 2.HTTPアクセスコマンド（wgetまたはcurl）
if   type curl    >/dev/null 2>&1; then
 CMD_CURL='curl'
elif type wget    >/dev/null 2>&1; then
 CMD_WGET='wget'
else
 error_exit 1 'No HTTP-GET/POST command found.'
fi
```

コマンドの序盤でこのようにして、必要なWebアクセス系のコマンドが利用可能かどうか調べておる。1つの実装に依存することが過ちであるから、cURLかWgetという複数の実装のどれか1つがあればよいように作ってある。さすがにどれも無ければエラー終了させるしかないがな……。

次に注目すべき箇所は195〜211行目だ。

```sh:twmediup.sh(195-211)
s=$(mime-make -m)
ct_hdr="Content-Type: multipart/form-data; boundary=\"$s\""
eval mime-make -b "$s" $mimemake_args |
if   [ -n "${CMD_WGET:-}" ]; then
  cat > "$Tmp-mimedata"
  "$CMD_WGET" --no-check-certificate -q -O - \
              --header="$oa_hdr"             \
              --header="$ct_hdr"             \
              --post-file="$Tmp-mimedata"    \
              "$API_endpt"
elif [ -n "${CMD_CURL:-}" ]; then
  "$CMD_CURL" -ks              \
              -H "$oa_hdr"     \
              -H "$ct_hdr"     \
              --data-binary @- \
              "$API_endpt"
fi
```

こうやってcURLとWgetのうち存在する方のコマンドを使っている。書式が異なるのでif文を使い、cURL用のコード、Wget用のコードを用意しているわけだ。このコードには新POSIX原理主義を実践するうえで重要な記述が含まれている。それは“mime-make”というコマンドの利用だ。HTMLの`<form>`タグでファイルを送信するフォームを作る時、“`enctype='multipart/form-data'`”という属性を付けるだろう。mime-makeはあの時にWebブラウザーが内部で生成するデータと同じ物をつくるためのコマンドだ。そしてこのコマンドは、我々が旧来のPOSIX原理主義シェルスクリプトで作った独自コマンドである。[GitHubでも公開](https://github.com/ShellShoccar-jpn/misc-tools/blob/master/mime-make)しているぞ。

話を195〜211行目の説明に戻すが、mime-makeというコマンドを使い、アップロードするファイルのMIMEマルチパートデータを独自に作成し、それをcURLやWgetに渡している点に注目せよ。`eval mime-make`と書かれた行の最後にパイプ記号“`|`”が付いていて、後続のif節に繋げてあるからその様子がわかるな。このコマンドがあればcURLのファイルアップロード用オプション“-F”に依存せずに済む。WgetにはcURLの“-F”に相当するオプションが存在しない（つまりファイルアップロード機能がない）から、もしcURLの“-F”に依存する作り方をしていたらWgetという別の実装への交換可能性が確保できん。これでは万が一がcURL使えなくなった時に逃げ道が残されていないことになってしまうのだよ。

だから我々は、mime-makeというコマンドを苦労しながらも再発明した。これこそが新POSIX原理主義の実践である。

# POSIXでできることはPOSIXでやれ！

再発明したのはmime-makeだけではない。他にもいくつかの処理を実現するコマンドを再発明してきた。次の図を見よ！

## OAuth1.0aを自力でやる

![Twitter_OAuth1.0a.png](https://qiita-image-store.s3.amazonaws.com/0/9113/27fa7ac5-5e57-373a-0cc3-987845671033.png)

Twitter APIアクセスの肝である[OAuth](http://oauth.net/)1.0aの処理も小鳥男にとって欠かせない機能であるが、そのデータフロー図だ。OAuth1.0aはこの図に示したとおり嫌気が差すほど複雑だ。図の中の台形で描かれた枠が1つ1つのデータの加工処理を示しておるが、この図にはそれが26か所もある。ちなみに太枠の台形部分は先程説明したOpenSSLとcURL/Wgetに依存する部分だ。

それ以外の台形の部分に注目せよ。大半がprintf相当と、URLエンコードで、それ以外に1か所だけBase64があるのがわかるな。printf相当の処理などは、実際にprintfコマンドでやってもよいし、sedやAWKの類を使ってシンプルに書くこともできるのでどちらにせよ難なくできる。だが問題は、URLエンコードとBase64の処理だ。POSIX原理主義の重要性が理解できていなかったらお前たちはきっと、[nkfコマンド](https://osdn.jp/projects/nkf/)あたりを拾ってきてURLエンコード処理をしたり、base64コマンド(GNU製で、大抵のLinuxに搭載されている。)を使ってBase64エンコード処理をしていたところだろう。**それが大間違いなのだ。**

お前たちはnkfやbase64コマンドが使えなくなった時の逃げ道をちゃんと用意しているか？用意しているならまあよいが、そんな処理ごときPOSIXの範囲で十分だ。もちろん我々は、POSIXの範囲でやっておる[^2]。自作の[urlencodeコマンド](https://github.com/ShellShoccar-jpn/misc-tools/blob/master/urlencode)とか[base64コマンド](https://github.com/ShellShoccar-jpn/misc-tools/blob/master/base64)でな。

[^2]: 小鳥男は実際にはBase64エンコードもOpenSSLに任せているのがな。なぜならOpenSSLはBase64エンコード機能も持っていて、小鳥男は元々OpenSSLに依存しているからだ。

## JSONパースもPOSIXでできる

さらに言えば、JSONのパースもPOSIXの範囲で実装している（→[jq、xmllintコマンドさようなら。俺はパイプが好きだから](http://qiita.com/richmikan@github/items/e051b5d882c3dd2a39c6#%E7%84%A1%E3%81%84%E3%82%82%E3%81%AE%E3%81%AF%E4%BD%9C%E3%82%8B%E6%97%A2%E5%AD%98%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%81%AE%E7%B5%84%E3%81%BF%E5%90%88%E3%82%8F%E3%81%9B%E3%81%A0%E3%81%91%E3%81%A7%E3%82%82%E7%9B%B8%E5%BD%93%E3%81%AA%E5%A8%81%E5%8A%9B)）。

さっきの図の一番下に、レスポンス（JSON形式）と書いてある箇所があるだろう。そう、Twitter APIは結果をJSON形式で返してくるから、JSONデータを読み解かなければならんのだ。そこでまた[jq](https://stedolan.github.io/jq/)などといったプログラムに手を出していったら……、最終的に一体どれだけのプログラムの気まぐれに翻弄されることになるのやら。**世の中の大半のプログラムは、こうやっていくつも急所を曝け出しているのだ**。まったく、開発者どもには使う側の身にもなってもらいたいものだな。

# さぁ行け！優秀なる戦闘員たちよ

よいか、こうやって1箇所1箇所、交換可能性を担保するために配慮することが、POSIX原理主義という理想郷を目指すためには重要なのだ。確かにPOSIXの範囲でコマンドを自作することは大変だ。しかし、一度作ってしまえばあとは皆で共有すれば済むではないか。だからこそ我々は、世界のプログラマーどもをPOSIX原理主義教に引き入れようとしているのだ。

さぁ行け、優秀なる戦闘員（プログラマー）たちよ。世界中のコンピューターをハッキングして怪人「小鳥男」を送り込み、アブナいツイートを乱発させて、世のTwitter住民どもを炎上させるのだ。この調子なら、冬コミ4日目を迎える来年あたりには世界征服も完了しそうだな。ワッハッハ！

# その前に[冬コミ](http://www.comiket.co.jp/info-a/C89/C89info.html)でシェルスクリプトに染まれ！

我ら秘密結社シェルショッカーが暗躍する記事の他、WebやIoT界のイカした記事を収録した同人誌「[ななかInside PRESS vol.8](https://sites.google.com/site/dai7sec/)」が[冬コミ](http://www.comiket.co.jp/info-a/C89/C89info.html)3日目(2015-12-31)「[東ム38b](https://webcatalog-free.circle.ms/Circle/12314299)」の[第7開発セクション](https://sites.google.com/site/dai7sec/)から発行されるぞ！

そしてその隣「[東ム38a](https://webcatalog-free.circle.ms/Circle/12306459)」、日本支部の責任者であるこの私が世を忍ぶサークル[松浦リッチ研究所](http://richlab.org/)ではこの[新POSIX原理主義の聖典](https://richlab.org/coterie/ssr2015.html)を頒布する。

さぁお前たち、大晦日は[ビッグサイト](http://www.bigsight.jp/)でシェルスクリプトに染まるのだ。ワーッハッハッハッハッ！