doorlockd: backend: support local authentication

Signed-off-by: Ralf Ramsauer <ralf@binary-kitchen.de>
This commit is contained in:
Ralf Ramsauer 2018-09-18 00:25:21 +02:00
parent f6eabcd8cf
commit 45724f37c8
3 changed files with 76 additions and 1 deletions

View File

@ -17,6 +17,7 @@ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
"""
import hashlib
import ldap
import logging
import sys
@ -76,6 +77,7 @@ run_hooks = webapp.config.get('RUN_HOOKS')
room = webapp.config.get('ROOM')
title = webapp.config.get('TITLE')
welcome = webapp.config.get('WELCOME')
file_local_db = webapp.config.get('LOCAL_USER_DB')
html_title = '%s (%s - v%s)' % (title, __status__, __version__)
@ -143,6 +145,7 @@ def start_hook(script):
class AuthMethod(Enum):
LDAP_USER_PW = 1
LOCAL_USER_DB = 2
class DoorState(Enum):
@ -319,6 +322,28 @@ class DoorHandler:
class Logic:
def __init__(self):
self.door_handler = DoorHandler(serial_port)
self.local_db = dict()
if not file_local_db:
return
with open(file_local_db, 'r') as f:
for line in f:
line = line.split()
user = line[0]
pwd = line[1].split(':')
self.local_db[user] = pwd
def _try_auth_local(self, user, password):
if user not in self.local_db:
return LogicResponse.Perm
stored_pw = self.local_db[user][0]
stored_salt = self.local_db[user][1]
if stored_pw == hashlib.sha256(stored_salt.encode() + password.encode()).hexdigest():
return LogicResponse.Success
return LogicResponse.Perm
def _try_auth_ldap(self, user, password):
if simulate_ldap:
@ -343,6 +368,8 @@ class Logic:
method = credentials[0]
if method == AuthMethod.LDAP_USER_PW:
return self._try_auth_ldap(credentials[1], credentials[2])
elif method == AuthMethod.LOCAL_USER_DB:
return self._try_auth_local(credentials[1], credentials[2])
return LogicResponse.Inval
@ -428,10 +455,16 @@ def api():
json['status'] = logic.state.value
return jsonify(json)
method = request.form.get('method')
user = request.form.get('user')
password = request.form.get('pass')
command = request.form.get('command')
if method == 'local':
method = AuthMethod.LOCAL_USER_DB
else: # 'ldap' or default
method = AuthMethod.LDAP_USER_PW
if any(v is None for v in [user, password, command]):
log.warning('Incomplete API request')
abort(400)
@ -441,7 +474,7 @@ def api():
return json_response(LogicResponse.Inval,
'Invalid username or password format')
credentials = AuthMethod.LDAP_USER_PW, user, password
credentials = method, user, password
if command == 'status':
return json_response(logic.try_auth(credentials))

40
doorlockd-passwd Executable file
View File

@ -0,0 +1,40 @@
#!/usr/bin/env python3
"""
Doorlockd -- Binary Kitchen's smart door opener
Copyright (c) Binary Kitchen e.V., 2018
Author:
Ralf Ramsauer <ralf@binary-kitchen.de>
This work is licensed under the terms of the GNU GPL, version 2. See
the LICENSE file in the top-level directory.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
details.
"""
import getpass
import hashlib
import uuid
import sys
if len(sys.argv) != 3:
print('Usage: %s db username' % sys.argv[0])
quit(-1)
username = sys.argv[2]
try:
password = getpass.getpass()
except Exception as error:
print('ERROR', error)
quit(-1)
salt = uuid.uuid4().hex
password = hashlib.sha256(salt.encode() + password.encode()).hexdigest() + ':' + salt
with open(sys.argv[1], 'a') as file:
file.write('%s %s\n' % (username, password))

View File

@ -14,4 +14,6 @@ BOOTSTRAP_SERVE_LOCAL = True
TITLE = 'Binary Kitchen Doorlock'
ROOM = 'Hauptraum'
WELCOME = 'Willkommen in der Binary Kitchen'
# LOCAL_USER_DB = './db.dat'
SERIAL_PORT = '/dev/ttyAMA0'