ラベル IT の投稿を表示しています。 すべての投稿を表示
ラベル IT の投稿を表示しています。 すべての投稿を表示

2015年1月3日土曜日

地デジ・BS/CSの視聴制限の仕組み

新年明けましておめでとうございます。
昨年2014年は本部ログを全然更新できていませんでした。
更新の時間がまったく無いほど忙しかった・・・と言うほど
忙しかったわけではなく、書く手間と書いた後の満足度のバランスというか
要はモチベーションがあまり上がらなかったというのが更新の少なさの原因だと思います。

#収益とか抜きにしたとしても、アクセス数が伸びないと
#モチベーションが上がらないことにようやく気づいたのである。

そこで今年からは、別のモチベーションを作ることにしました。
自分のための記録、として新たに知ったこと気づいたこと等を
例えささいなことでも記録していきたいと思います。

さっそくですが、正月に福袋で購入したブルレコの導入の際に
疑問に思った掲題の件について、知ったことを記録します。


疑問

視聴契約が必要なBS・CS放送(NHK、WOWOW等)って、
画面にメッセージが出たり、視聴が制限されたりしますよね。
この視聴制限の仕組みは、何となくではありますがあのB-CASカードによるもの
だということは多くの方がご存知かと思います。
私もこれまでそう思っていた一人ですが、少し掘り下げて考えると
疑問に思うことがありました。

最近のブルレコやTVは、インターネット接続することができますが、
接続しなくても利用することはもちろんできます。
その場合、通信の方向は当然、放送局→TV・レコの一方通行になります。
この前提だと、視聴制限を行うためには以下のいずれかを行う必要がある。

  • 視聴契約時に契約者のB-CASカードに特別なデータを書き込む
  • 放送電波に各個人のBーCASカード宛の個別情報をブロードキャストする

私はNHKの視聴契約は一応しています(全然見ていませんが)が、
B-CASカードを専用機器に通した記憶はありません。
(BーCASカードの番号の申告はしたかもしれませんが)

なので、後者の方式で行われているのでしょうが、
果たして日本の全世帯(BーCASカード数)の個別情報を
常日頃ブロードキャストしているとは(データ量的に)思えないので、
B-CASカードの仕組みに対する疑問が発生しました。

答え

ググってみると答えは見つかりました。私の予想は半分あっていましたが、実は
  • 視聴契約時に契約者のB-CASカードに特別なデータを書き込む
  • 放送電波に各個人のBーCASカード宛の個別情報をブロードキャストする
の両方が行われているようです。
放送電波のTSパケットに含まれるEMMというデータが
各個人のBーCASカード宛の個別情報(宛先情報ID6byte含)になっていて、
TVやレコーダの受信機が自分のB-CASカード宛かをチェックし、
自分宛であれば、B-CASカードの記憶領域にEMM内のデータ
(契約情報など)を格納するそうです。
意外にも、TVやレコーダはスタンバイ時にも
EMMの受信やBーCASカードへの書き込みを行っているとか。
このBーCASカードに書き込まれた情報を元にTVやレコーダが視聴制限を行っているそうです。

公共電波はいかにもブロードキャストなイメージを持っていましたが、
各個人宛のデータも含まれているということに意外性(データ量的に)を感じました。

例えば日本国民の数(1.3億=130M)のBーCASカードに対し、1KByteのデータを送るとすると、
130MByteのデータを送る必要があります。
地デジの1チャンネルあたりの帯域は約16Mbps=2MByte/sで、
各チャンネル帯域にうっすらEMMが乗っていると仮定し、その割合を1%と仮定すると、
EMMに使える帯域は20KByte/s、1.3億のEMMを送るためには6500秒、
すなわち約2時間を要します。
あれ?EMMが1KBだとしても最大2時間の遅延、意外と短時間でした。

実際は
EMMが送られるタイミングは不明(常時?契約変更時のみ?)だし、
国民の数よりもB-CASカード数が多くなる可能性はあるし、
EMMのサイズも1KB以下に圧縮されているでしょうし、
EMMに割り当てられている帯域も異なると思うので
2時間というのは参考値ですが、
数時間というオーダーは大きくは外れていないかと思います。


