home of the madduck/ blog/ feeds/
madduck's linux.com posts

The following blog posts appear on linux.com. Please visit my main blog page for all my posts.

Linux.conf.au 2010 has come to an end and I am looking back at an intense week of conferencing. A big shout out to the organisers for their excellent work. I think LCA (as well as DebConf) just keeps getting better every year. This does not at all discredit previous organisers, because they were the best at their times and then passed on the wisdom and experience to help make it even better in the following year.

The week started off with the DistroSummit, which Fabio and I organised. Slides are forthcoming, as I failed to get them off the speakers right after their talks — it's interesting how stress levels and adrenaline can cause one to forget the most obvious things. This is where experience comes in. I'll be there again next year, I hope, to do things better.

The theme of the day was cross-distro collaboration, and we started the day a little bit on the Debian-side with Lucas Nussbaum telling us about quality assurance in Debian, alongside an overview of available resources. We hoped to give people from other distros pointers, and solicit feedback that would enable us to tie quality assurance closer together.

Next up was Bdale Garbee who talked about the status of the Linux Standard Base. While I am really interested in such standardisation efforts, I realised during his talks that I had considerable difficulties paying attention because as organiser of the conference, I had all sorts of other things occupying my thoughts.

I proceeded to tell the audience — the room was mostly filled throughout the day with an estimated 40–50 folks, and I'd say about half of them stayed throughout, while the other half came in and left the room between talks. I could not get the projector to work with my laptop after the upgrade to Kernel Mode Setting, and thus used the whiteboard to give a brief introduction to vcs-pkg.org, talk about the current state of affairs, summarise the trends in discussions around patch management and collaboration, give an outlook of what's up next, and solicit some discussion.

Sadly, just like during Bdale's talk, I found myself worrying over the organisation of the day, rather than actually taking in most of the discussion. Fortunately, others have written about the most important points, so I defer to them.

Michael Homer then told us about GoboLinux's Aliens system, which is a way to integrate domain-specific packages with distro-specific package maintenance — e.g. how to get APT to handle CPAN directly, or how to let YUM manage Python packages. The ensuing discussion was interesting, and we carried it over to the next slot, because Scott, the next speaker, was stuck in traffic. To summarise briefly: scripting languages have a lot of NIH-style solutions because it works for them, but these are a nightmare to distro packagers. One symptom of the status quo is that complex software packages like Zimbra are forced to distribute all required components in their installation packages, which make distro packaging, quality assurance, and security support even harder. I don't think we found a solution, other than the need for further standardisation (like the LSB), but the road seems to be a long and windy one.

Laszlo Peter introduced the audience to SourceJuicer, a new build system used by OpenSolaris. The idea is that contributors submit packages via a web interface, kicking off a workflow incorporating discussion and vetting, and only after changes have been signed-off are packages forwarded to auto-builders and eventually end up in the package repository. This is very similar to upload ideas I've had a while ago, which I've started to (finally) implement. Unfortunately, SourceJuicer seems very specific to OpenSolaris, as well as non-modular, so that I probably won't be able to reuse e.g. the web interface on top of a Debian-specific package builder.

After the break, Dustin Kirkland stepped up to tell us about his user experience of Launchpad. Unfortunately, I found his talk a bit too enthusiastic. Launchpad undoubtedly has some very cool features and ideas, but it's just one of the available solutions.

The dicussion of Launchpad also dominated the next talk, in which Lucas Nussbaum told us about the Debian-Ubuntu relationship. While his presentation showed that the relationship was improving (Matt Zimmerman made the point that there are rather many relationships, rather than one relationship), I was a bit disturbed by the comments of Launchpad developers in the room, ranging from "Debian is declining anyway" to "Just use Launchpad if you want to collaborate with others and not go down". There was a slight aura of arrogance in their comments which tainted my experience of the otherwise constructive discussions of the day.

Overall I had a great time. Debian and Ubuntu made up the vast majority of attendants, with only a handful of representatives from other distros present. I wonder why that would be. One reason might be that around 70% of LCA attendants declared themselves Debian or Ubuntu users, and so there weren't many other distros around. Another might be that I still haven't spread the word enough. Let's hope to do better next year!

Thanks to all the speakers. We may have organised the day, but you made it happen and interesting!

Slides and recordings of the talks will be linked from the archived website when they become available (yes, the archive page does not exist yet either).

Update: Jelmer informed me that the people who spoke up against Debian during and after the Launchpad talk were not officially affiliated with Launchpad. It's a shame that this negatively reflected upon Launchpad for some of the attendees (not just myself).

Posted Sat 06 Feb 2010 05:55:32 CET Tags:

If you deal with SMTP servers, you probably know swaks, the "Swiss Army Knife for SMTP". Great tool for anything related to sending mails.

Today, I found its counterpart for receiving mails:

python -m smtpd -n -c DebuggingServer localhost:1025

that binds a no-frills SMTP server to the specified socket which does nothing but talk SMTP to connecting clients and print "received" messages to stdout, e.g.:

---------- MESSAGE FOLLOWS ----------
Date: Fri, 22 May 2009 21:21:40 +0200
To: madduck@madduck.net
From: madduck@lotus.madduck.net
Subject: test Fri, 22 May 2009 21:21:40 +0200
X-Mailer: swaks v20061116.0 jetmore.org/john/code/#swaks
X-Peer: 127.0.0.1

This is a test mailing

------------ END MESSAGE ------------

Sweet, very sweet!

NP: Porcupine Tree: Signify

Posted Fri 22 May 2009 21:29:32 CEST Tags:

xmodmap has long been the only way to modify the keyboard map of the X server, short of the complex configuration daemon approaches used by the large desktop managers, like KDE and GNOME. But it has always been a hack: it modifies the X keyboard map and thus requires a baseline to work from, kind of like a patch needs the correct context to be applicable.

Worse yet, xmodmap weirdness required me to invoke it twice to get the effect I wanted.

When the recent upgrade to X.org 7.4 broke larger parts of my elaborate xmodmap configuration, I took the time to finally ditch xmodmap and implement my modifications as proper xkb configuration.

Background information

I had tried before to use per-user xkb configuration, but could not find the answers I want. It was somewhat by chance that I found Doug Palmer's "Unreliable Guide to XKB configuration" at the same time that Julien Cristau and Matthew W. S. Bell provided me the necessary hints on the #xorg/irc.freenode.org IRC channel to get me started.

The other resource worth mentioning is Ivan Pascal's collection of XKB documents, which were instrumental in my gaining an understanding of xkb.

And just as I am writing this document, Debian's X Strike Force have published their Input Hotplug Guide, which is a nice complement to this very document you are reading right now, since it focuses on auto-configuration of xkb with HAL. The default xkb configuration comes with a lot of flexibility, and often you don't need anything else.

But when you do, then this is how to do it:

Installing a new keyboard map

The most basic way to install a new keyboard map is using xkbcomp, which can also be used to dump the currently installed map into a file. So, to get a bit of an idea of what we'll be dealing with, please run the following commands:

xkbcomp $DISPLAY xkb.dump
editor xkb.dump
xkbcomp xkb.dump $DISPLAY

The file is complex and large, and it completely went against my aesthetics to simply edit it to have xkb work according to my needs. I sought a way in which I could use as much as possible of the default configuration, and only place self-contained additional snippets in place to do the things I wanted done differently.

setxkbmap and rule files

Thus began my voyage into the domain of rule files. But before we dive into those, let's take a look at setxkbmap. Despite the trivial invocation of e.g. setxkbmap us to install a standard US-American keyboard map, the command also takes arguments. More specifically, it allows you to specify the following high-level parameters, which determine the sequence of events between key press and an application receiving a KeyPress event:

  • Model: the keyboard model, which defines which keys are where
  • Layout: the keyboard layout, which defines what the keys actually are
  • Variant: slight variantions in the layout
  • Options: configurable aspects of keyboard features and possibilities

Thus, with the following command line, I would select a US layout with international (dead) keys for my Thinkpad keyboard, and switch to an alternate symbol group with the windows keys (more on that later):

setxkbmap -model thinkpad -layout us -variant intl -option grp:win_switch

In many cases, between all combinations of the aforementioned parameters, this is all you ever need.

But I wanted more.

If you append -print to the above command, it will print the keymap it would install, rather than installing it:

% setxkbmap -model thinkpad -layout us -variant intl -option grp:win_switch -print
xkb_keymap {
  xkb_keycodes  { include "evdev+aliases(qwerty)"       };
  xkb_types     { include "complete"    };
  xkb_compat    { include "complete"    };
  xkb_symbols   { include "pc+us(intl)+inet(evdev)+group(win_switch)"   };
  xkb_geometry  { include "thinkpad(us)"        };
};

There are two things to note:

  1. The -option grp:win_switch argument has been turned into an additional include group(win_switch) on the xkb_symbols line, just like the model, layout, and variant are responsible for other aspects in the output.

  2. The output seems related to what xkbcomp dumped into the xkb.dump file we created earlier. Upon closer inspection, it turns out that the dump file is simply a pre-processed version of the keyboard map, with include instructions exploded.

At this point, it became clear to me that this was the correct way forward, and I started to investigate those points in order.

The translation from parameters to an xkb_keymap stanza by setxkbmap is actually governed by a rule file. A rule is nothing more than a set of criteria, and what setxkbmap should do in case they all match. On a Debian system, you can find this file in /usr/share/X11/xkb/rules/evdev, and /usr/share/X11/xkb/rules/evdev.lst is a listing of all available parameter values.

The xkb_symbols include line in the above xkb_keymap output is the result of the following rules in the first file, which setxkbmap had matched (from top to bottom) and processed:

! model         layout              =       symbols
  [...]
  *             *                   =       pc+%l(%v)

! model                             =       symbols
  *                                 =       +inet(evdev)

! option                            =       symbols
  [...]
  grp:win_switch                    =       +group(win_switch)

It should now not be hard to deduce the xkb_symbols include line quoted above, starting from the setxkbmap command line. I'll reproduce both for you for convenience:

setxkbmap -model thinkpad -layout us -variant intl -option grp:win_switch
xkb_symbols   { include "pc+us(intl)+inet(evdev)+group(win_switch)"   };

A short note about the syntax here: group(win_switch) in the symbols column simply references the xkb_symbols stanza named win_switch in the symbols file group (/usr/share/X11/xkb/symbols/group).

Thus, the rules file maps parameters to sets of snippets to include, and the output of setxkbmap applies those rules to create the xkb_keymap output, to be processed by xkbcomp (which setxkbmap invokes implicitly, unless the -print argument was given on invocation).

It seems that for a criteria (option, model, layout, …) to be honoured, it has to appear in the corresponding listing file, evdev.lst in this case. There is also evdev.xml, but I couldn't figure out its role.

Attaching symbols to keys

I ended up creating a symbols file of reasonable size, which I won't discuss here. Instead, let's solve the following two tasks for the purpose of this document:

  1. Make the Win-Hyphen key combination generate an "en" dash (–), and Win-Shift-Hyphen an "em" dash (—).

  2. Let the Caps Lock key generate Mod4, which can be used e.g. to control the window manager.

To approach these two tasks, let's create a symbols file in ~/.xkb/symbols/xkbtest and add two stanzas to it:

partial alphanumeric_keys
xkb_symbols "dashes" {
  key <AE11> {
    symbols[Group2] = [ endash, emdash ]
  };
};

partial modifier_keys
xkb_symbols "caps_mod4" {
  replace key <CAPS> {
    [ VoidSymbol, VoidSymbol ]
  };
  modifier_map Mod4 { <CAPS> };
};

Now let me explain these in turn:

  1. We used the option grp:win_switch earlier, which told xkb that we would like to use the windows keys to switch to group 2. In the custom symbols file, we now simply define the symbols to be generated for each key, when the second group has been selected.

    Key <AE11> is the hyphen key. To find out the names of all the other keys on your keyboard, you can use the following command:

    xkbprint -label name $DISPLAY - | gv -orientation=seascape -
    
    

    I had to declare the stanza partial because it is not a complete keyboard map, but can only be used to augment/modify other maps. I also declared it alphanumeric_keys to tell xkb that I would be modifying alphanumeric keys inside it. If I also wanted to change modifier keys, I would also specify modifier_keys.

    The rest should be straight-forward. You can get the names of available symbols from keysymdef.h (/usr/include/X11/keysymdef.h on a Debian system, package x11proto-core-dev), stripping the XK_ prefix.

  2. The second stanza replaces the Caps Lock key definition and prevents it from generating symbols (VoidSymbol).

    The important aspect of the second stanza is the modifier_map instruction, which causes the key to generate the Mod4 modifier event, which I can later use to bind key combinations for my window manager (awesome).

    A note about VoidSymbol (as opposed to e.g. Hyper L as the symbol to be generated by the caps lock key: As far as I understood, Control, Shift, and Caps are necessary symbols, but all the others (including Alt and Meta) are actually just symbols and independent from any other function of the keys. In particular, modifier_map seems completely independent of the symbols. As many applications use Meta/Alt, you won't get around generating those, but I don't know of applications that use Super or Hyper, so I prefer not to generate them.

The easiest way to verify those changes is to put the setxkbmap -print output of the keyboard map you would like to use as a baseline into ~/.xkb/keymap/xkbtest, and append snippets to be included to the xkb_symbols line, e.g.:

"pc+us(intl)+inet(evdev)+group(win_switch)+xkbtest(dashes)+xkbtest(caps_mod4)"

When you try to load this keyboard map with xkbcomp, it will fail because it cannot find the xkbtest symbol definition file. You have to let the tool know where to look, by appending a path to its search list (note the use of $HOME instead of ~, which the shell would not expand):

xkbcomp -I$HOME/.xkb ~/.xkb/keymap/xkbtest $DISPLAY

You can use xev to verify the results, or just type Win-Hyphen into a terminal; does it produce ?

By the way, I found xev much more useful for such purposes when invoked as follows (thanks to Penny for the idea):

xev | sed -ne '/^KeyPress/,/^$/p'

xev can also tell you which modifiers are in effect. For that, you have to hold the modifying key down, press another key, and take note of the state field, which is the hexadecimal sum of all modifiers in effect. The ones I found are:

0x0001 Shift
0x0002 Caps
0x0004 Control
0x0008 Alt
0x0010 NumLock
0x0030 Mod3
0x0040 Mod4
0x2000 Mode_switch

Thanks to Marius Gedminas for the hint.

Rules again, and why I did not use them in the end

Once I got this far, I proceeded to add option-to-symbol-snippet mappings to the rules file, and added each option to the listing file too. A few bugs [[!debbugs 524512 desc=later]], I finally had setxkbmap spit out the right xkb_keymap and could install the new keyboard map with xkbcomp, like so:

setxkbmap -I$HOME/.xkb [...] -print | xkbcomp -I$HOME/xkb - :0

I wrote a small script to automatically do that at the start of the X session and could have gone to play outside, if it hadn't been for the itch I felt due to the entire rule file stored in my configuration. I certainly did not like that, but I could also not find a way to extend a rule file with additional rules.

When I looked at the aforementioned script again, it suddenly became obvious that I was going a far longer path than I had to. Even though the rule system is powerful and allows me to e.g. automatically include symbol maps to remap keys on my Thinkpad, based on the keyboard model I configured, the benefit (if any) did not justify the additional complexity.

In the end, I simplified the script that loads the keyboard map, and defined a default xkb_keymap, as well as one for the Thinkpad, which I identify by its fully-qualified hostname. If a specific file is available for a given host, it is used. Otherwise, the script uses the default.

Posted Fri 08 May 2009 07:36:25 CEST Tags:

Do you use GPG or PGP to sign or encrypt your emails and/or files?

This is a reminder to those who answered yes: make sure you have a revocation certificate, as well as backups of your private/public key pair, ideally in multiple safe locations.

It's always a good idea to keep backups. But what is more important with GPG is the revocation certificate. That's your emergency brake. If someone ever gains control over your key, this is the only way for you to minimise (further) abuse of your key and your identity.

However, even a revocation certificate won't be able to prevent all abuse, by nature of the design of the GPG Web of Trust. You also need to exercise utmost care in protecting your key and making sure third parties cannot gain control over it. Do not keep it on machines you don't trust, and make sure to use a safe, non-guessable passphrase!

With GnuPG, generating a revocation certificate is as easy as this; replace $KEYID with your 8 or 16 digit hexadecimal key ID:

gpg --gen-revoke $KEYID > $KEYID.revoke.asc

and store it away. Do not import it until you need to revoke your key!

In my case, the process was this; lines requiring my input are prefixed with an arrow ('→'):

  sec  1024D/330C4A75 2001-06-20 Martin F. Krafft <mail@martin-krafft.net>

→ Create a revocation certificate for this key? (y/N) y
  Please select the reason for the revocation:
    0 = No reason specified
    1 = Key has been compromised
    2 = Key is superseded
    3 = Key is no longer used
    Q = Cancel
  (Probably you want to select 1 here)
→ Your decision? 1
  Enter an optional description; end it with an empty line:
→ > 
  Reason for revocation: Key has been compromised
  (No description given)
→ Is this okay? (y/N) y

  You need a passphrase to unlock the secret key for
  user: "Martin F. Krafft <mail@martin-krafft.net>"
  1024-bit DSA key, ID 330C4A75, created 2001-06-20

  ASCII armored output forced.
  Revocation certificate created.

  Please move it to a medium which you can hide away; if Mallory gets
  access to this certificate he can use it to make your key unusable.
  It is smart to print this certificate and store it away, just in case
  your media become unreadable.  But have some caution:  The print system of
  your machine might store the data and make it available to others!

I then printed the file, put it in the safe, stored it on a removable disk and hid it away. Even though I exercise great care over my key material, I can now sleep better at night, knowing that I can at least minimise any damage done by an attacker who compromises my key.

Also, that way I can make sure to declare unused keys as such, since there is no other way to revoke a published key for which you've lost the private key or forgotten its passphrase. I've left such traces in my past and wish I had known what I was doing at the time: A8FA196E, C22D1C01, 1EF0975C.

This is your chance to do it right. Make yourself a revocation certificate now (along with backups)! And always exercise care and keep your key secure.

NP: Mono: One More Step and You Die