* WPMU OpenID and SSL

Posted on July 28th, 2010 by John. Filed under site maintenance.


It’s no secret that I’m using WordPress MU for this website. It makes it very easy to keep the main site as well as my and Tati’s blogs updated. Recently I’ve been wanting to continue properly securing the blogs and added HTTPS support as well as Yubikey required logins. Once that was in place my next goal was to get OpenID integrated with the sites again. This way the blogs can be used as our OpenID identify. I also wanted to use OpenID to allow others to comment on posts. I ended up using the WordPress OpenID plugin and with a little tweaking works perfectly with WPMU.

All total setting everything up did not go as smoothly as I had hoped but it all got implemented and is working properly. The easiest part of adding HTTPS support was getting Apache configured. I’m not going to go into detail about how to use SSL with Apache mainly because there are plenty of tutorials available for this.

I ran into HTTPS problems with WordPress itself. I first read the WordPress guide for Administration Over SSL but could not get the force SSL options to work. I ended up using the rewrite rules. The rewrite rules worked fine until I tried adding OpenID. Since they rewrite the URL from HTTP to HTTPS under certain circumstances it was causing the OpenID redirects to fail. Removing the rewrite rules would made everything work. After a while I went back to trying to get the force SSL options working. What I discovered is the following options need to be toward the beginning of the wp-config.php file not the end. Putting them at the end causes them to not be loaded.

define('FORCE_SSL_ADMIN', true);
define('FORCE_SSL_LOGIN', true);

The SSL issues didn’t end there. The OpenID plugin’s FAQ says that the following option needs to be set when using the force SSL options.

define('OPENID_SSL', true);

However, don’t set the OPENID_SSL option because it will cause OpenID logins to fail. WordPress MU (at least 3.0) will redirect to SSL for login and then redirect back just fine without OpenID needing to account for the HTTPS connection itself.

That takes care of getting SSL working getting OpenID working with SSL. However, I did have two issues with getting the OpenID plugin working.

First, I was using the Bad Behavior plugin. I say was because it causes OpenID logins to fail. For some reason Bad Behavior detects OpenID logins directed to the OpenID server that the OpenID plugin has created as attacks on the blog. I have not tried to find a way to make the two work together and instead just removed Bad Behavior. This was an easy decision because in the past few months I was using Bad Behavior it only reports stopping a very low number of attacks.

Second, the latest release of the OpenID plugin does not work properly with PHP 5.3. Luckily there is a patch to fix this. Changing the two lines makes is all that’s need to get it working.

The OpenID plugin works with WordPress MU 3.0 and works with and SSL protected logins. You need to patch OpenID if you are using PHP 5.3 and don’t set the OPENID_SSL option. Also, don’t use Bad Behavior and use WordPress’s built in SSL options instead of rewrite rules.

Tags: , , , .



* Yubikey Auto Lock in Gnome

Posted on July 25th, 2010 by John. Filed under Linux, Uncategorized.


I recently purchased a Yubikey from Yubico. What got me to buy it was the discount they’re offering to Security Now! listeners. So far I’m liking it quite a bit and have been looking to use it any way I can. One of the uses I found was to have the presence of they Yubikey unlock and lock Gnome Screen Saver.

Toward the end of the forum thread there is a very nice set of udev rules that work perfect for me and are very clean. I put the following into /etc/udev/rules.d/85-yubikey.rules

ACTION=="add", ENV{ID_VENDOR}=="Yubico", RUN+="/usr/local/bin/gnome-screensaver-unlock"
ACTION=="remove", ENV{ID_VENDOR}=="Yubico", RUN+="/usr/local/bin/gnome-screensaver-lock"

I really dislike the scripts that are in the thread for locking and unlocking the computer. Gnome Screen Saver is a DBus enabled application so controlling it is very easy. Below are the unlock and lock scripts I’ve written. They use qdbus to send the dbus commands. This could be replaced with dbus-send but I use Qt and qdbus’s syntax is easier to work with.

gnome-screensaver-unlock

#!/bin/sh
 
