SVX日記

2004|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|
2021|01|02|03|04|05|06|07|08|09|10|11|12|
2022|01|02|03|04|05|06|07|08|09|10|11|12|
2023|01|02|03|04|05|06|07|08|09|10|11|12|
2024|01|02|03|04|05|06|07|08|09|10|11|

2023-09-01(Fri) Maveでデジタル署名付きメールを検証する

  Maveでデジタル署名付きメールを送信できるようになったら、当然、デジタル署名付きメールを受信できるようにもなるべきで、つまりそれは、メールの署名を検証する機能の追加である。

  つうわけで追加してみた。これも、メール本文を丸ごとPKCS7クラスに食わせるだけでできてしまった。後で気づいて、送信者のメールアドレスと証明書内のメールアドレスが一致していることの確認も追加したが。

+   #--------------------------------------------- MaveMail ----
+   #
+   #   メールの署名を検証する
+   #
+   def verify_sign
+       sender = (from =~ /(.*)<(.+)>/ ? $2 : from).strip
+       if(@header['Content-type'] =~ /^multipart\/signed/)
+           begin
+               pkcs7 = OpenSSL::PKCS7.read_smime(File.open(path).read)
+               addrs = []; pkcs7.certificates.each {|cert|
+                   cert.subject.to_a.each {|name|
+                       name[0] == 'emailAddress' and addrs << name[1]
+                   }
+               }
+               if(sender != addrs[0])
+                   yield([_('Digital Signature is NOT Valid. reason=[%s]'), 'Sender does not match Signer.'])
+                   folder.invalid_sign(sq)
+               elsif(pkcs7.verify(nil, @configs[:CERTS_STORE]))
+                   yield([_('Message is Signed.')])
+                   folder.valid_sign(sq)
+               else
+                   yield([_('Digital Signature is NOT Valid. reason=[%s]'), pkcs7.error_string])
+                   folder.invalid_sign(sq)
+               end
+           rescue
+               yield([_('Digital Signature Verify Error. reason=[%s]'), $!.to_s])
+               folder.invalid_sign(sq)
+           end
+       else
+           yield([_('Mail has no signature.')])
+       end
+   end

  画像の説明

  署名を検証はpop時に行うようにし、結果は「@(添付あり)」の表示位置に押し込んだ。「C」なら署名が有効「?」なら無効だ。署名自体が添付ファイルではあるものの、添付ファイル付きの署名付きメールとの識別ができなくなるが、それはまぁよしとする。

  そんなことをやっていると、送信側にバグを見つけた。署名を行う処理に、認証局証明書や中間証明書が必要な場合にそれを含める処理が抜けていた。以下に修正。

        pkcs12 = @account.pkcs12
-       pkcs7 = OpenSSL::PKCS7.sign(pkcs12.certificate, pkcs12.key, data, [], OpenSSL::PKCS7::DETACHED)
+       pkcs7 = OpenSSL::PKCS7.sign(pkcs12.certificate, pkcs12.key, data, pkcs12.ca_certs, OpenSSL::PKCS7::DETACHED)
        smime = OpenSSL::PKCS7.write_smime(pkcs7)               # 署名付きメール(crlf, lf が混じっている)

  そんなこんなで、電子署名(S/MIME)機能の実装はひと通り完了してしまったわけだが、実装しながら別のアイデアを思いついてしまった。テキストベースのメーラなのに、画像の表示ができたら面白いなと。

  解像度がないのでややモザイク状にはなるものの、端末画面に画像を表示する「catimg」というプログラムは既に存在していて、だいぶ前に自ら使いやすいラッパーを作って便利に使っていた。つうか、そのエントリで既にMaveに組み込むアイデアについて記述してあるじゃねぇか。

  そこでcatimgの出力を流用しようとしたがうまくいかない。つうか、そんなことやるよりcatimgのコード読んでスクラッチからRubyで書くべきじゃないか?と、思い直してコードを読む。ほほーん。そういう原理だったのか。

  端末には「文字色」と「背景色」を24bitカラーで指定できるエスケープシーケンスがある。それを使えば「文字単位」でドット表示ができる。しかし、それだと縦長のドットになってしまう。そこで「▀」という「上半分塗りつぶし」文字を使えば「文字色」と「背景色」とで上下を塗り分けることができ、ほぼ正方形のドット表示が可能になる。単純な原理だが、発想がすごいな。実にmz-700っぽく、不可能はないっぽい。

  つうわけで、試験的にコードを書いてみた。

require 'rmagick'
 
png_image = Magick::Image.read('r9.png')
w = png_image[0].columns
h = png_image[0].rows
 
(h >> 1).times {|y|
    w.times {|x|
        cs = []
        c = png_image[0].pixel_color(x, y * 2)
        cs << (c.red >> 8); cs << (c.green >> 8); cs << (c.blue >> 8)
        c = png_image[0].pixel_color(x, y * 2 + 1)
        cs << (c.red >> 8); cs << (c.green >> 8); cs << (c.blue >> 8)
        print("\e[38;2;%d;%d;%dm\e[48;2;%d;%d;%dm\u2580\e[m" % cs)
    }
    puts
}

  画像の説明

  おぉお……我ながら感動的だ。いったんファイルに出力し、catで表示しているのがキモだ。「画面はハメコミ合成ではありません」ぜw。


2023-09-04(Mon) スイッチ、ングハブ、交換

  先月の23日、ネットにつながらなくなった。落雷でスイッチングハブが壊れたようだ。こんなことあるんだな。

  無線LANルータのオマケの4ポートをスイッチの代わりに、最低限のマシンだけ有線接続する応急対処の後、100Mで5ポートの手持ちのスイッチで増設、なんてことをやっているうちに、ポチっておいたハブが到着したので交換。NETGEARは最安ではないが、特段の何の問題も起こしてこなかった実績があるんだから、そりゃ続投だ。

  画像の説明

  思い返せば、自宅の新築に伴い24ポートを導入したが、ファンが異音を発するようになってきたので、ファンレスの16ポートに交換したところ、今回の破損だ。3年はちょっと短いがしゃーないな。


2023-09-05(Tue) Rubyで端末画面に画像を表示する

  一応、CUIコンソール画面に画像を出力できたんだが、Maveに実装することを考えれば、縮小(ついでに拡大)機能と、右側のトリミング機能が必要だ。ついでに透過処理もできるとカッコいい。

  さて、透過処理はどうすれば……と考え込んだところで「▀」という「上半分塗りつぶし」文字と「▄」という「下半分塗りつぶし」文字を使い分ける必要があることに気づく。そういや、参考に読んだcatimgのコードで両方を使い分けていたのはそういうことだっとのか。

  しかし、どうも美しく実装できない。上から順に処理しつつ、上下2ドットを同時に処理する、というのが厄介。

  ちなみに、今回のケースもやや当てはまるのだが、こういう処理が必要な状況って時々ある。

# ./grouping.rb 
["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R"]
1: A,B,C,D,E
2: F,G,H,I,J
3: K,L,M,N,O
4: P,Q,R

  で、以下のようなコードを書いたりするのだが。

#!/usr/bin/env ruby
 
x = '@'; xs = []; 18.times {
    xs << x.succ!.dup
}
puts(xs.inspect)
 
n = 0; xp = []; xs.each {|x|
    xp << x
    if(xp.size == 5)
        puts('%d: %s' % [n += 1, xp.join(',')]) # same!
        xp.clear
    end
}
puts('%d: %s' % [n += 1, xp.join(',')])         # same!
 
__END__

  ここで「same!」とある行を2度書くのがすごくイヤなんだよな。こういうのに対応する構文を持つ言語ってあるのかしらん……とか考えつつ、その部分はさておき、他はどうにかこうにか納得できるコードが書けた。

#!/usr/bin/env ruby
 
require 'rmagick'
 
if(ARGV.size == 0)
    abort(<<USAGE)
Usage: rcatimg image_file [width] [trim]
USAGE
end
 
image = Magick::Image.read(ARGV[0])
w = image[0].columns
h = image[0].rows
 
tgt_w = `tput cols`.to_i
tgt_w > w and tgt_w = w
(it = ARGV[1]) and tgt_w = it.to_i
trm_x = false
(it = ARGV[2]) and trm_x = it.to_i
tgt_h = h * tgt_w / w
sstep = (h << 8) / tgt_h
 
# +---------+   tdms = [    [ 0b00, 'Ar;Ag;Ab', 'Wr;Wg;Wb' ],
# | A   C D |               [ 0b10,        nil, 'Xr;Xg;Xb' ],
# | W X   Z |               [ 0b01, 'Cr;Cg;Cb',        nil ],
# +---------+               [ 0b00, 'Dr;Dg;Db', 'Zr;Zg;Zb' ] ]
 
ess = [ "\e[38;2;%2$sm\e[48;2;%3$sm\u2580\e[m", # 0b00: f_col,  b_col,  [▀]
        "\e[38;2;%2$sm\u2580\e[m",              # 0b01: f_col,          [▀]
        "\e[38;2;%3$sm\u2584\e[m",              # 0b10:         f_col,  [▄]
        ' ' ]                                   # 0b11:                 [ ]
 
