From bfb35b2517bf583146de97bc0641ac0f005d246f Mon Sep 17 00:00:00 2001 From: koksnuss Date: Wed, 10 Jul 2019 23:45:39 +0200 Subject: [PATCH] beautify --- build.sh | 0 src/have_I_b33n_pwned.py | 125 ++++++++++++++++----------------------- 2 files changed, 52 insertions(+), 73 deletions(-) mode change 100644 => 100755 build.sh mode change 100644 => 100755 src/have_I_b33n_pwned.py diff --git a/build.sh b/build.sh old mode 100644 new mode 100755 diff --git a/src/have_I_b33n_pwned.py b/src/have_I_b33n_pwned.py old mode 100644 new mode 100755 index 2b442cd..b2b4503 --- a/src/have_I_b33n_pwned.py +++ b/src/have_I_b33n_pwned.py @@ -27,80 +27,65 @@ from os import name from sys import argv, stdout, exit +from re import match from argparse import ArgumentParser from hashlib import sha1 from getpass import getpass from requests import get -if name == 'nt': +if name == 'nt': # disable colors for windows environment (RED, GREEN, RESET) = ("", "", "") else: - RED = "\033[1;31m" - GREEN = "\033[0;32m" - RESET = "\033[0;0m" -API = 'https://api.pwnedpasswords.com/range/' -API_MAIL = 'https://haveibeenpwned.com/api/v2/breachedaccount/' -ROW = '{:<30}{:<10}{:<45}' -HIDDEN = False + (RED, GREEN, RESET) = ("\033[1;31m", "\033[0;32m", "\033[0;0m") + +PASSWORD_API = 'https://api.pwnedpasswords.com/range/' +MAIL_API = 'https://haveibeenpwned.com/api/v2/breachedaccount/' +ROW = '{:<30}{:<10}{:<45}' +HIDDEN = True +INFINITE = True parser = ArgumentParser( description='Check if your email or password appears in a data leak.', - epilog='Moritz Münch, moritzmuench@mailbox.org, willipink.eu, GPL3+' -) -parser.add_argument('-m', '-mail', '--mail', - metavar='foo@adress.bar', - nargs='+', - help='Email address which should be checked against the leak database.' -) -parser.add_argument('-p', '-password', '--password', - metavar='password', - nargs='+', - help='Password which should be checked against the leak database.' -) + epilog='Moritz Münch, moritzmuench@mailbox.org, willipink.eu, GPL3+') +parser.add_argument('input', + nargs='*', + metavar='password or mail adress', + help='''You can specify passwords and mail adresses seperated by spaces. + If the password contains a space you have to enclose it in quotes like ' or + "''') +parser.add_argument('-s', '-show', '--show', + nargs='?', + help='Show entered in leak summary') args = parser.parse_args() - +if args.show: + HIDDEN = False -def header(): - print() - print(ROW.format('password', 'leaked', 'sha1')) - print('-' * 80) - - -def prompt_password_or_mail(): - print() - while True: - choice = input('Do you wannt to check a password [p] or an email adress [e]: ') - if choice == 'p': - prompt_password() - elif choice == 'e': - prompt_mail() - - -def prompt_password(): - print() - password = getpass('Tell me your password: ') +def input_prompt(): global HIDDEN - HIDDEN = True - header() - query_password(password) + if HIDDEN: + user_input = getpass('Tell me your password or mail adress: ') + else: + user_input = input('Tell me your password or mail adress: ') + check_mail_or_password(user_input) -def prompt_mail(): - print() - mail = input('Tell me your mail adress: ') - global HIDDEN - HIDDEN = True - header() - query_mail(mail) +def check_mail_or_password(user_input): + valid_mail = match(r'^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$', user_input) + if valid_mail: + query_mail(valid_mail.group()) + else: + query_password(user_input) def query_password(password): + ''' Query the first 5 digits of the sha1 hash of the user input + ti the haveibeenpwned.com api. ''' password_hash = sha1(password.encode('UTF-8')).hexdigest().upper() request = password_hash[:5] - response = get(API + request).text + response = get(PASSWORD_API + request).text hash_searched = 'not yet' for answer in response.splitlines(): data = answer.split(':') @@ -108,26 +93,23 @@ def query_password(password): if password_hash == combined_hash: hash_searched = int(data[1]) break - if hash_searched == 'not yet': stdout.write(GREEN) else: stdout.write(RED) - if HIDDEN: password = '*' * len(password) - + print(ROW.format('password', 'leaked', 'sha1')) + print('-' * 80) print(ROW.format(password, hash_searched, password_hash)) stdout.write(RESET) - - if HIDDEN: - prompt_password_or_mail() + if INFINITE: + input_prompt() def query_mail(mail): - print() try: - response = get(API_MAIL + mail).json() + response = get(MAIL_API + mail).json() for breach in response: print('Name: {}'.format(breach['Name'])) print('Title: {}'.format(breach['Title'])) @@ -137,28 +119,25 @@ def query_mail(mail): print('Modified date: {}'.format(breach['ModifiedDate'])) print('Pwn count: {}'.format(breach['PwnCount'])) print('Description: {}'.format(breach['Description'])) + stdout.write(RED) print('Breached data: {}'.format(', '.join([data for data in breach['DataClasses']]))) + stdout.write(RESET) print('Verified: {}'.format('yes' if breach['IsVerified'] == 1 else 'No')) print('Fabricated: {}'.format('yes' if breach['IsFabricated'] == 1 else 'No')) print('Sensitive: {}'.format('yes' if breach['IsSensitive'] == 1 else 'No')) print('Retired: {}'.format('yes' if breach['IsRetired'] == 1 else 'No')) print('Spam: {}'.format('yes' if breach['IsSpamList'] == 1 else 'No')) except: - print('The mail adress {} was not found in any leak databases so far'.format(mail)) - - if HIDDEN: - prompt_password_or_mail() + stdout.write(GREEN) + print('The mail adress {} is not in the leak database.'.format(mail)) + stdout.write(RESET) + query_password(mail) if __name__ == '__main__': - if args.password: - header() - for password in args.password: - query_password(password) - elif args.mail: - for mail in args.mail: - query_mail(mail) + if args.input: + for user_input in args.input: + check_mail_or_password(user_input) else: - prompt_password_or_mail() - print() - exit(0) + INFINITE = True + input_prompt()