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,47 +4,82 @@ 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, '$') self.data = {}
salt = spl[2]
hash = subprocess.check_output(['openssl', 'passwd', '-apr1', '-salt', salt, pw]).decode('utf-8').strip()
return hash==pwhash
def __init__(self, file): def set_data(no, email, passwd):
self.data = {} lc_id = lower(no)
try: self.data[lc_id] = {}
fp = open(file,"r") self.data[lc_id]["id"] = no
except: self.data[lc_id]["email"] = email
fp = None self.data[lc_id]["passwd"] = passwd
if fp != None:
while True:
line = fp.readline()
if not line: break
line = strip(line)
[id, email, passwd] = split(line, ":")[0:3]
lc_id = lower(id)
self.data[lc_id] = {}
self.data[lc_id]["id"] = id
self.data[lc_id]["email"] = email
self.data[lc_id]["passwd"] = passwd
fp.close()
def check(self, id, passwd): def load_database(self, file):
pw = self.get_passwd(id) conn = sqlite3.connect(file)
if pw[0:6]=='$apr1$': c = conn.cursor()
return self._check_apr1(pw, passwd) c.execute('SELECT MAX(turn) FROM factions')
return pw == passwd 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 get_passwd(self, id): def load_file(self, file):
return self.data[lower(id)]["passwd"] try:
fp = open(file,"r")
def get_email(self, id): except:
return self.data[lower(id)]["email"] fp = None
if fp != None:
def get_canon_id(self, id): while True:
return self.data[lower(id)]["id"] line = fp.readline()
if not line: break
line = strip(line)
[id, email, passwd] = split(line, ":")[0:3]
self.set_data(id, email, passwd)
fp.close()
def fac_exists(self, id): def check(self, id, passwd):
return self.data.has_key(lower(id)) pw = self.get_passwd(id)
if pw[0:4]=='$2a$' or pw[0:4]=='$2y$':
return bcrypt.checkpw(passwd, pw)
return pw == passwd
def get_passwd(self, id):
return self.data[lower(id)]["passwd"]
def get_email(self, id):
return self.data[lower(id)]["email"]
def get_canon_id(self, id):
return self.data[lower(id)]["id"]
def fac_exists(self, id):
return self.data.has_key(lower(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