forked from embedded/micropython-ili9341
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
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()
|