Sunday, April 13, 2008

user database, activerecord, and extension to HTTP

Today was mostly about figuring out the intricacies of the certificate generation in openssl, and wrapping them into the appropriate Ruby code - and a bit of standalone ActiveRecord coding.

As a result, I now have the module, that implements PKI in a way that allows to operate it without the major headache:


uca = UCA::UCA.new([ ["CN", "Test CA" ] ],
"Test CA", Proc.new { |flag| "test" })

u = User.new
u.firstname = "Dalien"
u.lastname = "Talbot"
cn = [ ["CN", u.firstname + "_" +
u.lastname + "@" + 'localhost' ] ]
rsa, csr = UCA::Utils::generate_csr(1024, cn)
cert = uca.sign_csr(csr)
u.rsa_cert = cert.to_pem
u.rsa_key = rsa.export(
OpenSSL::Cipher::DES.new(:EDE3, :CBC), "test" )
u.save!



This small fragment of code creates the user, initializes a tiny CA, and creates a new user record with the certificate signed by this CA.

Now, in the previous post about groups, presence, etc. I was thinking about nice half-persistent connections between the presence servers. HTTP would not necessarily fit there unless I'd be interested to make two unidirectional connections - which is boring.

So, the other part of the fun was figuring out the way to do it in a simplest way, such that I could reuse the webrick as much as I can... And I think I found a pretty fun hack to do it - CONNECT method.
There's an old draft which somewhat describes this method, and from what I know, de-facto it is implemented (even though I could not find the published RFC describing it).

I'm (ab)using this method to provide the "direct connection" between the two stream-oriented applications on client and server. As soon as the server replies with the standard HTTP reply "200 OK" - the two endpoints on the client and the server are connected with asynchronous stream, and can send the data to each other whenever they want. The only difference between the "classic" usage and mine is that I will probably use the URI in lieu of hostname:port - which will describe the point to connect to on the server. (especially since obviously the server would not tunnel the connection anywhere further).

It's a bit of arm-twisting, but seems to integrate quite nicely both with webrick and the C code that I have. And since the stream will be SSL-encrypted anyway - noone should care.

Obviously the process of "short-circuiting" will need to take into the account the certificates presented by both sides, and possibly establish the ACL/QoS based on that.

Also, the Ruby code got an excellent UUID library, so now both the C and Ruby can generate the mac-based UUIDs.

Update:

on a second thought, the "CONNECT" idea is quite a bad one. The end result is that the code on both sides will have to demultiplex the flow of data in two different directions - which adds the complexity and bugs... So it will be put into a box for now.

No comments: