make python password checks use the database and bcrypt

This commit is contained in:
Enno Rehling 2018-09-27 16:57:39 +02:00
parent 04b8068979
commit 5a1c96bd93
4 changed files with 92 additions and 44 deletions

View file

@ -6,14 +6,19 @@ from epasswd import EPasswd
if len(sys.argv)<4: if len(sys.argv)<4:
sys.exit(-2) sys.exit(-2)
passfile=sys.argv[1] filename=sys.argv[1]
myfaction=sys.argv[2] myfaction=sys.argv[2]
mypasswd=sys.argv[3] mypasswd=sys.argv[3]
if mypasswd[0]=='"': if mypasswd[0] == '"':
mypasswd=mypasswd[1:len(mypasswd)-1] mypasswd = mypasswd.strip('"')
pw_data = EPasswd()
try:
pw_data.load_database(filename)
except:
pw_data.load_file(filename)
pw_data=EPasswd(passfile)
if pw_data.fac_exists(myfaction): if pw_data.fac_exists(myfaction):
if pw_data.check(myfaction, mypasswd): if pw_data.check(myfaction, mypasswd):
sys.exit(0) sys.exit(0)

View file

@ -4,16 +4,55 @@ from string import split
from string import strip from string import strip
from string import lower from string import lower
import subprocess import subprocess
import bcrypt
import sqlite3
def baseconvert(n, base):
"""convert positive decimal integer n to equivalent in another base (2-36)"""
digits = "0123456789abcdefghijkLmnopqrstuvwxyz"
try:
n = int(n)
base = int(base)
except:
return ""
if n < 0 or base < 2 or base > 36:
return ""
s = ""
while True:
r = n % base
s = digits[r] + s
n = n / base
if n == 0:
break
return s
class EPasswd: class EPasswd:
def _check_apr1(self, pwhash, pw): def __init__(self):
spl = split(pwhash, '$')
salt = spl[2]
hash = subprocess.check_output(['openssl', 'passwd', '-apr1', '-salt', salt, pw]).decode('utf-8').strip()
return hash==pwhash
def __init__(self, file):
self.data = {} self.data = {}
def set_data(no, email, passwd):
lc_id = lower(no)
self.data[lc_id] = {}
self.data[lc_id]["id"] = no
self.data[lc_id]["email"] = email
self.data[lc_id]["passwd"] = passwd
def load_database(self, file):
conn = sqlite3.connect(file)
c = conn.cursor()
c.execute('SELECT MAX(turn) FROM factions')
args = c.fetchone()
for row in c.execute('SELECT no, email, password FROM factions WHERE turn=?', args):
(no, email, passwd) = row
self.set_data(baseconvert(no, 36), email, passwd)
conn.close()
def load_file(self, file):
try: try:
fp = open(file,"r") fp = open(file,"r")
except: except:
@ -24,17 +63,13 @@ class EPasswd:
if not line: break if not line: break
line = strip(line) line = strip(line)
[id, email, passwd] = split(line, ":")[0:3] [id, email, passwd] = split(line, ":")[0:3]
lc_id = lower(id) self.set_data(id, email, passwd)
self.data[lc_id] = {}
self.data[lc_id]["id"] = id
self.data[lc_id]["email"] = email
self.data[lc_id]["passwd"] = passwd
fp.close() fp.close()
def check(self, id, passwd): def check(self, id, passwd):
pw = self.get_passwd(id) pw = self.get_passwd(id)
if pw[0:6]=='$apr1$': if pw[0:4]=='$2a$' or pw[0:4]=='$2y$':
return self._check_apr1(pw, passwd) return bcrypt.checkpw(passwd, pw)
return pw == passwd return pw == passwd
def get_passwd(self, id): def get_passwd(self, id):

View file

@ -128,7 +128,11 @@ def echeck(filename, locale, rules):
return mail return mail
#print "reading password file..." #print "reading password file..."
pw_data = EPasswd(os.path.join(game_dir,"passwd")) pw_data = EPasswd()
try:
pw_data.load_database(os.path.join(game_dir,"eressea.db"))
except:
pw_data.load_file(os.path.join(game_dir,"passwd"))
#print "reading orders.queue..." #print "reading orders.queue..."
# move the queue file to a save space while locking it: # move the queue file to a save space while locking it:

View file

@ -30,7 +30,11 @@ LOCKFILE="$ERESSEA/.report.lock"
echo "$(date):report:$GAME:$EMAIL:$FACTION:$PASSWD" >> "$ERESSEA/request.log" echo "$(date):report:$GAME:$EMAIL:$FACTION:$PASSWD" >> "$ERESSEA/request.log"
cd "$ERESSEA" || exit cd "$ERESSEA" || exit
checkpasswd.py "game-$GAME/passwd" "$FACTION" "$PASSWD" || reply "Das Passwort fuer die Partei $FACTION ist ungueltig" PWFILE="game-$GAME/eressea.db"
if [ ! -e "$PWFILE" ]; then
PWFILE="game-$GAME/passwd"
fi
checkpasswd.py "$PWFILE" "$FACTION" "$PASSWD" || reply "Das Passwort fuer die Partei $FACTION ist ungueltig"
cd "$ERESSEA/game-$GAME/reports" || exit cd "$ERESSEA/game-$GAME/reports" || exit
if [ ! -e "${FACTION}.sh" ]; then if [ ! -e "${FACTION}.sh" ]; then