Subversion Repositories pub

Compare Revisions

Ignore whitespace Rev 180 → Rev 181

/relevation/branches/1.1/relevation.py
47,14 → 47,17
import sys
import zlib
 
# Import PyCrypto if present, fall back to PyCryptoPlus otherwise
USE_PYCRYPTO = True
 
try:
from Crypto.Cipher import AES
except ImportError:
USE_PYCRYPTO = False
try:
from CryptoPlus.Cipher import AES
from crypto.cipher import rijndael, cbc
from crypto.cipher.base import noPadding
except ImportError:
sys.stderr.write('Error: Either PyCrypto or PyCryptoPlus must be installed\n')
sys.stderr.write('Either PyCrypto or cryptopy are required\n')
raise
 
__author__ = 'Toni Corvera'
64,6 → 67,19
__version__ = '.'.join(map(str, __version_info__))
RELEASE=True
 
# These are pseudo-standardized exit codes, in Linux (*NIX?) they are defined
#+in the header </usr/include/sysexits.h> and available as properties of 'os'
#+In windows they aren't defined at all
 
if 'EX_OK' not in dir(os):
# If not defined set them manually
codes = { 'EX_OK': 0, 'EX_USAGE': 64, 'EX_DATAERR': 65,
'EX_NOINPUT': 66, 'EX_SOFTWARE': 70, 'EX_IOERR': 74,
}
for (k,v) in codes.items():
setattr(os, k, v)
del codes, k, v
 
def usage(channel):
' Print help message '
def p(s):
205,7 → 221,7
if os.path.isfile(cfg):
if os.access(cfg, os.R_OK):
wr = world_readable(cfg)
if wr:
if wr and sys.platform != 'win32':
sys.stderr.write('Configuration (~/.relevation.conf) is world-readable!!!\n')
parser = ConfigParser.ConfigParser()
parser.read(cfg)
213,7 → 229,7
if 'file' in ops:
fl = os.path.expanduser(parser.get('relevation', 'file'))
if 'password' in ops:
if wr and sys.platform != 'win32': # TODO: how to check in windows?
if wr: # TODO: how to check in windows?
sys.stderr.write('Your password can be read by anyone!!!\n')
pw = parser.get('relevation', 'password')
else: # exists but not readable
220,6 → 236,29
sys.stderr.write('Configuration file (~/.relevation.conf) is not readable!\n')
return ( fl, pw )
 
def decrypt_gz(key, cipher_text):
'''
decrypt(str, str) -> cleartext (gzipped xml)
Decrypt cipher_text using key.
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
 
def main():
datafile = None
password = None
310,12 → 349,8
f.close()
# Pad password
password += (chr(0) * (32 - len(password)))
# Data IV
c = AES.new(password)
iv = c.decrypt(data[12:28])
# Decrypt. Decrypted data is compressed
c = AES.new(password, AES.MODE_CBC, iv)
cleardata_gz = c.decrypt(data[28:])
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)