With numerous recent laptops (including the X1), Lenovo not only changed the connector dimensions of their trackpoint (now called Super- or even Ultra Low Profile) now being incompatible with old ones, but they apparently also discontinued all variants of the trackpoint cap besides Soft Dome. That's a shame, since I'm a dedicated trackpoint-only user and I really hate Soft Dome. I'm more of a Classic Dome guy, since it's smaller in diameter (better for scrolling) and provides much more grip.

I didn't know how to help myself besides leaving my comfort zone (software) and trying to actually working with my hands. I kind of transformed my Soft Dome to something Classic Domey, and it works like a charm. Does it look ugly? Sure. But it performs exceptionally well and feels almost exactly as the Classic Dome - the grip is even better.

Update: The procedure also works for the X1 Yoga Gen3 (thanks to Ran for confirming). This patch is said to work. However, you can always go without a working patch file, see Plan B on how to proceed.

-

If you own a Lenovo X1 6th generation and want to use Linux, you're not going to be happy from the start. The entire range of hardware works splendidly and almost out of the box (let alone the fingerprint reader), but Lenovo decided to make one major change in the new UEFI firmware image. They removed traditional deep sleep (ACPI S3 sleep state) in favor of a new, Microsoft-driven sleep state called Windows Modern Standby, aka Si03. This sleep state doesn't fully turn off all components except for main memory, but puts the devices themselves into an ultra low-power state. This way, much like modern smartphones do, some devices can briefly wake up particular components of the system - most notably communication devices. The idea is, to have an always-connected feature, to e.g. download updates while sleeping or stay connected to a WiFi during sleep. This may or may not be preferable idea, but for me it is not.

On the Intel Core architecture, Linux doesn't deal with Si03 too well (as opposed to Intel Atom CPUs) and suspend energy consumption is around 4 watts on the X1, which is extremely high and won't even give you a single day of suspend time.

Luckly, together with great help from a few hackers from the Arch Linux forums (especially Ranguvar for sorting things out and fiji-flo for the working patch), we could establish a workaround. The idea is to patch the DSDT tables, a part of the ACPI firmware, written in ACPI machine language (a freakish place). Using that patch, sleep energy consumption drops from 4 to 0.15 watts on my machine.

If you follow this guide, no one is responsible for any damage to your hardware or any other kind of harming your machine. However, we didn't hear a single report of such cases as of now, and it works fine for all of us who tried it and reported to us.

The following steps should guide you to how you can do it yourself.

Reboot, enter your BIOS/UEFI. Go to Config - Thunderbolt (TM) 3 - set Thunerbolt BIOS Assist Mode to Enabled. It has also been reported that Security - Secure Boot must be disabled.

Note: Hunk 6 may fail due to different specified memory regions. In this case, simply edit the (almost fully patched) dsdt.dsl file, search for and entirely delete the two lines reading solely the word "One". You can look at hunk 6 in the patch file to see how the lines above and below look like if you're unsure.

Plan B: If this does not work (patch is rejected): It has been the case, that certain UEFI settings may lead to different DSDT images. This means that it may be possible that the above patch doesn't work at all with your decompiled DSL. If that is the case, don't worry: Go through the .patch file in your editor, and change your dsdt.dsl by hand. This means locating the lines which are removed in the patch and removing them in your dsl. The patch contains only one section at the end which adds a few lines - these are important and make the sleep magic happen.

Make sure that the hex number at the end of the first non-commented line is incremented by one (reading DefinitionBlock, should be around line 21). E.g., if it was 0x00000000 change it to 0x00000001. Otherwise, the kernel won't inject the new DSDT table.

Recompile your patched version of the .dsl source.

$ iasl -ve -tc dsdt.dsl

There shouldn't be any errors. When recompilation was successful, iasl will have built a new binary .aml file including the S3 patch. Now we have to create a CPIO archive with the correct structure, which GRUB can load on boot (much like initrd is loaded). We name the final image acpi_override and copy it into /boot/.

We yet have to tell GRUB to load our new DSDT table on boot in its configuration file, usually located in /boot/grub/grub.cfg or something similar. Look out for the GRUB menu entry you're usually booting, and simply add our new image to the initrd line. It should look somewhat like that (if your initrd line contains other elements, leave them as they are and simply add the new ACPI override):

initrd /acpi_override /initramfs-linux.img

Note: You will need to do this again when your distribution updates the kernel and re-writes the GRUB configuration. I'm looking for a more automated approach, but was too lazy to do it so far.

Moreover, GRUB needs to boot the kernel with a parameter setting the deep sleep state as default. The best place to do this is /etc/default/grub, since that file is not going to be overwritten when the GRUB config becomes regenerated. Simply add mem_sleep_default=deep to the GRUB_CMDLINE_LINUX_DEFAULT configuration option. It should look somewhat like that:

GRUB_CMDLINE_LINUX_DEFAULT="quiet mem_sleep_default=deep"

Reboot.

If everything worked, you shouldn't see any boot errors and the kernel will confirm that S3 is working. The output of the following commands should look the same on your machine:

In most setups, simply closing the lid will probably trigger deep sleep. If you're using a systemd-based distribution (most of which are), you can also verify if it works on the command line:

$ systemctl suspend -i

Once again, many thanks to Ranguvar for the great collaboration on the Arch forums, and to fiji-flo for managing to hack the first fully working patch. Also, to whomever wrote the article on DSDT patching in the glorious Arch Wiki. And the entire Arch community in general, you're wonderful.

Is it 2017 already? Time for a update for the Beamer template. Widescreen is supposedly the new thing, so here we go. The base template has been updated to reflect the corporate design somehow, see yourself. Headline is now smaller to allow more content to be placed. A lot of new macros have been added through the years (almost none of them documented in a sane way). There's support for slides with code listings, triple-pages, tabular cell colors, algorithms, custom color names, crazy bubbles, easily aligned equations and lots of fixes.

Moreover, it now uses regular OTF and TTF fonts by default which are shipped with the archive (SIL licensed only) due to xelatex replacing pdflatex.

The current version 4 of the template can be downloaded here. It includes a simple showcase, in both PDF and TEX format as well as the actual template source. It's easy to use and modify, so grab it and make your slides smile.

The x11log source has been slightly updated, and its repository has moved from launchpad to Github. There probably won't be custom Ubuntu package builds in the near future, although I'll do my best to keep the /debian/ subdirectory reasonably up to date. However, x11log is now available via the Arch User Repository.

