made input upper case. renamed login to hack and added new login
This commit is contained in:
parent
84d382cfef
commit
b672f086d2
5 changed files with 399 additions and 258 deletions
|
@ -2,6 +2,7 @@
|
||||||
import fallout_login as login
|
import fallout_login as login
|
||||||
import fallout_boot as boot
|
import fallout_boot as boot
|
||||||
import fallout_locked as locked
|
import fallout_locked as locked
|
||||||
|
import fallout_hack as hack
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
hard = False
|
hard = False
|
||||||
|
@ -9,8 +10,11 @@ if len(sys.argv) == 2 and sys.argv[1].lower() == 'hard':
|
||||||
hard = True
|
hard = True
|
||||||
|
|
||||||
if boot.beginBoot(hard):
|
if boot.beginBoot(hard):
|
||||||
if login.beginLogin():
|
pwd = hack.beginLogin()
|
||||||
|
if pwd != None:
|
||||||
|
login.beginLogin(hard, 'ADMIN', pwd)
|
||||||
print 'Login successful'
|
print 'Login successful'
|
||||||
else:
|
else:
|
||||||
locked.beginLocked()
|
locked.beginLocked()
|
||||||
print 'Login failed'
|
print 'Login failed'
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
from fallout_functions import slowWrite
|
from fallout_functions import slowWrite
|
||||||
|
from fallout_functions import INPUT_PAUSE
|
||||||
|
from fallout_functions import TYPE_DELAY
|
||||||
|
from fallout_functions import upperInput
|
||||||
import curses
|
import curses
|
||||||
|
|
||||||
######################## global 'constants' ##############
|
######################## global 'constants' ##############
|
||||||
|
@ -11,9 +14,6 @@ ENTRY_3 = 'SET HALT RESTART/MAINT'
|
||||||
|
|
||||||
ENTRY_4 = 'RUN DEBUG/ACCOUNTS.F'
|
ENTRY_4 = 'RUN DEBUG/ACCOUNTS.F'
|
||||||
|
|
||||||
INPUT_PAUSE = 500 # ms
|
|
||||||
|
|
||||||
TYPE_DELAY = 25
|
|
||||||
|
|
||||||
######################## text strings ####################
|
######################## text strings ####################
|
||||||
|
|
||||||
|
@ -35,12 +35,16 @@ MESSAGE_3 = 'Initializing Robco Industries(TM) MF Boot Agent v2.3.0\n' \
|
||||||
def runBoot(scr, hardMode):
|
def runBoot(scr, hardMode):
|
||||||
"""
|
"""
|
||||||
Start the boot portion of the terminal
|
Start the boot portion of the terminal
|
||||||
|
|
||||||
|
hardMode - boolean indicating whether the user has to enter the ENTRY
|
||||||
|
constants, or if they are entered automatically
|
||||||
"""
|
"""
|
||||||
curses.use_default_colors()
|
curses.use_default_colors()
|
||||||
scr.erase()
|
scr.erase()
|
||||||
scr.move(0, 0)
|
scr.move(0, 0)
|
||||||
|
|
||||||
curses.echo()
|
curses.noecho()
|
||||||
|
scr.scrollok(True)
|
||||||
|
|
||||||
slowWrite(scr, MESSAGE_1 + '\n\n')
|
slowWrite(scr, MESSAGE_1 + '\n\n')
|
||||||
|
|
||||||
|
@ -49,7 +53,7 @@ def runBoot(scr, hardMode):
|
||||||
entry = ''
|
entry = ''
|
||||||
while entry.upper() != ENTRY_1.upper():
|
while entry.upper() != ENTRY_1.upper():
|
||||||
slowWrite(scr, '>')
|
slowWrite(scr, '>')
|
||||||
entry = scr.getstr()
|
entry = upperInput(scr)
|
||||||
else:
|
else:
|
||||||
# input is entered for them
|
# input is entered for them
|
||||||
slowWrite(scr, '>')
|
slowWrite(scr, '>')
|
||||||
|
@ -62,10 +66,10 @@ def runBoot(scr, hardMode):
|
||||||
entry = ''
|
entry = ''
|
||||||
while entry.upper() != ENTRY_2.upper():
|
while entry.upper() != ENTRY_2.upper():
|
||||||
slowWrite(scr, '>')
|
slowWrite(scr, '>')
|
||||||
entry = scr.getstr()
|
entry = upperInput(scr)
|
||||||
while entry.upper() != ENTRY_3.upper():
|
while entry.upper() != ENTRY_3.upper():
|
||||||
slowWrite(scr, '>')
|
slowWrite(scr, '>')
|
||||||
entry = scr.getstr()
|
entry = upperInput(scr)
|
||||||
else:
|
else:
|
||||||
slowWrite(scr, '>')
|
slowWrite(scr, '>')
|
||||||
curses.napms(INPUT_PAUSE)
|
curses.napms(INPUT_PAUSE)
|
||||||
|
@ -80,7 +84,7 @@ def runBoot(scr, hardMode):
|
||||||
entry = ''
|
entry = ''
|
||||||
while entry.upper() != ENTRY_4.upper():
|
while entry.upper() != ENTRY_4.upper():
|
||||||
slowWrite(scr, '>')
|
slowWrite(scr, '>')
|
||||||
entry = scr.getstr()
|
entry = upperInput(scr)
|
||||||
else:
|
else:
|
||||||
slowWrite(scr, '>')
|
slowWrite(scr, '>')
|
||||||
curses.napms(INPUT_PAUSE)
|
curses.napms(INPUT_PAUSE)
|
||||||
|
|
|
@ -4,6 +4,16 @@ import sys
|
||||||
|
|
||||||
LETTER_PAUSE = 5
|
LETTER_PAUSE = 5
|
||||||
|
|
||||||
|
INPUT_PAUSE = 500 # ms
|
||||||
|
|
||||||
|
TYPE_DELAY = 30
|
||||||
|
|
||||||
|
HIDDEN_MASK = '*'
|
||||||
|
|
||||||
|
NEWLINE = 10
|
||||||
|
|
||||||
|
DELETE = 127
|
||||||
|
|
||||||
def slowWrite(window, text, pause = LETTER_PAUSE):
|
def slowWrite(window, text, pause = LETTER_PAUSE):
|
||||||
"""
|
"""
|
||||||
wrapper for curses.addstr() which writes the text slowely
|
wrapper for curses.addstr() which writes the text slowely
|
||||||
|
@ -12,3 +22,40 @@ def slowWrite(window, text, pause = LETTER_PAUSE):
|
||||||
window.addstr(text[i])
|
window.addstr(text[i])
|
||||||
window.refresh()
|
window.refresh()
|
||||||
curses.napms(pause)
|
curses.napms(pause)
|
||||||
|
|
||||||
|
def upperInput(window, hidden = False, can_newline = True):
|
||||||
|
"""
|
||||||
|
Reads user input until enter key is pressed. Echoes the input in upper case
|
||||||
|
|
||||||
|
hidden - if true the output will be masked
|
||||||
|
can_newline - if true the input is followed by a newline and the screen is
|
||||||
|
scrolled if necessary
|
||||||
|
"""
|
||||||
|
inchar = 0
|
||||||
|
instr = ''
|
||||||
|
while inchar != NEWLINE:
|
||||||
|
inchar = window.getch()
|
||||||
|
# convert lower case to upper
|
||||||
|
if inchar > 96 and inchar < 123:
|
||||||
|
inchar -= 32
|
||||||
|
# deal with backspace
|
||||||
|
if inchar == DELETE:
|
||||||
|
if len(instr) > 0:
|
||||||
|
instr = instr[:-1]
|
||||||
|
cur = window.getyx()
|
||||||
|
window.move(cur[0], cur[1] - 1)
|
||||||
|
window.clrtobot()
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
elif inchar > 255:
|
||||||
|
continue
|
||||||
|
# output the character
|
||||||
|
elif inchar != NEWLINE:
|
||||||
|
instr += chr(inchar)
|
||||||
|
if hidden:
|
||||||
|
window.addch(HIDDEN_MASK)
|
||||||
|
else:
|
||||||
|
window.addch(inchar)
|
||||||
|
elif can_newline:
|
||||||
|
window.addch(NEWLINE)
|
||||||
|
return instr
|
||||||
|
|
272
fallout_hack.py
Normal file
272
fallout_hack.py
Normal file
|
@ -0,0 +1,272 @@
|
||||||
|
import curses
|
||||||
|
import random
|
||||||
|
import os
|
||||||
|
from fallout_functions import slowWrite
|
||||||
|
from fallout_functions import upperInput
|
||||||
|
|
||||||
|
################## text strings ######################
|
||||||
|
|
||||||
|
HEADER_TEXT = 'ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL'
|
||||||
|
|
||||||
|
################## global "constants" ################
|
||||||
|
|
||||||
|
# number of characters for hex digits and spaces
|
||||||
|
CONST_CHARS = 16
|
||||||
|
|
||||||
|
# position of the attempt squares
|
||||||
|
SQUARE_X = 19
|
||||||
|
SQUARE_Y = 3
|
||||||
|
|
||||||
|
LOGIN_ATTEMPTS = 4
|
||||||
|
|
||||||
|
HEADER_LINES = 5
|
||||||
|
|
||||||
|
# amount of time to pause after correct password input
|
||||||
|
LOGIN_PAUSE = 3000
|
||||||
|
|
||||||
|
# starting number for hex generation
|
||||||
|
START_HEX = 0xf650
|
||||||
|
|
||||||
|
# list of possible symbols for password hiding
|
||||||
|
SYMBOLS = '!@#$%^*()_-+={}[]|\\:;\'",<>./?'
|
||||||
|
|
||||||
|
################## functions #########################
|
||||||
|
|
||||||
|
def generateHex(n):
|
||||||
|
"""
|
||||||
|
generates n numbers starting at START_HEX and increasing by 12 each time
|
||||||
|
"""
|
||||||
|
num = START_HEX
|
||||||
|
list = []
|
||||||
|
for i in xrange(n):
|
||||||
|
list.append(num)
|
||||||
|
num += 12
|
||||||
|
return list
|
||||||
|
|
||||||
|
|
||||||
|
def getSymbols(n):
|
||||||
|
"""
|
||||||
|
return n random symbols
|
||||||
|
"""
|
||||||
|
count = len(SYMBOLS)
|
||||||
|
result = ""
|
||||||
|
for i in xrange(n):
|
||||||
|
result += SYMBOLS[random.randint(0, count - 1)]
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def getPasswords():
|
||||||
|
"""
|
||||||
|
Returns an array of strings to be used as the password and the decoys
|
||||||
|
"""
|
||||||
|
groups = []
|
||||||
|
|
||||||
|
# script file / password file location
|
||||||
|
__location__ = os.path.realpath(os.path.join(os.getcwd(),
|
||||||
|
os.path.dirname(__file__)))
|
||||||
|
|
||||||
|
# read from passwords.txt
|
||||||
|
with open(os.path.join(__location__, "passwords.txt")) as pwfile:
|
||||||
|
for line in pwfile:
|
||||||
|
if not line.strip():
|
||||||
|
groups.append([])
|
||||||
|
elif len(groups) > 0:
|
||||||
|
groups[len(groups) - 1].append(line[:-1])
|
||||||
|
|
||||||
|
passwords = groups[random.randint(0, len(groups) - 1)]
|
||||||
|
|
||||||
|
random.shuffle(passwords)
|
||||||
|
return passwords
|
||||||
|
|
||||||
|
|
||||||
|
def getFiller(length, passwords):
|
||||||
|
"""
|
||||||
|
Return a string of symbols with potential passwords mixed in
|
||||||
|
|
||||||
|
length - the length of the string to create
|
||||||
|
passwords - an array of passwords to hide in the symbols
|
||||||
|
"""
|
||||||
|
filler = getSymbols(length)
|
||||||
|
|
||||||
|
# add the passwords to the symbols
|
||||||
|
pwdLen = len(passwords[0])
|
||||||
|
pwdCount = len(passwords)
|
||||||
|
i = 0
|
||||||
|
for pwd in passwords:
|
||||||
|
# skip a distance based on total size to cover then place a password
|
||||||
|
maxSkip = length / pwdCount - pwdLen
|
||||||
|
i += random.randint(maxSkip - 2, maxSkip)
|
||||||
|
filler = filler[:i] + pwd + filler[i + pwdLen:]
|
||||||
|
i += pwdLen
|
||||||
|
return filler
|
||||||
|
|
||||||
|
|
||||||
|
def initScreen(scr):
|
||||||
|
"""
|
||||||
|
Fill the screen to prepare for password entry
|
||||||
|
|
||||||
|
scr - curses window returned from curses.initscr()
|
||||||
|
"""
|
||||||
|
size = scr.getmaxyx()
|
||||||
|
height = size[0]
|
||||||
|
width = size[1]
|
||||||
|
fillerHeight = height - HEADER_LINES
|
||||||
|
|
||||||
|
hexes = generateHex(fillerHeight * 2)
|
||||||
|
|
||||||
|
hexCol1 = hexes[:fillerHeight]
|
||||||
|
hexCol2 = hexes[fillerHeight:]
|
||||||
|
|
||||||
|
# generate the symbols and passwords
|
||||||
|
fillerLength = width / 2 * fillerHeight
|
||||||
|
passwords = getPasswords()
|
||||||
|
filler = getFiller(fillerLength, passwords)
|
||||||
|
fillerCol1 = filler[:len(filler) / 2]
|
||||||
|
fillerCol2 = filler[len(filler) / 2:]
|
||||||
|
|
||||||
|
# each column of symbols and passwords should be 1/4 of the screen
|
||||||
|
fillerWidth = width / 4
|
||||||
|
|
||||||
|
# print the header stuff
|
||||||
|
slowWrite(scr, HEADER_TEXT)
|
||||||
|
slowWrite(scr, '\nENTER PASSWORD NOW\n\n')
|
||||||
|
slowWrite(scr, str(LOGIN_ATTEMPTS) + ' ATTEMPT(S) LEFT: ')
|
||||||
|
for i in xrange(LOGIN_ATTEMPTS):
|
||||||
|
scr.addch(curses.ACS_BLOCK)
|
||||||
|
slowWrite(scr, ' ')
|
||||||
|
slowWrite(scr, '\n\n')
|
||||||
|
|
||||||
|
# print the hex and filler
|
||||||
|
for i in xrange(fillerHeight):
|
||||||
|
slowWrite(scr, "0x%X %s" % (hexCol1[i], fillerCol1[i * fillerWidth: (i + 1) * fillerWidth]), 1)
|
||||||
|
if i < fillerHeight - 1:
|
||||||
|
scr.addstr('\n')
|
||||||
|
|
||||||
|
for i in xrange(fillerHeight):
|
||||||
|
scr.move(HEADER_LINES + i, CONST_CHARS / 2 + fillerWidth)
|
||||||
|
slowWrite(scr, '0x%X %s' % (hexCol2[i], fillerCol2[i * fillerWidth: (i + 1) * fillerWidth]), 1)
|
||||||
|
|
||||||
|
scr.refresh()
|
||||||
|
|
||||||
|
return passwords
|
||||||
|
|
||||||
|
|
||||||
|
def moveInput(scr, inputPad):
|
||||||
|
"""
|
||||||
|
moves the input pad to display all text then a blank line then the cursor
|
||||||
|
"""
|
||||||
|
size = scr.getmaxyx()
|
||||||
|
height = size[0]
|
||||||
|
width = size[1]
|
||||||
|
|
||||||
|
inputPad.addstr('\n>')
|
||||||
|
|
||||||
|
# cursor position relative to inputPad
|
||||||
|
cursorPos = inputPad.getyx()
|
||||||
|
|
||||||
|
inputPad.refresh(0, 0,
|
||||||
|
height - cursorPos[0] - 1,
|
||||||
|
width / 2 + CONST_CHARS,
|
||||||
|
height - 1,
|
||||||
|
width - 1)
|
||||||
|
|
||||||
|
|
||||||
|
def userInput(scr, passwords):
|
||||||
|
"""
|
||||||
|
let the user attempt to crack the password
|
||||||
|
|
||||||
|
scr - curses window returned from curses.initscr()
|
||||||
|
passwords - array of passwords hidden in the symbols
|
||||||
|
"""
|
||||||
|
size = scr.getmaxyx()
|
||||||
|
height = size[0]
|
||||||
|
width = size[1]
|
||||||
|
|
||||||
|
# set up a pad for user input
|
||||||
|
inputPad = curses.newpad(height, width / 2 + CONST_CHARS)
|
||||||
|
|
||||||
|
attempts = LOGIN_ATTEMPTS
|
||||||
|
|
||||||
|
# randomly pick a password from the list
|
||||||
|
pwd = passwords[random.randint(0, len(passwords) - 1)]
|
||||||
|
curses.noecho()
|
||||||
|
|
||||||
|
while attempts > 0:
|
||||||
|
# move the curser to the correct spot for typing
|
||||||
|
scr.move(height - 1, width / 2 + CONST_CHARS + 1)
|
||||||
|
|
||||||
|
# scroll user input up as the user tries passwords
|
||||||
|
moveInput(scr, inputPad)
|
||||||
|
|
||||||
|
guess = upperInput(scr, False, False)
|
||||||
|
cursorPos = inputPad.getyx()
|
||||||
|
|
||||||
|
# write under the last line of text
|
||||||
|
inputPad.move(cursorPos[0] - 1, cursorPos[1] - 1)
|
||||||
|
inputPad.addstr('>' + guess.upper() + '\n')
|
||||||
|
|
||||||
|
# user got password right
|
||||||
|
if guess.upper() == pwd.upper():
|
||||||
|
inputPad.addstr('>Exact match!\n')
|
||||||
|
inputPad.addstr('>Please wait\n')
|
||||||
|
inputPad.addstr('>while system\n')
|
||||||
|
inputPad.addstr('>is accessed.\n')
|
||||||
|
|
||||||
|
moveInput(scr, inputPad)
|
||||||
|
|
||||||
|
curses.napms(LOGIN_PAUSE)
|
||||||
|
return pwd
|
||||||
|
|
||||||
|
# wrong password
|
||||||
|
else:
|
||||||
|
pwdLen = len(pwd)
|
||||||
|
matched = 0
|
||||||
|
try:
|
||||||
|
for i in xrange(pwdLen):
|
||||||
|
if pwd[i].upper() == guess[i].upper():
|
||||||
|
matched += 1
|
||||||
|
except IndexError:
|
||||||
|
pass # user did not enter enough letters
|
||||||
|
|
||||||
|
inputPad.addstr('>Entry denied\n')
|
||||||
|
inputPad.addstr('>' + str(matched) + '/' + str(pwdLen) +
|
||||||
|
' correct.\n')
|
||||||
|
|
||||||
|
attempts -= 1
|
||||||
|
# show remaining attempts
|
||||||
|
scr.move(SQUARE_Y, 0)
|
||||||
|
scr.addstr(str(attempts))
|
||||||
|
scr.move(SQUARE_Y, SQUARE_X)
|
||||||
|
for i in xrange(LOGIN_ATTEMPTS):
|
||||||
|
if i < attempts:
|
||||||
|
scr.addch(curses.ACS_BLOCK)
|
||||||
|
else:
|
||||||
|
scr.addstr(' ')
|
||||||
|
scr.addstr(' ')
|
||||||
|
|
||||||
|
# Out of attempts
|
||||||
|
return None
|
||||||
|
|
||||||
|
def runLogin(scr):
|
||||||
|
"""
|
||||||
|
Start the login portion of the terminal
|
||||||
|
Returns the password if the user correctly guesses it
|
||||||
|
"""
|
||||||
|
curses.use_default_colors()
|
||||||
|
size = scr.getmaxyx()
|
||||||
|
width = size[1]
|
||||||
|
height = size[0]
|
||||||
|
random.seed()
|
||||||
|
# set screen to initial position
|
||||||
|
scr.erase()
|
||||||
|
scr.move(0, 0)
|
||||||
|
passwords = initScreen(scr)
|
||||||
|
return userInput(scr, passwords)
|
||||||
|
|
||||||
|
|
||||||
|
def beginLogin():
|
||||||
|
"""
|
||||||
|
Initialize curses and start the login process
|
||||||
|
Returns the password if the user correctly guesses it
|
||||||
|
"""
|
||||||
|
return curses.wrapper(runLogin)
|
312
fallout_login.py
312
fallout_login.py
|
@ -1,270 +1,84 @@
|
||||||
import curses
|
import curses
|
||||||
import random
|
|
||||||
import os
|
|
||||||
from fallout_functions import slowWrite
|
from fallout_functions import slowWrite
|
||||||
|
from fallout_functions import INPUT_PAUSE
|
||||||
|
from fallout_functions import TYPE_DELAY
|
||||||
|
from fallout_functions import upperInput
|
||||||
|
from fallout_functions import HIDDEN_MASK
|
||||||
################## text strings ######################
|
################## text strings ######################
|
||||||
|
|
||||||
HEADER_TEXT = 'ROBCO INDUSTRIES (TM) TERMLINK PROTOCOL'
|
HEADER_TEXT = 'WELCOME TO ROBCO INDUSTRIES (TM) TERMLINK'
|
||||||
|
|
||||||
|
PASSWORD_PROMPT = 'ENTER PASSWORD NOW'
|
||||||
|
|
||||||
|
PASSWORD_ERROR = 'INCORRECT PASSWORD, PLEASE TRY AGAIN'
|
||||||
|
|
||||||
################## global "constants" ################
|
################## global "constants" ################
|
||||||
|
|
||||||
# number of characters for hex digits and spaces
|
ENTRY = 'LOGON '
|
||||||
CONST_CHARS = 16
|
|
||||||
|
|
||||||
# position of the attempt squares
|
|
||||||
SQUARE_X = 19
|
|
||||||
SQUARE_Y = 3
|
|
||||||
|
|
||||||
LOGIN_ATTEMPTS = 4
|
|
||||||
|
|
||||||
HEADER_LINES = 5
|
|
||||||
|
|
||||||
# amount of time to pause after correct password input
|
|
||||||
LOGIN_PAUSE = 3000
|
|
||||||
|
|
||||||
# starting number for hex generation
|
|
||||||
START_HEX = 0xf650
|
|
||||||
|
|
||||||
# list of possible symbols for password hiding
|
|
||||||
SYMBOLS = '!@#$%^*()_-+={}[]|\\:;\'",<>./?'
|
|
||||||
|
|
||||||
################## functions #########################
|
################## functions #########################
|
||||||
|
|
||||||
def generateHex(n):
|
def runLogin(scr, hardMode, username, password):
|
||||||
"""
|
"""
|
||||||
generates n numbers starting at START_HEX and increasing by 12 each time
|
Start the login process
|
||||||
"""
|
|
||||||
num = START_HEX
|
|
||||||
list = []
|
|
||||||
for i in xrange(n):
|
|
||||||
list.append(num)
|
|
||||||
num += 12
|
|
||||||
return list
|
|
||||||
|
|
||||||
|
hardMode - boolean indicating whether the user has to enter the username
|
||||||
def getSymbols(n):
|
and password or if they are entered automatically
|
||||||
"""
|
username - the username to log in
|
||||||
return n random symbols
|
password - the password to log in
|
||||||
"""
|
Returns true if hardMode == false or if the user entered the correct string
|
||||||
count = len(SYMBOLS)
|
|
||||||
result = ""
|
|
||||||
for i in xrange(n):
|
|
||||||
result += SYMBOLS[random.randint(0, count - 1)]
|
|
||||||
return result
|
|
||||||
|
|
||||||
|
|
||||||
def getPasswords():
|
|
||||||
"""
|
|
||||||
Returns an array of strings to be used as the password and the decoys
|
|
||||||
"""
|
|
||||||
groups = []
|
|
||||||
|
|
||||||
# script file / password file location
|
|
||||||
__location__ = os.path.realpath(os.path.join(os.getcwd(),
|
|
||||||
os.path.dirname(__file__)))
|
|
||||||
|
|
||||||
# read from passwords.txt
|
|
||||||
with open(os.path.join(__location__, "passwords.txt")) as pwfile:
|
|
||||||
for line in pwfile:
|
|
||||||
if not line.strip():
|
|
||||||
groups.append([])
|
|
||||||
elif len(groups) > 0:
|
|
||||||
groups[len(groups) - 1].append(line[:-1])
|
|
||||||
|
|
||||||
passwords = groups[random.randint(0, len(groups) - 1)]
|
|
||||||
|
|
||||||
random.shuffle(passwords)
|
|
||||||
return passwords
|
|
||||||
|
|
||||||
|
|
||||||
def getFiller(length, passwords):
|
|
||||||
"""
|
|
||||||
Return a string of symbols with potential passwords mixed in
|
|
||||||
|
|
||||||
length - the length of the string to create
|
|
||||||
passwords - an array of passwords to hide in the symbols
|
|
||||||
"""
|
|
||||||
filler = getSymbols(length)
|
|
||||||
|
|
||||||
# add the passwords to the symbols
|
|
||||||
pwdLen = len(passwords[0])
|
|
||||||
pwdCount = len(passwords)
|
|
||||||
i = 0
|
|
||||||
for pwd in passwords:
|
|
||||||
# skip a distance based on total size to cover then place a password
|
|
||||||
maxSkip = length / pwdCount - pwdLen
|
|
||||||
i += random.randint(maxSkip - 2, maxSkip)
|
|
||||||
filler = filler[:i] + pwd + filler[i + pwdLen:]
|
|
||||||
i += pwdLen
|
|
||||||
return filler
|
|
||||||
|
|
||||||
|
|
||||||
def initScreen(scr):
|
|
||||||
"""
|
|
||||||
Fill the screen to prepare for password entry
|
|
||||||
|
|
||||||
scr - curses window returned from curses.initscr()
|
|
||||||
"""
|
|
||||||
size = scr.getmaxyx()
|
|
||||||
height = size[0]
|
|
||||||
width = size[1]
|
|
||||||
fillerHeight = height - HEADER_LINES
|
|
||||||
|
|
||||||
hexes = generateHex(fillerHeight * 2)
|
|
||||||
|
|
||||||
hexCol1 = hexes[:fillerHeight]
|
|
||||||
hexCol2 = hexes[fillerHeight:]
|
|
||||||
|
|
||||||
# generate the symbols and passwords
|
|
||||||
fillerLength = width / 2 * fillerHeight
|
|
||||||
passwords = getPasswords()
|
|
||||||
filler = getFiller(fillerLength, passwords)
|
|
||||||
fillerCol1 = filler[:len(filler) / 2]
|
|
||||||
fillerCol2 = filler[len(filler) / 2:]
|
|
||||||
|
|
||||||
# each column of symbols and passwords should be 1/4 of the screen
|
|
||||||
fillerWidth = width / 4
|
|
||||||
|
|
||||||
# print the header stuff
|
|
||||||
slowWrite(scr, HEADER_TEXT)
|
|
||||||
slowWrite(scr, '\nENTER PASSWORD NOW\n\n')
|
|
||||||
slowWrite(scr, str(LOGIN_ATTEMPTS) + ' ATTEMPT(S) LEFT: ')
|
|
||||||
for i in xrange(LOGIN_ATTEMPTS):
|
|
||||||
scr.addch(curses.ACS_BLOCK)
|
|
||||||
slowWrite(scr, ' ')
|
|
||||||
slowWrite(scr, '\n\n')
|
|
||||||
|
|
||||||
# print the hex and filler
|
|
||||||
for i in xrange(fillerHeight):
|
|
||||||
slowWrite(scr, "0x%X %s" % (hexCol1[i], fillerCol1[i * fillerWidth: (i + 1) * fillerWidth]), 1)
|
|
||||||
if i < fillerHeight - 1:
|
|
||||||
scr.addstr('\n')
|
|
||||||
|
|
||||||
for i in xrange(fillerHeight):
|
|
||||||
scr.move(HEADER_LINES + i, CONST_CHARS / 2 + fillerWidth)
|
|
||||||
slowWrite(scr, '0x%X %s' % (hexCol2[i], fillerCol2[i * fillerWidth: (i + 1) * fillerWidth]), 1)
|
|
||||||
|
|
||||||
scr.refresh()
|
|
||||||
|
|
||||||
return passwords
|
|
||||||
|
|
||||||
|
|
||||||
def moveInput(scr, inputPad):
|
|
||||||
"""
|
|
||||||
moves the input pad to display all text then a blank line then the cursor
|
|
||||||
"""
|
|
||||||
size = scr.getmaxyx()
|
|
||||||
height = size[0]
|
|
||||||
width = size[1]
|
|
||||||
|
|
||||||
inputPad.addstr('\n>')
|
|
||||||
|
|
||||||
# cursor position relative to inputPad
|
|
||||||
cursorPos = inputPad.getyx()
|
|
||||||
|
|
||||||
inputPad.refresh(0, 0,
|
|
||||||
height - cursorPos[0] - 1,
|
|
||||||
width / 2 + CONST_CHARS,
|
|
||||||
height - 1,
|
|
||||||
width - 1)
|
|
||||||
|
|
||||||
|
|
||||||
def userInput(scr, passwords):
|
|
||||||
"""
|
|
||||||
let the user attempt to crack the password
|
|
||||||
|
|
||||||
scr - curses window returned from curses.initscr()
|
|
||||||
passwords - array of passwords hidden in the symbols
|
|
||||||
"""
|
|
||||||
size = scr.getmaxyx()
|
|
||||||
height = size[0]
|
|
||||||
width = size[1]
|
|
||||||
|
|
||||||
# set up a pad for user input
|
|
||||||
inputPad = curses.newpad(height, width / 2 + CONST_CHARS)
|
|
||||||
|
|
||||||
attempts = LOGIN_ATTEMPTS
|
|
||||||
|
|
||||||
# randomly pick a password from the list
|
|
||||||
pwd = passwords[random.randint(0, len(passwords) - 1)]
|
|
||||||
curses.echo()
|
|
||||||
|
|
||||||
while attempts > 0:
|
|
||||||
# move the curser to the correct spot for typing
|
|
||||||
scr.move(height - 1, width / 2 + CONST_CHARS + 1)
|
|
||||||
|
|
||||||
# scroll user input up as the user tries passwords
|
|
||||||
moveInput(scr, inputPad)
|
|
||||||
|
|
||||||
guess = scr.getstr()
|
|
||||||
cursorPos = inputPad.getyx()
|
|
||||||
|
|
||||||
# write under the last line of text
|
|
||||||
inputPad.move(cursorPos[0] - 1, cursorPos[1] - 1)
|
|
||||||
inputPad.addstr('>' + guess.upper() + '\n')
|
|
||||||
|
|
||||||
# user got password right
|
|
||||||
if guess.upper() == pwd.upper():
|
|
||||||
inputPad.addstr('>Exact match!\n')
|
|
||||||
inputPad.addstr('>Please wait\n')
|
|
||||||
inputPad.addstr('>while system\n')
|
|
||||||
inputPad.addstr('>is accessed.\n')
|
|
||||||
|
|
||||||
moveInput(scr, inputPad)
|
|
||||||
|
|
||||||
curses.napms(LOGIN_PAUSE)
|
|
||||||
return True
|
|
||||||
|
|
||||||
# wrong password
|
|
||||||
else:
|
|
||||||
pwdLen = len(pwd)
|
|
||||||
matched = 0
|
|
||||||
try:
|
|
||||||
for i in xrange(pwdLen):
|
|
||||||
if pwd[i].upper() == guess[i].upper():
|
|
||||||
matched += 1
|
|
||||||
except IndexError:
|
|
||||||
pass # user did not enter enough letters
|
|
||||||
|
|
||||||
inputPad.addstr('>Entry denied\n')
|
|
||||||
inputPad.addstr('>' + str(matched) + '/' + str(pwdLen) +
|
|
||||||
' correct.\n')
|
|
||||||
|
|
||||||
attempts -= 1
|
|
||||||
# show remaining attempts
|
|
||||||
scr.move(SQUARE_Y, 0)
|
|
||||||
scr.addstr(str(attempts))
|
|
||||||
scr.move(SQUARE_Y, SQUARE_X)
|
|
||||||
for i in xrange(LOGIN_ATTEMPTS):
|
|
||||||
if i < attempts:
|
|
||||||
scr.addch(curses.ACS_BLOCK)
|
|
||||||
else:
|
|
||||||
scr.addstr(' ')
|
|
||||||
scr.addstr(' ')
|
|
||||||
|
|
||||||
# Out of attempts
|
|
||||||
return False
|
|
||||||
|
|
||||||
def runLogin(scr):
|
|
||||||
"""
|
|
||||||
Start the login portion of the terminal
|
|
||||||
"""
|
"""
|
||||||
curses.use_default_colors()
|
curses.use_default_colors()
|
||||||
size = scr.getmaxyx()
|
|
||||||
width = size[1]
|
|
||||||
height = size[0]
|
|
||||||
random.seed()
|
|
||||||
# set screen to initial position
|
|
||||||
scr.erase()
|
scr.erase()
|
||||||
scr.move(0, 0)
|
scr.move(0, 0)
|
||||||
passwords = initScreen(scr)
|
|
||||||
return userInput(scr, passwords)
|
curses.noecho()
|
||||||
|
scr.scrollok(True)
|
||||||
|
|
||||||
|
slowWrite(scr, HEADER_TEXT + '\n\n')
|
||||||
|
|
||||||
|
if hardMode:
|
||||||
|
# use must enter the correct text to proceed
|
||||||
|
entry = ''
|
||||||
|
while entry.upper() != ENTRY.upper() + username.upper():
|
||||||
|
slowWrite(scr, '> ')
|
||||||
|
entry = upperInput(scr)
|
||||||
|
else:
|
||||||
|
# input is entered for them
|
||||||
|
slowWrite(scr, '> ')
|
||||||
|
curses.napms(INPUT_PAUSE)
|
||||||
|
slowWrite(scr, ENTRY + username.upper() + '\n', TYPE_DELAY)
|
||||||
|
|
||||||
|
slowWrite(scr, '\n' + PASSWORD_PROMPT + '\n\n')
|
||||||
|
|
||||||
|
if hardMode:
|
||||||
|
# use must enter the correct text to proceed
|
||||||
|
entry = ''
|
||||||
|
while entry.upper() != password.upper():
|
||||||
|
if entry:
|
||||||
|
slowWrite(scr, PASSWORD_ERROR + '\n\n')
|
||||||
|
|
||||||
|
slowWrite(scr, '> ')
|
||||||
|
entry = upperInput(scr, True)
|
||||||
|
else:
|
||||||
|
# input is entered for them
|
||||||
|
slowWrite(scr, '> ')
|
||||||
|
curses.napms(INPUT_PAUSE)
|
||||||
|
password_stars = HIDDEN_MASK * len(password)
|
||||||
|
slowWrite(scr, password_stars + '\n', TYPE_DELAY)
|
||||||
|
|
||||||
|
curses.napms(500)
|
||||||
|
|
||||||
|
|
||||||
def beginLogin():
|
def beginLogin(hardMode, username, password):
|
||||||
"""
|
"""
|
||||||
Initialize curses and start the login process
|
Initialize curses and start the login process
|
||||||
Returns true if the user correctly guesses the password
|
|
||||||
|
hardMode - boolean indicating whether the user has to enter the username
|
||||||
|
and password or if they are entered automatically
|
||||||
|
username - the username to log in
|
||||||
|
password - the password to log in
|
||||||
|
Returns true if hardMode == false or if the user entered the correct string
|
||||||
"""
|
"""
|
||||||
return curses.wrapper(runLogin)
|
res = curses.wrapper(runLogin, hardMode, username, password)
|
||||||
|
return res
|
||||||
|
|
Loading…
Reference in a new issue