u-ryo's blog

various information for coding...

Digest Authentication and File Realm on Glassfish

| Comments

客先から「192.168.1.134にdiget認証のrelmsを作成してください」と 相変わらずわけわかんない指令を受けたので、 「何かに使う『digest』認証を任意の『Realm』で設定」 と解釈して取り組みました。 一番簡単なFileRealmでいいっしょ、 これは4848のGUIからRealms辿ってManage Usersボタンからuser足せばいいし、 Digest Authは<auth-method>DIGEST</auth-method>で瞬殺、 とか思ってたら、ハマりました。 index.htmlweb.xmlのみの最小構成でproof application作ったのですが、 どうしても認証できないのです。 server.log見ると、

1
SEC1105: A PasswordCredential was required but not provided.

と言われています。えー!? 何で? 試しにBASIC認証にしてみると、(紆余曲折ありましたが要するに)通ります。 だから、keyfileの書き方が悪いわけでは無いんですね。 勿論色々ググりました。が、なかなか出て来ません類似例。 辛うじて同じような症状があっても、Answerがついてません。 半日悩みました。 GlassfishのRealmって、 JAAS Contextを指定する必要があって、これは.../domains/domain/config/login.confで規定されているんですね。 これを見ると、 fileについてはfileRealmは一つなのに、 jdbcについてはjdbcRealmjdbcDigestRealmってあるぢゃないですか。 をぉ、と思って、source treeを探してみると、 com.sun.enterprise.security.auth.login.DigestLoginModule というのもあるんですね。 これどうやって使うんでしょうね。 使い方とかも例も、 JavaDocに書いてないしググっても出て来ませんでした。 試しにdigestRealmなんてlogin.confに他のを真似して、 上のDigestLoginModuleを指定して作って使ってみたのですが、 fileから読み込むようにはなっていないようで、

1
WEB9102: Web Login Failed: com.sun.enterprise.security.auth.login.common.LoginException: Login failed: unable to instantiate LoginModule: null

と言われて失敗してました。 ...って、これabstract classだから当たり前じゃないですか恥ずかしい。 DigestLoginModuleをextendsしてるのはJDBCDigestLoginModuleだけだから、 file realmで使うならJDBCDigestLoginModuleみたいなのを自前で作らないとならないんじゃないでしょうかね。 でもそうならどっかにそう書いといてよねー。

結局、大人しくjdbcDigestRealmを使うように変更することで面倒を回避しました。 まぁ、それだけ世にDigest Authenticationのdemandがない、 という証左なのかなと思いました。

minimum web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="UTF-8" ?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
                             http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Digest Authentication Test</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
      <role-name>someRole</role-name>
    </auth-constraint>
  </security-constraint>
  <login-config>
    <auth-method>DIGEST</auth-method>
    <realm-name>someCreatedRealmUsingjdbcDigestRealmOnJAASContext</realm-name>
  </login-config>
  <security-role>
    <role-name>someRole</role-name>
  </security-role>
</web-app>

WEB-INF/glassfish-web.xml

glassfishの場合は、以下のようにrole-namegroup-nameを結びつけるglassfish-web.xmlもないとダメでした。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-web-app PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Servlet 3.0//EN" 
"http://glassfish.org/dtds/glassfish-web-app_3_0-1.dtd">
<glassfish-web-app error-url="">
  <security-role-mapping>
    <role-name>user</role-name>
    <group-name>user</group-name>
  </security-role-mapping>
  <class-loader delegate="true"/>
  <jsp-config>
    <property name="keepgenerated" value="true">
      <description>.</description>
    </property>
  </jsp-config>
</glassfish-web-app>

Make SqlCipher Faster

| Comments

他に言及しているsourceが全く無かったのでまさかと思っていたのですが、keyの形式を変えて爆速には本当でした。 試しに、Allcaridaからc.binだけ持ってきてAndroid sample applicationを作って計測した所、従来のkey(4文字)だと約0.4秒、上記ページ例の64字だと0.02秒と顕著な差がありました。

従いまして、「SqlCipherのkeyを64文字の16進数にすれば速くなる」が結論です。

1
2
3
4
5
6
7
従来
09-27 16:25:59.010 30173-30173/sqlcipher.test.jmtech.co.jp.sqlciphertest D/Open: /data/user/0/sqlcipher.test.jmtech.co.jp.sqlciphertest/databases/c.bin
09-27 16:25:59.400 30173-30173/sqlcipher.test.jmtech.co.jp.sqlciphertest D/After open: /data/user/0/sqlcipher.test.jmtech.co.jp.sqlciphertest/databases/c.bin

64字key
09-27 16:24:26.060 28517-28517/sqlcipher.test.jmtech.co.jp.sqlciphertest D/Open: /data/user/0/sqlcipher.test.jmtech.co.jp.sqlciphertest/databases/c2.bin
09-27 16:24:26.080 28517-28517/sqlcipher.test.jmtech.co.jp.sqlciphertest D/After open: /data/user/0/sqlcipher.test.jmtech.co.jp.sqlciphertest/databases/c2.bin

そこで、実際にAllcaridaでc.bin,r.binだけ64字key版を作って「履歴一覧」画面表示を比較してみると、従来約3.5秒のところ約0.2秒で開けることを確認しました。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
従来 3.46秒(約0.6秒×5+α)
09-27 17:53:03.670 9054-9054/jp.ideacross.allcardia.main D/After: <<HistoryMainActivity#activityStart:49>> 履歴一覧
09-27 17:53:03.680 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> c.bin Open
09-27 17:53:04.360 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open
09-27 17:53:04.380 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> r.bin Open
09-27 17:53:05.010 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open
09-27 17:53:05.050 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> c.bin Open
09-27 17:53:05.710 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open
09-27 17:53:05.720 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> r.bin Open
09-27 17:53:06.370 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open
09-27 17:53:06.390 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> r.bin Open
09-27 17:53:07.030 9054-10071/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open

