0
0
Fork 0
mirror of https://github.com/boltgolt/howdy.git synced 2024-09-19 09:51:19 +02:00

Implemented conversations and better config

This commit is contained in:
boltgolt 2018-01-17 21:28:10 +01:00
parent 542549934b
commit 7b9db83ad0
6 changed files with 45 additions and 28 deletions

3
.gitignore vendored
View file

@ -102,6 +102,3 @@ ENV/
# generated models
/models
# config file
config.py

View file

@ -12,7 +12,7 @@ sudo apt install libpam-python fswebcam libopencv-dev python-opencv
After that, install the face_recognition python module. There's an excellent step by step guide on how to do this on [its github page](https://github.com/ageitgey/face_recognition#installation).
In the root of your cloned repo is a file called `config_template.py`. Duplicate this file and call it `config.py`. The `device_id` variable in this file is important, make sure it is the IR camera and not your normal webcam.
In the root of your cloned repo is a file called `config.ini`. The `device_id` variable in this file is important, make sure it is the IR camera and not your normal webcam.
Now it's time to let Howdy learn your face. The learn.py script will make 3 models of your face and store them as an encoded set in the `models` folder. To run the script, open a terminal, navigate to this repository and run:
@ -22,7 +22,7 @@ python3 learn.py
The script should guide you through the process.
Finally we need to tell PAM that there's a new module installed. Open `/etc/pam.d/sudo` as root (`sudo nano /etc/pam.d/sudo`) and add the following line to the top of the file:
Finally we need to tell PAM that there's a new module installed. Open `/etc/pam.d/common-auth` as root (`sudo nano /etc/pam.d/common-auth`) and add the following line to the top of the file:
```
auth sufficient pam_python.so /path/to/pam.py

View file

@ -7,9 +7,11 @@ import cv2
import sys
import os
import json
import configparser
# Import config
import config
# Read config from disk
config = configparser.ConfigParser()
config.read(os.path.dirname(__file__) + "/config.ini")
def stop(status):
"""Stop the execution and close video stream"""
@ -34,14 +36,14 @@ tries = 0
try:
encodings = json.load(open(os.path.dirname(__file__) + "/models/" + user + ".dat"))
except FileNotFoundError:
stop(10)
sys.exit(10)
# Verify that we have a valid model file
if len(encodings) < 3:
stop(1)
sys.exit(1)
# Start video capture on the IR camera
video_capture = cv2.VideoCapture(config.device_id)
video_capture = cv2.VideoCapture(int(config.get("video", "device_id")))
while True:
# Grab a single frame of video
@ -57,11 +59,11 @@ while True:
# Check if any match is certain enough to be the user we're looking for
for match in matches:
if match < config.certainty and match > 0:
if match < int(config.get("video", "certainty")) and match > 0:
stop(0)
# Stop if we've exceded the maximum retry count
if tries > config.frame_count:
if tries > int(config.get("video", "frame_count")):
stop(11)
tries += 1

19
config.ini Normal file
View file

@ -0,0 +1,19 @@
[core]
# Do not print anything when a face vericication succeeds
no_confirmation = false
# When a user without a known face model tries to use this script, don't
# show an error but fail silently
supress_unknown = false
[video]
# The certainty of the detected face belonging to the user of the account
# On a scale from 1 to 10, values above 5 are not recomended
certainty = 3
# The number of frames to capture and to process before timing out
frame_count = 30
# The /dev/videoX id to capture frames from
# In my case, video0 is the normal camera and video1 is the IR version
device_id = 1

View file

@ -1,10 +0,0 @@
# The certainty of the detected face belonging to the user of the account
# On a scale from 1 to 10, values above 5 are not recomended
certainty = 3
# The number of frames to capture and to process before timing out
frame_count = 80
# The /dev/videoX id to capture frames from
# On my laptop, video0 is the normal camera and video1 is the IR version
device_id = 1

21
pam.py
View file

@ -5,6 +5,13 @@ import subprocess
import sys
import os
# pam-python is running python 2, so we use the old module here
import ConfigParser
# Read config from disk
config = ConfigParser.ConfigParser()
config.read(os.path.dirname(__file__) + "/config.ini")
def doAuth(pamh):
"""Start authentication in a seperate process"""
@ -13,19 +20,21 @@ def doAuth(pamh):
# Status 10 means we couldn't find any face models
if status == 10:
print("No face model is known for this user, skiping")
return pamh.PAM_SYSTEM_ERR
if config.get("core", "supress_unknown") != "true":
pamh.conversation(pamh.Message(pamh.PAM_ERROR_MSG, "No face model known"))
return pamh.PAM_USER_UNKNOWN
# Status 11 means we exceded the maximum retry count
if status == 11:
print("Timeout reached, could not find a known face")
return pamh.PAM_SYSTEM_ERR
pamh.conversation(pamh.Message(pamh.PAM_ERROR_MSG, "Face detection timeout reached"))
return pamh.PAM_AUTH_ERR
# Status 0 is a successful exit
if status == 0:
print("Identified face as " + os.environ.get("USER"))
if config.get("core", "no_confirmation") != "true":
pamh.conversation(pamh.Message(pamh.PAM_TEXT_INFO, "Identified face as " + pamh.get_user()))
return pamh.PAM_SUCCESS
# Otherwise, we can't discribe what happend but it wasn't successful
print("Unknown error: " + str(status))
pamh.conversation(pamh.Message(pamh.PAM_ERROR_MSG, "Unknown error: " + str(status)))
return pamh.PAM_SYSTEM_ERR
def pam_sm_authenticate(pamh, flags, args):