Latex beamer is a wonderful way for hacking slide-sets. However, using only the original beamer package, the source-code for slide-sets can become quite extensive and therefore hard to navigate through.

That's why I wrote a small tex template, uncreatively called FH Beamer Template. It's super-easy to use and will save you a lot of time, not building tons of nested begin/end environments and many other things. Many heavily-used tasks usually required for professional slide-sets are provided via shortcuts, by defining new commands and macros (usually prefixed with \fh) to make your life easier with Latex.

The current version 3.0 of the template can be downloaded here. It includes a simple showcase, in both PDF and TEX format as well as the actual template source. It's easy to use and modify, so grab it and make your slides smile.

A few months ago, I decided to enroll for OSCP certification, by scheduling the Penetration Testing with Kali Linux (PWK) course. After a spending a considerable amount of time in Offensive Security's hack-labs, the day of the ming-bending 24h-exam has come. The exam was actually harder than expected, but required nothing one would not have came along during PWK - which, however, also included the really tricky hosts to own.

I hacked almost the entiry lab network in a rather short time period due to extraneous circumstances, but during that time frame, I basically had no life. It was exciting, challenging, eye-opening. OSCP follow a superb certification methodology previously unseen in the landscape of security certifications. OffSec did an outstanding job designing the lab environment, and I will surely continue that path, longing for OSCE sooner or later.

In today's Forschung Spezial (research section) of Austrian newspaper DerStandard, journalist Katharina Mittelstaedt published an interview with me concerning the current state of my research, and concerns it may not help struggling with. The article was published in today's regular print edition and has recently been made available online.

This is the perfect love story. We met 15 years ago, and at was love at first sight. As of now, there's basically no text processing task I wouldn't prefer to accomplish with Vim: From editing configuration files, typesetting LaTeX documents to regular programming. I can't think of an editing approach more efficient than Vim's modal concept.

Over the years, my .vimrc configuration file has reached a point where I wanna share it with you. The file is well-structured and is supposed to be self-explanatory. Feel free to do with it whatever you want.

