scox.info - Random Thoughts

To content | To menu | To search

Tuesday, June 10 2008

Migrating from Mephisto to Dotclear 2

It's been a while since my last post. Beside the fact that I was busy, the reason preventing me from posting is that the blogging engine I was using (Mephisto) was in a bad shape. It seemed unmaintaned, managed to consume all the server memory and didn't survive a rails upgrade.

That's why I've decided to migrate to Dotclear 2, which seems to be a nice and clean blogging engine. However, in the migration process, I didn't want to lose:

  • All my previsous posts (both published and pending)
  • All the comments
  • Associated metadata (categories, tags and so on)

Dotclear has a nice builtin plugin called Import/Export which let you save and restore backups of your blog. All I did was writing a Ruby script that generates a dump of the Mephisto database using ActiveRecord in the same format as Import/Export, ready to be imported. It is available here and works in the following way:

  • Place it under the script directory of your Mephisto rails root
  • Edit the first lines (set your Dotclear 2 login and blog id)
  • Run it and redirect the output to your favorite location:

ruby script/migrate_to_dc2.rb > public/dump.dc2

  • Retrieve the dump file (e.g. dump.dc2) and import it in the "Import/Export" area, under the Import a single blog section.

That's it, you're done. It should have imported all your blog posts (and preserved publish dates as well as many other attributes), comments, metadatas etc.

I also wanted to maintain backward URL compatibility with Mephisto. A couple of mod_rewrite rules did the trick:

# Mephisto URL compatiblity
RewriteEngine On
# Feeds
RewriteRule ^/feed/atom.xml /feed/atom [L,R=301]
RewriteRule ^/feed/all_comments.xml$ /feed/atom/comments [L,R=301]
# Posts
RewriteRule (^/200\d.*) /post$1 [QSA,L,R=301]

That's all. I hope it will be useful to anyone wishing to migrate to Dotclear 2, as the process of creating that script is quite annoying :)

Saturday, September 15 2007

Yet another release of pam_usb

Just a quick blog entry to introduce you to the new version of pam_usb (0.4.2), which I've just released a few minutes ago.

This release focuses on bugfixes and small enhancements. Here's a non exhaustive list of them:

  • Better hardware support: Thanks to user feedback, a lot of improvements have been made in hardware support. Now devices without vendor and model informations can be used for authentication.
  • Support for non USB devices: You can now use every kind of removable storage devices, such as SD or MMC cards.
  • Reduced writing to the device: Pads aren't updated everytime you authenticate anymore, but (by default) only once an hour. This feature can be turned off by setting pads_expiration to 0, or you can adjust it to a more suitable value (2h, 10m etc are valid options).
  • Many other smaller bugfixes and features have been included, such as the DBUS workaround and support for Python 2.5.

I'd like to thank all the users who contributed by sending their feedback and patches.

Saturday, August 25 2007

Using D-Bus from setuid applications

When trying to connect to the system bus from a setuid application, D-Bus throws back the following error:

Did not receive a reply. Possible causes include: the remote application did not send a reply, the message bus security policy blocked the reply, the reply timeout expired, or the network connection was broken.

After some debugging, I found that the problem is a bug in the D-Bus EXTERNAL authentication method: the library sends the real UID while the daemon checks the effective UID, which of course doesn't work at all in setuid applications.

I filed a bug report in the Freedesktop Bugzilla and provideda patch which is yet to be merged.

In the meantime, if you need to use D-Bus in a setuid application, the following code might help:

DBusConnection *my_dbus_bus_get(DBusBusType type, DBusError *error)
{
DBusConnection *bus = NULL;

if (!(bus = dbus_bus_get(type, error)))
{
/* The connection to the BUS failed, we now check
* if we are running as setuid. */
uid_t ruid;
uid_t euid;

if (!(euid = geteuid()) && (ruid = getuid()))
{
/* In that case, we temporary change our
* real uid to the effective uid and try again */
dbus_error_free(error);
setreuid(euid, euid);
bus = dbus_bus_get(type, error);
setreuid(ruid, euid);
}
}
return bus;
}

This workaround is a function you'll have to call instead of the regular dbus_bus_get(). In case the connection fails and it's running on a setuid application, it will change the real UID to match the effective UID so the authentication process will succeed, make a connection to D-Bus and restore everything back.

Sunday, April 22 2007

Mephisto Obfuscation Plugin