user=`ps aux | grep gnome-screensaver | head -n 1 | awk '{print $1}'`
 
if [ -n $user ]; then
        GNOME_SCREENSAVER_PROC=`ps xa | grep gnome-screensaver | head -n 1 | awk '{print $1}'`
        export `grep -z DBUS_SESSION_BUS_ADDRESS /proc/$GNOME_SCREENSAVER_PROC/environ`
 
        su $user -c "qdbus org.gnome.ScreenSaver / SetActive false"
fi

gnome-screensaver-lock

#!/bin/sh
 
user=`ps aux | grep gnome-screensaver | head -n 1 | awk '{print $1}'`
 
if [ -n $user ]; then
	GNOME_SCREENSAVER_PROC=`ps xa | grep gnome-screensaver | head -n 1 | awk '{print $1}'`
	export `grep -z DBUS_SESSION_BUS_ADDRESS /proc/$GNOME_SCREENSAVER_PROC/environ`
 
	su $user -c "qdbus org.gnome.ScreenSaver / SetActive true"
fi

One thing that isn’t mentioned in the forum thread that is very important, this unlocking method is highly insecure. The locking portion is fine but unlocking shouldn’t actually be done in this way. The above udev rules only checks that a Yubikey is inserted. It does not which which Yubikey is inserted. Any Yubikey can bypass your password and unlock the computer. The unlocking script does not preform any additional checks against the yubikey. Due to this, I don’t have the unlock code enabled on my computer.

However, it is possible to make unlocking secure. You can use one of the two yubikey pam modules, Yubico’s yubico-pam and Securix Live’s yubipam. Yubico-pam requires internet access because it validates against Yubico’s servers. Yubipam does not need internet access but you will have to reprogram your Yubikey with a new AES key. The new key must be stored in the computer. Each has it’s advantages and disadvantages but using the pam module with Gnome Screen Saver (I haven’t actually tried so it might not work) will provide you with a secure unlock.

Thinking about secure unlocks there is a clever solution that allows for the Yubikey to be used with SSH without the need for the pam module. If I can find a way (I haven’t looked yet) to have an input that can capture the Yubikey’s output then it would be possible to handle the unlock in a secure manner without the need for the pam module…

Tags: , , , .



* KDocker 4.4 Released

Posted on July 17th, 2010 by John. Filed under KDocker, Uncategorized.


I’ve released KDocker 4.4 today. It is mostly bug fixes and clean up. However, there is one major change. The feature to dock when the window decorator close button (the x in the upper corner) is clicked has been removed. This feature was introduced in 4.3 and I really like how it. It gives KDocker a feature that no similar application has. However, I was not able to keep it due to a number of issues it introduced.

The dock when closed feature was implemented via XEmbed. Basically I was creating my own window mimicking the window border of the application’s window. I would then remove the border from the application’s window and embed it into my window. Events would be passed from my window into the embedded window. This should work just fine in theory but it didn’t work out so nicely. Embedding caused five issues. The first four are serious and the last is only an annoyance.

The most serious issue was, it broke drag and drop. This looks to be an issue with X itself because I could recreate the problem using Qt and GTK’s embed support as well as writing the embed calls myself using xlib.

Another issue it caused related to support windows. When the main window was embedded it broke the connection between the main window and it’s support windows. So when docking the main window there were issues docking the applications other windows. This is an issue for applications such as XMMS and the Gimp.

Embedding didn’t get along very well with borderless windows. Applications like Chrome and XMMS draw their own window border in place of using the window manager’s decorations. These applications have special handling for moving when clicking and dragging their border. When they are embedded you end up with one of two situations. You can click and drag the window but only in the container window. So instead of moving the window you just move the window’s contents. The other situation is moving via the border doesn’t work at all. In this case resizing doesn’t work either. Oh, and the minimize, maximize, close buttons might not work either. In both cases you can still move the window using alt+left mouse button but this isn’t ideal.

Focus handling with embedded windows didn’t work correctly between different window managers and possibly different versions of Xorg. Some combinations it was fine. Others focus handling only followed the mouse. There were issues with the embedded window never getting focus or only getting focus when using alt+tab to select the window after it was docked.

The only annoying issue that I was okay with having was when undocking a window the window manager (compiz) would cause it to move a little bit. When undocking the position of the container window is recorded, the embedded window is removed from the container and moved to it’s location. Then the container window is destroyed. Compiz didn’t like placing two windows in the exact same place and kept moving the second window down and right by the size of the decoration and frame. This isn’t a very big issue but I really don’t want to have window manager specific work arounds in the code base.

The decision to remove iconify on close wasn’t taken lightly. It was only due to the large number of issues it created. There is not point in using KDocker if it is only going to make docked applications unusable. I have created a branch for iconify on close so I can hopefully get it working properly.

Tags: , .



* lebookread 0.2

Posted on July 11th, 2010 by John. Filed under Uncategorized.


I’ve made a new release of lebookread. This version supports the following formats: palmdoc, ztxt, epub, tcr, rb, mobi, and fb2. The library is usable but still needs a lot of work. Unit testing, examples, more code comments and more formats to name a few things.

.



* Qt Remove Directory and Its Contents

Posted on June 8th, 2010 by John. Filed under programming.


When dealing with directories, Qt has a large number of functions to make manipulating them easy. However, it does not include a way to delete a non-empty directory. This little omission is easily solved.

Following is a recursive function that will delete a directory along with all of it’s contents. This will delete depth first. Meaning it will recurse into sub-directories and only start deleting once the directory has no sub-directories. Changing QDir::DirsFirst to QDir::DirsLast will change this into a breadth first search.

fileutils.h

#ifndef FILEUTILS_H
#define FILEUTILS_H
 
#include <QString>
 
class FileUtils
{
public:
    static bool removeDir(const QString &dirName);
};
 
#endif // FILEUTILS_H

fileutils.cpp

#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QFileInfoList>
 
#include "fileutils.h"
 
/*!
   Delete a directory along with all of its contents.
 
   \param dirName Path of directory to remove.
   \return true on success; false on error.
*/
bool FileUtils::removeDir(const QString &dirName)
{
    bool result = true;
    QDir dir(dirName);
 
    if (dir.exists(dirName)) {
        Q_FOREACH(QFileInfo info, dir.entryInfoList(QDir::NoDotAndDotDot | QDir::System | QDir::Hidden  | QDir::AllDirs | QDir::Files, QDir::DirsFirst)) {
            if (info.isDir()) {
                result = removeDir(info.absoluteFilePath());
            }
            else {
                result = QFile::remove(info.absoluteFilePath());
            }
 
            if (!result) {
                return result;
            }
        }
        result = dir.rmdir(dirName);
    }
 
    return result;
}

Tags: , .



* C++ Derived Classes and Object Destruction

Posted on May 29th, 2010 by John. Filed under programming.


While working on lebookread I realized that the the destructor for my reader classes would never be called. lebook read has a base class (FormatReader) that exports all of the necessary functionality for use by applications using the library. All of the readers are a subclass of FormatReader. The library will find the appropriate reader for the specified ebook create a reader object and return it as a FormatReader pointer.

When you are dealing with a pointer p of type base that points to an object of type derived you need to take special care. To have the destruction of p call the derived and base destructor the base class must have a virtual destructor. Otherwise only the base class’s destructor will be called. This is one of those little things to look out for when dealing with C++.

Here is some example code to demonstrate the above.

main.cpp

#include <iostream>
 
#include "base.h"
#include "deriv.h"
 
using namespace std;
 
int main(int argc, char** argv)
{
    cout << "Base *b = new Base();" << endl;
    cout << "delete b;" << endl;
    Base *b = new Base();
    cout << " --- " << endl;
    delete b;
    cout << " --- " << endl;
    cout << "b destroyed" << endl;
 
    cout << endl;
 
    cout << "Deriv *d = new Deriv();" << endl;
    cout << "delete d" << endl;
    Deriv *d = new Deriv();
    cout << " --- " << endl;
    delete d;
    cout << " --- " << endl;
    cout << "d destroyed" << endl;
 
    cout << endl;
 
    cout << "Base *c = new Deriv();" << endl;
    cout << "delete c" << endl;
    Base *c = new Deriv();
    cout << " --- " << endl;
    delete c;
    cout << " --- " << endl;
    cout << "c destroyed" << endl;
 
    return 0;
}
#ifndef BASE_H
#define BASE_H
 
class Base
{
public:
    ~Base();
};
 
#endif /* BASE_H */

base.cpp

#include <iostream>
 
#include "base.h"
 
using namespace std;
 
Base::~Base()
{
    cout << "base dest" << endl;
}

deriv.h

#ifndef DERIV_H
#define DERIV_H
 
#include "base.h"
 
class Deriv : public Base
{
public:
    ~Deriv();
};
 
#endif /* DERIV_H */

deriv.cpp

#include <iostream>
 
#include "deriv.h"
 
using namespace std;
 
Deriv::~Deriv()
{
    cout << "deriv dest" << endl;
}

The output of this will be:

$ ./a.out 
Base *b = new Base();
delete b;
 --- 
base dest
 --- 
b destroyed
 
Deriv *d = new Deriv();
delete d
 --- 
deriv dest
base dest
 --- 
d destroyed
 
Base *c = new Deriv();
delete c
 --- 
base dest
 --- 
c destroyed

Notice that when destroying c only the Base’s destructor is called. To fix this and have both Base and Deriv’s destructors called just make Base’s destructor virtual.

#ifndef BASE_H
#define BASE_H
 
class Base
{
public:
    virtual ~Base();
};
 
#endif /* BASE_H */

This simple change will cause the output to become:

$ ./a.out 
Base *b = new Base();
delete b;
 --- 
base dest
 --- 
b destroyed
 
Deriv *d = new Deriv();
delete d
 --- 
deriv dest
base dest
 --- 
d destroyed
 
Base *c = new Deriv();
delete c
 --- 
deriv dest
base dest
 --- 
c destroyed

Now when destroying c the destructor for both Base and Deriv are called.

To compile

$ g++ base.cpp deriv.cpp main.cpp

Tags: .



* lebookread

Posted on May 16th, 2010 by John. Filed under lebookread, programming.


I have been taking a short break from blogging again. The pressure at work has only increased and is eating into a lot of my time. I haven’t been motivated to work on personal projects because well they are work. However, this has recently changed a bit.

I’ve started a Qt based library for reading ebooks in a generic manner. It is called lebookread! It is it’s early stages. So far I have it supporting epub, palmdoc pdb, ztxt pdb, tcr, and rb files. I plan to support ereader pdb, mobi, and plucker files in the near future.

The main goal of this project is to make reading ebooks easy for Qt based projects. I’ve chose to write the library in C++. This is also my first attempt at writing a library and it shows. I hope that it will be used by Sigil.

The real motivation of writing lebook read is I really want a good light weight ebook reader. The current offering have issues. I want something that is a bit more advanced in it’s rendering than FBReader. I also didn’t want anything with as large a dependency list as calibre. So, I plan on using lebookread to write my own ebook viewer.

Tags: , , , , , , , .



* Long time no see

Posted on March 10th, 2010 by John. Filed under calibre, site maintenance.


It’s been a while since I’ve made any posts. Mainly work and other matters have kept me away. I haven’t been working on very much recently.

This isn’t to say my participation with calibre has been abandoned. I’m still making regular bug fixes. I’ve also been working on a rather large change that is coming along much slower that I would like. Mainly metadata caching and muli way syncing. I was shooting for the end of March to complete the changes but it might not be done until the end of April.

I’ve also moved this blog off of the shared hosting package I was using. It’s now hosted on my own virtual private server. Attachments, images and the now reading list did not make it over in the transition. I’m still using WordPress but instead of having multiple separate installs of it all the blogs here are powered by one WordPress MU installation.

Tags: .



* Cybook t4b Format Specification

Posted on January 13th, 2010 by John. Filed under hardware.


The new epub thumbnail files (.epub.thn) are what Bookeen calls t4b files. They are very similar to the older t2b thumbnail files they were using in earlier versions of the Cybook firmware. As the name suggests instead of using 2 bits to represent color values 4 bits are now used. This increases the number of colors from 4 to 16. In addition to the increased color range the t4b files now require a header of “t4bp” without the quotes.

The image’s dimensions are 96×144. The bits representing 0, 1, 2, 3… are written directly to the file. it is very similar to a pgm file in this regard. Each 4 bit sequence represents a pixel color. Only black, white and shades of gray are supported.

Every t4b file will have 13,824 pixels. The file size will always be 6,916 bytes. The formula to determine this is: (height x width x 2 bits per pixel) / 8 bits per byte. ((96 * 144 * 4) / 8 ) + 4 = 6,916. The + 4 is the header.

Following are two python scripts for converting an image to a t4b file and for converting a t4b file into a pgm image.

image2t4b.py

#!/usr/bin/env python
 
import sys, Image
 
REDUCE_MARKS = [16, 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, 240]
 
def reduce_color(c):
    val = 0
    for mark in REDUCE_MARKS:
        if c &gt; mark:
            val += 1
        else:
            break
    return val
 
def main():
    if len(sys.argv) != 3:
        raise Exception('Must have 2 arguments. %s input.image output.epub.thn' % sys.argv[0])
 
    outf = open(sys.argv[2], 'wb')
 
    im = Image.open(sys.argv[1]).convert("L")
    im.thumbnail((96, 144))
 
    newim = Image.new('L', (96, 144), 'white')
 
    x,y = im.size
    newim.paste(im, ((96-x)/2, (144-y)/2))
 
    outf.write('t4bp')
 
    px = []
    for p in newim.getdata():
        px.append(p)
        if len(px) == 2:
            byte_val = bin(reduce_color(px[0]))[2:].zfill(4) + bin(reduce_color(px[1]))[2:].zfill(4)
            outf.write(chr(int(byte_val, 2)))
            px = []
        elif len(px) &gt; 2:
            raise Exception('Fatal error px length increased past 2.')
 
    outf.close()
 
if __name__ == '__main__':
    main()

t4b2pgm.py

#!/usr/bin/env python
 
import sys, os
 
def get_greys(b):
    if not b:
        return 0, 0
 
    b = bin(int(ord(b)))
    b = b[2:].zfill(8)
 
    w = str(int(b[0:4], 2))
    x = str(int(b[4:8], 2))
 
    return w, x
 
def main():
    if len(sys.argv) != 3:
        raise Exception('Must have 2 arguments. %s input.epub.thm output.pgm' % sys.argv[0])
 
    t4bfile = open(sys.argv[1], 'rb')
    pgmfile = open(sys.argv[2], 'w')
 
    pgmfile.write('P2\n96 144\n15\n')
 
    # Read past the t4b header
    t4bfile.read(4)
 
    for i in range(144):
        for j in range(48):
            b = t4bfile.read(1)
 
            vals = get_greys(b)
            pgmfile.write('%s %s ' % (vals[0], vals[1]))
        pgmfile.write('\n')
 
    pgmfile.close()
    t4bfile.close()
 
if __name__ == '__main__':
    main()

Tags: , , , , , , .



* Cybook 2.0 Thumbnail Observations

Posted on January 13th, 2010 by John. Filed under hardware.


The 2.0 fimware for the Cybook and Opus have new thumbnails for epub files. They use the .thn extension and it is append after the .epub extension. This is unlike the _6090.t2b thumbnails which use the book name without the extension and _6090.t2b appended to it. I have yet to start figuring out this new format but at first glance it looks to be similar to the _6090.t2b files.

What I have found is, if a _6090.t2b file is present that will be used and the .thn file will not be generated and the _6090.t2b will be used as the thumbnail. However, if both the _6090.t2b and .thn are present then the .thn will be used.

Tags: , , , .