y8 = 0; tdms = []; tgt_h.times {
    x8 = 0; tgt_w.times {|cx|
        trm_x and (cx < trm_x or break)
        c = image[0].pixel_color(x8 >> 8, y8 >> 8)
        tdms[cx] ||= [0]
        tdms[cx][0] <<= 1
        if(c.opacity < 64)
            tdms[cx] << '%d;%d;%d' % [c.red >> 8, c.green >> 8, c.blue >> 8]
        else
            tdms[cx][0] += 1    # 透明
            tdms[cx] << nil
        end
        x8 += sstep
    }
    if(tdms[0].size == 3)
        tdms.each {|tdm|
            print(ess[tdm[0]] % tdm)
        }
        puts; tdms.clear
    end
    y8 += sstep
}
if(tdms.size != 0)
    tdms.each {|tdm|
        print(ess[(tdm[0] << 1) + 1] % tdm)
    }
    puts
end
 
if(ENV['INFO'])
    puts('#' * trm_x) if(trm_x)
    puts('#' * tgt_w)
    puts('[%d, %d] -> x%d/%d -> [%d, %d]' % [w, h, 256, sstep, tgt_w, tgt_h])
end
 
__END__

  画像の説明

  さて、次はMaveの方を見てみるかな。


2023-09-11(Mon) クレギオン、ロケットガール、ダブルリーチ

  6月の中頃、ポイントが余っていることもあり、何か面白い小説でもないかと探していると目に止まったのが、野尻抱介氏の「クレギオン」シリーズ。軽い気持ちで電子書籍版を買ってみたところ、これが近年マレに見る面白さ。スペースオペラで、ダーティペアに近い雰囲気だが、それに比べハードSF成分が高いのに、展開はソフトという感じ。

  元は富士見ファンタジア文庫での出版だったが、今はハヤカワ文庫で再販されているという状況が驚くほど自然に思える内容だ。ライトノベルとハードSFの見事な融合。なんというかライトでハードってアルミノベル!?

  野尻氏の作品は、過去に「南極点のピアピア動画」「沈黙のフライバイ」「太陽の簒奪者」「ふわふわの泉」のいずれも読んでいて好印象だったが、それにも増して面白い。「クレギオン」は平成4年出版開始だが、まったく古さを感じさせない。

  1冊目の「ヴェイスの盲点」を読了したところで、躊躇なく2冊目の「フェイダーリンクの鯨」へ進む。が、ひとつ問題が。挿絵がまったくないので、いまひとつ宇宙空間の状況が入ってこない。主役メカであるアルフェッカ号の形もピンと来ていない。

  どうも、ハヤカワ文庫に移籍した時に挿絵が捨てられてしまったようだ。いや、それはあったほうがいいのだがな。まだ先に5冊もあるのに、このまま挿絵のない電子書籍版を買い進めるのは、特にこの作品においてはもったいなさすぎるように思える。

  しかし、一方で紙の本は食事中に読み進められないという問題がある。非常に不真面目な読書態度で申し訳ないのだが、最近の自分は「細切れの数分の時間を使って、数ページずつ読み進める」というスタイルなのだ。自分の場合、それでも十分に内容は頭に入るし、存分に楽しめるのだ。というわけで、それが解決になるのかはわからないものの、とりあえず「書見台」というものを買ってみることにした。

  画像の説明

  すると、これが想像以上に快適で、紙の本に限って読み進められないという問題が完全に解決されてしまった。未読の作品の都合もあるが、電子書籍を読む時間が寝る前だけになってしまったほどだ。

  で、3冊目の「アンクスの海賊」から紙の本で読み始めた……のだが、期待に反し、挿絵は人物画ばかりでSF的な情景を描いたものは皆無だった。ま、そうなるか。とはいえ、マージもメイも、オマケにロイドも、顔はあったほうがいい。結局、7冊目の「ベクフッドの虜」まで紙の本で調達してしまい、その勢いで、間違いなく「ロケットガール」シリーズも面白いハズだから読むべきと思い、これも紙の本を調達。当然、ハヤカワ版ではなく、富士見の再販版である。ついでに、さかのぼってクレギオンの1,2冊目も調達。

  画像の説明

  こんな気持ちになるのは珍しいが、7冊目の「ベクフッドの虜」はもったいなくて読まずに残し「ロケットガール」に進む。これまた、無闇に面白い。笹本祐一氏の「星のパイロット」シリーズと内容も面白さもだいぶ被るが、リアルな宇宙開発を舞台にしてるだけなのに、なんでこんなに面白いのか。

  そして、いま3冊目の「私と月につきあって」を読み終わったところである。それにしても、どの話にしても、もちっとエピローグを書いてもいいくらい、最終ページ直前までクライマックスである。ホント尻尾の先までアンコだなぁ。

  つうわけで、まちがいなく面白いが、読んでしまったら終わってしまうという、ダブルリーチ状態。どっちを先に読むべきか迷っているのであった。贅沢な悩みだなぁ。