Advertisement
Guest User

Untitled

a guest
Nov 26th, 2016
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.45 KB | None | 0 0
  1. #!/usr/bin/env python3
  2.  
  3. import argparse
  4. import sys
  5. import datetime
  6. import secretstorage
  7. import functools
  8.  
  9.  
  10. def datetime_from_ss(ts):
  11. datetime.datetime.fromtimestamp(int(ts) / 10000000)
  12.  
  13.  
  14. @functools.total_ordering
  15. class StoredPassword:
  16. def __init__(self, item):
  17. self.item = item
  18. self.url = item.get_label()
  19. self.password = item.get_secret().decode()
  20. attributes = item.get_attributes()
  21. self.realm = attributes['signon_realm']
  22. self.username = attributes['username_value']
  23. self.created = datetime_from_ss(attributes['date_created'])
  24. self.synced = datetime_from_ss(attributes['date_synced'])
  25.  
  26. def __id__(self):
  27. return id(self.item)
  28.  
  29. def __eq__(self, other):
  30. return self.item == other.item
  31.  
  32. def __hash__(self):
  33. return hash(self.item)
  34.  
  35. def __lt__(self, other):
  36. return (self.created, self.synced) < (other.created, other.synced)
  37.  
  38. def __repr__(self):
  39. date_format = '%Y-%m-%d'
  40. return 'StoredPassword(%s %s %s %s %s)' % (
  41. self.realm, self.username, self.password,
  42. self.created.strftime(date_format),
  43. self.synced.strftime(date_format))
  44.  
  45.  
  46. def get_all_passwords():
  47. print('Loading passwords...')
  48. bus = secretstorage.dbus_init()
  49. collection = secretstorage.get_default_collection(bus)
  50. collection.ensure_not_locked()
  51. return [StoredPassword(item)
  52. for item in collection.get_all_items()
  53. if item.get_attributes()['xdg:schema'] ==
  54. 'chrome_libsecret_password_schema']
  55.  
  56.  
  57. def password_for_site_matching(pattern, all_passwords):
  58. matching = [item for item in all_passwords if pattern in item.realm]
  59. pws = set(m.password for m in matching)
  60. if len(pws) > 1:
  61. print('Found %d passwords across %d password manager entries:')
  62. for m in matching:
  63. print(' %s %s' % (m.username, m.url))
  64. print('Use a more specific match.')
  65. sys.exit(1)
  66. return pws.pop()
  67.  
  68.  
  69. def find_matching_passwords(password, site_pattern, all_passwords):
  70. reuse = [item
  71. for item in all_passwords
  72. if item.password == password and (site_pattern is None or site_pattern not in item.realm)]
  73. reuse.sort(key=lambda pw: pw.realm)
  74. if len(reuse):
  75. print('Found password. It is reused across %d sites:' % len(reuse))
  76. username_width = max(len(item.username) for item in reuse)
  77. for item in reuse:
  78. print('{:{width}} {}'.format(item.username,
  79. item.realm,
  80. width=username_width))
  81.  
  82.  
  83. if __name__ == '__main__':
  84. parser = argparse.ArgumentParser(description='Find reused passwords')
  85. parser.add_argument(
  86. '--site',
  87. type=str,
  88. help='Find sites reusing a the password from this site')
  89. parser.add_argument('--password',
  90. type=str,
  91. help='Find sites using this password')
  92. args = parser.parse_args()
  93.  
  94. if not args.site and not args.password:
  95. parser.print_help()
  96. sys.exit(1)
  97.  
  98. if args.site and args.password:
  99. parser.print_help()
  100. print()
  101. print('You can only pass one of --site and --password')
  102. sys.exit(1)
  103.  
  104. all_passwords = get_all_passwords()
  105. if args.site:
  106. password = password_for_site_matching(args.site, all_passwords)
  107. else:
  108. password = args.password
  109. find_matching_passwords(password, args.site, all_passwords)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement