You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

110 lines
3.6 KiB
Python

5 years ago
"""Search online for pwned passwords."""
from machine import Pin, SPI
from hashlib import sha1
from ubinascii import hexlify
from urequests2 import get
from network import STA_IF, WLAN
import gc
from xpt2046 import Touch
from ili9341 import Display, color565
from xglcd_font import XglcdFont
from touch_keyboard import TouchKeyboard
from time import sleep
class PwnLookup(object):
"""Checks if password is pwned."""
def __init__(self, spi1, spi2, dc=4, cs1=16, rst=17, cs2=5, rotation=270):
"""Initialize PwnLookup."""
# Set up display
self.display = Display(spi1, dc=Pin(dc), cs=Pin(cs1), rst=Pin(rst),
width=320, height=240, rotation=rotation)
# Load font
self.unispace = XglcdFont('fonts/Unispace12x24.c', 12, 24)
# Set up Keyboard
self.keyboard = TouchKeyboard(self.display, self.unispace)
# Set up touchscreen
self.xpt = Touch(spi2, cs=Pin(cs2), int_pin=Pin(0),
int_handler=self.touchscreen_press)
self.wlan = WLAN(STA_IF)
def lookup(self, pwd):
"""Return the number of times password found in pwned database.
Args:
pwd: password to check
Returns:
integer: password hits from online pwned database.
Raises:
IOError: if there was an error due to WiFi network.
RuntimeError: if there was an error trying to fetch data from dB.
UnicodeError: if there was an error UTF_encoding the password.
"""
sha1pwd = sha1(pwd.encode('utf-8')).digest()
sha1pwd = hexlify(sha1pwd).upper().decode('utf-8')
head, tail = sha1pwd[:5], sha1pwd[5:]
if not self.wlan.isconnected():
raise IOError('WiFi network error')
hits = 0
gc.collect()
with get('https://api.pwnedpasswords.com/range/' + head) as response:
for line in response.iter_lines():
l = line.decode(response.encoding).split(":")
if l[0] == tail:
hits = int(l[1])
break
gc.collect()
return hits
def touchscreen_press(self, x, y):
"""Process touchscreen press events."""
if self.keyboard.handle_keypress(x, y, debug=False) is True:
self.keyboard.locked = True
pwd = self.keyboard.kb_text
self.keyboard.show_message("Searching...", color565(0, 0, 255))
try:
hits = self.lookup(pwd)
if hits:
# Password found
msg = "PASSWORD HITS: {0}".format(hits)
self.keyboard.show_message(msg, color565(255, 0, 0))
else:
# Password not found
msg = "PASSWORD NOT FOUND"
self.keyboard.show_message(msg, color565(0, 255, 0))
except Exception as e:
if hasattr(e, 'message'):
self.keyboard.show_message(e.message[:22],
color565(255, 255, 255))
else:
self.keyboard.show_message(str(e)[:22],
color565(255, 255, 255))
self.keyboard.waiting = True
self.keyboard.locked = False
def main():
"""Start PwnLookup."""
spi1 = SPI(1, baudrate=51200000,
sck=Pin(14), mosi=Pin(13), miso=Pin(12))
spi2 = SPI(2, baudrate=1000000,
sck=Pin(18), mosi=Pin(23), miso=Pin(19))
pwn = PwnLookup(spi1, spi2)
while True:
sleep(.1)
main()