-
Products
JBoss Enterprise Middleware
Web Server Developer Studio Portfolio Edition JBoss Operations Network FuseSource Integration Products Web Framework Kit Application Platform Data Grid Portal Platform SOA Platform Business Rules Management System (BRMS) Data Services Platform Messaging JBoss Community or JBoss enterprise -
Solutions
By IT challenge
Application development Business process management Enterprise application integration Interoperability Operational efficiency Security VirtualizationMigration Center
Migrate to Red Hat Enterprise Linux Systems management Upgrading to Red Hat Enterprise Linux JBoss Enterprise Middleware IBM AIX to Red Hat Enterprise Linux HP-UX to Red Hat Enterprise Linux Solaris to Red Hat Enterprise Linux UNIX to Red Hat Enterprise Linux Start a conversation with Red Hat Migration services
Issue #12 October 2005
Features
- Adding encryption support to HAL: A user's experience with Fedora development
- Python programming on Linux
- Integrating your applications into the desktop, Part 1
- The state of Java on Linux
- Maintaining an autotools-enabled package
- Performance tuning with GCC, Part 2: Analyzing performance problems
- Using OProfile to analyze an RPM package build
- Remix culture comes to film at the Internet Archive
- Video: Red Hat and TSANet coordinate customer support
- Summit 2006: Not just country
- Video: Red Hat and BEA have no time for downtime
- Video: Red Hat Learning Services get real-world results
From the Inside
In each Issue
- Editor's blog
- Red Hat speaks
- Ask Shadowman
- Tips & tricks
- Fedora status report
- Magazine archive
- Contest
Feedback
Adding encryption support to HAL: A user's experience with Fedora™ development
by W. Michael Petullo
- Introduction
- HAL recognizes encrypted device
- gnome-volume-manager reacts to new encrypted device
- HAL recognizes dm-crypt device
- Conclusion
- About the author
Introduction
I was first introduced to the ideas behind D-BUS and the Hardware Abstraction Layer (HAL) during a presentation Havoc Pennington gave at the Free and Open Source Developers' European Meeting 2003. During his lecture, Havoc laid out the goals of his new D-BUS project. He also talked about the concept of what would become HAL. At the time, my experiences with Linux® hardware interfaces were limited to working with the Linux CD-ROM interface and other simple ioctl system calls. I did not realize the true value of HAL until I began seeing software that took advantage of the system. Built around the D-BUS and HAL technologies, recent GNOME distributions are able to interact very well with modern, dynamic hardware. NetworkManager, gnome-volume-manager, and hal-cups-utils have all been developed with HAL and under the mantra of making hardware "Just Work."
This article introduces the reader to how HAL may be extended to support new device types. Specifically, it discusses how HAL was modified to make it easy to use removable, encrypted devices from within the GNOME environment. An understanding of HAL's architecture and its usefulness should be the result. As a non-Red Hat employee, I demonstrate the willingness of the company to support volunteer development within the Fedora Project. HAL's source code may be found at http://cvs.freedesktop.org/hal/hal/ and is an important companion to this article.
The Hardware Abstraction Layer provides software developers with a consistent view of the devices attached to a system. The core of the system is a daemon that watches for new hardware and may be queried to determine the properties of a system's devices. Device properties are simply key/value pairs. David Zeuthen's Desktop and hardware configuration article provides a general overview of the HAL system. Get on D-BUS by John Palmieri introduces one to D-BUS.
On Linux, HAL ties into the hotplug system.
Most communication with the HAL daemon is performed using the D-BUS
API it provides. Policies exist that determine what actions the HAL
daemon will perform when a given device is attached to the system.
For example, a HAL device property with the key info.callouts.add
may be included in a HAL policy. This property's value is the path to
a script that is executed when the device is detected.
David Zeuthen, the primary maintainer of HAL, made a proposal for an encrypted disk system in December 2004. In his proposal, David outlined an addition to HAL that would detect an encrypted disk, prompt the user for a password, and then use that password to unlock the encrypted file system. The system would be built around dm-crypt (See sidebar), the encrypted disk mechanism that is supported by the Fedora Project. A diagram demonstrating David's architecture may be found in Figure 1, “HAL crypto architecture”.
After studying David's architecture, I decided that I had the experience necessary to help implement the system. I approached David on the HAL mailing list, and he accepted my offer of help. David was very willing to assist me as I became familiar with the HAL codebase.
David's original proposal called for the development of a system that stores encryption parameters on disk before the file system. This header could then be read by HAL so that HAL could decrypt the disk. David's proposal named this system Sesame. After some research, David and I identified the Linux Unified Key Setup (LUKS) as a candidate to replace Sesame. LUKS (see sidebar) stores encryption parameters, such as the cipher name and mode, as a plaintext header before an encrypted file system. After some experimentation, we decided that LUKS would be adequate and stopped work on Sesame.
HAL recognizes encrypted device
Once the LUKS header format was chosen, we were ready to start modifying HAL. When a removable disk is attached to a Linux system, the kernel identifies it and notifies the HAL daemon. To identify an encrypted disk, the HAL daemon must be able to recognize its LUKS header. This was the first modification to HAL that was required. The gnome-luks-format utility formats an encrypted file system with a LUKS header so that HAL will recognize it. Refer to Figure 2, “gnome-luks-format utility”.
The most important addition to HAL was a function named volume_id_probe_luks()
that is implemented in a new source file named luks.c. This function
looks at a volume and determines if it contains a LUKS header.
If such a header is found, the HAL daemon will set the
HAL daemon's usage variable to VOLUME_ID_CRYPTO, set the
volume.uuid property to the UUID read from the LUKS header, and set
its volume.fstype to crypto_LUKS. A similar change was necessary
in probe_volume.c. The set_volume_id_values() function was modified
to set the volume.fsusage property to
crypto. Figure 3, “View of an encrypted volume” shows
hal-device-manager displaying the properties
of an encrypted volume.
HAL required a few other minor modifications so that encrypted volumes could be identified. These were additions to various utility functions.
gnome-volume-manager reacts to new encrypted device
Now that the HAL daemon has the ability to identify a volume as
a LUKS device, it will publish the device's information using D-BUS.
However, before the device may be decrypted, a digital key must be
obtained. I chose to modify gnome-volume-manager, a daemon that
performs user-level actions on newly connected devices, to perform
this work.
As mentioned before, when the HAL daemon detects a new device,
it broadcasts the event using D-BUS. This message is picked up by
gnome-volume-manager, and eventually the process examines the device's
properties. The gnome-volume-manager process was modified to look at the
volume.fsusage property of the newly attached device.
If the value of this property is crypto, then the device contains an
encrypted file system, and gnome-volume-manager will
prompt the user for a passphrase.
Once gnome-volume-manager has obtained a valid passphrase, it must ensure that
the dm-crypt device is properly set up. Because gnome-volume-manager
generally runs with a user's privileges, it cannot perform this action
directly. Instead, gnome-volume-manager forwards the passphrase back to
the HAL daemon, which normally runs with root privileges, and asks the HAL daemon to set up
the dm-crypt device. gnome-volume-manager does this using the HAL daemon's new
methods interface.
Once the user provides a passphrase, gnome-volume-manager sends a
D-BUS message to the HAL daemon, invoking the HAL daemon's
Setup method. The message sent is equivalent to executing
dbus-send --system --print-reply --dest="org.freedesktop.Hal"
<UDI> org.freedesktop.Hal.Device.Volume.Crypto.Setup
string:<PASSWORD>.
The first version of HAL's method interface was announced by David Zeuthen in July of 2005. For the HAL daemon to provide a method such as Setup, two things are required. First, a device information file should define the interface for the method. Second, a script must implement the method. The HAL daemon will invoke the script when called upon to perform the corresponding method.
Device information files belong in a directory such as
/usr/share/hal/fdi/. The device information
file that defines the Setup interface can be found in Example 1, “Contents of 15-storage-luks.fdi”.
<?xml version="1.0" encoding="ISO-8859-1"?> <!-- -*- SGML -*- --> <deviceinfo version="0.2"> <device> <match key="volume.fsusage" string="crypto"> <match key="volume.fstype" string="crypto_LUKS"> <append key="info.interfaces" type="strlist">org.freedesktop.Hal.Device.Volume.Crypto</append> <append key="org.freedesktop.Hal.Device.Volume.Crypto.method_names" type="strlist">Setup</append> <append key="org.freedesktop.Hal.Device.Volume.Crypto.method_signatures" type="strlist">s</append> <append key="org.freedesktop.Hal.Device.Volume.Crypto.method_execpaths" type="strlist">hal-luks-setup</append> </match> </match> </device> </deviceinfo>
The implementation scripts are installed at the path listed in the same
device information file that defines their interface. HAL properties are
provided to the script as environment variables. The method's parameters
are read from stdin. The script named hal-luks-setup
implements the Setup interface and can be found in Example 2, “Contents of hal-luks-setup”.
read password LUKSSETUP=@SBINDIR@/luks-setup HALSETPROPERTY=@BINDIR@/hal-set-property if [ ! -f $LUKSSETUP ]; then echo org.freedesktop.Hal.Device.Volume.Crypto.SetupError <&2 echo Error setting up $HAL_PROP_BLOCK_DEVICE - $LUKSSETUP not found <&2 exit 1 fi if ! echo $password | $LUKSSETUP $HAL_PROP_BLOCK_DEVICE 2< /dev/null; then echo org.freedesktop.Hal.Device.Volume.Crypto.SetupError <&2 echo Error setting up $HAL_PROP_BLOCK_DEVICE - bad password? <&2 exit 1 fi if ! $HALSETPROPERTY --udi="$HAL_PROP_INFO_UDI" --key="info.callouts.remove" --strlist-pre="hal-luks-remove" 2< /dev/null; then echo org.freedesktop.Hal.Device.Volume.Crypto.SetupError <&2 echo Error setting info.callouts.remove <&2 exit 1 fi exit 0
It may seem odd that HAL reads properties from environment variables and parameters from stdin. David developed HAL's method interface while we were working on HAL's encryption support. For security reasons, parameters are read from stdin instead of the environment. On some flavors of UNIX®, users may view the environment associated with any process. Therefore, it is not safe to pass a passphrase between processes using environment variables. The stdin buffer provides a secure alternative.
After the HAL daemon receives a passphrase from gnome-volume-manager,
the process executes hal-luks-setup, providing HAL
properties in the script's environment and writing the passphrase to
the script's stdin buffer. The hal-luks-setup
script also adds the string hal-luks-remove to the device's
info.callouts.remove property. This ensures that the
dm-crypt device is properly removed when the device is disconnected.
HAL recognizes dm-crypt device
Once gnome-volume-manager and the HAL daemon are able to work
together to set up a dm-crypt device, only two issues remain. First,
dm-crypt devices are not like normal devices because it is unclear
what their parent device is. A USB drive's parent device is the USB bus.
On Linux, this relationship is made clear by sysfs. Less information is
provided for dm-crypt devices, and the HAL daemon must be modified to
discover some relationships on its own. Second, when the HAL daemon
process starts up, it must ensure that it processes previously existing
device mapper devices after all of the system's block devices have been
processed. If this ordering is not enforced, the HAL daemon will
not be able to identify key relationships when it starts. This process
is called cold-plugging and required the modification of
coldplug_compute_visit_device() in coldplug.c.
Modifications to blockdev.c allow the HAL daemon to discover the
relationship necessary to properly identify dm-crypt devices. The
blockdev_get_luks_uuid() function is a utility that determines the UUID
for the backing device of a dm-crypt device. Given a device file such
as dm-0, the function looks for the corresponding device in /dev/mapper.
When luks-setup creates a device in /dev/mapper, it names it using the
convention luks_crypto_12345678-9012-3456-7890-123456789012. Once the
appropriate device is found, it is trivial to read the LUKS UUID from
its filename. The blockdev_get_luks_parent() function now identifies
a dm-crypt device's parent by looking for a volume whose volume.uuid
property matches the UUID returned by blockdev_get_luks_uuid(). This
volume is the dm-crypt device's backing volume and parent. The property
volume.crypto_luks.clear.backing_volume is set to this
parent device. Figure 4, “View of a dm-crypt device” shows the properties associated with a dm-crypt
device that has been unlocked.
Conclusion
HAL provides a very robust system for managing devices on a modern computer. The system provides a clear way of notifying applications of the presence of new hardware. Along with D-BUS and the Linux hotplug system, HAL allows for a central location from which to define the policies that determine how newly attached devices are handled. HAL's new methods interface increases the system's flexibility drastically. Furthermore, the developers behind HAL, especially David Zeuthen, are very willing to provide guidance and help to individuals that wish to extend HAL. HAL clearly deserves its place at the center of many modern desktops and does much to accomplish the goal of making hardware "Just Work."






