Merge pull request #48 from boltgolt/dev

Version 2.3.0
This commit is contained in:
boltgolt 2018-06-28 16:10:03 +02:00 committed by GitHub
commit faef639432
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
11 changed files with 87 additions and 33 deletions

View file

@ -1,24 +1,42 @@
# Howdy for Linux [![](https://img.shields.io/travis/Boltgolt/howdy/master.svg)](https://travis-ci.org/Boltgolt/howdy) [![](https://img.shields.io/github/release/Boltgolt/howdy.svg?colorB=4c1)](https://github.com/Boltgolt/howdy/releases) ![](https://boltgolt.nl/howdy_badge/installs.php?nc) ![](https://boltgolt.nl/howdy_badge/views.php) # Howdy for Linux [![](https://img.shields.io/travis/boltgolt/howdy/master.svg)](https://travis-ci.org/boltgolt/howdy) [![](https://img.shields.io/github/release/boltgolt/howdy.svg?colorB=4c1)](https://github.com/boltgolt/howdy/releases) ![](https://boltgolt.nl/howdy_badge/installs.php?nc) ![](https://boltgolt.nl/howdy_badge/views.php)
Windows Hello™ style authentication for Ubuntu. Use your built-in IR emitters and camera in combination with face recognition to prove who you are. Windows Hello™ style authentication for Linux. Use your built-in IR emitters and camera in combination with face recognition to prove who you are.
Using the central authentication system in Linux (PAM), this works everywhere you would otherwise need your password: Login, lock screen, sudo, su, etc. Using the central authentication system (PAM), this works everywhere you would otherwise need your password: Login, lock screen, sudo, su, etc.
### Installation ## Installation
* Ubuntu: Add the following ppa with ``` sudo add-apt-repository ppa:boltgolt/howdy ``` and ``` sudo apt update```. Then install Howdy with ``` sudo apt install howdy ```. Howdy is currently available for Ubuntu/Debian and Arch Linux. If youre interested in packaging Howdy for your distro, dont hesitate to open an issue.
* Arch Linux: Install the following package from the AUR: ``` howdy ```. Please read the [ArchWiki entry](https://wiki.archlinux.org/index.php/Howdy) for additional information.
**Note:** The build of dlib can hang on 100% for over a minute, give it time. **Note:** The build of dlib can hang on 100% for over a minute, give it time.
This will guide you through the installation. When that's done run `sudo howdy add` to add a face model. ### Ubuntu (apt)
Run the installer by pasting (`ctrl+shift+V`) the following commands into the terminal one at a time:
```
sudo add-apt-repository ppa:boltgolt/howdy
sudo apt update
sudo apt install howdy
```
This will guide you through the installation.
### Arch Linux
Install the `howdy` package from the AUR. For AUR installation instructions, take a look at this [wiki page](https://wiki.archlinux.org/index.php/Arch_User_Repository#Installing_packages).
You will need to do some additional configuration steps. Please read the [ArchWiki entry](https://wiki.archlinux.org/index.php/Howdy) for more information.
## Setup
After installation, you need to let Howdy learn your face. Run `sudo howdy add` to add a face model.
If nothing went wrong we should be able to run sudo by just showing your face. Open a new terminal and run `sudo -i` to see it in action. If nothing went wrong we should be able to run sudo by just showing your face. Open a new terminal and run `sudo -i` to see it in action.
If you're curious you can run `sudo howdy config` to open the central config file and see the options Howdy has. If you're curious you can run `sudo howdy config` to open the central config file and see the options Howdy has. On most systems this will open the nano editor, where you have to press `ctrl`+`x` to save your changes.
### CLI ## CLI
The installer adds a `howdy` command to manage face models for the current user. Use `howdy --help` or `man howdy` to list the available options. The installer adds a `howdy` command to manage face models for the current user. Use `howdy --help` or `man howdy` to list the available options.
@ -37,17 +55,17 @@ howdy [-U user] [-y] command [argument]
| `remove` | Remove a specific model for an user | | `remove` | Remove a specific model for an user |
| `test` | Test the camera and recognition methods | | `test` | Test the camera and recognition methods |
### Contributing [![](https://img.shields.io/travis/Boltgolt/howdy/dev.svg?label=dev%20build)](https://github.com/Boltgolt/howdy/tree/dev) [![](https://img.shields.io/github/issues-raw/Boltgolt/howdy/enhancement.svg?label=feature+requests&colorB=4c1)](https://github.com/Boltgolt/howdy/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement) ## Contributing [![](https://img.shields.io/travis/boltgolt/howdy/dev.svg?label=dev%20build)](https://github.com/boltgolt/howdy/tree/dev) [![](https://img.shields.io/github/issues-raw/boltgolt/howdy/enhancement.svg?label=feature+requests&colorB=4c1)](https://github.com/boltgolt/howdy/issues?q=is%3Aissue+is%3Aopen+label%3Aenhancement)
You can contribute in many ways. The easiest are reporting bugs and opening github issues for features you'd like to see in howdy. Code contributions are also very welcome. You can contribute in many ways. The easiest are reporting bugs and opening github issues for features you'd like to see in howdy. Code contributions are also very welcome.
### Troubleshooting ## Troubleshooting
Any python errors get logged directly into the console and should indicate what went wrong. If authentication still fails but no errors are printed you could take a look at the last lines in `/var/log/auth.log` to see if anything has been reported there. Any python errors get logged directly into the console and should indicate what went wrong. If authentication still fails but no errors are printed you could take a look at the last lines in `/var/log/auth.log` to see if anything has been reported there.
If you encounter an error that hasn't been reported yet, don't be afraid to open a new issue. If you encounter an error that hasn't been reported yet, don't be afraid to open a new issue.
### A note on security ## A note on security
This script is in no way as secure as a password and will never be. Although it's harder to fool than normal face recognition, a person who looks similar to you or well-printed photo of you could be enough to do it. This script is in no way as secure as a password and will never be. Although it's harder to fool than normal face recognition, a person who looks similar to you or well-printed photo of you could be enough to do it.

10
debian/changelog vendored
View file

@ -1,3 +1,13 @@
howdy (2.3.0) xenial; urgency=medium
* Added a config option to set the frame height and width (thanks @wzrdtales!)
* Rewrote the code that fetches the non-root username (thanks @dmig!)
* Changed the config command so it uses the default editor (thanks @stellarpower and @dmig!)
* Fixed issue where a "y" could be interpreted as a no (thanks @ramkrishna757575!)
* Fixed division by zeno (thanks @stellarpower!)
-- boltgolt <boltgolt@gmail.com> Thu, 28 Jun 2018 14:59:52 +0100
howdy (2.2.2) xenial; urgency=medium howdy (2.2.2) xenial; urgency=medium
* Fixed fetching of wrong config section (thanks @halcyoncheng and @arifeinberg!) * Fixed fetching of wrong config section (thanks @halcyoncheng and @arifeinberg!)

6
debian/control vendored
View file

@ -4,12 +4,12 @@ Priority: optional
Standards-Version: 3.9.7 Standards-Version: 3.9.7
Build-Depends: python, dh-python, devscripts, dh-make, debhelper Build-Depends: python, dh-python, devscripts, dh-make, debhelper
Maintainer: boltgolt <boltgolt@gmail.com> Maintainer: boltgolt <boltgolt@gmail.com>
Vcs-Git: https://github.com/Boltgolt/howdy Vcs-Git: https://github.com/boltgolt/howdy
Package: howdy Package: howdy
Homepage: https://github.com/Boltgolt/howdy Homepage: https://github.com/boltgolt/howdy
Architecture: all Architecture: all
Depends: ${misc:Depends}, git, python3, python3-pip, python3-dev, python3-setuptools, build-essential, libpam-python, fswebcam, libopencv-dev, python-opencv, cmake Depends: ${misc:Depends}, git, python3, python3-pip, python3-dev, python3-setuptools, build-essential, libpam-python, fswebcam, libopencv-dev, python-opencv, cmake
Description: Howdy: Windows Hello style authentication for Ubuntu. Description: Howdy: Windows Hello style authentication for Linux.
Use your built-in IR emitters and camera in combination with face recognition Use your built-in IR emitters and camera in combination with face recognition
to prove who you are. to prove who you are.

4
debian/howdy.1 vendored
View file

@ -1,7 +1,7 @@
.\" Please adjust this date whenever revising the manpage. .\" Please adjust this date whenever revising the manpage.
.TH HOWDY 1 "April 9, 2018" "Howdy help" "User Commands" .TH HOWDY 1 "April 9, 2018" "Howdy help" "User Commands"
.SH NAME .SH NAME
howdy \- Windows Hello style authentication for Ubuntu howdy \- Windows Hello style authentication for Linux
.SH DESCRIPTION .SH DESCRIPTION
Howdy IR face recognition implements a PAM module to use your face as a authentication method. Howdy IR face recognition implements a PAM module to use your face as a authentication method.
.SS "Usage:" .SS "Usage:"
@ -44,4 +44,4 @@ Skip all questions.
Show this help message and exit. Show this help message and exit.
.PP .PP
.SH AUTHOR .SH AUTHOR
Howdy was written by boltgolt. For more information visit https://github.com/Boltgolt/howdy Howdy was written by boltgolt. For more information visit https://github.com/boltgolt/howdy

4
debian/postinst vendored
View file

@ -187,7 +187,7 @@ if "HOWDY_NO_PROMPT" not in os.environ:
ans = input("Apply this change? [y/N]: ") ans = input("Apply this change? [y/N]: ")
# Abort the whole thing if it's not # Abort the whole thing if it's not
if (ans.lower() != "y"): if ans.lower().strip() != "y" or ans.lower().strip() == "yes":
print("Interpreting as a \"NO\", aborting") print("Interpreting as a \"NO\", aborting")
sys.exit(1) sys.exit(1)
@ -223,7 +223,7 @@ if "HOWDY_NO_PROMPT" not in os.environ:
diag_out += "```" diag_out += "```"
# Print it all as a clickable link to a new github issue # Print it all as a clickable link to a new github issue
print("https://github.com/Boltgolt/howdy-reports/issues/new?title=Post-installation%20camera%20information&body=" + urllib.parse.quote_plus(diag_out) + "\n") print("https://github.com/boltgolt/howdy-reports/issues/new?title=Post-installation%20camera%20information&body=" + urllib.parse.quote_plus(diag_out) + "\n")
# Let the user know what to do with the link # Let the user know what to do with the link
print("Installation complete.") print("Installation complete.")

2
debian/preinst vendored
View file

@ -89,7 +89,7 @@ for dev in devices:
os.killpg(os.getpgid(sub.pid), signal.SIGTERM) os.killpg(os.getpgid(sub.pid), signal.SIGTERM)
# Set this camera as picked if the answer was yes, go to the next one if no # Set this camera as picked if the answer was yes, go to the next one if no
if ans.lower() == "y" or ans.lower() == "yes": if ans.lower().strip() == "y" or ans.lower().strip() == "yes":
picked = dev[5:] picked = dev[5:]
break break
else: else:

View file

@ -10,10 +10,13 @@ import argparse
import builtins import builtins
# Try to get the original username (not "root") from shell # Try to get the original username (not "root") from shell
user = subprocess.check_output("echo $(logname 2>/dev/null || echo $SUDO_USER)", shell=True).decode("ascii").strip() try:
user = os.getlogin()
except:
user = os.environ.get("SUDO_USER")
# If that fails, try to get the direct user # If that fails, try to get the direct user
if user == "root" or user == "": if user == "root" or user == None:
env_user = getpass.getuser().strip() env_user = getpass.getuser().strip()
# If even that fails, error out # If even that fails, error out
@ -28,7 +31,7 @@ parser = argparse.ArgumentParser(description="Command line interface for Howdy f
formatter_class=argparse.RawDescriptionHelpFormatter, formatter_class=argparse.RawDescriptionHelpFormatter,
add_help=False, add_help=False,
prog="howdy", prog="howdy",
epilog="For support please visit\nhttps://github.com/Boltgolt/howdy") epilog="For support please visit\nhttps://github.com/boltgolt/howdy")
# Add an argument for the command # Add an argument for the command
parser.add_argument("command", parser.add_argument("command",
@ -73,7 +76,8 @@ builtins.howdy_user = args.user
# Check if we have rootish rights # Check if we have rootish rights
# This is this far down the file so running the command for help is always possible # This is this far down the file so running the command for help is always possible
if os.getenv("SUDO_USER") is None: if os.getenv("SUDO_USER") is None:
print("Please run this command with sudo") print("Please run this command as root:\n")
print("\tsudo howdy " + " ".join(sys.argv[1:]))
sys.exit(1) sys.exit(1)
# Beond this point the user can't change anymore, if we still have root as user we need to abort # Beond this point the user can't change anymore, if we still have root as user we need to abort

View file

@ -6,10 +6,7 @@ import time
import subprocess import subprocess
# Let the user know what we're doing # Let the user know what we're doing
print("Opening config.ini in gedit") print("Opening config.ini in the default editor")
# Open gedit as a subprocess and fork it # Open gedit as a subprocess and fork it
subprocess.Popen(["gedit", os.path.dirname(os.path.realpath(__file__)) + "/../config.ini"], subprocess.call(["/etc/alternatives/editor", os.path.dirname(os.path.realpath(__file__)) + "/../config.ini"])
cwd="/",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)

View file

@ -24,6 +24,13 @@ video_capture = cv2.VideoCapture(int(config.get("video", "device_id")))
if config.get("video", "force_mjpeg") == "true": if config.get("video", "force_mjpeg") == "true":
video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237) video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237)
# Set the frame width and height if requested
if int(config.get("video", "frame_width")) != -1:
video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, int(config.get("video", "frame_width")))
if int(config.get("video", "frame_height")) != -1:
video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, int(config.get("video", "frame_height")))
# Let the user know what's up # Let the user know what's up
print(""" print("""
Opening a window with a test feed Opening a window with a test feed

View file

@ -62,8 +62,16 @@ video_capture = cv2.VideoCapture(int(config.get("video", "device_id")))
# Force MJPEG decoding if true # Force MJPEG decoding if true
if config.get("video", "force_mjpeg") == "true": if config.get("video", "force_mjpeg") == "true":
# Set a magic number, will enable MJPEG but is badly documentated
video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237) video_capture.set(cv2.CAP_PROP_FOURCC, 1196444237)
# Set the frame width and height if requested
if int(config.get("video", "frame_width")) != -1:
video_capture.set(cv2.CAP_PROP_FRAME_WIDTH, int(config.get("video", "frame_width")))
if int(config.get("video", "frame_height")) != -1:
video_capture.set(cv2.CAP_PROP_FRAME_HEIGHT, int(config.get("video", "frame_height")))
# Capture a single frame so the camera becomes active # 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 # This will let the camera adjust its light levels while we're importing for faster scanning
video_capture.read() video_capture.read()
@ -97,6 +105,11 @@ while True:
# All values combined for percentage calculation # All values combined for percentage calculation
hist_total = int(sum(hist)[0]) hist_total = int(sum(hist)[0])
# If the image is fully black, skip to the next frame
if hist_total == 0:
dark_tries += 1
continue
# Scrip the frame if it exceeds the threshold # Scrip the frame if it exceeds the threshold
if float(hist[0]) / hist_total * 100 > float(config.get("video", "dark_threshold")): if float(hist[0]) / hist_total * 100 > float(config.get("video", "dark_threshold")):
dark_tries += 1 dark_tries += 1
@ -159,5 +172,5 @@ while True:
print("Winning model: " + str(match_index) + " (\"" + models[match_index]["label"] + "\")") print("Winning model: " + str(match_index) + " (\"" + models[match_index]["label"] + "\")")
# End peacegully # End peacefully
stop(0) stop(0)

View file

@ -1,4 +1,5 @@
# Howdy config file # Howdy config file
# Press CTRL + X to save in the nano editor
[core] [core]
# Do not print anything when a face verification succeeds # Do not print anything when a face verification succeeds
@ -37,6 +38,12 @@ max_height = 320
# YUYV raw frame deconding # YUYV raw frame deconding
force_mjpeg = false force_mjpeg = false
# 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 # 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 # Skip the frame if the lowest 1/8 of the histogram is above this percentage
# of the total # of the total
@ -46,5 +53,3 @@ dark_threshold = 50
[debug] [debug]
# Show a short but detailed diagnostic report in console # Show a short but detailed diagnostic report in console
end_report = false end_report = false
dummy = true