2008-10-31 16:29:30

If you forgot screen in irssi

There's always something new to learn on #netbsd. If you happened to forget to start irssi inside screen, it suffices to run:

/upgrade /usr/pkg/bin/screen /usr/pkg/bin/irssi

…and your session will be running inside screen.

Posted by Tonnerre Lombard | Permanent link | File under: general

2008-10-29 13:45:42

Iterating hot air

Python allows to create iterators through the builtin function iter. This function has two ways of being called:

  • iter(collection) -> iterator
  • iter(callable, sentinel) -> iterator

The first call is rather unproblematic for sure. It calls a class method, it gets its object and that's it.

The second variant is however utterly useless. The callable is not called with any object — in fact, the call to iter does not even know what object is being iterated. This requires the programmer to store the state externally in some kind of global variable, or not to have any state at all. The latter would render the iterator rather pointless, since a crucial part of the purpose of an iterator is to externalize the state.

Posted by Tonnerre Lombard | Permanent link | File under: broken, programming

2008-10-28 16:08:20

Why Greylisting is harmful (2)

An ISP has a mail cluster solution which is distributed over a number of hosts in a /24 subnet. The SPF record correctly reads:

$ host -t TXT isp.com isp.com descriptive text "v=spf1 ip4:subnet/24" $

Since the mail cluster has to deliver a large amount of mails per day, it is attached to a SAN and distributes message delivery over the various servers. A random server picks up a message and attempts to deliver it. Locking works well so no double attempts to deliver it are made, ever. This effectively prevents messages with delivery problems from clogging up the queue on a specific server.

Here's why the ISP can forget their great mail server: greylisting. A lot of implementors don't investigate in any way what they whitelist — there's a variety of options ranging from SPF over the RIPE database to server name wildcards (which would be nasty, though) — but instead whitelist one single host. Then, however, the likelyhood of the resend attempt being performed by the same server is fairly low, so the next server will also hit the greylisting barrier. This can continue for a long time until the mail is finally delivered — or, if things go really bad, rejected.

While this is not an argument against greylisting itself, it is one against a majority of implementations.

Posted by Tonnerre Lombard | Permanent link | File under: network

2008-10-27 11:16:54

Integer() is an int, but be aware that it's not

In Python's external ASN.1 toolkit features a special type, Integer(), which can be written to or fetched from an ASN.1 structure transparently. The resulting object, despite being an instance of pyasn1.Integer, behaves like any other integer: all operations can be applied as one would apply them to an integer.

All operations? Not quite! A single function parameter is holding out, strong as ever, against the integer compatibility. Life is not easy for the programmers attempting to make use of the resulting objects.

In fact it's quite funny: the problem is with the function pow. As the documentation says:

In [1]: pow.__doc__
Out[1]: 'pow(x, y[, z]) -> number\n\nWith two arguments, equivalent to x**y. With three arguments,\nequivalent to (x**y) % z, but may be more efficient (e.g. for longs).'

Since crypto wants speed, and ASN.1 is frequently used in crypto, we now try to combine pyasn1 and the amk crypto toolkit, since Python itself does not contain any crypto. We use the DSA sign function, which basically only calls pow() for us. This is where we get bitten. The reason is simple and astonishing:

In [2]: i = pyasn1.type.univ.Integer(23)
In [3]: pow(i, 23)
Out[3]: Integer('20880467999847912034355032910567')
In [4]: pow(23, i)
Out[4]: Integer('20880467999847912034355032910567')
In [5]: pow(23, 23, i)
TypeError Traceback (most recent call last)

/home/tonnerre/<ipython console> in <module>()

TypeError: unsupported operand type(s) for pow(): 'int', 'int', 'instance'

In [6]:

Astonishingly, the Integer instance is allowed as the first and second argument to pow(), but not as the third one. More astonishingly, all of them are supposed to be ints. Even more weirdly, if pow is called with 3 pyasn1 Integer()s, the error message is still the same: the first two Integer()s are said to be int, the last one remains an instance.

Posted by Tonnerre Lombard | Permanent link | File under: broken, programming

2008-10-23 13:16:39

ASN.1 for DSA public and private keys

I spent some hours today looking for an adequate description of the ASN.1 structure of a DSA public and private key. In theory, RFC3279 should cover this, and it does, in some way or other: section 3.2.3 has very confusing information about the structure.

But even though I am coding Python at this point in time, Perl has once again saved me: the Crypt::DSA::Key::PEM module contains the ASN in its source code:

DSAPrivateKey ::= SEQUENCE {
    version INTEGER,
    p INTEGER,
    q INTEGER,
    g INTEGER,
    pub_key INTEGER,
    priv_key INTEGER

DSAPublicKey ::= SEQUENCE {
    inner SEQUENCE {
        DSAParams SEQUENCE {
            p INTEGER,
            q INTEGER,
            g INTEGER
    pub_key BIT STRING

DSAPubKeyInner ::= INTEGER

Thanks a ton, Perl!

Posted by Tonnerre Lombard | Permanent link | File under: programming