Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python3
- import argparse
- import sys
- import datetime
- import secretstorage
- import functools
- def datetime_from_ss(ts):
- datetime.datetime.fromtimestamp(int(ts) / 10000000)
- @functools.total_ordering
- class StoredPassword:
- def __init__(self, item):
- self.item = item
- self.url = item.get_label()
- self.password = item.get_secret().decode()
- attributes = item.get_attributes()
- self.realm = attributes['signon_realm']
- self.username = attributes['username_value']
- self.created = datetime_from_ss(attributes['date_created'])
- self.synced = datetime_from_ss(attributes['date_synced'])
- def __id__(self):
- return id(self.item)
- def __eq__(self, other):
- return self.item == other.item
- def __hash__(self):
- return hash(self.item)
- def __lt__(self, other):
- return (self.created, self.synced) < (other.created, other.synced)
- def __repr__(self):
- date_format = '%Y-%m-%d'
- return 'StoredPassword(%s %s %s %s %s)' % (
- self.realm, self.username, self.password,
- self.created.strftime(date_format),
- self.synced.strftime(date_format))
- def get_all_passwords():
- print('Loading passwords...')
- bus = secretstorage.dbus_init()
- collection = secretstorage.get_default_collection(bus)
- collection.ensure_not_locked()
- return [StoredPassword(item)
- for item in collection.get_all_items()
- if item.get_attributes()['xdg:schema'] ==
- 'chrome_libsecret_password_schema']
- def password_for_site_matching(pattern, all_passwords):
- matching = [item for item in all_passwords if pattern in item.realm]
- pws = set(m.password for m in matching)
- if len(pws) > 1:
- print('Found %d passwords across %d password manager entries:')
- for m in matching:
- print(' %s %s' % (m.username, m.url))
- print('Use a more specific match.')
- sys.exit(1)
- return pws.pop()
- def find_matching_passwords(password, site_pattern, all_passwords):
- reuse = [item
- for item in all_passwords
- if item.password == password and (site_pattern is None or site_pattern not in item.realm)]
- reuse.sort(key=lambda pw: pw.realm)
- if len(reuse):
- print('Found password. It is reused across %d sites:' % len(reuse))
- username_width = max(len(item.username) for item in reuse)
- for item in reuse:
- print('{:{width}} {}'.format(item.username,
- item.realm,
- width=username_width))
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='Find reused passwords')
- parser.add_argument(
- '--site',
- type=str,
- help='Find sites reusing a the password from this site')
- parser.add_argument('--password',
- type=str,
- help='Find sites using this password')
- args = parser.parse_args()
- if not args.site and not args.password:
- parser.print_help()
- sys.exit(1)
- if args.site and args.password:
- parser.print_help()
- print()
- print('You can only pass one of --site and --password')
- sys.exit(1)
- all_passwords = get_all_passwords()
- if args.site:
- password = password_for_site_matching(args.site, all_passwords)
- else:
- password = args.password
- find_matching_passwords(password, args.site, all_passwords)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement