Search
Enter Keywords:
Thursday, 28 August 2008
Home arrow All
All
Using DBUS to take action on a USB storage device
Written by Dan   
Sunday, 11 November 2007

I keep my password-encrypted SSH and PGP keys on a small USB key.  I do this to keep these sensitive files separate from my laptop, in case I were to lose it.  I figure it's easier to keep a USB key on me whenever I'm at work or traveling.  I don't want to have to keep my USB key inserted all the time to encrypt files and emails or SSH to remote hosts.  Even though that would probably be more secure, I think I'd wear out the flash memory and would probably get annoyed before that even happened.  So, I want to cache the sensitive data in memory, so that it's lost on powerdown, but available to me while working normally.

Luckily, ssh-agent provides this sort of functionality already, but GPG does not (that I know of).  What I want is some way for me to just insert my key and have the PGP files copied to a volatile location and the SSH keys inserted into the agent automatically (prompting for a password first, of course).  I could do this with an autorun file on the key itself, but then inserting it into random machines might copy my sensitive files, which would be really bad.  Since DBUS seems to be pretty nifty, I figured I should see about writing a little app to respond to the DBUS mount event to run a script for me.  I don't know much about DBUS, so it seemed like a good exercise.

At first, I saw a Linux Journal article about doing this with udev rules, but that isn't as nice because you don't have DISPLAY set, and it doesn't run as your own user.  Still workable, but less nice.  So, I googled for examples of using DBUS from Python and came up with the following dispatch app:

#!/usr/bin/python

DEVICE_TAG="dansmith"
WORK_SCRIPT="/home/dan/bin/sshkey.sh"

import dbus
import gobject
import dbus.mainloop.glib
import os

def handler(*args, **kwargs):
    if not kwargs["member"] == "VolumeMountedSignal":
        return

    uri = args[0][4].replace("file://", "")
    tag = args[0][6]

    if tag == DEVICE_TAG:
        os.system("%s %s" % (WORK_SCRIPT, uri))
            
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
bus = dbus.SessionBus()
bus.add_signal_receiver(handler,
                        interface_keyword="dbus_interface",
                        member_keyword="member")

loop = gobject.MainLoop()
loop.run()

I can then exec this as part of my gnome session startup.  The app listens for the "VolumeMountedSignal" and checks the volume label against what I know my USB key has.  If it matches, it runs my little helper script.  The script mounts a tmpfs in a subdirectory of $HOME, copies the PGP files into place, and then runs ssh-add on all of the SSH keys.  Since DISPLAY is set, I get the GUI ssh-askpass box to unlock each key.

It would be interesting to extend this little dispatch app to have a GUI interface to let you add device labels and associated actions.  It might be handy to have a couple things like "exec script foo", "copy contents to /path/bar", "freshen a tarball backup", etc. 

 
Finally: T41p, radeon, and DVI hotplug
Written by Dan   
Saturday, 10 November 2007

Maybe I'm just an idiot, but I've never been able to use the open-source radeon driver with my T41p.  The main reason being that the radeon driver seemed doomed to permanent suckage when it came to using my external 1600x1200 DVI flat panel.  Sure, I could boot up with the lid closed and the DVI plugged in and then reboot when moving to the couch to use the integrated display, but come on, that's ridiculous.

Recent versions of the evil fglrx driver seemed to solve my problem with the dynamic --enable-monitor flag.  I wrote a little script that took the output of --query-monitor and stuffed it into --enable-monitor.  This meant any time I switched configs, I could just run that script and it would enable whatever monitors were connected.  I could then use xrandr to change the resolution to what I wanted and be happy.

Ubuntu Gutsy Gibbon promised to make this all better.  However, when I upgraded, the new display settings tool didn't seem to do much for me.  It detected my external flat panel as the laptop display and I couldn't make it do anything with minimal work.  So, I restored my xorg.conf with the fglrx settings and went back to what I had.  However, fglrx in Gutsy seemed to break my ability to suspend, which is something I had just gotten used to.

This afternoon, I sat down determined to put some more time into the new bits and see if I could make something work.  First, I moved my xorg.conf file away (to a safe hiding spot) and restarted X.  I then went into the display config tool and forced the laptop display to 1400x1050.  It didn't show my external monitor, so I saved the settings and restarted.  When I got back in, my external display showed up, model undetected, but present.  So, I configured the model and resolution, saved, and restarted.  I got nothing.  The login screen showed in 1400x1050 on the internal display, and an offset 1600x1200 on the external, but after login the external display went black and I just had the internal display.

From there, I opened up a terminal to run the command-line xrandr program.  Wow, has that changed!  It now shows me connected monitors, resolutions, etc:

Screen 0: minimum 320 x 200, current 1600 x 1200, maximum 1600 x 1200
VGA-0 disconnected (normal left inverted right)
DVI-0 connected 1600x1200+0+0 (normal left inverted right) 367mm x 275mm
   1600x1200      60.0*+   59.9  
   1280x1024      75.0     59.9  
   1152x864       74.8  
   1024x768       75.1     60.0  
   800x600        75.0     60.3  
   640x480        75.0     60.0  
   720x400        70.1  
LVDS connected (normal left inverted right)
   1400x1050      50.0 +
   1280x1024      59.9  
   1280x960       59.9  
   1280x800       60.0  
   1280x768       60.0  
   1024x768       60.0     59.9  
   800x600        60.3     59.9  
   640x480        59.9     59.4  
S-video disconnected (normal left inverted right)

 Playing around a little, I noticed that I could turn on and off either display, by doing:

$ xrandr --output DVI-0 --off
$ xrandr --output DVI-0 --auto
$ xrandr --output LVDS --off
$ xrandr --output LVDS --auto

The current resolution would switch to 1400x1050 when the LVDS output was enabled (its maximum) and 1600x1200 when the LVDS output was disabled (the DVI-0 maximum).  This is perfect!  All I need is for this to happen when the lid ACPI event triggers.  If the lid is open, enable LVDS.  If it's closed, disable LVDS.  For both cases, "auto" mode for DVI-0 should be fine.  So, I wrote the following script:

 #!/bin/bash

. /usr/share/acpi-support/power-funcs
. /usr/share/acpi-support/policy-funcs
. /etc/default/acpi-support

do_it() {
    STATE=$(cat /proc/acpi/button/lid/*/state | awk '{print $2}')
    
    if [ "$STATE" = "closed" ]; then
        echo Setting LVDS off
        xrandr --output LVDS --off
    else
        echo Setting LVDS on
        xrandr --output LVDS --auto
    fi
    
    echo Setting DVI auto
    xrandr --output DVI-0 --auto
}

# Give the displays a chance to settle
sleep 2

for x in /tmp/.X11-unix/*; do
    displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
    getXuser;
    if [ x"$XAUTHORITY" != x"" ]; then
        export DISPLAY=":$displaynum"
    do_it
    fi
done

Next, I created a /etc/acpi/local/lid.sh.pre file to call my script and marked it executable (you could put the above in the lid.sh.pre itself, of course).  I copied the display setting code from /etc/acpi/lid.sh.  This ensures that DISPLAY is set appropriately so that xrandr will work correctly.

Now, when I cycle my lid (or press the little sunken button myself for testing) the display output and resolution switch automagically.  Not only that, but I can even suspend my machine again :)

I would have really hoped that Gutsy would bring this level of polish with it.  Maybe it did and I'm just completely inept, but I didn't find any mention of it working flawlessly in the first page of a google search, so I assume I'm not alone here. 

 
A fireplace blower retrofit
Written by Dan   
Friday, 09 November 2007

We have a Heatilator GNDC30 direct-vent fireplace unit in our house.  It's wired for a blower unit, but the builder didn't install it (which is pretty common).  Instead of paying someone to come out and stick one in, I decided to order the blower itself and give it a shot.

The blower I got was a non-OEM replacement for the manufacturer's FK21 fan kit.  I'm sure that the OEM kit has a bracket that holds the fan in place under the fire box, but this one did not.  It really only needs to sit under the firebox and shoot air up the back

Th e blower itself is just a small squirrel cage with an AC motor and a variable motor control.  The motor is a little too heavy, so it leans to one side if you don't hold it in place.  During test-fitting I noticed that not only does it lean to one side, but that the opening of the fan is larger than the slot that carries air up the back of the firebox.  I made a little box out of sheet aluminum and stuffed a roll of non-slip in the middle to give me a cutom-sized vibration-reducing block to hold the motor level.  The difference in duct sizing causes a lot of wind noise even at low speeds.  To remedy this, I made a little duct flap out of sheet aluminum to point the air appropriately.  Here are the pieces.  And the final result with the flap installed in the blower housing.

To further reduce noise and vibration, I cut another piece of non-slip to set the whole thing on once it's in-place.  I would tend to bet that the stock unit just mounts to the sheet metal and thus could potentially rattle.

Next, I just slid the whole thing into place in the back of the firebox, and put the little support box under the motor.

It's a little hackish (okay, maybe a lot hackish), but it is a retrofit.  Hopefully tonight we can test it out and see if it makes a difference in heating the living room :)

 
Libvirt-CIM: out in the wild
Written by Dan   
Monday, 05 November 2007

I'm happy to say that today the official announcement was made, which is the final step in bringing libvirt-cim out into the open.  I have worked for the last several months on this internally with a few other colleagues, intending to take it open at some point.

There is still a lot of work to do to get it into the key distros, expand its platform support, and work out all the kinks.  But it feels good to finally have it out in the wild after all this time! 

 
Garage door monitor
Written by Dan   
Friday, 02 November 2007

Taylor and I both seem to be completely incapable of remembering to close the garage door in all but the most simple arrival scenarios.  Okay, maybe it's me more often that not, but still, it's a problem.  Several times, we have gone to leave in the morning and found that the garage door is already open.  Being in such a dense neighborhood, this is also a point of embarrassment, not just security.

So, as I do whenever I need a part of my home automated, I went to SmartHome in search of a handy device
to help solve my problem.  I found some devices that attempt to close the door if you leave it open, but it seemed like user reviews were less than favorable.  I finally settled on this one from Chamberlain that just monitors the door and offers a solid green light when it's closed and a blinking red light when it's open.  I would prefer to have a buzzer attached to a timer to offer an auditory cue when the door needs checking, but it's a start.

Of course, I have considered hacking the device and putting a timer/buzzer in place.  Taylor doesn't like the idea of a hand-made project box being anywhere visible, although I think I might just give it a shot and see how "bad" it is.  I've also thought of making my own, using these neato serial RF transmitters and receivers I found, in combination with encoder/decoder chips.  However, I don't see any reasonable way to have multiple devices on different frequencies, which means I wouldn't want to waste 8 digital I/O channels on just the garage door.  Now I feel compelled to find something else to automate!

 
<< Start < Prev 1 2 3 4 5 Next > End >>

Results 19 - 27 of 38

© 2008 danplanet
Joomla! is Free Software released under the GNU/GPL License.