added sample and prettier conf
parent
2937b3ae21
commit
00a1618807
@ -0,0 +1,6 @@
|
||||
{
|
||||
"trailingComma": "es5",
|
||||
"tabWidth": 4,
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
# Howdy's config file: https://github.com/boltgolt/howdy/blob/beta/howdy/src/config.ini
|
||||
# Press CTRL + X to save in the nano editor
|
||||
|
||||
[core]
|
||||
# Print that face detection is being attempted
|
||||
detection_notice = false
|
||||
|
||||
# Print that face detection has timed out
|
||||
timeout_notice = true
|
||||
|
||||
# Do not print anything when a face verification 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
|
||||
suppress_unknown = false
|
||||
|
||||
# Disable Howdy in remote shells
|
||||
abort_if_ssh = true
|
||||
|
||||
# Disable Howdy if lid is closed
|
||||
abort_if_lid_closed = true
|
||||
|
||||
# Disable howdy in the PAM
|
||||
# The howdy command will still function
|
||||
disabled = false
|
||||
|
||||
# Use CNN instead of HOG
|
||||
# CNN model is much more accurate than the HOG based model, but takes much more
|
||||
# computational power to run, and is meant to be executed on a GPU to attain reasonable speed.
|
||||
use_cnn = 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 recommended
|
||||
# Lower is better
|
||||
certainty = 3.5
|
||||
|
||||
# The number of seconds to search before timing out
|
||||
timeout = 4
|
||||
|
||||
# The path of the device to capture frames from
|
||||
# Should be set automatically by an installer if your distro has one
|
||||
device_path = none
|
||||
|
||||
# Print a warning if the the video device is not found
|
||||
warn_no_device = true
|
||||
|
||||
# Scale down the video feed to this maximum height
|
||||
# Speeds up face recognition but can make it less precise
|
||||
max_height = 320
|
||||
|
||||
# Set the camera input profile to this width and height
|
||||
# The largest profile will be used if set to -1
|
||||
# Automatically ignored if not a valid profile
|
||||
frame_width = -1
|
||||
frame_height = -1
|
||||
|
||||
# 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
|
||||
# The lower this setting is, the more dark frames are ignored
|
||||
dark_threshold = 50
|
||||
|
||||
# The recorder to use. Can be either opencv (default), ffmpeg or pyv4l2.
|
||||
# Switching from the default opencv to ffmpeg can help with grayscale issues.
|
||||
recording_plugin = opencv
|
||||
|
||||
# Video format used by ffmpeg. Options include vfwcap or v4l2.
|
||||
# FFMPEG only.
|
||||
device_format = v4l2
|
||||
|
||||
# Force the use of Motion JPEG when decoding frames, fixes issues with YUYV
|
||||
# raw frame decoding.
|
||||
# OPENCV only.
|
||||
force_mjpeg = false
|
||||
|
||||
# Specify exposure value explicitly. This disables autoexposure.
|
||||
# Use qv4l2 to determine an appropriate value.
|
||||
# OPENCV only.
|
||||
exposure = -1
|
||||
|
||||
[snapshots]
|
||||
# Capture snapshots of failed login attempts and save them to disk with metadata
|
||||
# Snapshots are saved to the "snapshots" folder
|
||||
save_failed = false
|
||||
|
||||
# Do the same as the option above but for successful attempts
|
||||
save_successful = false
|
||||
|
||||
[rubberstamps]
|
||||
# Enable specific extra checks after the user has been recognised
|
||||
enabled = false
|
||||
|
||||
# What type of stamps to run and with what options. The type, timeout and
|
||||
# failure mode are required. One line per stamp. Rule syntax:
|
||||
# stamptype timeout (failsafe | faildeadly) [extra_argument=value]
|
||||
stamp_rules =
|
||||
nod 5s failsafe min_distance=12
|
||||
|
||||
[debug]
|
||||
# Show a short but detailed diagnostic report in console
|
||||
# Enabling this can cause some UI apps to fail, only enable it to debug
|
||||
end_report = false
|
||||
|
||||
# More verbose logging from the rubberstamps system
|
||||
verbose_stamps = false
|
||||
|
||||
# Pass output of the GTK auth window to the terminal
|
||||
gtk_stdout = false
|
@ -0,0 +1,179 @@
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
|
||||
from i18n import _
|
||||
|
||||
from importlib.machinery import SourceFileLoader
|
||||
|
||||
|
||||
class RubberStamp:
|
||||
"""Howdy rubber stamp"""
|
||||
|
||||
UI_TEXT = "ui_text"
|
||||
UI_SUBTEXT = "ui_subtext"
|
||||
|
||||
def set_ui_text(self, text, type=None):
|
||||
"""Convert an ui string to input howdy-gtk understands"""
|
||||
typedec = "M"
|
||||
|
||||
if type == self.UI_SUBTEXT:
|
||||
typedec = "S"
|
||||
|
||||
return self.send_ui_raw(typedec + "=" + text)
|
||||
|
||||
def send_ui_raw(self, command):
|
||||
"""Write raw command to howdy-gtk stdin"""
|
||||
if self.config.getboolean("debug", "verbose_stamps", fallback=False):
|
||||
print("Sending command to howdy-gtk: " + command)
|
||||
|
||||
# Add a newline because the ui reads per line
|
||||
command += " \n"
|
||||
|
||||
# If we're connected to the ui
|
||||
if self.gtk_proc:
|
||||
# Send the command as bytes
|
||||
self.gtk_proc.stdin.write(bytearray(command.encode("utf-8")))
|
||||
self.gtk_proc.stdin.flush()
|
||||
|
||||
# Write a padding line to force the command through any buffers
|
||||
self.gtk_proc.stdin.write(bytearray("P=_PADDING \n".encode("utf-8")))
|
||||
self.gtk_proc.stdin.flush()
|
||||
|
||||
|
||||
def execute(config, gtk_proc, opencv):
|
||||
verbose = config.getboolean("debug", "verbose_stamps", fallback=False)
|
||||
dir_path = os.path.dirname(os.path.realpath(__file__))
|
||||
installed_stamps = []
|
||||
|
||||
# Go through each file in the rubberstamp folder
|
||||
for filename in os.listdir(dir_path):
|
||||
# Remove non-readable file or directories
|
||||
if not os.path.isfile(dir_path + "/" + filename):
|
||||
continue
|
||||
|
||||
# Remove meta files
|
||||
if filename in ["__init__.py", ".gitignore"]:
|
||||
continue
|
||||
|
||||
# Add the found file to the list of enabled rubberstamps
|
||||
installed_stamps.append(filename.split(".")[0])
|
||||
|
||||
if verbose: print("Installed rubberstamps: " + ", ".join(installed_stamps))
|
||||
|
||||
# Get the rules defined in the config
|
||||
raw_rules = config.get("rubberstamps", "stamp_rules")
|
||||
rules = raw_rules.split("\n")
|
||||
|
||||
# Go through the rules one by one
|
||||
for rule in rules:
|
||||
rule = rule.strip()
|
||||
|
||||
if len(rule) <= 1:
|
||||
continue
|
||||
|
||||
# Parse the rule with regex
|
||||
regex_result = re.search("^(\w+)\s+([\w\.]+)\s+([a-z]+)(.*)?$", rule, re.IGNORECASE)
|
||||
|
||||
# Error out if the regex did not match (invalid line)
|
||||
if not regex_result:
|
||||
print(_("Error parsing rubberstamp rule: {}").format(rule))
|
||||
continue
|
||||
|
||||
type = regex_result.group(1)
|
||||
|
||||
# Error out if the stamp name in the rule is not a file
|
||||
if type not in installed_stamps:
|
||||
print(_("Stamp not installed: {}").format(type))
|
||||
continue
|
||||
|
||||
# Load the module from file
|
||||
module = SourceFileLoader(type, dir_path + "/" + type + ".py").load_module()
|
||||
|
||||
# Try to get the class with the same name
|
||||
try:
|
||||
constructor = getattr(module, type)
|
||||
except AttributeError:
|
||||
print(_("Stamp error: Class {} not found").format(type))
|
||||
continue
|
||||
|
||||
# Init the class and set common values
|
||||
instance = constructor()
|
||||
instance.verbose = verbose
|
||||
instance.config = config
|
||||
instance.gtk_proc = gtk_proc
|
||||
instance.opencv = opencv
|
||||
|
||||
# Set some opensv shorthands
|
||||
instance.video_capture = opencv["video_capture"]
|
||||
instance.face_detector = opencv["face_detector"]
|
||||
instance.pose_predictor = opencv["pose_predictor"]
|
||||
instance.clahe = opencv["clahe"]
|
||||
|
||||
# Parse and set the 2 required options for all rubberstamps
|
||||
instance.options = {
|
||||
"timeout": float(re.sub("[a-zA-Z]", "", regex_result.group(2))),
|
||||
"failsafe": regex_result.group(3) != "faildeadly"
|
||||
}
|
||||
|
||||
# Try to get the class do declare its other config variables
|
||||
try:
|
||||
instance.declare_config()
|
||||
except Exception:
|
||||
print(_("Internal error in rubberstamp configuration declaration:"))
|
||||
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
continue
|
||||
|
||||
# Split the optional arguments at the end of the rule by spaces
|
||||
raw_options = regex_result.group(4).split()
|
||||
|
||||
# For each of those aoptional arguments
|
||||
for option in raw_options:
|
||||
# Get the key to the left, and the value to the right of the equal sign
|
||||
key, value = option.split("=")
|
||||
|
||||
# Error out if a key has been set that was not declared by the module before
|
||||
if key not in instance.options:
|
||||
print("Unknow config option for rubberstamp " + type + ": " + key)
|
||||
continue
|
||||
|
||||
# Convert the argument string to an int or float if the declared option has that type
|
||||
if isinstance(instance.options[key], int):
|
||||
value = int(value)
|
||||
elif isinstance(instance.options[key], float):
|
||||
value = float(value)
|
||||
|
||||
instance.options[key] = value
|
||||
|
||||
if verbose:
|
||||
print("Stamp \"" + type + "\" options parsed:")
|
||||
print(instance.options)
|
||||
print("Executing stamp")
|
||||
|
||||
# Make the stamp fail by default
|
||||
result = False
|
||||
|
||||
# Run the stamp code
|
||||
try:
|
||||
result = instance.run()
|
||||
except Exception:
|
||||
print(_("Internal error in rubberstamp:"))
|
||||
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
continue
|
||||
|
||||
if verbose: print("Stamp \"" + type + "\" returned: " + str(result))
|
||||
|
||||
# Abort authentication if the stamp returned false
|
||||
if result is False:
|
||||
if verbose: print("Authentication aborted by rubber stamp")
|
||||
sys.exit(14)
|
||||
|
||||
# This is outside the for loop, so we've run all the rules
|
||||
if verbose: print("All rubberstamps processed, authentication successful")
|
||||
|
||||
# Exit with no errors
|
||||
sys.exit(0)
|
Loading…
Reference in New Issue