Skip to content

Commit

Permalink
Merge pull request #48 from boltgolt/dev
Browse files Browse the repository at this point in the history
Version 2.3.0
  • Loading branch information
boltgolt authored Jun 28, 2018
2 parents 527db61 + 4bab7d9 commit faef639
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 33 deletions.
44 changes: 31 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
@@ -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 ```.

* 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.
Howdy is currently available for Ubuntu/Debian and Arch Linux. If you’re interested in packaging Howdy for your distro, don’t hesitate to open an issue.

**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 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.

Expand All @@ -37,17 +55,17 @@ howdy [-U user] [-y] command [argument]
| `remove` | Remove a specific model for an user |
| `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.

### 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.

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.

Expand Down
10 changes: 10 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -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 <[email protected]> Thu, 28 Jun 2018 14:59:52 +0100

howdy (2.2.2) xenial; urgency=medium

* Fixed fetching of wrong config section (thanks @halcyoncheng and @arifeinberg!)
Expand Down
6 changes: 3 additions & 3 deletions debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ Priority: optional
Standards-Version: 3.9.7
Build-Depends: python, dh-python, devscripts, dh-make, debhelper
Maintainer: boltgolt <[email protected]>
Vcs-Git: https://github.com/Boltgolt/howdy
Vcs-Git: https://github.com/boltgolt/howdy

Package: howdy
Homepage: https://github.com/Boltgolt/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: 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
to prove who you are.
4 changes: 2 additions & 2 deletions debian/howdy.1
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
.\" Please adjust this date whenever revising the manpage.
.TH HOWDY 1 "April 9, 2018" "Howdy help" "User Commands"
.SH NAME
howdy \- Windows Hello style authentication for Ubuntu
howdy \- Windows Hello style authentication for Linux
.SH DESCRIPTION
Howdy IR face recognition implements a PAM module to use your face as a authentication method.
.SS "Usage:"
Expand Down Expand Up @@ -44,4 +44,4 @@ Skip all questions.
Show this help message and exit.
.PP
.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 changes: 2 additions & 2 deletions debian/postinst
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ if "HOWDY_NO_PROMPT" not in os.environ:
ans = input("Apply this change? [y/N]: ")

# 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")
sys.exit(1)

Expand Down Expand Up @@ -223,7 +223,7 @@ if "HOWDY_NO_PROMPT" not in os.environ:
diag_out += "```"

# 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
print("Installation complete.")
Expand Down
2 changes: 1 addition & 1 deletion debian/preinst
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ for dev in devices:
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
if ans.lower() == "y" or ans.lower() == "yes":
if ans.lower().strip() == "y" or ans.lower().strip() == "yes":
picked = dev[5:]
break
else:
Expand Down
12 changes: 8 additions & 4 deletions src/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@
import builtins

# 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 user == "root" or user == "":
if user == "root" or user == None:
env_user = getpass.getuser().strip()

# If even that fails, error out
Expand All @@ -28,7 +31,7 @@
formatter_class=argparse.RawDescriptionHelpFormatter,
add_help=False,
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
parser.add_argument("command",
Expand Down Expand Up @@ -73,7 +76,8 @@
# Check if we have rootish rights
# This is this far down the file so running the command for help is always possible
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)

# Beond this point the user can't change anymore, if we still have root as user we need to abort
Expand Down
7 changes: 2 additions & 5 deletions src/cli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,7 @@
import subprocess

# 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
subprocess.Popen(["gedit", os.path.dirname(os.path.realpath(__file__)) + "/../config.ini"],
cwd="/",
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
subprocess.call(["/etc/alternatives/editor", os.path.dirname(os.path.realpath(__file__)) + "/../config.ini"])
7 changes: 7 additions & 0 deletions src/cli/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@
if config.get("video", "force_mjpeg") == "true":
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
print("""
Opening a window with a test feed
Expand Down
15 changes: 14 additions & 1 deletion src/compare.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,16 @@ def stop(status):

# Force MJPEG decoding if 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)

# 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
# This will let the camera adjust its light levels while we're importing for faster scanning
video_capture.read()
Expand Down Expand Up @@ -97,6 +105,11 @@ def stop(status):
# All values combined for percentage calculation
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
if float(hist[0]) / hist_total * 100 > float(config.get("video", "dark_threshold")):
dark_tries += 1
Expand Down Expand Up @@ -159,5 +172,5 @@ def print_timing(label, offset):

print("Winning model: " + str(match_index) + " (\"" + models[match_index]["label"] + "\")")

# End peacegully
# End peacefully
stop(0)
9 changes: 7 additions & 2 deletions src/config.ini
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Howdy config file
# Press CTRL + X to save in the nano editor

[core]
# Do not print anything when a face verification succeeds
Expand Down Expand Up @@ -37,6 +38,12 @@ max_height = 320
# YUYV raw frame deconding
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
# Skip the frame if the lowest 1/8 of the histogram is above this percentage
# of the total
Expand All @@ -46,5 +53,3 @@ dark_threshold = 50
[debug]
# Show a short but detailed diagnostic report in console
end_report = false

dummy = true

0 comments on commit faef639

Please sign in to comment.