You can download the entire .vim directory here, which also includes the .vimrc (don't forget to symlink or copy it directly into your home directory).

Either copy .vim/vimrc to your home and prefix a dot, or better symlink it via ln -sf .vim/vimrc .vimrc

Open Vim and have fun!

To avoid errors, you should also install the exuberant-ctags package, or comment the corresponding line in your Vim configuration file.

There is a built-in Vim cheat-sheet available with the Ex command :Cheat - it will open a new Vim vertical split window showing some really tricks and hints regarding Vim commands. Here is an excerpt from the cheat sheet (which has nothing to do with the vimrc):

Ubuntu 12.10 (Quantal) packages of the x11log keylogger are now available on my Launchpad PPA. It finally ships with a Unix manpage and provides better automatic recognition of the primary X11 $DISPLAY to log keystrokes from.

Skype is a huge mess. It's proprietary, the GUI client is poorly designed and only available with QT, and there is no native 64bit Linux build. Implementation specifics concerning crypto routines make it virtually impossible to reverse engineer the code and develop an open client. Therefore, no true alternative client exists, although open-source support (or at least freely usable libs) would have been announced years ago.

However, unfortunately, Skype has become a widely used de-facto standard software among instant messaging and VoIP. Here are the instructions for running Skype on a headless Linux server, make it interact with Bitlbee and use Skype directly from within Irssi (or your favourite IRC client), specifically for an Ubuntu Server 64bit installation.

The workflow at a glance: Irssi connects to Bitlbee, which connects to Skype4Py (a Skype gateway/DBUS translator), which connects to the Public Skype API of the local Skype binary, which actually communicates with the Skype servers. In order to run Skype headless, we run the Skype binary in a virtual Xserver using xvfb-run. You won't need X11 or Xorg to do this.

Get bitlbee from your distribution or build it from source. Skype-support is built-in as of Bitlbee version 3+, but some distros don't yet provide the new versions in their repositories. You either can build it from source (recommended), or you use your distro's version and additionally install the bitlbee-plugin-skype package separately, which provides Skype support as plugin for older Bitlbee versions.

Get Skype4Py and build it from source. Decompress, cd to the Skype4Py directory an run sudo python setup.py install

Get the original Skype binary package. I used the dynamic package, so you're more independent from your distro. I suggest you decompress the archive to /opt/skype/.

64-bit users only: Make sure you have ia32-libs installed. Currently, only one required library isn't included in ia32-libs, namely libphonon4. In order to get this working, get the libphonon Ubuntu package, open in archive-manager and only extract the libphonon.so.4 library to your Skype directory (e.g. /opt/skype), without actually installing the package.

.

2. Configure Skype4Py

Place the following code in ~/.skyped/skyped.conf, and change username and password. The password is generated on the shell via echo -n yourskypepassword|sha1sum:

In your open VNC window running skype, a DBUS message should appear, asking for permission for Skype4Py to access the public Skype API of your client installation. Accept it. Once this has been done, you can quit VNC client and server, you won't need them anymore.

4. Have fun chatting

That's all. You don't necessarily have to use screen, although I recommend it. For using Skype through Bitlbee, make sure the native Skype binary (using xvfb-run) and Skype4Py (the skyped binary) are running before you try to connect in Bitlbee.

Update: You can omit all VNC-related stuff if you modify your Skype config manually. Open ~/.Skype/username/config.xml, go to node config->UI->API and change the Authorizations line to <Authorizations>Skype4Py</Authorizations>, save and exit.

Lately, I was presenting a paper (being part of my PhD thesis) at IEEE-AESS in Rome, participating at the IEEE Security & Privacy Special Track on Oct 4th, entitled A robust watermarking scheme for large databases. It incorporates a novel approach towards watermarking relational databases in a blind, robust and reversible manner, and supporting a requirement inevitable especially for large databases: Incremental watermarking. The full paper will be available via this very post sooner or later. The paper is available via IEEE Xplore.

XML made its way since almost 15 years now. And although seeminly everybody is using XML nowadays (mainly because the W3C recommendation), I didn't meet any developer forced to use XML without completely messing around with its excesses.

This is reasoned in the way XML was sold to us, as the ultra-simple human-readable allrounder in terms of data storage. The following things are particularly fun:

Messing around with incompatible parsers, APIs, implementations, etc

Messing around with empty strings, whitespaces and NULL values

Messing around with technologies you did not want to use/learn/mess up, like XPath, XQuery, XSLT, XProc, XInclude, and so on... some of these get really complicated, even to do simple stuff.

Messing around with encodings: Try to store an XML document on your favourite filesystem in a different encoding than what appears in your XML header. And don't even think of your clients...

XML canonicalization is "ready" for over a decade, but good luck getting into it.

Tons of applications nowadays use XML for their configuration files. Not only that key=value pairs would suffice in estimated 95 percent of all cases, but they can get you in considerable trouble: Try to versionize your XML configuration (hint: added/deleted/renamed attributes are especially fun to deal with). Try to always store your configuration pretty-printed (configs are supposed to be editable, aren't they?).

XML Namespaces. I don't even comment those. Don't get me wrong, namespaces are a good idea in theory, but the common usage in real-life make things more difficult and complex.

Who needs obligatory entity references in the wonderful world of Unicode? Utilizing different character sets (like iso8859-1 aka latin1) is pointless as processors are not required to support them.

And in case you think you know the XML ecosystem, I'd refer to the landscape by Kenneth Sall (note that this is from 2003):

To keep a long story short: The XML ecosystem suggests apparent simplicity, but offers enormous internal complexity, which will make you cry. It is like a Kraken with dozens of tentacles. If you still don't believe me, at least believe Linus.

A few months ago, I bought an Orange Dual terror guitar amp, which is an amazing small-scale 30 watts dual-channel tube amp. Although the sound is utterly powerful and aggressive, it lacks an FX loop feature which is crucial for my playing.

Some 20 minutes of research later, I found out that Jule Amps do custom mods for Orange amps, including the Dual Terror, and also do a posteriori FX loops. However, the homepage says: Because of the design of the Dual Terror, the effects loop must go on either the FAT or the Tiny Terror channel. It will not work with both. What a pity.

I subsequently contacted the guys at Nepomuk Amps, a small Austrian company which builds excessively high-end handmade guitar amps and cabinets. These guys not only added a high-quality FX loop to my Dual Terror, but they even managed to get the thing done on both channels, using a relay which switches according to what channel is currently active. Moreover, they modified the channel-selector foot switch to support dual-switches, whereas one is (like originally intended) for channel switching, and one for activating and deactivating the FX loop circuit, regardless of which channel is active.

On the top right corner, you can see they even squeezed in an additional tube for the loop return, which is an amazing thing due to the small size factor of the amp. This gives the amp zero signal loss using the effects loop, while still being 100% analogue.

Did you ever get confused reading chord names like F#m6add9 or Ab°sus2sus4? Well, me too. This is why you should have a look at some basic theory on how guitar chords are constructed in a very easy way.

Let's get started

First of all, a basic chord is a triad - just three notes played simultaneously. Since most scales consist of 7 tones (to the next octave, selected from the 12-tone chromatic scale), we can easily say what tones (or steps) are needed for a particular chord (e.g. a basic major chord consists of steps 1 3 5, so for C major, this would be C E G).

There are only four basic triads, all other chords are derived from:

Major: 1 3 5 Minor: 1 b3 5 Augmented: 1 3 #5 Diminished: 1 b3 b5

Extensions

Next, we extend these basic chords. The most common extensions are to the 7th, 9th, 11th and 13th step, resulting in chords like C7 or A9. (Note: The '_' character in the following listings is a placeholder for the basic chord name). We distinguish between the Dominant (e.g. C7), the Major (e.g. Cmaj7) and the Minor (C7) chords here.

_7: 1 3 5 b7 _maj7: 1 3 5 7 _m7: 1 b3 5 b7

So Cmaj7, e.g. would result in C E G B. In the same way, we can also construct chords with the 9th, 11th and 13th tone, but note that these extensions must necessarily include the 7th step as "carrier" anyway (this is why the 7 isn't separately noted in the chord name). On the other hand, if extending to 11, playing the 9th is optional, and if extending to the 13th, playing 9 and/or 11 is optional.

_9: 1 3 5 b7 9 _11: 1 3 5 b7 (9) 11 _13: 1 3 5 b7 (9) (11) 13

Even more extensions

Of course, we can do these extensions with all four basic traids, namely major, minor, augmented and diminished. Diminished chords are usually noted with a ° (or 'dim'), while augmented chords are noted with an + character (or 'aug'):

Alterations are chords with altered notes, which directly emerge from the chord's name. An example would be Cm7#5 - obviously a Cm7 chord, with a #5 instead of 5. Alterations are usually self-explanatory and can alter arbitrary notes, but the most common ones include b5, #5, b6, b9, #9, #11, b13.

Moreover, there are add-chords which actually add a notes instead of altering one. Some examples would be:

_add9 _(9)

Here, the given notes will always be played in addition to the original chord - anyway, those additional notes are mostly enharmonic anyway.

Conclusion

With those few rules, you can construct virtually any chord on your guitar. Anyway, you may want to be careful with exotic constructions (e.g. via alterations), since they may put your chord out of key (which doesn't necessarily mean that it doesn't sound good). Enjoy!

The amazing newest model of the famous Boss GT series has recently been released by Roland, called the GT-100. It's not functional on Linux out of the box, so ALSA has to be tweaked in order to get it working as USB in/out sound interface which also supports MIDI.

The chipset itself isn't entirely new, but the USB device ID changed, which is the reason for Linux not readily recognizing the floorboard.

Get your kernel source and head to the ALSA USB headers and edit the quirks table for USB interfaces:

cd /usr/src/linux-source-`uname -r`/sound/usbvi quirks-table.h

According to lsusb -v its device ID is 0582:014d, so we simply add a new entry to the end of the tables header:

The very last step is only needed if you want your newly patched module during the boot process. Note: There is a very interesting OSS project called FxFloorBoard, already offering a development preview for managing the GT-100, although it's not quite working with the new device at this time. I'm really looking forward to this piece of software in the near future. Enjoy!

This is somehow offtopic - but if you're a guitarist, you may consider having a look.

Do you really know your fretboard? Interestingly, there are plenty of awesome guitarists out there who really know how to pull the strings - playing fast, playing accurate, using exotic techniques. But when it comes to theory of harmonics, incredibly many guitarists throw the towel (at least, that's what I have experienced). Most of them have heard of (and played) different modes, but when you jam around and tell them "Okay Fred, give me some F sharp Locrian lick around this riff", you may run into troubles.

Beyond tapping, sweeping and shredding, your very foundation is the fretboard. As a guitarist, therefore, you should really know your fretboard. Luckily, it's really easy to gain knowledge of all different Modes, how they are played, where you find specific notes, and how to play your favourite keys and modes on the 4th, 9th or 15th fret - or basically, wherever you want.

All you need to do, is to learn the following 7 finger position diagrams by heart. Yes, this may take a few days, but it's a small price to pay compared to what you get.

Note: The fret numbers below the guitar tab (and the corresponding mode, given in square brackets next to "Nr") describe C major. This is only for easier understanding - if you know the finger positions, you can play any mode you want.

The 7 diagrams represent the church modes. The modes are independent from certain frets, but once you memorized them you'll be able to play every key you can imagine. The modes are (ignore the square brackets at first):

When you start playing the guitar, you usually start with C Major scale on the lower end of the fretboard (including open strings). Talking about church modes, this would be E Phrygian. Why E you ask? Shouldn't a Major scale be Ionian?

It's simple: When you play [Note][Mode] (like E Phrygian), then [Note] is always the very first note you play. However, if you play in C Major scale (C Ionian), beginning with the open E string, you simply don't start playing a C note - hence, if you wanna play C Major while starting with an open E string, you naturally don't play C Ionian (since you begin with an E) or E Ionian (since this would be E Major then), but E Phrygian.

Why Phrygian? We now know: If you play C Ionian (C Major), you begin with a C. E.g., you start with the 10th fret on the E string (see Fig. 1, No 7). If you wanna reside in C Major scale, but your new solo requires you to play, let's say, 4 frets higher, the first note you play can't obviously be a C again (actually, it's an E). Since the keynote changes, the Ionian scale in Fig. 1 would bring you out of C Major. Therefore, the finger-positions change - to the church mode which starts 4 frets (or half-tones) higher. Look at Fig. 1 and viola: It must be Phrygian (E Phrygian).

Every mode (except exotic ones) is basically picking 7 tones from the chromatic scale (which consists of 12 half-tones, which are one full octave), and choosing specific intervals. The intervals for the Major scale (or Ionian) is

full-full-half-full-full-full-half C D E F G A H C

Alternative explanation: So the half-tone steps are between 3/4 and 7/8. If you play C Major and you begin with C, everything's perfectly fine - you're playing C Ionian. But if you wanna play C Major and begin with E, things change. If you play E and follow the scale above, you get E Major. If you want to reside in C Major, you have to change the intervals to F-H-F-F-F-H-F (which is, shifting the intervals one note). So the half-tone steps for C Major (if you start with E), are at 2/3 and 6/7. This is exactly what we call Phrygian (look at the square brackets in Fig. 2!).

Implicitely, if you play C Major starting with the open E string, and play that scale throughout one whole octave, you will run through every single church mode sequentially before again returning to Ionian, where naturally the first note you play is C again.

Beginning with fret 0, we play E Ionian. If we want to begin with fret 2, we play F-sharp Dorian. If we start with fret 4, we play G-sharp phrygian, and so on.

Enough theory: All you need is here..

Look again at the figure below. Note, that there are no fret numbers - everything you need to know, are the relative finger positions. This way, you can place your finger on any fret you want playing #1, and you can be sure you're playing in the scale of your keynote (which is, the first note in the Ionian mode, and every note in Fig. 1 having a round dot nearby).

If you want to reside in that scale, but play on a different fret, choose the correct finger position diagram, and you're done.

Once you know the diagrams by heart, you always know what scale you are playing in just by recognizing the keynotes (dots in the Figure).

As scientist, there is no way around LaTeX. There is a good reason for this: LaTeX does your typesetting in a professional manner and is easy to use. However, especially when designing a slideset, I'm not actually comfortable with countless begin/end nestings like:

\begin{frame}[allowpagebreak] \frametitle{Catchy title in here} \begin{columns} \column{0.7\textwidth} \begin{itemize} \item Char-count for this slide: 400 \end{itemize} \column{0.3\textwidth} \begin{figure}[H] \centering \includegraphics[width=14cm]{someimage.png} \caption{So much work to include an image} \label{fig:1} \end{figure} \end{columns}\end{frame}

This is why I always do my own LaTeX templates. Hereby, you don't have to reinvent the wheel for achieving quite some success towards saving a lot of time: Simply wrap environments you use very often (and which require a lot of paperwork) into your own LaTeX commands.

The title already tells you everything. I got highly disappointed by virtually every blog engine I could find, so I wrote my own one, keeping it simple and stupid. 150115 85 lines of Perl it is, no more, no less.

Years ago, I implemented a prototype for an X11 keylogger, providing the advantage of not requiring root privileges to run. I decided to give the code another chance, did some refactoring work and implemented a couple of nice and hopefully useful features, including local logging to a file, and remote logging to a TCP port and to a webserver via HTTP GET requests.

It now has its own project on Launchpad where you can fetch the source and report bugs. Moreover, there are already prebuilt Ubuntu packages on one of my Launchpad PPAs for simple installation. The code is licensed under GPLv3.

Delta-Xi finally offers a DKIM public key DNS record, and adds an X-DKIM header signature to each outgoing message for easy verification.

Why? Mainly because GMail sucks. Their spam-filtering is acceptible, but completely intransparent, as quite everything concerning Google. For some reason, messages sent from DX are always put into the spam-folder on Gmail boxes without any comprehensible reason. (Note: Okay, maybe. There was a time, about 2008-2009, when the DX MTA entirely prevented accepting mails from or transmitting mails to GMaill, because I simply don't want to support their evil data-mining; maybe I annoyed Google? ;-).

Trustworthy mail providers take one of several ways in order to at least outline reasons for spam suspicion (e.g. via X-headers), but not Google.

Finally, the sources of the Open AS Communication Gateway have made their way into public space. The proect aims to be an SMTP gateway for spam- and virus-scanning, which is entirely managed via a pretty web-frontend. It supports recipient maps, RBLs, greylisting, email-based quarantining, and much more.

After two years of absence, I'm now back. I have been employed by an IT security company in Austria, where I took responsibility for one of the two main product lines: an SMTP gateway, mainly dealing with anti-spam technologies.

Finally, I decided to quit and go back to university where I got a job offer as Senior Scientist, and will subsequently work on my PhD.

The good news is, that the company's CEO has willingly decided to make the whole project open-source. The release date is soon to come, keep an eye open.

The thesis which served as basis for my Master's Degree in Networks & Security is now freely available for download here, and has been entitled Strong interface-independent authentication enforcement through commidity storage devices under GNU/Linux. The project's source-code is downloadable via this link, and represents the latest snapshot from the git repository. These documents and codes are delivered as-is.

An article from the DX maintainer about data recovery in Linux systems has recently been released in the german hakin9 print magazine 01/2009, covering file-system reconstruction, forensic imaging, string-analysis, file-carving, slack observation and more.

The direct successor to USBAuth (pam_usbauth) is called pam_usbng and represents a complete rewrite with many enhancements. It's much easier to get the module up and running, and offers new nice features. You may have a look to the project page here.

As MySQL versions 4.1, 4.2 and early builds of 5.0 are vulnerable to a simple but devastating bug in the source code of the database server for which I couldn't find any exploit, here's a short description how to code it on your own.

I decided to take a look in hardening MySQL on Unix-like systems. The resulting paper includes some information about securing the operating system behind, secure local databases and network traffic by using cryptography and some other hints. The paper can be downloaded here.

Cryptographic routines and algorithms often rely on randomness, which is an essential fundament, especially in key-generation applications. This paper discusses how pseudo and real random numbers may be generated and how threatening unconcerness due to lack of entropy may seriously risk security. In addition, a brief overview of well-known and massively-used RNGs like Linux /dev/random are presented.

Most keylogging solutions deserve to be called as root-user; Userspace-Loggers as well as Kernelspace-Loggers. This simple piece of code shows you how you can use X11 to get a nice workaround for keylogging X-sessions.

There are generally two types of keyloggers under Linux. Firstly, the kernelspace keyloggers. Writing a kernelspace logger isn't that easy, and deserves skills in writing kernel code. Morover, running a kernel module still needs root access to the machine.

The second type of loggers are userspace keyloggers. Normally, the logging is done via io-Calls and catching interrupts; which can also be only done as root.

That's the reason why I tried to find a way to catch keys without root access and found a wonderful lovely hack (or "workaround"), making fun out of the mighty Xlib.

For some reason, the XGrabKey/XGrabKeyboard functions won't result in more than BadAccess Errors of Xorg. Fortunately, Xlib provides a function called XQueryKeymap(), which puts the whole keyboard status into a large 32-Byte character vector.

The code basically reruns the XQueryKeymap call infinitely and checks if changes have been recognized; if this is the case, check which key has been pressed, get the keycode, get the keysym and print out a human-readable representation of the key.

You may browse the source here. The project has been revised and moved to Launchpad. Get it here. Renewed in 2011.

An article about secure authentication systems has recently been released in the hakin9 print magazine, also covering USBAuth, which has been renewed and now also supports additional PIN-based hashed authentication for even more security.

Also a Gentoo E-Build is finally available, thanks to Hades for these patches. In about one month, I'll release a paper about Randomness in Cryptography, the needs and behaviours of strong cryptographic algorithms which rely on true randomness and how stary-eyed RNGs can defeat strong encipherment.

Due to contract issues, Delta Xi unfortunately had a downtime for about 6 days. These problems affected not only the HTTP/S service, but also SVN and the USBAuth space. Several updates are to be announced. Thanks to ph030, who's ideas about using USBAuth with non-usb memory devices (e.g. SD), some bug tracking and a Gentoo ebuild will flow into the main code within the next 3-4 weeks.

USBAuth has grown very fast, thank all users for reports, testing and feedback. I've put a lot of security-concerned stuff into the code, which makes USBAuth quite secure and ready for every-day use. The documentation, as well as the source and a Debian package of release 0.3 can be obtained from the USBAuth project site. Update: This information is obsolete, the project is now called usbng and available here.

Crypto smartcards, as provided by the FSFE are a really great idea - passwordless authentication everywhere and for everything. But there are two big disadvantages: First, cryptographic smartcards can't be just "buyed and configured", but you have to choose a company providing them, and trust them.

Secondly, you need a smartcard reader - most laptops don't have a built-in smartcard reader, so you can't use them everywhere you want.

Here, the PAM plugin pam_usbauth.so gets the middle way: Whenever you have plugged in your local storage device (primary designed for USB-storage devices, but suitable for nearly every device), you'll get authenticated passwordless for every service (or PAM-suporting program) you would like to use.

The package also provides uapasswd, a client program which makes writing the configuration file and setting up an existing USB device much easier than doing it manually.

All configuration options (valid users, devices where keys are stored, etc) are defined in /etc/usbauth.conf. You can use every storage device, not only USB (e.g. SC, MC of CF cards). It's strongly recommended to set up a 1024k partition for the key(s) - nevertheless, the rest of your device is still accessable to use them as storage.

It can be obtained from svn.delta-xi.net, or via svn co svn://delta-xi.net/svn/pam_usbauth, and has to be compiled and installed via "make". Have fun! Sorry, SVN has been deactivated.

Notice: USB authentication isn't as secure as using smartcards, because USB storage devices doesn't have a built-in logic - so don't use it in really sensitive environment.

Passwords are a quite debatable way of authentification. Passwords can be sniffed and widely used with other services, if the same passwords are used on more than one service.

Biometrical identification is another form of authetication, but not quite suitable via remote access. An excellent standard is defined by s/Key. Read how to use this on Linux boxes...

s/Key defines how one time passwords are implement within a standard. The classical skeyinit command doesn't exist on Linux out of the box, but on this point, the OPIE (One-time password is everything) implementation of s/Key takes place.

First of all, we need OPIE. Debian etch currently provides opie-server as well as opie-client, which are both to be installed on the system.

The main idea is the following: The administrator creates an s/Key seed. By creating the seed, a password is used which builds the direct basis of the afterwards generaded one-time-passwords. When logging in via SSH remotely, the server tells the user which password numbers of which seed is needed for the current login.

The one time passwords are about six quite-readable English words, generated from the seed and the password number. So, we have to options at the client:

We can calculate the password by ourselves on the client. This option has two disadvantages: First, we need the seed-password given while initializing OPIE on the server, and second, of course we need a client with OPIE installed.

The second option is that the administrator gives out a list of passwords (let's say, 100), and we just give SSH the password it wants to hear.

Finally we have to tell SSH to use our OTPs, by editing /etc/ssh/sshd_config on the server: ChallangeResponseAuthentication yes

Now let's login:

# ssh user@host.tldopt-md5 498 v38294 ext, Response:

SSH now tells us, which password it wants to hear. If we havn't printed out a password list, we can easily recalculate the password by typing the following command on a client (it's not relevant on which machine we do this; this can even be done on palmtops of cellphones):

$ opiekey 498 v38294

OPIE will ask for the password seed, given at the server, and finally returns the password string, something like this:

498: NICK FAY SEND BERT ALTO BANE

Type this password at the SSH login, and you're done. Capitilization is not relevant!

If you're the admin of the server and doesn't want to give the seed password to the users, just print out a list of passwords, counting down from 499:

$ opiekey -n 100 498 v38294

498 just tells OPIE the password-number to start with. This list can safely be given to your clients which need secure SSH accounts.

Syslogd is the friend of all administrators. No serious admin would miss taking a look in /var/log/* consistantly. Reading and working out log files is a very time consuming process, and even more complicated when administrating multiple server boxes.

This mini-howto shows you how to centralize your logs.

A typical Unix system has a wide range of important log files, such as:

The file /etc/syslog.conf (or something similar) defines which facilties under which priorities are logged to which files on the system. But what if you have to administrate 15 server machines, running Postfix, Bind, vsftpd, Apache and so on? It's not an easy thing to come up with all the logs all the time.

One possible solution to this is centralized logging. So we have a logging server box, which takes all the logs of the other machines which are centralized and possibly compressed and encoded.

To do this, just rerun syslogd with the "-r" argument are tell you firewall(s) to pass through port 514, which syslogd listens for incoming logs.

On your client systems, you may want to change your syslog.conf to this:

*.* @logging-server

which tells syslog to send all logs to your server. But be careful where your syslogd is actually running, it should by no means be reachable from the outside world! Otherwise anyone could send data to port 514.

You may also make the box more secure by ssh-tunneling the logging traffic, even if it's only about the internal network.

The above example would route all the logs to your server, which of course is not the best option: Kernel-specific logs for example shouldn't be somewhere else than on the machine which actually runs the kernel.

Additionally, it may be a good idea to save the logs locally as well as remotely. Diff and/or sha512sum could help you to make sure everything is ok. Crackers often try to delete logs corresponding to their attack, but it's quite hard to do this on a remote machine. Always compare both versions if the same data integrity is given.

One and a half decades before, firewalls have had an exciting hype towards the whole Internet community. A few years later, numberous companies tried to get customers by releasing (partitally really obscure) security systems by calling them "Intrusion detection", then, again a few years later, "Intrusion prevention" and nowadays also prevention is not enough, but the software is called "Intrusion Reaction".

However, something like a host-based intrusion detection system can be established via a small FreeBSD tool called Mtree.

Mtree is a tool, which checks the filesystems integrity by watching for changes in the main system. If this is done regulary, a couple of rootkit-systems can be detected easily.

Mtree builds a database of what-ever filesystem you want, and stores the directory tree with all common file attributes and a hash-key of the objects in a file. This file is being checked against changes in succeeding mtree calls.

freebsd-mtree -c -K cksum -p /bin > /var/log/mtree_dump_`date`

This command build the tree for the /bin directory. Checking mtree against the whole root filesytem isn't the best point to start, because many files will change regulary, especially in /home and /var.

However, if treed against /etc, /bin/, /sbin, /usr, /boot and probably /lib you have a collections of fs-dumps which are not to be changed by anyone else than root.

By typing

freebsd-mtree < /var/log/mtree_dump*

the current filesystem is checked against the dump, and all changes are printed to the console. You can easily have a look on what's going on on your system, especially if some nasty tool has changed non-suspicious-looking programs like ls or ps, which are commonly abused by rootkits.

It's really worth a try, putting al mtree dumps in a SSH-tunneled SVN repository, which are automatically crond-checked nightly - you can even let mtree mail you all changes. Easy, isn't it?

I really missed to provide an SSL-certificate for HTTPS usage of Delta Xi. You can finally use the more secure access, via https://www.delta-xi.net.

Here is a short introduction how to create your own certificates and use them with Apache2.

What do you need? Most the distributed packages of Apache2 already have an SSL module installed. If not, just type ln -sf /etc/apache2/mods-available/ssl.load /etc/apache2/mods-enables/ssl.load && ln -sf /etc/apache2/mods-available/ssl.conf /etc/apache2/mods-enabled/ssl.conf.

Now you Apache should be ready to use certificates, which are to be created now. Make sure you have openssl installed on your system.

With these commands, we generate our server's private key as well as a certificate request for the server. This request is to be signed by an certificate authority. For our purpose, it's OK to sign the certificate by ourself.

openssl req -new -x509 -days 1460 -key server.key -out server.crt

Ok, your certificate is ready to use. We finally have to tell Apache2 to use it with HTTPS support. Just find the Virtual Host you want to be capable of SSL and add a few entries. The result will probably look something like this:

PGP is a wonderful tool. It implements asymmetric cryptography and allows everybody to send mails all over the world, in a very secure way. But asymmetric algorithms doesn't fit very well on users who don't have the knowledge about public and private keys.

I recently developed a tool called SMC, which is a proof-of-concept realization that secure mailing isn't limited to asymmetric cryptography...

The idea of asymmetric cryptography is simple: Let there be two keys instead of one; one for encoding and one for decoding data. When communicating with tools like PGP or GPG, every participant has his own keypair. One of those, the public key, is published on a server, comparable to a phonebook.

If Alice wants to mail Bob, she retrieves Bob's public key and encrypts the message with it. After encrypting, no one is able to decode the message except for Bob, because he's the only one who has the corresponding private key.

Simple idea, not-so-simple tool. Most people using e-mails, doesn't even know that a public key is (not worth mentioning how to create a keypair). This led me to trying out a symmetric mail client.

SMC is a tool, which realizes completely symmetric and secure mailing across the Net. It can be used with existing mail addresses and doesn't require the creation of any keys by hand.

The first mail sent, is a so-called invitation mail, where the recipient is asked if the he wants the sender to be able to add him to his contacts. Behind this invitation-process, the mail includes data, encoded with the SMC mail protocol.

In short, Diffie-Hellmann key-exchange is used to get the key to both participants on an insecure channel. An possible attacker Eve who is listing all the time, won't be able to crack the password. This can be mathematically proven due to the extremely compex problem of solving descrete logarithms.

When Bob responds to the invitation email, both parties are able to calculate the same 512bit key.

Further, each SMC-encoded message is secured by the Rijndael algorithm, the current Advanced Encryption Standard, proven by NIST. Beyond this, each message includes something like a symmetric digital signature, done by HMAC - a procedure which concatinates the plain text message with the key and computes a mathematical 160 bit one-way function (SHA).

This means that SMC can definitely proove (1) who has sent the message, and (2) that the message is integre. So, the sender can't claim that he didn't send the mail because he's the only one with the corresponding key. Besides, no one can modify the mail when it's on the Net - otherwise it will be detected and deleted.

The source is written in Perl for scientific use on the Johannes Kepler University of Linz. Enjoy!

You're sitting in front of your box, but the screensaver is on because you're not actually working on it (even admins show the need for non-unix human requirements). In that case, just code your own keyboard LED handling routine, and let you what's going on on your system.

LEDs are present on virtually all keyboards. Especially the Scroll-Lock LED is commonly unused nowadays, so it's a good point to start hacking here.

When using all three LEDs, you're able to let the LEDs indicate eight different states (2 to the power of 3). But even when using just one diode, it's possible to indicate quite important system status messages - like in/outgoing traffic, or newly arrived IM messages.

The following code is a hack for X11/xorg, because most systems have X installed (otherwise you'd have to set the LEDs for every TTY). Before trying to compile, make sure you have libX11 and libXtst installed (including development files).

The program itself just fakes the X-server by simulating a key event from the keyboard, which has actually not been pressed.

To the simple code: We have to get a pointer to our X display at first. Then we start an infinite loop, where every LED (Capslock, Scrolllock and Numlock) is being activated for 200ms. Every LED call is to be done twice, one event for key-pressed and one for key-released. As a result, the three LEDs will change their status in a knight-rider like style.

If you want to be informed when ICQ messages arrive, the easiest way is to just figure out where to configure how to play sounds with your IM client. Psi as well as Licq for example offer options, which allow you to select an application to start when certain events occur (e.g. message received). Now just point this event-handling routines to your LED app.

Of course you can also make tcpdump check your router for new packets and inform your application which will change the LED status according to what tcpdump said.

There is quite a wide range of keyloggers for Win32/64 operating systems, OSS as well as commercial ones. This fact differs on Linux boxes, but some administrative tasks deserve logging keyboard inputs (or at least, make them much easier). Here you'll read how to code your own logger.

To log your keyboard inputs you have basically two different options: Programming in userspace or in kernelspace. Writing kernel modules isn't that hard, but the kernel space provides much more (and mostly previously unseen by normal programmers) techniques for advanced programming.

Therefore I'll focus on userland programming. The basic idea is to grab the keyboard hardware I/O ports and copy everything which is buffered there. The results won't be ASCII characters like 'a' or 'z', but the kernel internal representation of different keys: The keycodes. Keycodes are numerical integer values, beginning with zero. Every key on your keyboard (except some strange multimedia functionalities, possibly) has its own keycode representation. This representation is more or less the same on every keyboard, irrelevant which language is offered.

Some keyboards provide special keys like the common fn-key on laptops as well es multimedia keys. Most of them also return keycode values, but nevertheless it's possible that no keycode is passed to the kernel when pressing these keys because the implementation of what to do when the key is pressed is done directly in the hardware (mostly seen on laptops).

As a result you need something like a conversion function, which does the mapping between keycode and the key which is meant (these differ, in dependence on linguistic layout of your keyboard). In my solution, the mapping is done by keymap.h which contains only one function (decode_key()). The use of a decode function is more a dirty hack than an industrial strength implementation, because every keyboard layout has to be coded and recompiled, so if you intend to use a keylogger in a more professional way you might want to write something like a config file interpreter, reading the keycode maps and their key mappings on different keyboards from an ASCII file.

Now let's have a look on the code. About line 28, we're trying to get the permission to read from the keyboard ports. We'll need two of them, the keyboard status port (0x64) and the port where the keys are sent to (0x60). These port numbers (ok, to be exact, we're talking about registers) are not Linux specific, but depend on Intel compatible architectures - so don't expect this to run on PPC. Note that we'll only get these permissions if we're starting the tool as root.

About lint 40, the main loop is defined. This infinite loop is executed every SLEEP_TIME milliseconds (1 by default), otherwise the routine would be called far too often. If a key is pressed, we'll grab the keycode (key = inb(P_KB)). You may notice that we only grab the keycode, if the keyboard status register returns 20 - that means that no other special keys are pressed (e.g. CTRL). If the code doesn't work for you that way, just comment out this if-statement and every combination will be logged. Before writing this code to our logfile, we need to check if the same keycode has been called shortly before, otherwise we'd spam the logfile exessively when pressing a key for more than a few millisedonds.

Finally, when writing to our log file, it needs to be flushed because the fclose() is outside our infinite loop (which isn't a programming style you should prefer, of course ;-). Now have fun logging your keys!

"Grand challenge" defines problems which are, at least theoretically, solvable with todays computational capacities - but not in a reasonable amount of time. Therefore, massivly paralleled processor systems are used to compute how atomic bombs distribute particles and get the weather forcast for tomorrow (and the day after tomorrow, and the day after the day after ...).

Programs are normally not SMP capable by dafault, you have to tell the program which processor has to do which work. The main challenges in this programming style are briefly shown here.

When writing programs which should be using multiple processors, the POSIX and ANSI library standards for Unix won't give you enough information how to tell the system which part of the program should run on which processor. The resource of choice is now an implementation library of OpenMPI, which would be e.g. MPICH or LAMPI. The following code segments will show how to work with MPICH.

First of all, you need to install the MPICH library and development headers for your favoured distribution.

Besides the necessary libraries MPI comes with two important executables: mpicc and mpirun. All programs should be compiled with mpicc, which is something like a precompiler for gcc. The applications are run with mpirun to coordinate the program structures with the processors. If programming on a single processor machine, mpirun forces to simulate multiple processors with using multiple processes.

The first step is to call MPI_init(&argc, &argv), to initialize the MPI environment with the given arguments to the program (which does not replace the standard main function). While coding, you don't necessarily have to know on how many processors the final program will be running on, therefore the function MPI_Comm_size(MPI_COMM_WOLD, &size) will retrieve the number of processors we're running on, and MPI_Comm_rank(MPI_COMM_WORLD, &rank) will determine the number of the actual CPU, the program is running on.

The most important thing is that the processes can communicate to each other, which is done by so-called message passing. There are quite a couple of functions for message sending and receiving, but the most commons are:

*data: Pointer to the data we want to send.count: Count how many times the given datatype size should be transfered (usable for arrays, e.g.).MPI_datatype: This would be for example MPI_INT, MPI_FLOAT, etc.destination_processor: The number of the processor (returned by MPI_rank().tag: This is just an additional functionality to separate messages from others; should be an integer.MPI_COMM_WORLD is defined after calling MPI_Init() and just determines the right processor space, so to say.

What I'm doing here is simple: All processes (we could do this easily so that the algorithm isn't limited to four processors, of course) send their number to the master processors, initially the zero-ranked CPU. The master checks which is the lowest value and resends the global minimum to all processes.

Most people ask why they should use raw sockets nowadays. The answer is: There is no reason. At least, for most programming purposes. On the other hand, raw sockets offer a wonderful method for writing own packets of OSI layers 3 (network) and 4 (transport).

Writing sniffers, scanners, injection tools as well as TCP connection resetters isn't difficult, like shown in this mini-howto.

When programming POSIX sockets, you normally force to use SOCK_STREAM for TCP connections or SOCK_DGRAM for stateless UDP packets. However, there are severel reasons not to use these protocols.

When debugging TCP connections, also SOCK_STREAM won't give you information about layer 4 headers, because the kernel will decompile received packets and is only willing to return the payload. This means, that also sniffer programming deserves (at least) SOCK_RAW.

Besides SOCK_STREAM and SOCK_DGRAM, there are two more options available: SOCK_RAW and SOCK_PACKET.

SOCK_RAW allows you to build your own IP- and TCP/UDP packets. SOCK_PACKET again deepens the OSI model, providing the ability of writing layer 2 (data link layer) packets. Because these are not routable, it's far less interesting.

Let's have a look at SOCK_RAW. The following source code will show you how to implement a minimalistic sniffing tool, capturing TCP connections:

This code would also work when using SOCK_STREAM, but the buffer we'll printing won't have the TCP header information within.

The next step will be to create our own IP-based packets. The following code will realize a program which takes source- and destination IP addresses, and tries to send RST packets at predefined ports to the given host. This is useful for TCP connection interruption.

Who needs graphical instant messaging? Shelladdicted users prick up your ears - get rid of GUI IMs and let an FPS-like console do the work for you.

When Quake 1 was released, an incredibly new feature took place in modern FPS games, which only Unix geeks have used before: The gaming shell. A popup-based shell-like environment, fading from the top of the screen, but not covering the main FPS viewing scene to provide a fast, flexible and wonderfully versatile tool for changing about one million gaming options.

Many sequencing games have duplicated this concept but (although beloved by everyone) nearly no Unix nerd has ever thought about using a popup shell in an Unix environment. I finally found tilda, a really amazing tool which does exactly what it is called to be - the tilde key (which can be remapped) is thought to show a shell immediately.

When studying the currently available Linux ICQ client programs, you won't find the solution you might have been searching for. Particular ones have a disgusting GUI, are based on obnoxious libs or just have a lack of features. With mICQ, you have a full-featured replacement for nearly-every IM protocol ever invented. So why don't use micq + tilda and make your instant messaging habits be supported by your own desktop shell?

Installing Linux on a laptop with getting all features to work isn't always a bed of roses. This howto will show you how to install and configurate a perfectly working Debian box, shown by example on a Sony Vaio TX3 notebook.

After taking a look on MPlayer, I decided to have an eye on VLC, the OSS media players which is more frequently used in Win32-systems than MPlayer, although both are available on a couple of platforms.

When browsing the source for possible overflow vulnerabilities, the programmers of VLC didn't make it hard to find an overflow .. they explicitely found 'em themselves.

The VLC sources of revision 0.8.6a contain exactly 167 sprintf() calls. When I openend src/extras/dirent.c at first, I briefly checked the upcoming calls, and noticed two sprintfs() with overflows possible.

Shortly afterwards I noticed that I don't even have to search on my own, like line 150 told me:

Again, the app tries to get the absolute pathname... Should filesystem's programmers nowadays probably unevent the wheel by not allowing directories at all? Application-level programming would be too easy.

I recently discovered a (previously unknown?) buffer overflow vulnerability in the mplayer sources. It's hopefully not enough to execute homebrewn code, but can still crash the application.

The overflow relys on Win32 (either native or via cygwin), when Real-Media codecs are used. Because the Real-Media codecs are proprietary closed-source, the application has to load the corresponding library to decode the v/a-stream correctly.

To do this, the right path to the codecs has to be set. In get_path.c, MPlayer calls the set_path_env() function, which declares a tmppath char array, in the size of 2*MAXPATH + 1, because two different paths (called "realpath" and "win32path") are copied in the tmppath array.

The upcoming problem is that those both paths have to be devided by a semicolon character to get recognized by the OS correctly. If both paths have the size MAXPATH, the last free byte of the array is used by the semicolon, so we implicitly don't have space left for \0 termination, leading to the segmentation fault.

As the code says, win32path is set by a cygwin built-in function called cygwin_conv_to_full_win32_path(), which takes WIN32_PATH - a define which is set when mplayer compiles (check ./configure, about line 6055). This path is translated to a "real" win32-path, if given in POSIX. The cygwin function also converts a relatively given path to an absolute one, but doesn't check if the second argument (the non-const string, win32path) has enough bytes to fill.

Of course it is, but isit the most efficient way to branch? Are you sure why the following code works?

return y=!!x;

Get a few information about the almighty If-Statement...

If-branches, one of the thing nearly every programming language has to implement. If-statements make use of the brachning system, the current CPU architecture provides (well, not all CPUs do, but virtually).

Unfortunately, for CPUs it's much harder to realize and execute jumping than simple arithmetic, or even better, bitwise operations. Have a look at the introducing code:

Well, still we branch. More skilled C/Java/Perl-programmers would make use of the ternary operator:

int compare(int x, int y, int z) { return (x==0) ? y : z;}

These operators save time, because the compiler (normally) doesn't realize this as an normal if-statement, but although executes branches. Have a look at the following code:

int compare(int x, int y) { int a[] = {x,y}; return a[x==0];}

This code substitues the branch, usually done by an if-statement, by just performing a comparison (x==0). The clue is that comparison operators can only return true or false since a comparison naturally only defines two states of results - it can be the same or not the same.

In other words, the code won't work with more than two variables, although we can check against something other than zero. However, the point is we finally managed to quit using jumps, but we still rely on defining an array. Let's go a step further:

int compare(int x, int y){ return y=!!x;}

The above code also works with only two variables. The way this works, is the following: We want to compare x and y, and return true if both are the same and false if they are different. The first negotiation of x makes sure that only true or false (in fact 0 or 1) is returned. At this base, we again negotiate the negotiation - what we get is true if x was a positive integer and false if x was zero. Using if's, the code would be:

int compare(int x, int y){ if(x==0) y = 1; else y = 0; return y;}

However, this only works with two variables, and only with binary return values. If you need a compare-function not using branching at all, with all three parameters of any positive value, here's a quite nice piece of code working perfectly: