2013-02-21

リモートREPLとTLS

別に今のところ使う必要がないのだけど、あると便利かなと思ってリモートREPLを作ってみた。最初はYpsilonのtrunkにあったような簡単なのにしてたんだけど、そうするとreadがエラー投げまくりだったので、もう少しまともなプロトコルを使うようにした。以下のような感じで使える。

;; server side
(import (sagittarius remote-repl))
(define auth (make-username&password-authenticate "test" "test"))
(define server (make-remote-repl "5000" :authenticate auth))
(server)

;; client side
(import (sagittarius remote-repl))
(connect-remote-repl "localhost" "5000")

リモートでいろいろやれるようになるとそのうち便利なことがあるだろうけど、当然問題もでてくる。認証とセキュリティの問題がまずあがるだろう。認証はコードを見ればなんとなく分かると思うけど、ユーザ名とパスワードの認証が実装してある。:authenticateキーワードを省略すると認証なしになる。

さて、セキュリティの問題だが、通信を覗かれるとこのままでは丸見えである。そこで今まで割りと放置気味だったTLSのサーバーソケットを急いで実装した。使い方は以下のようになる。
(import (rnrs) (rfc tls) (rfx x.509))
(define certificate (call-with-input-file make-x509-certificate :transcoder #f))
(define server-socket (make-server-tls-socket "5000" (list certificate))
;; (rfc tls) exports server-accept method so that
;; user can use it for both usual socket and TLS socket.
(let ((socket (server-accept server-socket)))
  ;; so is call-with-socket
  (call-with-socket socket
    (lambda (socket)
      ;; do whatever
     )))
クライアント側がDHEなプロトコルを実装しているなら秘密鍵は要らない。DHE以外のCipher specも使いたいなら秘密鍵を:private-keyで渡してやる必要がある。

TLSの実装はかなりと汚いのでソースを見たい人は覚悟してほしい。そのうちリファクタリングとかまじめにステートを追うようにする予定(今はクライアント、もしくはサーバーが正しい順序でパケットを送ると仮定している)。

この辺まで作ってといざリモートREPLをTLSでと思ったときに証明書がないことに気づいた。(手元にあるときはそれを適当に使っていた)。なので(rfc x.509)ライブラリに簡単なX509証明書生成手続きを足そうかと考え中。鍵対生成は既にあるので。

No comments:

Post a Comment