ciplogic.com
Live with grace. Write superb software.

I assume the server is freshly installed and does not have any keys preinstalled.

First things first:

1. Install stonevpn and openvpn

# yum install -y openvpn stonevpn

If you now try to run stonevpn, you will see it gives some errors, so...

2. Fix your openssl config file.

# vim /etc/pki/tls/openssl.cnf

In particular fill the sections req_distinguished_name and in CA_default the dir location. I set mine to /etc/ssl/CA (you need to create this hierarchy).

3. Create the index.txt and serial files.

# cd /etc/ssl/CA
# touch index.txt
# touch serial

When running stonevpn -a we should get an empty list of client certificates. If you're here, so far so good.

4. Generate the server's certificate that will be used to sign all the other client certificates (steps taken from here). Do these in /etc/openvpn since this is by default in the /etc/stonevpn.conf. The names are also server.key and server.crt so it is better to just use these ones.

# cd /etc/openvpn
# openssl genrsa -des3 -out server.key 2048
# openssl req -new -key server.key -out server.csr
# openssl x509 -req -days 365 -in server.csr -signkey server.key -out server.crt

5. Next we need to update the pyOpenSSL to have support for X509Extensions. We can see that a simple test run will fail:

==================================================================
Warning: your version of pyOpenSSL doesn't support X509Extensions.
Please consult the README file that came with StoneVPN in order to
fix this. This is not trivial. The certificate will be generated.
==================================================================
Traceback (most recent call last):
  File "/usr/bin/stonevpn", line 18, in ?
    sys.exit(app.main() or 0)
  File "/usr/lib/python2.4/site-packages/StoneVPN/app.py", line 310, in main
    s.run()
  File "/usr/lib/python2.4/site-packages/StoneVPN/app.py", line 434, in run
    self.makeCert( self.fname, self.cname )
  File "/usr/lib/python2.4/site-packages/StoneVPN/app.py", line 997, in makeCert
    cert = self.createCertificate(req, (cacert, cakey), curSerial, (0, 24 * 60 * 60 * int(defaultDays)))
  File "/usr/lib/python2.4/site-packages/StoneVPN/app.py", line 799, in createCertificate
    cert.set_notBefore(now)
AttributeError: set_notBefore

So we need to download and build pyOpenSSL.

# wget https://launchpad.net/pyopenssl/main/0.11/+download/pyOpenSSL-0.11.tar.gz
# yum install gcc python-devel openssl-devel
# cd pyOpenSSL-0.11
# ./setup.py install

6. Now we're good to go.

I've seen a lot of APIs that have the bad habbit of having the event types described as String. jQuery (JavaScript) and SWT (Java) are two popular examples that allow extensions of the event system using String names. Generally the API is composed by 2 methods:

  1. the Add Listener method: on / addPropertyChangeListener
  2. the Fire Event method: fire / notifyPropertyChange

While the naming conventions are different, in spirit they do the same thing. The problem with this approach that if you do instead of:

1
element.on("click", function() { ... });

this

1
element.on("clickl", function() { ... }); // invalid event type

you won't even notice it unless many hours of pointless debugging have passed.

So I believe that JavaScript APIs (in particular) should go in a different direction, where you could see the problem the moment you try to listen to an event that does not exist, by throwing an exception on the Add Listener method. Thus, another method would be needed to actually register the event type to the specific element, so we will have:

  1. the Register Event method: event / addEvent (?)
  2. the Add Listener method: on / addPropertyChangeListener. Note that this will now throw an exception if an invalid listener will be registered.
  3. the Fire Event method: fire / notifyPropertyChange. This now can also throw an exception if the event was not registered.

Since we're developers here, some API calls would look like:

1
2
3
4
5
6
7
8
9
var element = $("#whatever");
 
// wrong
element.on("customevent", function() {...}); // throws exception
 
// good
element.event("customevent"); //now only we can register listeners to it.
// later ...
element.on("customevent", function() {...}); // works just fine.

Note, that it doesn't mean this should be the final API. Personally I think the best looking API is something along the way that after the registration, you could call the API only via members of the on object. Something like this:

1
2
3
element.on.customevent.addListener(function() {...});
element.on.customevent.removeListener(func);
element.on.customevent.notify(eventData); // trigger the actual event

But I am convinced that the actual event types should be tied to the object that can generate them.

Advantages

In my opinion this approach has these advantages:

  • Faster time from the error introduced in the code, to the error report. (we won't generate non existing events, nor listen to non existing ones).
  • The possibility of interrogating an object on what events it can raise at runtime.

The only drawback I can think of, is that you can't listen to events before they are registered, but I haven't yet seen any real life application where this actually happens.

Since FuseVPS is closing its doors (I was hosting this site at them with merely 5$ a month), I will need to switch from them. Since apparently their hardware layer provider decided to simply close their server without saying, guess what vendor I won't pick.

Original message from FuseVPS is here:

I regret to inform you that FuseVps will be closing its doors.

Due to complications with our dedicated server provider, Softlayer, we are unable to continue with FuseVps.

You may have noticed other OpenVZ providers discontinue their service at Softlayer over the last 12 months. While we cannot say this with certainty, we would not be surprised if they found the same difficulties  we have.

If your server is located on Odin, Softlayer disconnected the public access with no warning. We have requested on numerous occassions this be put online for you to acquire backups, and Softlayer has refused. For all other servers, you will have until Feb. 28 to backup any data and move to a new provider.

All paypal subscriptions have been cancelled. You should not get invoiced. All accounts will run unsuspended until Feb. 28.

It has been an honor working with you, our wonderful clients.

FuseVps. Out.

Bye-bye FuseVPS I enjoyed using your services.

I just received recently an email that had it's title looking like:

impossible

Yes it actually writes that. When opening it I got a reassuring introduction:

better than bacon

But there still is a lie in there:

"is pretty close"

To bacon?

Yeah, right.

What if you have a "users" table, and all the properties for the users are in the "property" table. Would a select like this be efficient in PosgreSQL?

select distinct u.*, p3.value
from users u
join property p1 on u.id = p1.user_id
join property p2 on u.id = p2.user_id
join property p3 on u.id = p3.user_id
where p1.name = 'admin'
and p1.value='false'
and p2.name = 'email'
and p2.value like '%mah%'
and p3.name = 'name'
order by p3.value;

 

Capture 

 

Surprisingly this is quite OK, since PostgreSQL won't be stupid enough to do the full Cartesian product. I love you PosgreSQL.

Disqus Comments

comments powered by Disqus

Germanium

The one to rule them all. The browsers that is.

SharpKnight

SharpKnight is an Android chess game.

MagicGroup

MagicGroup is an eclipse plugin.