Being tired of receiving tons of spam everyday, I wanted to hide my e-mail address in a more efficient way than the usual user at example dot com. I needed to obfuscate my address to spam crawlers while keeping it readable by human beings. I've created a simple Mephisto plugin to help me do so, called MephistoObfuscate.

Basically, this plugin encodes email addresses (or any text you'd like) into Base64 and lets the browser decode them using some JavaScript on the client side. That way, the address is protected from crawlers blindly scanning the HTML page but is still readable by JavaScript-enabled browsers.

Example

Using MephistoObfuscate is pretty straightforward, you can either use a Liquid filter on your templates (useful to show a contact address on the layout, just like the one on the right sidebar of this page):

{{ "user@example.com" | obfuscate }}
Or you can use a macro filter within your blog posts:

<filter:obfuscate>user@example.com</filter:obfuscate>


Both of these will be obfuscated into something like:

<span class="obfuscated">dXNlckBleGFtcGxlLmNvbQ==l</span>


Which is not something most if not all spam crawlers will understand. While loading the page the JavaScript code will restore the address back into a human readable fashion.

Installing

To install just run

script/plugin install svn://svn.sig11.org/mephisto_obfuscate


After this, add the javascript include statements into your layout:

{{ 'obfuscate' | javascript }}

That's it, you're done.

Monday, April 9 2007

pam_usb: Finally a new release

After way too much time, I have finally released pam_usb 0.4.0.

For those of you not familiar with the project, it "provides hardware authentication for Linux using ordinary USB Flash Drives".Basically, it makes applications such as GDM/KDM, gnome-screensaver/kscreensaver, su/sudo and so forth authenticate users using a USB stick instead of askingfor a password over and over. If you're lazy like me, you'll appreciate it.

So, what's new with this release ? Well, everything. For starters, I've rewritten everything from scratch. It contains many new features,including one time pads authentication and support for hardware detection throughHAL.

I've also written a set of tools in Python:

  • pamusb-agent, a daemon that can trigger actions (such as locking the screen) upon device authentication and removal.
  • pamusb-conf, a tool that can save you the hassle of editing pamusb.conf by hand. As for now, it supports the --add-device and --add-user options.

The project has now a brand new website powered by the Dokuwiki wiki engine.I have also reworked the documentation as the old one seemed to scare people. Someday I'll probably do a screencast to show how to setup pam_usb in 5 minutes. Until then, have fun with the documentation :)

Sunday, April 8 2007

One Time Pads: The new authentication model of pam_usb

The way pam_usb performed authentication was inspired by smartcards: a private key was stored inside the device and the public part of the key inside the computer. The problem is that, unlike smartcards, the content of a USB device is readable meaning that the private key could be stolen by anyone borrowing your flash drive. Sure, the device is also identified by its manufacturer attributes (serial number and alike), but I'm pretty much sure those informations can be forged.

Knowing that the content of the USB device is unreliable (as it can be stolen), I came up with a different approach for authenticating a device called One Time Pads authentication. Basically, a pad is just a bunch of random bytes stored on both the USB device and the computer. Every time you authenticate, those pads are compared. If they match, access is granted and the pads are regenerated, otherwise access is denied.

This means that even if someone manages to fake your device's manufacturer attributes and to steal your pads, as soon as you authenticate the pads will be regenerated, making the one they have stolen invalid.It's like having a very long random generated one time password, except the fact you don't have to remember such password.

Let's see one time pads in action:

  • First, just as our attacker, we start by stealing our own pad:
        scox@helium ~ $ cp /media/disk/.pamusb/root.helium.pad /tmp
  • Then we authenticate. As you can see, the pads are verified, then updated:
        scox@helium ~ $ su
* pam_usb vSVN
* Authentication request for user "root" (su)
* Device "sandisk" is connected (good).
* Performing one time pad verification...
* Verification match, updating one time pads...
* Access granted.
  • Now we are the attacker. We start by putting the stolen pad back into a device (assuming the device has the same serial number as ours) and try to authenticate:
        scox@helium ~ $ cp /tmp/root.helium.pad /media/disk/.pamusb/
scox@helium ~ $ su
* pam_usb vSVN
* Authentication request for user "root" (su)
* Device "sandisk" is connected (good).
* Performing one time pad verification...
* Pad checking failed !
* Access denied.
Password:

It may not be the safest authentication ever, but it's cheap (everyone has a USB flash drive nowadays), pretty much secure for common usage and avoids the hassle of remembering and typing passwords.I'll be releasing pam_usb 0.4.0 which contains one time pads authentication in the next few days, so stay tuned.