64字key 0.21秒(0.0+0.01+0.01+0.02+0.03+α)
09-27 17:50:57.350 4493-4493/jp.ideacross.allcardia.main D/After: <<HistoryMainActivity#activityStart:49>> 履歴一覧
09-27 17:50:57.360 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> c2.bin Open
09-27 17:50:57.360 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open
09-27 17:50:57.400 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> r2.bin Open
09-27 17:50:57.410 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open
09-27 17:50:57.460 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> c2.bin Open
09-27 17:50:57.470 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open
09-27 17:50:57.480 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> r2.bin Open
09-27 17:50:57.500 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open
09-27 17:50:57.530 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:964>> r2.bin Open
09-27 17:50:57.560 4493-5754/jp.ideacross.allcardia.main D/After: <<DatabaseHelper#open:970>> After Database Open

More concretely,

SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(databaseFile, "x\'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99\'", null);

in Java.

To get a rekeyed file,

1
2
3
4
5
6
7
8
9
10
11
$ sudo apt install sqlcipher
$ sqlcipher /tmp/c.bin
SQLCipher version 3.15.2 2016-11-28 19:13:37
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> PRAGMA key = '7824';
sqlite> ATTACH DATABASE 'c2.bin' AS c KEY "x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
sqlite> SELECT sqlcipher_export('c');

sqlite> DETACH DATABASE c;
sqlite>

You'll get c2.bin with the new 64bit key.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ sqlcipher r.bin
SQLCipher version 3.8.6 2014-08-15 11:46:33
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> PRAGMA key = "7824";
sqlite> ATTACH DATABASE 'r2.bin' AS r KEY "x'2DD29CA851E7B56E4697B0E1F08507293D761A05CE4D1B628663F411A8086D99'";
sqlite> SELECT sqlcipher_export('r');

sqlite> DETACH DATABASE r;sqlite> PRAGMA user_version;
0
sqlite> PRAGMA user_version = 6;
sqlite> PRAGMA user_version;
6
sqlite>

You'll get r2.bin with the new 64bit key and version 6.

PRAGMA user_version is needed because in SQLiteOpenHelper class judges whether it calls onCreate(table creation) by db.getVersion(). [Android]データベースをアップグレードする時

そもそも画面遷移に4秒も掛かるようなAndroidアプリをリリースするなんていうのもunbelievableですが、そういう人達なので...

まぁ、暗号化するにせよ自分ならRealm使うので、こんな知識不要ですけど、SqlCipher使うなら最初から64字16進code使うべきなんですね。

Test Failed on AndroidStudio

| Comments

Android Studio(2.3.1)で久し振りにtestを動かしてみると、

1
Caused by: java.lang.ClassNotFoundException: android.view.View$OnClickListener

と言われて動かなくなりました。 instrumentation testではなくフツーのtestですjunit4とmockitoの。 java.lang.NoClassDefFoundError:android and junit testを見付けて、えーとか思いつつもやってみたら、確かに直りました。

1
$ rm -rf .gradle

追記

projectをcleanした後、いくらbuildしても「databinding classが見つからない」と言われて困った時にも効きました。

BotUI - ChatBot Only by JavaScript

| Comments

paiza開発日誌で紹介されていたBotUI、なるほど予め型にはまった会話ならこれだけでお手軽にJavaScriptだけで(.then(function(){...})で繋ぐだけで)出来ちゃうんですね。注文を取るとか、特定のAPI叩く(Wizardを会話でやる)とか、サポートセンターで特定の電話番号につなぐとか。AIは使ってないので、user側の曖昧な自然言語を受け取って処理する、というものではないですけど、そういうのに繋げればいい? いや、IBMのWatsonとかみると、そういう会話のplatformも含めて提供しているので、そうなるとBotUIの出番は無い筈。 Git Repositoriesの総数を答えるsampleは、公式のsamplesより面白かった(興味深かった)です。

S Rank of CodeIQ

| Comments

もう昨日のことですが、Paizaに続いてようやっとCodeIQでもSランク取りました

まぁ、u-ryoさんなら当然だよね、とか言われておしまいでしょうけど。

Paizaにあった似た問題(←これで見ると失敗もありますが、これは最初に提出したcodeについてで、後でちゃんと全部通るようにしてます)からcode引っ張ってきて、でも勿論そのままでは使えなくて。土曜未明の一晩で終えるつもりが、間にバイトやmachine troubleを挟んで日曜の午後までかかっちゃいました。ふと探してみると、まんまのcodeがあるのにはびっくり。流石にそのままっていうのは癪なので、「直前の方向を使う」というideaと検算にだけありがたく使わせてもらいました。 探索順の違いによるエラーをなかなか潰せなくて。そっか全探索なのね、そのためには... BFSではなくDFSか、と辿って、あーそっか、その違いはstackかqueueかだけか、に最後の最後気付いてgoalでした。何か色々忘れてて、こういうのやり続けてないと錆び付いてたなーというのを思い知らされました。この手のalgorithm系は集中してやらないと!

コメント書きすぎでしょうか。でもまんまの置いてあるよりは遥かにマシかと。