kazuk は null に触れてしまった

C# / .NET 系技術ネタ縛りでお送りしております

月別アーカイブ: 6月 2013

Doc of code 販売開始のお知らせ


 

滅多にやらない宣伝記事が増えまして申し訳ありませぬ。

というわけで Doc<Code> については最後の宣伝記事になるでしょう。

販売サイトがオープンしましたので、「買ってくれ!」以上のこの記事には意味はございません。

http://kazuk.azurewebsites.net/

 

んで、今月中はキャンペーンを設定します。

日本時間での今月中にライセンスを購入いただくと、ライセンスの付与期間が倍でライセンスキーが発行されます。

1年ライセンスを買っていただくと 2年後に無効になるライセンスキーが送られるという事になります。

販売初期限定という事で、どうかよろしくお願いいたします。

 

会社等での購入をお考えの方は kazuk.dll@kazuk.jp にご連絡ください。見積書、納品書による対応のほか、銀行振り込みでの入金その他は現状メールでの対応とさせて頂きます。

普通の人は全く知らないでもいい MSIL の基礎知識


 

.NET基礎勉強会 http://connpass.com/event/2441/ で ILについてお話させていただく事になったんですが、まぁ 30分枠ぐらいだと、だいぶ話せる事が限られるんで、あらかじめ Blog に記事乗せといた方が良いかなー的に書いておきます。

 

「手元にございますMSIL命令表をご覧ください」 「えっ、どこよ?」

.NET Framework がインストールされている環境であれば、MSIL命令表は入っています。mscorlibアセンブリ、 System.Refrection.Emit 名前空間配下の OpCodes クラスのOpCode型フィールドをリフレクションで舐めてください。

命令表としての活用の仕方にもよりますが、プレフィックスバイト等も命令表には入っています (Prefix1 etc)、自分の用途でプレフィックスとか要らない場合には、そういう物をフィルタしてあげましょう。 OpCode の OpCodeType を見ればそれがプレフィックスなのか判別する事ができます。

MSIL バイト列の見かた

さて、MSILバイト列の見かたです。バイト列そのものは実行時にリフレクションで取るならば、 MethodInfo から MethodBody を引き、MethodBody から GetILAsByteArray メソッドで取得する事ができます。

このバイト列に各 IL 命令がどのように入っているかです。

オペコード

まず、IL オペコードには 1バイトと 2バイトがあります。

命令のサイズは OpCodes を舐めているならば、OpCode の Size プロパティから取得できます。 これが 1の物は 1バイト命令で、2の物は2バイト命令です。

オペコードの値そのものは OpCode 構造体の Value プロパティに入っています。

2バイトのオペコードはMSILバイト列にビッグエンディアンのバイト順で入ります。要するに 0xDEAD の Value を持つ命令のオペコードが 0xDE 0xAD の順でILバイト列に入ります。(1バイトのプレフィックス命令と、1バイト命令がつながって入っているともいえます。) ※ MSILバイト列で唯一のビッグエンディアンです、他はすべてリトルエンディアンになっています。

1バイトオペコード命令

OpCode オペランド(無い場合もある)

2バイトオペコード命令

Prefix
OpCode
OpCode
(LowByte)
オペランド(無い場合もある)

オペランド

オペランドはオペコードによりますが、 OpCode 構造体の OperandType で取得できます。

OperandType の switch だけが特殊ですが、それ以外は単純にオペランドのサイズは固定されています。そのバイト数分をリトルエンディアンとして読みだせばオペランド値として使える値を普通に取得する事ができます。

OperandType が switch の場合、switch のオペランドにはラベル数が入ります、ラベル数分 InlineBrTarget がバイト列に入ります。

ブランチオフセットの起点

ブランチオフセットの起点はブランチ命令の次の命令です。

たとえば IL Offset n に ShortInlineBrTarget で 3 を指定する1バイトのブランチ命令があった場合、 n +1 (opcode size ) +1 (operand size) がブランチオフセットの起点となり、n +1 (opcode size ) +1 (operand size) + 3(operand value) がブランチ先のIL Offset になります。

ILの動作フローを変える物はブランチ命令と、ret、throwとそれに関連する例外処理ぐらいしかありません。ブランチ命令のオフセットを解釈できるようになった今あなたはILのコントロールフロー解析ができるようになったという事です。

まとめ

7/20 日に話す事はここから後の話ですって事で、MSILの基礎の基礎でした。

7/20 日にはMSILの評価スタックと例外フレームについて話したいと思っているのですが、時間枠的に評価スタックの話で一杯かもしれません。

ASP.NET メンバーシップ、ロールを使って初期スーパーユーザーが無くて困る


タイトルのような事って起こりませんか?

管理者ロールみたいなの作ったとして、その管理者ロールに最初のユーザーをどうやって入れるねんとか。

IISマネージャがつながるとか、ASP.NETの構成ツールがつながれば、そっちからいかようにもできるんですが、そうもいかない環境ってありますよね。

簡単に言えば ASP.NET を Azure Web Sites で動かしてる時とか。

最初のユーザーを管理者ロールに入れるとかやるとして、ソレってできた瞬間から表に出てる Azure Web Sites でやって安全なん?とかとか。

アプリのつながるDBにユーザーレコード直接作ればいいっちゃ良いんだけど、IP固定してる回線でない場合には、現在IP調べてSQL Azure に一時的にそのIPを許可入れて、レコード作って、ここでIP許可外し忘れると同一プロバイダの誰かが偶然にもつながる穴が残るよねと。

まぁ、諸々面倒なんですわ、ロールベースで管理者ロール作って、しっかり管理系作ったとして最初のスーパーユーザーが居ないって事が。

そうですよね?

そんなわけで作った

要するにDBベースのASP.NET標準のメンバーシップやロールだけだと、初期ユーザーの作成とかがややこしいので、展開されるファイルベースの認証プロバイダがあればサイトが展開された時にはそのファイルに記述されたユーザーは居る事になると。

これをDBベースの認証プロバイダとカスケードしてスーパーユーザー以外はそっちにユーザー登録したり、認証するようにすればいいよねと。

PM> Install-Package ConfigBasedSecurityProviders

やってる事は単純に ExtendedMembershipProvider と RoleProvider の実装ですが、基本的にすべての更新系は基本となるプロバイダに転送し、同様に知らん事の参照系も基本となるプロバイダに流します。

そのうえでXMLで指定された多少の知っている事だけを認証処理したり認定します。

使い方

Nuget からパッケージをインストールすると、bin に認証プロバイダ本体が入ります。そして必要な web.config に対する修正が適用されます。App_Data 配下にサンプルとしてのxml が二つ入ります。あとルートに readme.html が入ります。

web.config の改行とかフォーマッティングが崩れるのは Nuget の仕業っぽいので気になるならオートフォーマットでも適用してください。

App_Data のXMLを修正して、ユーザーとパスワードを設定し、ロールのメンバーを設定します。

設定した XML は admin_users.xml / admin_roles.xml という名前に直せば、デフォルトで入る web.config の修正にあった形になります。逆に web.config 側でのファイルの位置指定を直せば、どこにでもファイルの置場や名前を設定できます。

これでファイルベースの認証を通した上で、必要な構成作業をやったうえで、要らなくなったら NuGet パッケージをアンインストールで取り外してしまってもいいし web.config の要らない所をコメントアウトして無効にしてしまっても良いでしょう。再デプロイでつぶしの反映を忘れずに。

まとめ

ASP.NET アプリケーションをクラウドに入れるのにあんまり安全じゃない事したくないよね。

認証回りの所に派手に作りこみしてバグ残すとセキュリティバグはすごく痛い思いするから初期構成の為に変な事もできないし、つけ外しがちゃんとできる格好でやらないと怖くてアレ。

そういったニーズに答えるパッケージのつもりでございます。

要するに、薄いゴムのアレですよ。うん。

注意事項

状態持たないので、ユーザーのパスワードミスによるロックアウトとかできません。なので強度の低いパスワードでユーザー作っておきっぱなしにすると、プルートフォースでやられる危険があります。

うん百文字のランダムとかプルートフォースされても「何千年頑張るの?」って言えるようにしておくか、初期構成作業を終えたら外すのお勧めです。