B-CASカードの仕組みや解読・偽造、
B-CASカードを運用している会社の賛否についてはいろいろと情報があるようなので
また別の機会に深堀りしてみたいと思います。

参考にした情報源


もっとライトに書きたかったのですが、
やはり書き出すと長くなってしまいますね。長続きしない予感が・・・

2013年1月1日火曜日

Ubuntu12.04LTSマシンへのnvidia-96適用

正月休みで実家に帰省中なのですが、
実家で使用していた自PC(以下、実家PCと呼ぶ)を修復。
その際の作業内容の備忘録兼情報共有。

【背景】
実家PCは私が高校生の時(なんと10年以上前)に自作したマシンで、
基本的な構成は当時とほとんど変わっていません。
CPUには当時比較的ハイスペックだったPentium4 1.6GHzが載っています。

RAMやHDDは消耗品のため、数回は換装されています。
ただしマザーボード、CPU、グラフィックカード、サウンドカード、NIC、モニターは当時のままです。

さてこの旧型PCですが、実家にいる間は、私のメインPCとなります。要は現役です。
今時、こんな電力効率の悪い低スペックPCなんて買い換えればいいのに
と思われるかもですが、
年間で実家にいる日数が10日くらいなことを考えると、
そのために新たにPCを購入するのはバカらしいではないですか。
破棄するにも手間暇やリサイクル費用がかかりますし。
また、家族共用のPCを使用するのも気持ち悪いし、
故に文句を言いながらも、愛用しつづけています。

OSは当初Windows98、その後WindowsXPへ移行し、
今年2012年はじめまで使用していました。
しかし2012年初等からHDDエラーが原因と思われるOSのハングアップが頻発したことから、
HDD換装と合わせてOSをUbuntu12.04LTS(32bit)に移行しました。

これまでも何度もHDD換装はしてきましたが、OSを変えることはしませんでした。
今回はXPもそろそろサポート対象外になるだろうし、
かと言ってWindows7はスペック不足だろうし、金もなるべく出したくないし、
ということで、ちょうどLTSが出たばかりのUbuntuに乗り換えました。
(自宅のメインPCもUbuntuですがw)

ただしそこで問題が。
実家PCのグラフィックボード、nVidia製GeForce4 MX440向けのドライバが
Ubuntu12.04で使用できないのです。
Ubuntu12.04デフォではnVidia製品向けにnouveauというOSSのドライバが
用意されていて、自動的に作動したのですが、
画面にノイズが入り始め、しまいにはハングアップしてしまいます。
nouveauをアンインストールし、VESA(汎用ビデオドライバ)で我慢することにしました。
ただしVESAだと画面解像度に制限があったり、描画性能が悪かったため、
使用しうるに耐えない状態でした。特に動画サイトの動画再生がまともにできませんでした。

そこで、この年の瀬の実家での余暇に、ビデオドライバの改善を試みたわけです。
だいぶ前置きが長くなりましたが、ここからが本題です。


【本題】
まず試したのがGeForce4 MX440のLinux向け公式ドライバnvidia-96のインストール。
$ sudo apt-get install nvidia-96
ただし、これはUbuntu12.04が当ドライバに対応していない、
正確にはnvidia-96がXorgの最新版の仕様(xorg-video-abi-12)に対応していないため、
パッケージ依存関係エラーでインストール不可。

http://askubuntu.com/questions/112206/how-can-i-get-nvidia-96-installed

そこで上記URL記事内にあるxorg-abi-compat-hackを入手し、
パッケージの依存関係を破壊した上でnvidia-96を強引に入れてみました。
xorg-abi-compat-hackの導入手順は以下。
$ sudo add-apt-repository ppa:diehard67/xorg-abi-compat-hack
$ sudo apt-get update
$ sudo apt-get install xorg-abi-compat-hack
nvidia-96のインストールに成功したので、
$ sudo nvidia-xconfig
を実行してxorg.confを設定した後リブートしたが、
ログイン画面まで到達できませんでした。
正確には、
背景の色とマウスカーソルが一瞬画面に表示されたかと思うと、
別の解像度に変更され、再度同じ画面が一瞬表示される。
これが永遠と繰り替えされてしまうという現象でした。
/var/log/Xorg.0.logを見ると、Segmentation faultが発生していました。

どうやらxorg-abi-compat-hackでは対処できないらしいです。
(ただしこの時、xorg.confの設定が腐っていた可能性があるので、
xorg-abi-compat-hackがダメだったのか100%で断言できませんが)

そこで、
http://askubuntu.com/questions/112206/how-can-i-get-nvidia-96-installed

で提案されている、Xorgのダウングレードに挑戦しました。
手順は上記URLで示されているURL
https://bugs.launchpad.net/ubuntu/+source/nvidia-graphics-drivers-173/+bug/922268
のpost7に書かれているのですが、若干分かり辛いので、

http://ubuntuforums.org/showthread.php?t=1986601
の#4を参考にしました。
ただし、設定例に誤りがあり私もハマったので、
訂正後の手順を以下に載せます。

(1)Ubuntu11.10(oneiric)のリポジトリを追加する。
$ sudo vi /etc/apt/sources.list.d/oneiric.list
deb http://archive.ubuntu.com/ubuntu oneiric main
deb-src http://archive.ubuntu.com/ubuntu oneiric main
(2)旧バージョン固定用のピン設定ファイルを作成する。
$ sudo vi /etc/apt/preferences.d/xorg-xerver-pin-1050
Package: xorg
Pin: release a=oneiric
Pin-Priority: 1050
Package: xserver-xorg*
Pin: release a=oneiric
Pin-Priority: 1050
(3)updateする。
$ sudo apt-get update
$ sudo apt-get upgrade
xorg、xserver-xorg-*のダウングレードをしてもよいか確認されるので、承認する。

(4)nvidia-96をインストールする。
$ sudo apt-get install nvidia-96
(5)xorg.confを初期化する。
$ sudo mv /etc/X11/xorg.conf /etc/X11/xorg.conf.bk
$ sudo nvidia-xconfig
(6)再起動

私はこの手順で無事、nvidiaドライバが使用できるようになりました。
(なぜかシステム設定の「追加のドライバー」では「このドライバーは有効ですが、現在使用していません。」と表示されますが、
OpenGLなどでハードウェアアクセラレーションが効いていることは確認できました)

ただ、動画サイトの動画再生は結局厳しかった・・・
そういえばWindowsXP入れてたときもカクカクしてたっけかな。残念。

あれ、これ書いているうちに年越してしまった。あけおめ!

2012年12月31日月曜日

AjaxベースのWebアプリにおけるCSRF対策

私の苦手なセキュリティまわりの話。
CSRFについて勉強、備忘録をここに残します。

言うまでもありませんが、CSRFは
攻撃者が作成した攻撃用サイトを利用者に利用させ、
利用者の意図しないリクエストを送信させる手法をさします。

CSRF対策として、form送信ベースのWebアプリでは、
ワンタイムトークンを利用するのがメジャーなようです。
ワンタイムトークンは危険なCookieには格納せず、
ページ内のhidden等に格納するのが安全とされます。
また、ブラウザのキャッシュ機構によるトークン再利用を避けるために、
リクエストにはGETを使わずPOSTにするなど。

ワンタイムトークンの欠点としては、
(1)タブ等による画面分裂に対応しづらい、
(2)ブラウザの戻る進むによってトークンが再利用されてしまう、
(3)Ajaxなど平行して複数リクエストが送信される場合の対応が難しい、
などがあります。

(1)(3)は複数のトークンをページに与えることで対応できなくはないのですが、
画面分裂、同時リクエスト数をクライアント側で制御する必要があり、実装が複雑になりそう。

そこで調べたところ、
(3)のAjaxで送信する場合に限れば、
ワンタイムトークン以外の簡単な方法でCSRF対策を補えそうです。

