Shogo's Blog

Sep 23, 2014 - 1 minute read - Comments - perl

Github::Hooks::ReceiverがX-Hub-Signatureをサポートしました

Github::Hooks::ReceiverにX-Hub-SignatureをサポートするPull Requestを送ったら、 速攻取り込まれ、さらにGithubのコミット権とPAUSEのco-maintパーミッションをもらったというお話。 X-Hub-Signature GithubのWebhookは大変便利なんですが、特に対策をしないままだと 他の人にcurlとかで叩かれてしまう可能性があります。 本来であればIPアドレスで制限をかけるべきなんですが、 iptablesの設定とかよくわからないし・・・と思ってGithubのドキュメントを読んでいたら、 もっとお手軽な方法発見。 Securing your webhooks GithubからのリクエストにはX-Hub-Signatureというのがついていて、 これを使うとPayloadの検証ができるらしい。 Github::Hooks::Receiverは このヘッダを全くみていないようだったのでPull Requestを送ってみた。 Github::Hooks::Receiver 0.02以降で、以下のようにsecretの指定ができるようになります。 use Github::Hooks::Receiver::Declare; my $receiver = receiver { secret 'secret1234'; # Webhookの設定画面のsecretの項目と同じものを入力 on push => sub { # レポジトリにPushされた時の処理とかをゴニョゴニョ書く }; }; my $psgi = $receiver->to_app; $receiver->run; これでsecretを知らない人がリクエストを偽装できなくなるので安心です。 secretはエントロピーが高いほうがいいので ruby -rsecurerandom -e 'puts SecureRandom.hex(20)' みたいなコマンド使うといいらしいですよ。 String::Compare::ConstantTime Signatureの比較にはRubyのsecure_compareのような関数を 使ったほうがいいらしい。 Github::Hooks::Receiverでは、そのPerl版のString::Compare::ConstantTimeを使ってみた。 ちょっと引数のチェックに甘いところがあって、segmentation fault場合があったので、こちらにもPull Requestを送っておきました。 Github::Hooks::Receiverは使う前にチェックを入れてあるので、現行バージョンでも問題なく動くはず。 String::Compare::ConstantTimeはXSで書かれたモジュールなんですが、 この手のバグが入り込みやすいのでXS難しいですね。 まとめ XS怖い Github::Hooks::Receiverにsecretを指定できるようになったので、IP制限がかけられない場合でも安心 でも、可能であればIP制限もしましょうね XS怖い 追記 IP制限について Songmu先生よりコメントをいただきました。

Sep 13, 2014 - 1 minute read - Comments - git

Githubさんにpack exceeds maximum allowed sizeって言われた

Githubに手元のレポジトリをpushしようとしたら、 「Pushできないよ!!」って言われたときのメモ。 コミット数が17kほどあって、画像とかサイズが比較的大きいファイルがたくさんあるレポジトリを、 一度に全部pushしようとしたら「制限を超えてます」って言われてダメだった。 $ git push origin master Counting objects: 280874, done. Delta compression using up to 4 threads. Compressing objects: 100% (60497/60497), done. remote: fatal: pack exceeds maximum allowed size error: pack-objects died of signal 13 error: failed to push some refs to 'git@github.com:***/****.git' ググってみると、おんなじような症状が見つかった。 Github remote push pack size exceeded リモートへのPushはオブジェクトを全部一つにPackしてしまうので、 一度に大量のコミットをPushしようとすると制限に引っかかるらしい。 (そして、サイズを制限する方法はないみたい) 解決策は「2回以上に分けてPushしてね」とのこと git push remoteB <some previous commit on master>:master ... git push remoteB <some previous commit after the last one>:master git push remoteB master 頑張ってコミットログを遡ってコミットハッシュを調べるのはつらかったので、 打ってあったタグからコミットハッシュを調べてPushした。

Sep 3, 2014 - 1 minute read - Comments -

秘密鍵から公開鍵をつくる

githubに公開鍵を登録しようと思ったけど、 手元に秘密鍵しかなくて困った時のメモ。 ssh-keygenを使うとできます。 # 秘密鍵を読み込んで公開鍵を出力する ssh-keygen -y -f ~/.ssh/id_rsa この公開鍵って登録したっけ? ってときには以下のコマンドでフィンガープリントを確認できます。 # 公開鍵のフィンガープリントを取得する ssh-keygen -l -f ~/.ssh/id_rsa.pub

Aug 31, 2014 - 1 minute read - Comments - perl

YAPC::Asia 2014 に行ってきた #yapcasia

YAPC::Asia 2014 に参加してきました。 「ブログに書くまでがYAPC」らしいので、メモ書き。 見たトーク Perl meets Real World 〜ハードウェアと恋に落ちるPerlの使い方〜 デモ中のURLが「localhost」になってたんであれ?って思ったんですが、WebサーバはPC上にあったんですね。RaspberryPi上でPerl動くんじゃなかったんですか! ネギ振りミククラウド化するって言ってたんで期待してます Go For Perl Mongers お待たせしました。Perl で BDD を簡単に実践する最高にクールなフレームワークができました DBIx::Class - what is it and what is it good for? HashRefInflatorの存在を初めて知りました 今関わってるプロジェクトでDBICのRowObject生成コストが問題になってるんで、後で試してみたいです Scala In Perl Company : Hatena WHERE狙いのキー、ORDER BY狙いのキー Get a kick out of CPAN 初心者が Web エンジニアのコミュニティに触れてみて感じたこと - ゆとりエンジニアの成長戦略

Jul 5, 2014 - 1 minute read - Comments - perl

PerlのXS中に起きたシグナルの扱い

Redis::Fast にIssueが来ていたので、 それに関して調査したお話です。 接続タイムアウトすると double free check に引っかかる brpop みたいな長時間ブロックするコマンド中にシグナルが入ると、最初の1回が無視される 前者はC言語つらいって話で頑張って double free になる条件を探せばいいんですが、 後者はシグナル時のPerlやPOSIX APIの挙動を知らなくと解決できなそう。 そういうわけで、主に後者について調べた結果をまとめておきます。 PERL_ASYNC_CHECKってXS中から呼んでもいいの? 言いたいことは最初に書いとけって偉い人に言われたので、最初にこの記事の結論を。 「よしななタイミングでPERL_ASYNC_CHECKを呼べばいいっぽい」みたいです。 でも、 ** 「PERL_ASYNC_CHECKってXS中から呼んでもいいの?」 ** という点に確証が持ててないので、 識者のご意見を募集してます! selectの挙動を調べる Redis::FastはRedisからのレスポンスを待つのにLinuxのselect apiを叩いてます。 ファイルとかが読み書き可能になるまで処理をブロックしてくれるいいやつです。 しかし、select が処理をブロックしている間にシグナルを受信すると、うまく処理ができてないらしい。 そこで割り込み発生時の挙動を確認してみます。 困った時のmanページ(select) をちゃんと読めば書いてありますね。 エラーならば -1 を返し、 errno にエラーを示す値が設定される; EINTR シグナルを受信した。 Redis::Fastはerrnoを特に確認せず、とにかくエラーが発生したらリトライになってたのでダメだったみたいです。 通信にエラーが起きたわけではないので、再接続処理とかみたいな複雑なリトライ処理は必要なく、 単にもう一度selectしなおせば良さそうです。 Perlさんのシグナル処理のタイミング 「割り込みかかったら再度select」っていうふうに修正してみたんですが、 今度はPerlのシグナルハンドラがなかなか呼び出されない!! use Redis::Fast; $SIG{TERM}= sub { warn "TERM handler called"; }; my $c =->new(reconnect=>2, every => 100, server => "localhost:6379"); $c->brpop("a", 100); # 100秒経ったら諦めて戻ってくる このコードを実行中にSIGTERMを送ると、送った瞬間に"TERM handler called"と表示されて欲しいのですが、 brpopコマンドが終わるまで実行されない……

Jun 4, 2014 - 1 minute read - Comments - perl unazusan

IRCに癒やしボットを入れてみた

別チームがIRCに癒やしボットを入れてたので、自分のチームのチャンネルにも入れてみた。 Instagramに登録する InstagramのDeveloperサイトに開発者として登録します。 Authentication のページを見ながら、Server-side (Explicit) Flow を参考にアクセストークンを取得します。 Instagram APIを叩く https://api.instagram.com/v1/tags/$TAGNAME/media/recent?access_token=YOUR_ACCESS_TOKENを叩くと TAGNAMEに関連する画像の情報がJSONで帰ってくるので、 Perlからこのエンドポイントを叩きます。 IRCとのやりとりにはUnazuSanを使いました。 !/usr/bin/env perl use 5.014; use warnings; use strict; use utf8; use Encode qw/encode_utf8/; use Furl; use JSON; use UnazuSan; sub neko { state $data = undef; state $time = 0; if( !$data || time - $time > 60 * 60) { $time = time; my $furl = Furl->new; my $res = $furl->get('https://api.instagram.com/v1/tags/%E7%8C%AB/media/recent?access_token=YOUR_ACCESS_TOKEN'); my $hash = JSON::decode_json($res->content); $data = $hash->{data}; } my $media = $data->[rand(scalar @$data)]; return $media->{images}{standard_resolution}{url}; } my $unazu_san; my $NICKNAME = 'iyashi'; $unazu_san = UnazuSan->new( host => '127.

Jun 1, 2014 - 1 minute read - Comments - javascript

キレイになったコトバとハートを元に戻すツール作った

現実世界にご満足の方消えてなくなってほしいの!!! しずかったーを使うと個性あふれるコトバを使ってもキレイにしてくれるので とっても便利ですね! でも、本当は何を言っているのか真意を知りたい・・・。 そんな人のために、キレイになったコトバとハートを元に戻す アンチしずかったー を作りました。 仕組み しずかったーは単純な文字列置換で動いているみたいなので、 対応表を頑張って作りました。 それをMeCab用の辞書に変換し、 Igoを使ってバイナリ辞書に変換、 igo-javascriptでブラ失礼しちゃう上で解析できるようにしました。 既知の問題点 しずかったー前後の文脈関係なく変換しちゃうので、 同音異義語は元に戻らないことがあります。 特にひらがな・カタカナは失敗することが多いです。(「(お昼寝したい)ふわふわ」だとか「ブラ失礼しちゃう」だとか) あと、マシュマロ的な内緒の言葉はさすがのしずかちゃんでも代替表現が思いつかなかったらしく、 全部ハートになってしまいます。 元に戻せと言う方が頑張ればなんとかできそうなので期待しないでく時代が変わればかっこいい。 まとめ またおもしろいものを作ってしまいましたが、 igo-javascriptのバグを発見できたりしたので、いいのです。 自宅警備員でお時間ある方の皆様、天才だと思ったらぜひおしゃべり広場や「いいね!」広場で共有をお願いします。

May 29, 2014 - 2 minute read - Comments - csharp

C#のconditional Attributeのコンパイル結果を見てみる

C#で「ある環境では関数の定義ごと消したい」みたいな要件があって、 そういう用途にconditinal attributeが使えるのかなーと話題のあがったので、実際に確認してみました。 結論から言えばできないのですが、せっかく調べたのでメモとして残しておきます。 conditional attribute 「デバッグ時のみにしか実行して欲しくない関数」みたいなものを定義するための機能です。 using System; using System.IO; using System.Diagnostics; namespace ConditionalAttributeTest { class MainClass { public static void Main (string[] args) { Log("fugu"); } [ConditionalAttribute("DEBUG")] public static void Log(string message) { Console.WriteLine(message); } } } こんなふうに書いておくと DEBUG シンボルが定義されている時にだけLogの呼び出しが行われます。 > mcs -d:DEBUG ConditionalAttributeTest.cs > mono ConditionalAttributeTest fugu > mcs ConditionalAttributeTest.cs > mono ConditionalAttributeTest 逆アセンブルしてみる DEBUG付きでコンパイルした結果を逆アセンブルしてみます。 // ...前略 // method line 2 .method public static hidebysig default void Main (string[] args) cil managed { // Method begins at RVA 0x2058 .

May 27, 2014 - 3 minute read - Comments - csharp

初期化なしのusing文ってOK?

C# の using ステートメント、普通は変数の初期化とか new とかをまとめてやるものだと思ってたんですが、 某プロジェクトでusing文をこんな感じで使っているのを見かけました。 var hoge = new Hoge(); using(hoge) { // using( var hoge = new Hoge() ) { ならよく見る ... } 見慣れない書き方だったので、本当にリソース解放が行われているのか不安・・・。 リソース解放が行われているのか調べてみました。 まずは結論 リソース解放自体は行われているので、ちゃんと書いてあれば問題なし しかしエラーをコンパイル時に見つけられない場合があるので非推奨 逆アセンブルして調べてみた コンパイル結果見ればちゃんとリソース解放されているかわかるよね! ってことでバイナリを逆アセンブルして調べてみました。 サンプルコード 検証に使ったのはこんなコード。 using System; using System.IO; namespace UsingTest { class MainClass { public static void Main (string[] args) { var sr = new StreamReader ("hoge.txt"); Console.WriteLine ("Hoge: {0}", sr.ReadLine ()); } } } 僕はMac使いに転向したので、Monoを使います。 mcsを使ってコンパイル、monodis ってのを使うとILを見れるらしいです。 Windowsだったら .

May 25, 2014 - 1 minute read - Comments - csharp unity messagepack

C# でお手軽にMessagePack解析!

MiniMessagePack.csってのを作った。 C#のプロジェクトにファイルひとつ導入するだけで、お手軽にMessagePackの解析ができます。 なんで作ったの? MiniJSON の置き換えが目的です。 とあるUnityプロジェクトでMB単位のJSONをパースする箇所があってですね・・・ パースにはMiniJSONを使っているのですが、さすがに対象がでかすぎて重たい。 そこでMessagePackへの置き換えを検討してみたわけです。 もちろん C# で動く MessagePack のパーサはすでにあって、 messagepack-cliとかmessagepack-unityとか見つけました。 しかし、Unityのちょっと古いMonoで動かすためにちょっとゴニョゴニョしないといけなかったり、 MiniJSON との互換性を取るためにもゴニョゴニョしないといけなかったり(実際やってみたらキャストが大量に失敗して辛かった・・・)、 今回の用途にはちょっと高機能かなーと思ったので作っちゃいました! つかいかた デコードする byteの配列を渡すとパースして返してくれます。 配列はList<object>で、マップはDictionary<string, object>になります。 using MiniMessagePack; // it means {"compact":true,"schema":0} in JSON var msgpack = new byte[] { 0x82, 0xa7, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0xc3, 0xa6, 0x73, 0x63, 0x68, 0x65, 0x6d, 0x61, 0x00 }; var packer = new MiniMessagePacker (); object unpacked_data = packer.Unpack (msgpack); /* unpacked_data = new Dictionary<string, object> { { "compact", true }, { "schema", 0}, }; */ エンコードする オブジェクトを渡すと MessagePack にエンコードして返してくれます。