commit
4ec9dc3a7a
12 changed files with 122 additions and 20 deletions
|
|
@ -23,3 +23,7 @@ notifications:
|
|||
email:
|
||||
on_success: never
|
||||
on_failure: always
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
# Howdy for Ubuntu [](https://travis-ci.org/Boltgolt/howdy) [](https://github.com/Boltgolt/howdy/releases) 
|
||||
# Howdy for Ubuntu [](https://travis-ci.org/Boltgolt/howdy) [](https://github.com/Boltgolt/howdy/releases)  
|
||||
|
||||
Windows Hello™ style authentication for Ubuntu. Use your built-in IR emitters and camera in combination with face recognition to prove who you are.
|
||||
|
||||
|
|
|
|||
|
|
@ -5,12 +5,42 @@
|
|||
_howdy() {
|
||||
local cur prev opts
|
||||
COMPREPLY=()
|
||||
# The argument typed so far
|
||||
cur="${COMP_WORDS[COMP_CWORD]}"
|
||||
# The previous argument
|
||||
prev="${COMP_WORDS[COMP_CWORD-1]}"
|
||||
opts="help list add remove clear"
|
||||
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
# Go though all cases we support
|
||||
case "${prev}" in
|
||||
# After the main command, show the commands
|
||||
"howdy")
|
||||
opts="add clear config disable list remove clear test"
|
||||
COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
# For disable, grab the current "disabled" config option and give the reverse
|
||||
"disable")
|
||||
local status=$(cut -d'=' -f2 <<< $(cat /lib/security/howdy/config.ini | grep 'disabled =') | xargs echo -n)
|
||||
|
||||
[ "$status" == "false" ] && COMPREPLY="true" || COMPREPLY="false"
|
||||
return 0
|
||||
;;
|
||||
# List the users availible
|
||||
"-U")
|
||||
COMPREPLY=( $(compgen -u -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
"--user")
|
||||
COMPREPLY=( $(compgen -u -- ${cur}) )
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
|
||||
# Nothing matched, so return nothing
|
||||
return 0
|
||||
}
|
||||
|
||||
# Register the autocomplete function
|
||||
complete -F _howdy howdy
|
||||
|
|
|
|||
10
debian/changelog
vendored
10
debian/changelog
vendored
|
|
@ -1,3 +1,13 @@
|
|||
howdy (2.2.1) xenial; urgency=medium
|
||||
|
||||
* Added mechanism to keep config files between updates
|
||||
* Added force_mjpeg option to fix YUYV image issues (thanks @arifeinberg!)
|
||||
* Revamped the bash autocompletion script
|
||||
* Fixed timeout never being reached in certain scenarios (thanks @Tkopic001!)
|
||||
* Fixed issue where BGR to RGB frame conversion caused a crash (thanks @Jerezano!)
|
||||
|
||||
-- boltgolt <boltgolt@gmail.com> Thu, 10 May 2018 15:14:03 +0200
|
||||
|
||||
howdy (2.1.0) xenial; urgency=medium
|
||||
|
||||
* First complete PPA release
|
||||
|
|
|
|||
2
debian/control
vendored
2
debian/control
vendored
|
|
@ -10,6 +10,6 @@ Package: howdy
|
|||
Homepage: https://github.com/Boltgolt/howdy
|
||||
Architecture: all
|
||||
Depends: ${misc:Depends}, git, python3, python3-pip, python3-dev, python3-setuptools, build-essential, libpam-python, fswebcam, libopencv-dev, python-opencv, cmake
|
||||
Description: Windows Hello style authentication for Ubuntu.
|
||||
Description: Howdy: Windows Hello style authentication for Ubuntu.
|
||||
Use your built-in IR emitters and camera in combination with face recognition
|
||||
to prove who you are.
|
||||
|
|
|
|||
30
debian/postinst
vendored
30
debian/postinst
vendored
|
|
@ -36,8 +36,34 @@ def handleStatus(status):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
# We're not in fresh configuration mode (probably an upgrade), so exit
|
||||
# We're not in fresh configuration mode so don't continue the setup
|
||||
if not os.path.exists("/tmp/howdy_picked_device"):
|
||||
# Check if we have an older config we can restore
|
||||
if len(sys.argv) > 2:
|
||||
if os.path.exists("/tmp/howdy_config_backup_v" + sys.argv[2] + ".ini"):
|
||||
# Get the config parser
|
||||
import configparser
|
||||
|
||||
# Load th old and new config files
|
||||
oldConf = configparser.ConfigParser()
|
||||
oldConf.read("/tmp/howdy_config_backup_v" + sys.argv[2] + ".ini")
|
||||
newConf = configparser.ConfigParser()
|
||||
newConf.read("/lib/security/howdy/config.ini")
|
||||
|
||||
# Go through every setting in the old config and apply it to the new file
|
||||
for section in oldConf.sections():
|
||||
for (key, value) in oldConf.items(section):
|
||||
try:
|
||||
newConf.set(section, key, value)
|
||||
# Add a new section where needed
|
||||
except configparser.NoSectionError as e:
|
||||
newConf.add_section(section)
|
||||
newConf.set(section, key, value)
|
||||
|
||||
# Write it all to file
|
||||
with open("/lib/security/howdy/config.ini", "w") as configfile:
|
||||
newConf.write(configfile)
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
# Open the temporary file containing the device ID
|
||||
|
|
@ -162,7 +188,7 @@ if "HOWDY_NO_PROMPT" not in os.environ:
|
|||
|
||||
# Abort the whole thing if it's not
|
||||
if (ans.lower() != "y"):
|
||||
print("Inerpeting as a \"NO\", aborting")
|
||||
print("Interpreting as a \"NO\", aborting")
|
||||
sys.exit(1)
|
||||
|
||||
print("Adding lines to PAM\n")
|
||||
|
|
|
|||
14
debian/preinst
vendored
14
debian/preinst
vendored
|
|
@ -16,6 +16,20 @@ import os
|
|||
import re
|
||||
import signal
|
||||
|
||||
# Backup the config file if we're upgrading
|
||||
if "upgrade" in sys.argv:
|
||||
# Try to copy the config file as a backup
|
||||
try:
|
||||
subprocess.call(["cp /lib/security/howdy/config.ini /tmp/howdy_config_backup_v" + sys.argv[2] + ".ini"], shell=True)
|
||||
|
||||
# Let the user know so he knows where to look on a failed install
|
||||
print("Backup of Howdy config file created in /tmp/howdy_config_backup_v" + sys.argv[2] + ".ini")
|
||||
except e:
|
||||
print("Could not make an backup of old Howdy config file")
|
||||
|
||||
# Don't continue setup when we're just upgrading
|
||||
sys.exit(0)
|
||||
|
||||
# Don't run if we're not trying to install fresh
|
||||
if "install" not in sys.argv:
|
||||
sys.exit(0)
|
||||
|
|
|
|||
|
|
@ -80,6 +80,12 @@ insert_model = {
|
|||
|
||||
# Open the camera
|
||||
video_capture = cv2.VideoCapture(int(config.get("video", "device_id")))
|
||||
|
||||
# Force MJPEG decoding if true
|
||||
if config.get("debug", "force_mjpeg") == "true":
|
||||
video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237)
|
||||
|
||||
# Request a frame to wake the camera up
|
||||
video_capture.read()
|
||||
|
||||
print("\nPlease look straight into the camera")
|
||||
|
|
|
|||
|
|
@ -21,13 +21,18 @@ if builtins.howdy_args.argument == None:
|
|||
sys.exit(1)
|
||||
|
||||
# Translate the argument to the right string
|
||||
if builtins.howdy_args.argument == "1":
|
||||
if builtins.howdy_args.argument == "1" or builtins.howdy_args.argument.lower() == "true":
|
||||
out_value = "true"
|
||||
elif builtins.howdy_args.argument == "0":
|
||||
elif builtins.howdy_args.argument == "0" or builtins.howdy_args.argument.lower() == "false":
|
||||
out_value = "false"
|
||||
else:
|
||||
# Of it's not a 0 or a 1, it's invalid
|
||||
print("Please only use a 0 (enable) or a 1 (disable) as an argument")
|
||||
print("Please only use false (enable) or true (disable) as an argument")
|
||||
sys.exit(1)
|
||||
|
||||
# Don't do anything when the state is already the requested one
|
||||
if out_value == config.get("core", "disabled"):
|
||||
print("The disable option has already been set to " + out_value)
|
||||
sys.exit(1)
|
||||
|
||||
# Loop though the config file and only replace the line containing the disable config
|
||||
|
|
|
|||
|
|
@ -20,6 +20,10 @@ config.read(path + "/../config.ini")
|
|||
# Start capturing from the configured webcam
|
||||
video_capture = cv2.VideoCapture(int(config.get("video", "device_id")))
|
||||
|
||||
# Force MJPEG decoding if true
|
||||
if config.get("debug", "force_mjpeg") == "true":
|
||||
video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237)
|
||||
|
||||
# Let the user know what's up
|
||||
print("""
|
||||
Opening a window with a test feed
|
||||
|
|
|
|||
|
|
@ -37,8 +37,6 @@ user = sys.argv[1]
|
|||
models = []
|
||||
# Encoded face models
|
||||
encodings = []
|
||||
# Amount of frames already matched
|
||||
tries = 0
|
||||
# Amount of ingnored dark frames
|
||||
dark_tries = 0
|
||||
|
||||
|
|
@ -62,6 +60,10 @@ timings.append(time.time())
|
|||
# Start video capture on the IR camera
|
||||
video_capture = cv2.VideoCapture(int(config.get("video", "device_id")))
|
||||
|
||||
# Force MJPEG decoding if true
|
||||
if config.get("video", "force_mjpeg") == "true":
|
||||
video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237)
|
||||
|
||||
# Capture a single frame so the camera becomes active
|
||||
# This will let the camera adjust its light levels while we're importing for faster scanning
|
||||
video_capture.read()
|
||||
|
|
@ -82,6 +84,10 @@ while True:
|
|||
# Increment the frame count every loop
|
||||
frames += 1
|
||||
|
||||
# Stop if we've exceded the time limit
|
||||
if time.time() - timings[3] > int(config.get("video", "timout")):
|
||||
stop(11)
|
||||
|
||||
# Grab a single frame of video
|
||||
# Don't remove ret, it doesn't work without it
|
||||
ret, frame = video_capture.read()
|
||||
|
|
@ -109,9 +115,6 @@ while True:
|
|||
# Save the new size for diagnostics
|
||||
scale_height, scale_width = frame.shape[:2]
|
||||
|
||||
# Convert from BGR to RGB
|
||||
frame = frame[:, :, ::-1]
|
||||
|
||||
# Get all faces from that frame as encodings
|
||||
face_encodings = face_recognition.face_encodings(frame)
|
||||
|
||||
|
|
@ -158,9 +161,3 @@ while True:
|
|||
|
||||
# End peacegully
|
||||
stop(0)
|
||||
|
||||
# Stop if we've exceded the maximum retry count
|
||||
if time.time() - timings[3] > int(config.get("video", "timout")):
|
||||
stop(11)
|
||||
|
||||
tries += 1
|
||||
|
|
|
|||
|
|
@ -33,6 +33,10 @@ device_id = 1
|
|||
# Speeds up face recognition but can make it less precise
|
||||
max_height = 320
|
||||
|
||||
# Force the use of Motion JPEG when decoding frames, fixes issues with
|
||||
# YUYV raw frame deconding
|
||||
force_mjpeg = false
|
||||
|
||||
# Because of flashing IR emitters, some frames can be completely unlit
|
||||
# Skip the frame if the lowest 1/8 of the histogram is above this percentage
|
||||
# of the total
|
||||
|
|
@ -42,3 +46,5 @@ dark_threshold = 50
|
|||
[debug]
|
||||
# Show a short but detailed diagnostic report in console
|
||||
end_report = false
|
||||
|
||||
dummy = true
|
||||
|
|
|
|||
Loading…
Reference in a new issue