HTTPヘッダのX-requested-withに値が設定されているか否かを
サーバ側でチェックすることにより、
CSRF対策ができます。(ただしクロスドメイン間通信を許容していない限り)

X-requested-withの値によって、
リクエストがAjaxのものなのか、Ajax以外のものかを判別することができるからです。
jQueryなどでAjax関数を実行すると、
X-requested-withに"XMLHttpRequest"を自動的につけるらしい。

同一生成元ポリシーにより
攻撃サイトからのAjax(XMLHttpRequest)リクエストが原則不可能なため、
Ajaxによるリクエストであるということが分かれば正規のリクエストと判別できます。

CSRFで使われるであろう、ブラウザのURL欄直接入力や、
javascriptのlocation.hrefやsubmit()からのリクエストには
X-requested-withが無い(かは確証がないが、少なくとも"XMLHttpRequest"以外である)
のと、ブラウザ側でX-requested-withを設定することができないことから、
攻撃サイトがAjaxリクエストを偽装することも不可。
上記理由によりJSONハイジャックも拒絶することができます。

ただし、XMLHttpRequestのLevel2ではクロスドメイン間でAjaxリクエストが可能なため、
当対策だけでは不十分になるので注意。

また、CSRFは防げてもセッションハイジャックなどの他のセキュリティ問題への
解決にはならないので、可能な限りトークンなどの他対策と組み合わせたほうがよいと思います。

SEがこんなこと言ってはいけないのですが、
セキュリティって考えるの面倒ですね・・・

2012年12月22日土曜日

Selenium@Androidの罠

この記事では、私が遭遇したSeleniumの問題およびその解決策を共有することを目的としています。
Android向けにSeleniumを利用している方の参考になれれば幸です。


Selenium WebDriverはWebアプリケーションの自動テストツールとして有名です。
SeleniumとWebDriverは元々別ツールだったのですが、1つのツールとして統合され、どちらの機能も利用できるようになり便利になりました。

統合前のSeleniumはテストドライバのコアがHTML/javascriptで実装されていた。
テスト対象アプリと同じブラウザ上で実行させ、テスト対象アプリをjavascriptにより操作、情報取得を行っていた。
ドライバはHTML/jsベースなため、様々なブラウザで汎用的に利用できるとされている。





一方、WebDriverはドライバがブラウザのプラグイン等を利用して実装されている。
ブラウザのプラグイン仕様はブラウザの種類毎に異なるため、
ドライバをブラウザ毎に開発する必要があるが、
HTML/jsベースのSelenium1よりも豊富かつ高性能なコマンドを利用することができ、
テスト性に優れているとされる。

ドライバはInternetExploreDriver、FirefoxDriver、ChromeDriverはもちろんのこと、
AndroidDriverやIPhoneDriverまで用意されている。




















Selenium1とWebDriverは統合され、
Selenium WebDriver(Selenium2)となった。
統合と言っても、製品を単に抱き合わせただけではない。
WebDriverでSelenium1のエミュレーションが利用できるようになり、
WebDriverを利用しながらSelenium1の機能を利用することができるのだ。
この場合SeleniumRCの起動は不要となる。

Selenium2では
WebDriverBackedSelenium

という名のエミュレート化されたSeleniumインスタンスが利用できる。

ここで取得したSeleniumインスタンスを用いて、従来のSelenium1同等の機能が利用できる。
しくみは至って単純である。
エミュレートに対応しているドライバは、「任意のjavascriptをブラウザ上で実行する」という指示をブラウザ上のドライバ(Plugin)に行うことができる。
Selenium1時代にドライバとして利用されていたjavascriptをPluginに実行指示することで、エミュレーションを実現している。























以上が私が付け焼き刃で覚えたSelenium2の知識です。(間違いが含まれているかも・・・)
さて、前置きがだいぶ長くなりましたが、ここからが本題です。
仕事でAndroid、iPhone向けにSelenium2を利用して自動テストを実施することになったのですが、
Androidのテスト実行時に問題が発生し、数日間頭を悩ませられました。
結果的には解決したのですが、情報が少なく解決に苦労した。
同じ事象に悩んでいるかた向けに、その時のノウハウを共有したいと思います。
(iPhoneはまだ未実施なので対象外)
対象バージョンは
Selenium2.25
AndroidDriver2.21
です。

