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:
sys.exit(-2)
passfile=sys.argv[1]
filename=sys.argv[1]
myfaction=sys.argv[2]
mypasswd=sys.argv[3]
if mypasswd[0]=='"':
mypasswd=mypasswd[1:len(mypasswd)-1]
if mypasswd[0] == '"':
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.check(myfaction, mypasswd):
sys.exit(0)

View File

@ -4,47 +4,82 @@ from string import split
from string import strip
from string import lower
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:
def _check_apr1(self, pwhash, pw):
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):
self.data = {}
def __init__(self, file):
self.data = {}
try:
fp = open(file,"r")
except:
fp = None
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 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 check(self, id, passwd):
pw = self.get_passwd(id)
if pw[0:6]=='$apr1$':
return self._check_apr1(pw, passwd)
return pw == 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 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 load_file(self, file):
try:
fp = open(file,"r")
except:
fp = None
if fp != None:
while True:
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):
return self.data.has_key(lower(id))
def check(self, id, passwd):
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
#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..."
# 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"
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
if [ ! -e "${FACTION}.sh" ]; then