Tox data parser

The tox data save is in binary format, I thought it would be nice to able to parse it, here is a little script to do it.

From crypto_core.h

#!/usr/bin/python

import struct
import sys

__author__ = "Mohamed Aziz Knani"

CRYPTO_PUBLIC_KEY_SIZE = 32
CRYPTO_SECRET_KEY_SIZE = 32

from messenger.c

MESSENGER_STATE_COOKIE_GLOBAL      = 0x15ed1b1f
MESSENGER_STATE_COOKIE_TYPE        = 0x01ce
MESSENGER_STATE_TYPE_NOSPAMKEYS    = 1
MESSENGER_STATE_TYPE_DHT           = 2
MESSENGER_STATE_TYPE_FRIENDS       = 3
MESSENGER_STATE_TYPE_NAME          = 4
MESSENGER_STATE_TYPE_STATUSMESSAGE = 5
MESSENGER_STATE_TYPE_STATUS        = 6
MESSENGER_STATE_TYPE_TCP_RELAY     = 10
MESSENGER_STATE_TYPE_PATH_NODE     = 11
MESSENGER_STATE_TYPE_END           = 255

This is calculated manually, so it can absolutely change, you can't assume for sure how much the size of the data is

FRIEND_SIZE = 2216 
COOKIE_LEN = 8
ERROR = -1
END   = -2

def read_chunk(data, offset, cookie, length):
    if cookie == MESSENGER_STATE_TYPE_NOSPAMKEYS:
	print "[!] Printing Keys"
	#nospam
	nospam = data[offset:offset+4].encode("hex")
	print "    Nospam: " + nospam
	#public key
	offset += 4
	pubkey = data[offset:offset+CRYPTO_PUBLIC_KEY_SIZE].encode("hex")
	print "    PubKey: " + pubkey
	#secret key
	seckey = data[offset+CRYPTO_PUBLIC_KEY_SIZE:offset+CRYPTO_PUBLIC_KEY_SIZE+CRYPTO_SECRET_KEY_SIZE].encode("hex")
	print "    SecKey: " + seckey + " ==="
    elif cookie == MESSENGER_STATE_TYPE_NAME:
	print "[!] Printing Name"
	print " "*4+data[offset:offset+length]
    elif cookie == MESSENGER_STATE_TYPE_STATUSMESSAGE:
	print "[!] Printing status message"
	print " "*4+data[offset:offset+length]
    elif cookie == MESSENGER_STATE_TYPE_FRIENDS:
	if length % FRIEND_SIZE != 0:
	    return ERROR
	num = length // FRIEND_SIZE
	buff = data[offset:length + offset]
	print "[!] Printing %d friends" % num
	friends = [buff[i:i+FRIEND_SIZE] for i in range(0, len(buff), FRIEND_SIZE)]
	for friend in friends:
	    #unpack
	    #struct.unpack(friend, )
	    pass
    elif cookie == MESSENGER_STATE_TYPE_END:
	return END

def read_save(data):
    data0 = struct.unpack_from("<I", data, 0)[0]
    data1 = struct.unpack_from("<I", data, 4)[0]
    offset = COOKIE_LEN
    if data0 == 0 and data1 == MESSENGER_STATE_COOKIE_GLOBAL:
	while True:
	    length = struct.unpack_from("<H", data, offset)[0]
	    offset += 4
	    cookie = struct.unpack_from("<H", data, offset)[0]
	    offset += 2
	    ck = struct.unpack_from("<H", data, offset)[0]
	    offset += 2
	    if ck != MESSENGER_STATE_COOKIE_TYPE:
		print "[-] state cookie not matching"
		return
	    ret = read_chunk(data, offset, cookie, length)
	    if ret == END:
		print "[*] END"
		break
	    offset += length

tox_save = sys.stdin.read()
read_save(tox_save)

Download the file here.

to parse your file just do a:

python toxparser.py < ~/.config/tox/tox_save.tox