Selenium2ではAndroidDriverというドライバが用意されており、Android標準ブラウザ上で自動テストを走行させることができます。

(余談)
ちなみにこのAndroidDriver、Androidアプリ(apk)として用意されています。アプリ内のWebViewにテスト対象アプリの画面を表示するようになっています。
標準ブラウザにプラグインを組込む術が無かったのでこのような実装になっていると思われますが、
WebViewと標準ブラウザは動きが若干異なるので、テストとして完全ではないと思います。。。


さて問題となっている罠です。
まず試しに、WebDriver流の書き方のテストスクリプトで走行させてみると、正常に動きました。


正常に走行する例)

それを見て安心し、Selenium1時代のSelenium流の書き方のテストスクリプトを再利用し、
先ほど紹介したSeleniumエミュレーションで走行させたところ、assertionエラーやnullpoが発生してしまいました。


エラーが発生する例)


Selenium流の書き方なんて必要ないし、たいした問題じゃないでしょ、という意見もあるかもですが、
回帰テストとして古いテストスクリプトを流用する必要がある場合に、大変な問題になります。

エラーの原因は当初謎でしたが、同じスクリプトをドライバをFirefoxDriverやChromeDriverに変えて走行させると正しく動作するので、Android由来の問題なのは確実だと思いました。
ソースの静的解析、ステップ実行、Android側のログ監視を続けた結果、ドライバ@Android側でjavascriptの文法エラーが発生していることを確認ました。
(私はAndroidエミュレータ4.0でのみ確認しています。)

Unexpected token ILLEGAL ...

タイミングからして、ドライバ@サーバ側から送られたSelenium1のjavascriptをWebView上で実行しようとしたタイミングで発生しているようです。
他ブラウザでは正常に動作することから、そのjavascript自体に文法ミスがあるとは考え辛い。
疑うべきはWebViewのjavascript実行機能のバグ、もしくは制限。

Selenium1のjavascriptはHTML要素を検索したり、ボタン押下を指示したりするような処理が書かれたコードであるが、比較的ボリュームがある(30kb前後)。
ちなみにSelenium2のjarの以下に当jsファイルが格納されている。
org/openqa/selenium/internal/seleniumemulation/

で、原因の仮説を二つ立てました。
(1) WebVewで実行できるjavascriptのサイズ上限がある。
(2) WebVewで実行できるjavascriptの行数上限がある。

(2)はAndroidで出力されていた「Unexpected token ILLEGAL ...」のエラー箇所がいつも13行目を示していたため、
行数が関係しているのでは、という思いつきから立てました。

(1)は以下の情報より正しくないことが分かったので、あとは(2)を確かめるのみ。
http://stackoverflow.com/questions/5051670/is-there-any-limitation-on-urls-length-in-androids-webview-loadurl-method

そこで
org/openqa/selenium/internal/seleniumemulation
配下の全jsの全改行文字を取っ払って、jarを作り直し、エラーとなっていたテストスクリプトを走行させたところ、
見事エラーが解消されました!
どうやら仮説(2)が正しかったようです。
Selenium2の問題というよりかはAndroid自体の問題のようですね。


最後に、当問題についてまとめます。

・Selenium2.25
・AndroidDriver2.21
で、WebDriverBackedSelenium(Selenium1のエミュレーション)を利用したテストスクリプトをAndroid上で走行させると、エラーが発生しテストが正しく行われない可能性がある。

原因は、Android側にエラーログ「Unexpected token ILLEGAL ...」が出力されていることから、
AndroidのWebViewが多数の改行を含むjavascriptを正常に実行できないことにあると推測された。

Selenium2のjar内にある、
org/openqa/selenium/internal/seleniumemulation/
配下のjsファイルの改行をすべて除去したjarで差し替えることにより、
当問題を回避することができた。