On Not | Mo Chit

March 06, 2004

JEP25 and Generators You've got to love Python generators. Generators can make even an amateur programmer like myself look like I know what I'm doing.

, HTTP Polling, allows people behind overly restrictive firewalls to connect to Jabber networks via HTTP. JEP-25 has a smarter, better looking cousin, , but the Jabber.org sages haven't finalized it yet.

Both JEP-25 and JEP-124 require a key generation algorithm to make it difficult for people to hijack a HTTP session.

The formulation for the key sequence algorithm is:
K(n, seed) = Base64Encode(SHA1(K(n - 1, seed))), for n > 0
K(0, seed) = seed, which is client-determined
Python generators makes producing the sequence a breeze:
def JEP25KeyGenerator(sequenceLength):

    kg = createSequenceGenerator(sequenceLength)

    def generatorWrap():
        return kg.next()

    return generatorWrap

def createSequenceGenerator(sequenceLength):

    sequence = generateSequence(sequenceLength)
    while True:
        key = sequence.pop()

        if not sequence:
            sequence = generateSequence(sequenceLength)
            newKey = sequence.pop()

            yield "%s;%s" % (key, newKey)
            yield key

def generateSequence(sequenceLength):

    seed = random.randint(1,2**15)

    sequence = []
    key = str(seed)

    for i in xrange(sequenceLength):
        key = sha.sha(key).digest().encode('base64').rstrip()

    return sequence

Instantiating the generator and executing a couple of interations yields:
>>> keyFactory = JEP25KeyGenerator(5)
>>> keyFactory()
>>> keyFactory()
>>> keyFactory()
>>> keyFactory()
>>> keyFactory()
>>> keyFactory()
On the 5th execution of KeyFactory(), the sequence is exhausted and a new key sequence is introduced. However, the change over to the new key generation is completely transparent to the generator client.

The strings produced be the key generator are suited for constructing the body of the HTTP request:
#sessionID;sequenceKey[; newSequenceKey],[body]
httpBody = sessionID + ";" + keyFactory() + "," + xmlStanza
response = urllib2.urlopen(proxyURL, httpBody)

Creative Commons License
This site is licensed under a
Creative Commons License