1,4 → 1,4 |
#!/usr/bin/env python3 |
#!/usr/bin/env python |
# -*- coding: UTF-8 -*- |
''' |
Relevation Password Printer |
17,7 → 17,7 |
''' |
# Relevation Password Printer |
# |
# Copyright (c) 2011,2012,2013,2014,2020 Toni Corvera |
# Copyright (c) 2011,2012,2013,2014 Toni Corvera |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
44,7 → 44,7 |
__date__ = '$Date$' |
__revision__ = '$Rev$' |
|
import configparser |
import ConfigParser |
import getopt |
import getpass |
from lxml import etree |
51,6 → 51,7 |
import locale |
import os |
import stat |
import string |
import sys |
import zlib |
# Help py2exe in packaging lxml |
74,16 → 75,6 |
sys.stderr.write('Either PyCrypto or cryptopy is required\n') |
raise |
|
RELEASE=True |
__author__ = 'Toni Corvera' |
__date__ = '$Date$' |
__revision__ = '$Rev$' |
__version_info__ = ( 1, 3, 1 ) #, 0 ) # Note: For x.y.0, only x and y are kept |
if not RELEASE: |
import traceback |
__version_info__ += ( '0-pre1', ) |
__version__ = '.'.join(map(str, __version_info__)) |
|
# 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 |
93,7 → 84,7 |
codes = { 'EX_OK': 0, 'EX_USAGE': 64, 'EX_DATAERR': 65, |
'EX_NOINPUT': 66, 'EX_SOFTWARE': 70, 'EX_IOERR': 74, |
} |
for (k,v) in list(codes.items()): |
for (k,v) in codes.items(): |
setattr(os, k, v) |
del codes, k, v |
|
194,13 → 185,13 |
needles = search_text |
else: |
# FIXME: Used for OR's |
assert type(search_text) == str or type(search_text) == str |
assert type(search_text) == str or type(search_text) == unicode |
needles = [ search_text, ] |
selector = '' |
for search in needles: |
if ignore_case: |
# must pass lowercase to actually be case insensitive |
search = search.lower() |
search = string.lower(search) |
# XPath 2.0 has lower-case, upper-case, matches(..., -i) etc. |
selector += '//text()[contains(translate(., "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz"), "%s")]/../..' % search |
else: |
247,7 → 238,7 |
def dump_single_result(typeName, name, descr, notes, fields): |
''' dump_single_result(str, unicode, unicode, list) -> None ''' |
printe('-------------------------------------------------------------------------------') |
s = '\n' |
s = u'\n' |
s += 'Type: %s\n' % typeName |
s += 'Name: %s\n' % name |
s += 'Description: %s\n' % descr |
256,15 → 247,12 |
s += '%s %s\n' % field # field, value |
try: |
# sys.stdout.encoding will be None if piped |
#print(s.encode(sys.stdout.encoding or locale.getpreferredencoding())) |
print(s) |
print s.encode(sys.stdout.encoding or locale.getpreferredencoding()) |
except UnicodeEncodeError: |
# XXX: In Python 2 there were unicode conversions, no longer needed in Python 3 |
# TODO: This branch shouldn't be entered anymore, but needs testing |
# E.g. console in ASCII ($ LC_ALL=C relevation) |
# TODO: Flag for notification |
#printe("WARNING: The console doesn't have a compatible encoding, falling back to UTF-8") |
print(s.encode('utf8')) |
print s.encode('utf8') |
|
def dump_result(res, query_desc, dumpfn=dump_single_result): |
''' Print query results. |
276,15 → 264,15 |
''' |
# Note the XML is in UTF-8, and that the extracted fields will be |
# either type |
if type(s) == str: |
if type(s) == unicode: |
return s |
return str(s.decode('utf8')) |
return unicode(s.decode('utf8')) |
|
print('-> Search %s: ' % query_desc, end=' ') |
print '-> Search %s: ' % query_desc, |
if not len(res): |
print('No results') |
print 'No results' |
return False |
print('%d matches' % len(res)) |
print '%d matches' % len(res) |
for x in res: |
typeName = x.get('type') |
name = None |
343,7 → 331,7 |
wr = world_readable(cfg) |
if wr and sys.platform != 'win32': |
printe('Configuration (~/.relevation.conf) is world-readable!!!') |
parser = configparser.ConfigParser() |
parser = ConfigParser.ConfigParser() |
parser.read(cfg) |
ops = parser.options('relevation') |
if 'file' in ops: |
367,9 → 355,9 |
''' Checks that the gzip-compressed 'data' is padded correctly. |
validate_compressed_padding(str) -> bool |
''' |
padlen = data[-1] # XXX: While on Python 2 we were using ord(data[-1]), ord(i), etc. |
padlen = ord(data[-1]) |
for i in data[-padlen:]: |
if i != padlen: |
if ord(i) != padlen: |
return False |
return True |
def validate_cipher_length(self, data): |
445,7 → 433,7 |
if not self.validate_compressed_padding(cleardata_gz): |
raise DataFormatError |
# Decompress actual data (15 is wbits [ref3] DON'T CHANGE, 2**15 is the (initial) buf size) |
padlen = cleardata_gz[-1] |
padlen = ord(cleardata_gz[-1]) |
try: |
# Note data is encoded in UTF-8 but not decoded yet (because |
# the XML parser is too easy to choke in that case) |
492,7 → 480,7 |
if not self.validate_compressed_padding(cleardata_gz): |
raise DataFormatError |
# Decompress |
padlen = cleardata_gz[-1] |
padlen = ord(cleardata_gz[-1]) |
try: |
return zlib.decompress(cleardata_gz[:-padlen]) |
except zlib.error: |
531,13 → 519,13 |
''' |
header = self._data[0:12] |
magic = header[0:4] |
if magic != b"rvl\x00": |
if magic != "rvl\x00": |
raise DataFormatError |
data_version = header[4] |
app_version = header[6:9] |
if data_version == 0x01: #'\x01': |
if data_version == '\x01': |
self._impl = DataReaderV1() |
elif data_version == 0x02: #'\x02': |
elif data_version == '\x02': |
self._impl = DataReaderV2() |
else: |
raise DataVersionError |
558,7 → 546,7 |
dump_xml = False |
mode = None |
|
printe('Relevation v%s, (c) 2011-2020 Toni Corvera\n' % __version__) |
printe('Relevation v%s, (c) 2011-2014 Toni Corvera\n' % __version__) |
|
# ---------- OPTIONS ---------- # |
( datafile, password, mode ) = load_config() |
569,8 → 557,8 |
'case-sensitive', 'case-insensitive', 'ask', |
'help', 'version', 'type=', 'xml', |
'and', 'or' ]) |
except getopt.GetoptError as err: |
print(str(err)) |
except getopt.GetoptError, err: |
print str(err) |
usage(sys.stderr) |
sys.exit(os.EX_USAGE) |
if args: |
583,14 → 571,14 |
release='' |
if not RELEASE: |
release=' [DEBUG]' |
print('Relevation version %s%s' % ( __version__, release )) |
print('Python version %s' % sys.version) |
print 'Relevation version %s%s' % ( __version__, release ) |
print 'Python version %s' % sys.version |
if USE_PYCRYPTO: |
import Crypto |
print('PyCrypto version %s' % Crypto.__version__) |
print 'PyCrypto version %s' % Crypto.__version__ |
else: |
# AFAIK cryptopy doesn't export version info |
print('cryptopy') |
print 'cryptopy' |
sys.exit(os.EX_OK) |
|
for opt, arg in ops: |
647,7 → 635,7 |
|
# ---------- QUERIES ---------- # |
if dump_xml: |
print(xmldata) |
print xmldata |
sys.exit(os.EX_OK) |
# Multiply values to search by type of searches |
numhits = 0 |