Postfix authentication isn't general enough

I want to set up Postfix SMTP authentication so I have two different passwords to authenticate with: one main one that gives me access to both SMTP and IMAP, for my own use with trusted clients, and a separate one that gives me the ability to send messages via SMTP only, and that will not work for IMAP.

The reason is that gmail will not let me send mail as an auxiliary mail identity through its own SMTP servers anymore, and requires a username and password to authenticate itself to my own SMTP servers. Since I’m unhappy giving gmail my main email password, I decided a second gmail-specific password would be a good idea.

This turns out to be difficult.

Postfix will authenticate either against Dovecot, or using Cyrus-SASL. Cyrus-SASL can talk to a number of things, and one of them is a SQL database, but it won’t let you use crypt for the passwords stored in the database. That’s a showstopper there. The other alternative is to back Cyrus-SASL with PAM, but that involves figuring out PAM. Painful, and another link in the (already long) chain: Postfix → Cyrus-SASL → PAM → Database.

I’ve asked on the Freenode #cyrus channel about the possibility of getting a patch for crypted SQL-database passwords accepted, but no replies yet.

There are a couple of patches out there that get close to what I want; the best (but still not quite right) is this one. It needs work to support other crypt schemes and to extract salt properly.

Perhaps I will give in and learn how to configure PAM…

Update: At the suggestion of the kind people on #cyrus, I’ve decided instead to set up a separate account on my email server for gmail to log into, and simply forward any mail that’s delivered there (by accident, presumably) to my main account.

Thoughts on Common Lisp

I happened across a few notes I made back in October 2011 regarding my experience of using Common Lisp for the first time.

2011-10-14 14:23:55 tonyg

Yesterday I hacked on ~/src/cmsg/lisp.

Network programming wasn’t so hard to get a basic socket listener up and running.

Streams are horribly broken though. No clean separation of encoding from binary I/O. Swank vs raw Slime streams differ, which led to some interesting issues when experimenting with my I/O code interactively. flexi-streams help take away some of the pain, but it’s still pretty awful.

The loop macro is neat. Feels like comprehensions. Comprehensions are pleasant in Erlang and Haskell, and I remember enjoying SRFI-42, but Racket misses them1.

The lack of proper tail recursion is HORRIBLE. Forces some very nasty code. E.g. the tagbody thing.

That everything-is-an-object is GREAT. I wish Racket had this.

Racket’s match is awesome. Totally awesome. Common-lisp pattern matching is in PARLOUS state. There’s nothing remotely close to as nice as Racket’s match. There is no common standard.

Exceptions on end-of-stream simplify the programming of network layers.

2011-10-19 08:06:10 tonyg

The multiple-values implementation is kind of nice, especially in those places where it enables subtle design touches like using floor to get both quotient and remainder at once. That particular example appeals to me also for its mnemonicity: using truncate instead of floor gives you the other variant2.

  1. It seems clear to me today that I had been overlooking Racket’s for, for/list, for/hash etc. I’d still like to see something more general that abstracts away from the variations in these, though.

  2. (the difference is the same as the difference between R6RS’s div/mod and div0/mod0, respectively).

Minimart and Network Calculus at (fourth Racketcon)

Here’s me giving a talk about my research on Minimart and Network Calculus at (fourth Racketcon) on the 20th of September, 2014:

Downloadable Prebuilt Binary RabbitMQ Plugins

From time to time, I make binary snapshot downloads of the RabbitMQ plugins that I have developed. You will be able to find the most recent downloads from this page. I sign the downloadable files with my public key.

Older builds for previous versions of RabbitMQ may be available but not linked above; check the directory itself for a full list.

How to Run the RabbitMQ Tests

RabbitMQ includes a suite of functional tests, as well as unit tests for each of its components. It’s not immediately obvious how to run the functional test suite, but fortunately, it’s straightforward.

You will need:

  • a Java JDK
  • Ant
  • Erlang
  • git
  • and I guess a Unix machine of some description; I don’t imagine running these tests on Windows will work well

Running the complete test suite takes about six minutes on my eight-core, 32GB i7 Linux box. Most of this time is spent sleeping, to ensure particular interleavings required by particular test cases.

Clone the repositories
$ git clone git://github.com/rabbitmq/rabbitmq-public-umbrella
$ cd rabbitmq-public-umbrella
$ git clone git://github.com/rabbitmq/rabbitmq-codegen
$ git clone git://github.com/rabbitmq/rabbitmq-java-client
$ git clone git://github.com/rabbitmq/rabbitmq-server
$ git clone git://github.com/rabbitmq/rabbitmq-test
Build and start the server in one window
$ cd rabbitmq-server
$ make run
Run the tests in another window

The tests are written in Java and come along with the RabbitMQ Java client source code.

Be sure to wait until the server has fully initialised itself before starting ant.

$ cd rabbitmq-java-client
$ ant test-suite

Things should tick along nicely for a few minutes at this point. From time to time, you’ll see the server print a new banner to its console: the tests restart the server occasionally as part of their normal operation.

Check the results

The tests leave their output in rabbitmq-java-client/build/TEST-* files. Each test suite (FunctionalTests, ClientTests, ServerTests, HATests) produces both a plain-text and an XML file summarising the results of the run.

How best to do PGP/GPG key management with Git?

I have parts of my home directory stored in git. In particular, I have my .gnupg/pubring.gpg and .gnupg/trustdb.gpg files in git. This is fine so long as absolutely no branching ever takes place.

My question to you, O lazyweb, is: does a tool exist for merging pubring.gpg etc. in a sensible fashion?

If the answer is “no”, then does a tool exist for exploding the contents of pubring.gpg etc into a directory full of tiny text files which are amenable to standard 3-way-merge?

New benchmarks of NaCl and scrypt in the browser

Back in March, I (crudely) measured the performance of js-nacl and js-scrypt running in the Browser.

Since then, emscripten has improved its code generation significantly, so I’ve rerun my tests. I’ve also thrown in node.js for comparison.1

The takeaway is: asm.js makes a big difference to NaCl and scrypt performance - on Firefox, that is. Firefox is between 2× and 8× faster.2 Other browsers have benefited from the improvements, but not as much.

The setup:

  • Firefox/23.0
  • Chrome/28.0.1500.95
  • Safari/534.59.8
  • node/v0.10.15
  • Macbook Air late 2010 (3,1), 1.6 GHz Core 2 Duo, 4 GB RAM, OS X 10.6.8

I’m running emscripten at git revision b1eaf55e (sources), of 8 August 2013.

(The benchmarks I ran in March were run with rev 4e09482e (sources) of 16 Jan 2013.)

What has changed since the last measurements?

Emscripten’s support for asm.js code generation is much better, and I am also now able to turn on -O2 optimization without things breaking.

On the minus side, the previous builds included a severe memory leak (!) because by default Emscripten includes a stub malloc() and free() implementation that never releases any allocated memory. The current builds include dlmalloc(), and so no longer leak memory, but run ever so slightly slower by comparison to using the stub allocator.

Safari seems to have severe problems with the current builds. I’m unsure where the bug lies (probably emscripten?), but many calls to crypto_box/crypto_box_open and scrypt() yield incorrect results. There are missing entries in the charts below because of this. (No sense in measuring something that isn’t correct.)

Since the previous round, Firefox has gained support for window.crypto.getRandomValues. Hooray!

Hashing (short) strings/bytes with SHA-512

Firefox handily dominates here, making the others look roughly equivalent.

Hash operations (per sec)

(Approximate speedups since January: Chrome = 1.2×; Firefox = 8.3×; Safari = 1.4×; node = 0.95×. Chart.)

Computing a shared key from public/private keys

These are operations whose runtime is dominated by the computation of a Curve25519 operation. In three of the four cases, the operation is used to compute a Diffie-Hellman shared key from a public key and a secret key; in the remaining case (crypto_box_keypair_from_seed) it is used to compute a public key from a secret key. Firefox again dominates, but Chrome is not far behind.

This is one of the areas where Safari yields incorrect results, leading to a missing data point. I’m not yet sure what the cause is.

Shared-key computations (per sec)

(Approximate speedups since January: Chrome = 2.5×; Firefox = 4.8×; Safari = 2×; node = 1×. Chart.)

Computing random nonces

This is a thin wrapper over window.crypto.getRandomValues, or the node.js equivalent, and so has not benefited from the emscripten improvements. I’m including it just to give a feel for how fast randomness-generation is.

Safari wins hands-down here. I wonder how good the generated randomness is?

Random nonce generation (per sec)

(Approximate speedups since January: Chrome = 0.96×; Firefox = 1×; Safari = 1×; node = 1×. Chart.)

Authenticated encryption using a shared key

These are Salsa20/Poly1305 authenticated encryptions using a precomputed shared key. Broadly speaking, boxing was quicker than unboxing. Firefox again dominates.

This another of the areas where Safari yields incorrect results. I’m not yet sure why.

Secret-key operations (per sec)

(Approximate speedups since January: Chrome = 1.5×; Firefox = 2.3×; Safari = 1.3×; node = 1.2×. Chart.)

Producing and validating signatures

These operations compute an elliptic-curve operation, but use the result to produce a digital signature instead of an authenticated/encrypted box. Signature generation is much faster than signature validation here. As for the other elliptic-curve-heavy operations, Firefox is fastest, but Chrome is not far behind.

Signature operations (per sec)

(Approximate speedups since January: Chrome = 1.8×; Firefox = 4.7×; Safari = 3.8×; node = 0.82×. Chart.)

scrypt Key Derivation Function

Here, Safari not only underperforms significantly but computes incorrect results. As above, I’m not sure why.

Firefox is about twice as fast as previously at producing scrypt()-derived keys. Both Firefox and Chrome are usably fast.

Signature operations (per sec)

(Approximate speedups since January: Firefox improved by around 2×; the others were roughly unchanged. Chart.)

Conclusions

scrypt is still slow. Safari has problems with this code, or vice versa. Precompute Diffie-Hellman shared keys where you can. Emscripten + asm.js = very cool!

  1. Of course, it’s a bit silly to include node.js here, since it can simply link against libsodium and get native-speed, optimized routines. Perhaps a Firefox extension could include a native XPCOM component offering a similar speed boost.

  2. The benefit is not quite as much as I claimed it was based on eyeballing the numbers.

NaCl/libsodium binding for Pharo and Squeak

I’ve just written Pharo/Squeak bindings to libsodium, which is a portable shared-library version of the NaCl cryptography library. A good description of the motivation of the library is this PDF.

Installing the software

To use the bindings, you will need to install the Monticello package Crypto-Nacl from http://smalltalkhub.com/mc/tonyg/Crypto-Nacl/main. The bindings depend on the FFI, so that must be installed.

From within Squeak:

(Installer repository: 'http://source.squeak.org/FFI')
   install: 'FFI-Pools';
   install: 'FFI-Kernel';
   install: 'FFI-Tests'.

(Installer repository: 'http://smalltalkhub.com/mc/tonyg/Crypto-Nacl/main')
   install: 'Crypto-Nacl'.

Most importantly, you will need a version of libsodium for your Smalltalk VM. Because most Squeak/Pharo VMs are 32-bit, you will need to get hold of a 32-bit libsodium. I’ve prebuilt some:

  • OS X, 32-bit VMs: libsodium.dylib.gz
    • decompress and put this in either
      • Squeak.app/Contents/Resources/libsodium (note: no extension!) for the Squeak VM, or
      • Pharo.app/Contents/MacOS/Plugins/libsodium (note: no extension!) for the Pharo VM.
  • Linux, 32-bit VMs: libsodium.so.gz
    • decompress and place the libsodium.so file in the same directory as vm-display-X11 and friends.
Compiling your own libsodium (optional)

Compiling libsodium to work with Squeak/Pharo can be tricky:

  • On OS X, configure libsodium with ./configure CFLAGS=-m32 to build a 32-bit version.

  • On 32-bit linux, ordinary ./configure works just fine, but I haven’t yet managed to get things working on a 64-bit linux. If anyone tries 64-bit and manages to get it to work, please let me know!

  • I haven’t tried it on Windows at all. Please let me know if you try this, and how it goes, either success or failure.

Running the tests

On the Smalltalk side, once you’ve loaded the .mcz, open a Test Runner and select the Crypto-Nacl tests. With Crypto-Nacl-tonyg.4, there should be 12 tests, and they should all pass if the shared library can be found in the right place.

You can also try it out in a Workspace: a printIt of Nacl sodiumVersionString will yield '0.3' or '0.4.1', depending on which version of libsodium you have.

Enjoy!

How to Build Racket on Windows 7

Here are the steps I followed to build Racket from a git checkout on a fresh Windows 7 installation.

  • Installed Visual Studio Express 2008 (not 2010 or 2012). This is hard to find on Microsoft’s website; this stackoverflow question linked to the Visual Studio Express 2008 ISO directly.

  • Used Virtual Clone Drive from SlySoft to mount the ISO in order to install Visual Studio, since Microsoft thoughtfully omitted ISO-mounting functionality from the core operating system.

  • Installed MASM32 to get a working assembler, since Microsoft thoughtfully omitted an assembler from their core compiler suite. (I am informed that later and/or non-Express editions of Visual Studio do actually include an assembler.)

  • Added the following directories to the system path:

    • C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin, for cl.exe etc.
    • C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE, for VCExpress.exe
    • C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\Tools, for vsvars32.bat
    • C:\masm32\bin, for ml.exe

    They do have to appear in that order, in particular with the MASM directory last, since it includes a link.exe that will otherwise conflict with the Visual Studio linker.

  • Installed Github for Windows and checked out Racket.

  • Opened a cmd.exe shell. NOTE not a PowerShell instance. Somehow environment variables are propagated differently in PowerShell from in cmd.exe! You want to only try to use cmd.exe to build Racket with.

  • Ran vsvars32.bat in that shell. This step is important, as otherwise the start of the xform stage in the build will fail to find stdio.h.

  • Navigated to my Racket checkout within that shell, and from there to src/worksp. Ran build.bat.

Following these steps will in principle lead to a fresh Racket.exe living in the root directory of your Racket checkout. There are many, many things that could go wrong however. Good luck!

What I do all day

Some people tell computers what to do. When they do, they have to talk about what the computer is to do each time it hears something new. They can’t easily talk about how the computer can learn which other computers are in the area. The computers can’t see each other, so usually computers find each other by talking to each other and listening to see if anyone talks back. Exactly how this should work is hard to explain to the computer.

My work is to try to find a way to let computers see each other. I want to let them see which other computers are near without the need for them to talk to each other about who is around and who is not all the time. That way we can tell computers how to do their job without needing to explain, over and over, the hard stuff about how they can learn which other computers are near.

We will be able to tell computers not only what to do when they hear something new, but also what to do when they see their friends come and go. It will be quicker and easier to tell computers how to do their jobs right, and harder to tell them wrong things to do.


I used this to make sure I only used allowed words. See also http://xkcd.com/1133/!