80,6 → 80,29 |
setattr(os, k, v) |
del codes, k, v |
|
TAGNAMES ={ 'generic-url': 'Url:', |
'generic-username': 'Username:', |
'generic-password': 'Password:', |
'generic-email': 'Email:', |
'generic-hostname': 'Hostname:', |
'generic-location': 'Location:', |
'generic-code': 'Code:', |
'generic-certificate': 'Certificate:', |
'generic-database': 'Database:', |
'generic-domain': 'Domain:', |
'generic-keyfile': 'Key file:', |
'generic-pin': 'PIN', |
'generic-port': 'Port' |
} |
|
def printe(s): |
' Print to stderr ' |
sys.stderr.write(s+'\n') |
|
def printen(s): |
' Print to stderr without added newline ' |
sys.stderr.write(s) |
|
def usage(channel): |
' Print help message ' |
def p(s): |
104,10 → 127,8 |
p('\n') |
|
def make_xpath_query(search_text=None, type_filter=None, ignore_case=True, negate_filter=False): |
''' |
''' Construct the actual XPath expression |
make_xpath_query(str, str, bool, bool) -> str |
|
Construct the actual XPath expression |
''' |
xpath = '/revelationdata//entry' |
if type_filter: |
137,7 → 158,7 |
res = tree.xpath(xpath) |
except etree.XPathEvalError: |
if not RELEASE: |
sys.stderr.write('Failed with xpath expression: %s\n' % xpath) |
printe('Failed with xpath expression: %s' % xpath) |
raise |
query_desc = '' |
if search_text: |
153,7 → 174,10 |
nr = dump_result(res, query_desc) |
return nr |
|
def dump_result(res, query_desc): |
def print_wrapper(s): |
print s |
|
def dump_result(res, query_desc, printfn=print_wrapper): |
''' Print query results. |
dump_result(list of entries, query description) -> int |
''' |
162,44 → 186,31 |
print 'No results' |
return False |
print '%d matches' % len(res) |
tagnames ={ 'generic-url': 'Url:', |
'generic-username': 'Username:', |
'generic-password': 'Password:', |
'generic-email': 'Email:', |
'generic-hostname': 'Hostname:', |
'generic-location': 'Location:', |
'generic-code': 'Code:', |
'generic-certificate': 'Certificate:', |
'generic-database': 'Database:', |
'generic-domain': 'Domain:', |
'generic-keyfile': 'Key file:', |
'generic-pin': 'PIN', |
'generic-port': 'Port' |
} |
for x in res: |
sys.stderr.write('-------------------------------------------------------------------------------\n') |
print '' |
print 'Type:',x.get('type') |
printe('-------------------------------------------------------------------------------') |
s = '\n' |
s += 'Type: %s\n' % x.get('type') |
for chld in x.getchildren(): |
n = chld.tag |
val = chld.text |
if n == 'name': |
print 'Name:',val |
s += 'Name: %s\n' % val |
elif n == 'description': |
print 'Description:',val |
s += 'Description: %s\n' % val |
elif n == 'field': |
idv = chld.get('id') |
if idv in tagnames: |
idv = tagnames[idv] |
print idv,chld.text |
print '' |
if idv in TAGNAMES: |
idv = TAGNAMES[idv] |
s += '%s %s\n' % ( idv, chld.text ) |
#s += '\n' |
printfn(s) |
# / for chld in x.children |
nr = len(res) |
plural = '' |
if nr > 1: |
plural = 's' |
sys.stderr.write('-------------------------------------------------------------------------------\n') |
sys.stderr.write('<- (end of %d result%s for {%s})\n\n' % ( nr, plural, query_desc )) |
printe('-------------------------------------------------------------------------------') |
printe('<- (end of %d result%s for {%s})\n' % ( nr, plural, query_desc )) |
return nr |
|
def world_readable(path): |
211,10 → 222,9 |
return bool(st.st_mode & stat.S_IROTH) |
|
def load_config(): |
""" |
''' Load configuration file is one is found |
load_config() -> ( str file, str pass ) |
Load configuration file is one is found |
""" |
''' |
cfg = os.path.join(os.path.expanduser('~'), '.relevation.conf') |
pw = None |
fl = None |
222,7 → 232,7 |
if os.access(cfg, os.R_OK): |
wr = world_readable(cfg) |
if wr and sys.platform != 'win32': |
sys.stderr.write('Configuration (~/.relevation.conf) is world-readable!!!\n') |
printe('Configuration (~/.relevation.conf) is world-readable!!!') |
parser = ConfigParser.ConfigParser() |
parser.read(cfg) |
ops = parser.options('relevation') |
233,13 → 243,13 |
sys.stderr.write('Your password can be read by anyone!!!\n') |
pw = parser.get('relevation', 'password') |
else: # exists but not readable |
sys.stderr.write('Configuration file (~/.relevation.conf) is not readable!\n') |
printe('Configuration file (~/.relevation.conf) is not readable!') |
return ( fl, pw ) |
|
def decrypt_gz(key, cipher_text): |
''' |
''' Decrypt cipher_text using key. |
decrypt(str, str) -> cleartext (gzipped xml) |
Decrypt cipher_text using key. |
|
This function will use the underlying, available, cipher module. |
''' |
if USE_PYCRYPTO: |
259,7 → 269,7 |
ct = c.decrypt(cipher_text[28:], iv=iv) |
return ct |
|
def main(): |
def main(argv): |
datafile = None |
password = None |
# values to search for |
269,13 → 279,13 |
searchTypes = [] |
dump_xml = False |
|
sys.stderr.write('Relevation v%s, (c) 2011 Toni Corvera\n\n' % __version__) |
printe('Relevation v%s, (c) 2011 Toni Corvera\n' % __version__) |
|
# ---------- OPTIONS ---------- # |
( datafile, password ) = load_config() |
try: |
# gnu_getopt requires py >= 2.3 |
ops, args = getopt.gnu_getopt(sys.argv[1:], 'f:p:s:0ciaht:x', |
ops, args = getopt.gnu_getopt(argv, 'f:p:s:0ciaht:x', |
[ 'file=', 'password=', 'search=', 'stdin', |
'case-sensitive', 'case-insensitive', 'ask', |
'help', 'version', 'type=', 'xml' ]) |
310,7 → 320,7 |
password = arg |
elif opt in ( '-a', '--ask', '-0', '--stdin' ): |
if opt in ( '-a', '--ask' ): |
sys.stderr.write('File password: ') |
printen('File password: ') |
password = sys.stdin.readline() |
password = password[:-1] |
elif opt in ( '-s', '--search' ): |
327,19 → 337,19 |
neg = True |
if not iarg in ( 'creditcard', 'cryptokey', 'database', 'door', 'email', |
'folder', 'ftp', 'generic', 'phone', 'shell', 'website' ): |
sys.stderr.write('Warning: Type "%s" is not known by relevation.\n' % arg) |
printe('Warning: Type "%s" is not known by relevation.' % arg) |
searchTypes.append( ( iarg, neg ) ) |
elif opt in ( '-x', '--xml' ): |
dump_xml = True |
else: |
sys.stderr.write('Unhandled option: %s\n' % opt) |
printe('Unhandled option: %s' % opt) |
assert False, "internal error parsing options" |
if not datafile or not password: |
usage(sys.stderr) |
if not datafile: |
sys.stderr.write('Input password filename is required\n') |
printe('Input password filename is required') |
if not password: |
sys.stderr.write('Password is required\n') |
printe('Password is required') |
sys.exit(os.EX_USAGE) |
|
# ---------- PASSWORDS FILE DECRYPTION AND DECOMPRESSION ---------- # |
387,12 → 397,12 |
|
if __name__ == '__main__': |
try: |
main() |
main(sys.argv[1:]) |
except zlib.error: |
sys.stderr.write('Failed to decompress decrypted data. Wrong password?\n') |
printe('Failed to decompress decrypted data. Wrong password?') |
sys.exit(os.EX_DATAERR) |
except etree.XMLSyntaxError as e: |
sys.stderr.write('XML parsing error\n') |
printe('XML parsing error') |
if not RELEASE: |
traceback.print_exc() |
sys.exit(os.EX_DATAERR) |
399,7 → 409,7 |
except IOError as e: |
if not RELEASE: |
traceback.print_exc() |
sys.stderr.write(str(e)+"\n") |
printe(str(e)) |
sys.exit(os.EX_IOERR) |
|
# vim:set ts=4 et ai fileencoding=utf-8: # |