Subversion Repositories pub

Compare Revisions

Ignore whitespace Rev 586 → Rev 587

/relevation/branches/1.3/relevation.py
18,7 → 18,7
"""
# Relevation Password Printer
#
# Copyright (c) 2011,2012,2013 Toni Corvera
# Copyright (c) 2011,2012,2013,2014 Toni Corvera
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
72,7 → 72,7
__author__ = 'Toni Corvera'
__date__ = '$Date$'
__revision__ = '$Rev$'
__version_info__ = ( 1, 2 , 1 ) # Note: For x.y.0, only x and y are kept
__version_info__ = ( 1, 3 ) #, 0 ) # Note: For x.y.0, only x and y are kept
__version__ = '.'.join(map(str, __version_info__))
RELEASE=True
 
279,7 → 279,7
return bool(st.st_mode & stat.S_IROTH)
 
def load_config():
''' Load configuration file is one is found
''' Load configuration file if one is found
load_config() -> ( str file, str pass )
'''
cfg = os.path.join(os.path.expanduser('~'), '.relevation.conf')
309,29 → 309,62
printe('Configuration file (~/.relevation.conf) is not readable!')
return ( fl, pw, mode )
 
def decrypt_gz(key, cipher_text):
''' Decrypt cipher_text using key.
decrypt(str, str) -> cleartext (gzipped xml)
This function will use the underlying, available, cipher module.
'''
if USE_PYCRYPTO:
# Extract IV
c = AES.new(key)
iv = c.decrypt(cipher_text[12:28])
# Decrypt data, CBC mode
c = AES.new(key, AES.MODE_CBC, iv)
ct = c.decrypt(cipher_text[28:])
else:
# Extract IV
c = rijndael.Rijndael(key, keySize=len(key), padding=noPadding())
iv = c.decrypt(cipher_text[12:28])
# Decrypt data, CBC mode
bc = rijndael.Rijndael(key, keySize=len(key), padding=noPadding())
c = cbc.CBC(bc, padding=noPadding())
ct = c.decrypt(cipher_text[28:], iv=iv)
return ct
class DataReaderV1(object):
def _decrypt_compressed_data(self, key, cipher_text):
''' Decrypt cipher_text using key.
decrypt(str, str) -> cleartext (gzipped xml)
This function will use the underlying, available, cipher module.
'''
# Old format:
# [0:12) 12B header: "rvl" 0x00, 0x01, 0x00
# [12:28) 16B ECB encrypted CBC IV
# [28:] encrypted data
if USE_PYCRYPTO:
# Extract IV
c = AES.new(key)
iv = c.decrypt(cipher_text[12:28])
# Decrypt data, CBC mode
c = AES.new(key, AES.MODE_CBC, iv)
ct = c.decrypt(cipher_text[28:])
else:
# Extract IV
c = rijndael.Rijndael(key, keySize=len(key), padding=noPadding())
iv = c.decrypt(cipher_text[12:28])
# Decrypt data, CBC mode
bc = rijndael.Rijndael(key, keySize=len(key), padding=noPadding())
c = cbc.CBC(bc, padding=noPadding())
ct = c.decrypt(cipher_text[28:], iv=iv)
return ct
def get_xml(self, data, password):
# Pad password
password += (chr(0) * (32 - len(password)))
# Decrypt. Decrypted data is compressed
cleardata_gz = self._decrypt_compressed_data(password, data)
# Length of data padding
padlen = ord(cleardata_gz[-1])
# Decompress actual data (15 is wbits [ref3] DON'T CHANGE, 2**15 is the (initial) buf size)
return zlib.decompress(cleardata_gz[:-padlen], 15, 2**15)
 
class DataReader(object):
def __init__(self, filename, data):
self._impl = None
self._data = data
self._check_header(filename)
def _check_header(self, filename):
header = self._data[0:12]
magic = header[0:4]
if magic != "rvl\x00":
raise IOError('File \'%s\' not in the correct format' % filename)
data_version = header[4]
app_version = header[6:9]
if data_version == '\x01':
self._impl = DataReaderV1()
else:
raise IOError('File \'%s\' is in a newer, unsupported, data format' % filename)
def get_xml(self, password):
return self._impl.get_xml(self._data, password)
 
def main(argv):
datafile = None
password = None
343,7 → 376,7
dump_xml = False
mode = None
 
printe('Relevation v%s, (c) 2011-2013 Toni Corvera\n' % __version__)
printe('Relevation v%s, (c) 2011-2014 Toni Corvera\n' % __version__)
 
# ---------- OPTIONS ---------- #
( datafile, password, mode ) = load_config()
438,14 → 471,7
finally:
if f:
f.close()
# Pad password
password += (chr(0) * (32 - len(password)))
# Decrypt. Decrypted data is compressed
cleardata_gz = decrypt_gz(password, data)
# Length of data padding
padlen = ord(cleardata_gz[-1])
# Decompress actual data (15 is wbits [ref3] DON'T CHANGE, 2**15 is the (initial) buf size)
xmldata = zlib.decompress(cleardata_gz[:-padlen], 15, 2**15)
xmldata = DataReader(datafile, data).get_xml(password)
# ---------- QUERIES ---------- #
if dump_xml:
/relevation/branches/1.3/CHANGELOG
1,5 → 1,8
$Date$
 
1.3 (?):
- Check file magic [#230] and reject unsupported data formats
 
1.2.1 (2013-11-05):
- Minimal GUI Fixes:
- Updated to the changes in 1.2