mirror of
https://github.com/boltgolt/howdy.git
synced 2024-09-19 09:51:19 +02:00
Moved camera detection to preinst so dpkg doesn't break on abort
This commit is contained in:
parent
52e6be7be8
commit
fceb61a91b
5 changed files with 128 additions and 88 deletions
|
@ -13,4 +13,4 @@ script:
|
|||
- sudo apt purge howdy -y
|
||||
|
||||
notifications:
|
||||
email: false
|
||||
email: true
|
||||
|
|
27
README.md
27
README.md
|
@ -1,4 +1,4 @@
|
|||
# Howdy for Ubuntu [![Build Status](https://travis-ci.org/Boltgolt/howdy.svg?branch=dev)](https://travis-ci.org/Boltgolt/howdy)
|
||||
# Howdy for Ubuntu [![](https://travis-ci.org/Boltgolt/howdy.svg?branch=dev)](https://travis-ci.org/Boltgolt/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.
|
||||
|
||||
|
@ -24,16 +24,21 @@ If nothing went wrong we should be able to run sudo by just showing your face. O
|
|||
|
||||
The installer adds a `howdy` command to manage face models for the current user. Use `howdy help` to list the available options.
|
||||
|
||||
| Command | Description | Needs user |
|
||||
|-----------|-----------------------------------------------|------------|
|
||||
| `add` | Add a new face model for the given user | Yes |
|
||||
| `clear` | Remove all face models for the given user | Yes |
|
||||
| `config` | Open the config file in nano | No |
|
||||
| `disable` | Disable or enable howdy | No |
|
||||
| `help` | Show a help page | No |
|
||||
| `list` | List all saved face models for the given user | Yes |
|
||||
| `remove` | Remove a specific model for the given user | Yes |
|
||||
| `test` | Test the camera and recognition methods | No |
|
||||
Usage:
|
||||
```
|
||||
howdy <command> [user] [argument]
|
||||
```
|
||||
|
||||
| Command | Description | User required |
|
||||
|-----------|-----------------------------------------------|---------------|
|
||||
| `add` | Add a new face model for the given user | Yes |
|
||||
| `clear` | Remove all face models for the given user | Yes |
|
||||
| `config` | Open the config file in nano | No |
|
||||
| `disable` | Disable or enable howdy | No |
|
||||
| `help` | Show a help page | No |
|
||||
| `list` | List all saved face models for the given user | Yes |
|
||||
| `remove` | Remove a specific model for the given user | Yes |
|
||||
| `test` | Test the camera and recognition methods | No |
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
|
|
79
debian/postinst
vendored
79
debian/postinst
vendored
|
@ -12,6 +12,9 @@ import signal
|
|||
import fileinput
|
||||
import urllib.parse
|
||||
|
||||
if "configure" not in sys.argv:
|
||||
sys.exit(0)
|
||||
|
||||
def log(text):
|
||||
"""Print a nicely formatted line to stdout"""
|
||||
print("\n>>> \033[32m" + text + "\033[0m\n")
|
||||
|
@ -22,77 +25,21 @@ def handleStatus(status):
|
|||
print("\033[31mError while running last command\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
# Check if we're running as root
|
||||
user = os.getenv("SUDO_USER")
|
||||
if user is None:
|
||||
print("Can't continue installation without root rights.")
|
||||
sys.exit(1)
|
||||
|
||||
log("Upgrading pip to the latest version")
|
||||
|
||||
# We're not in fresh configuration mode, so exit
|
||||
if not os.path.exists("/tmp/howdy_picked_device"):
|
||||
sys.exit(0)
|
||||
|
||||
in_file = open("/tmp/howdy_picked_device", "r")
|
||||
picked = int(in_file.read())
|
||||
in_file.close()
|
||||
|
||||
subprocess.call(["rm /tmp/howdy_picked_device"], shell=True)
|
||||
|
||||
# Update pip
|
||||
handleStatus(subprocess.call(["pip3 install --upgrade pip"], shell=True))
|
||||
|
||||
log("Starting camera check")
|
||||
|
||||
# Get all devices
|
||||
devices = os.listdir("/dev")
|
||||
# The picked video device id
|
||||
picked = -1
|
||||
|
||||
# If prompting has been disabled, skip camera check
|
||||
if "HOWDY_NO_PROMPT" in os.environ:
|
||||
print("\033[33mAUTOMATED INSTALL, YOU WILL NOT BE ASKED FOR INPUT AND CHECKS WILL BE SKIPPED\033[0m")
|
||||
picked = "0"
|
||||
else:
|
||||
# Loop though all devices
|
||||
for dev in devices:
|
||||
# Only use the video devices
|
||||
if (dev[:5] == "video"):
|
||||
time.sleep(.5)
|
||||
|
||||
# The full path to the device is the default name
|
||||
device_name = "/dev/" + dev
|
||||
# Get the udevadm details to try to get a better name
|
||||
udevadm = subprocess.check_output(["udevadm info -r --query=all -n " + device_name], shell=True).decode("utf-8")
|
||||
|
||||
# Loop though udevadm to search for a better name
|
||||
for line in udevadm.split("\n"):
|
||||
# Match it and encase it in quotes
|
||||
re_name = re.search('product.*=(.*)$', line, re.IGNORECASE)
|
||||
if re_name:
|
||||
device_name = '"' + re_name.group(1) + '"'
|
||||
|
||||
# Show what device we're using
|
||||
print("Trying " + device_name)
|
||||
|
||||
# Let fswebcam keep the camera open in the background
|
||||
sub = subprocess.Popen(["fswebcam -S 9999999999 -d /dev/" + dev + " /dev/null 2>/dev/null"], shell=True, preexec_fn=os.setsid)
|
||||
|
||||
try:
|
||||
# Ask the user if this is the right one
|
||||
print("\033[33mOne of your cameras should now be on.\033[0m")
|
||||
ans = input("Did your IR emitters turn on? [y/N]: ")
|
||||
except KeyboardInterrupt:
|
||||
# Kill fswebcam if the user aborts
|
||||
os.killpg(os.getpgid(sub.pid), signal.SIGTERM)
|
||||
raise
|
||||
|
||||
# The user has answered, kill fswebcam
|
||||
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"):
|
||||
picked = dev[5:]
|
||||
break
|
||||
else:
|
||||
print("Inerpeting as a \"NO\"\n")
|
||||
|
||||
# Abort if no camera was picked
|
||||
if (picked == -1):
|
||||
print("\033[31mNo suitable IR camera found\033[0m")
|
||||
sys.exit(1)
|
||||
|
||||
log("Cloning dlib")
|
||||
|
||||
# Clone the git to /tmp
|
||||
|
|
89
debian/preinst
vendored
Normal file
89
debian/preinst
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python3
|
||||
# Used to check cameras before commiting to install
|
||||
# Executed before primary apt install of files
|
||||
|
||||
def col(id):
|
||||
if id == 1: return "\033[32m"
|
||||
if id == 2: return "\033[33m"
|
||||
if id == 3: return "\033[31m"
|
||||
return "\033[0m"
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import signal
|
||||
|
||||
if "install" not in sys.argv:
|
||||
sys.exit(0)
|
||||
|
||||
# The picked video device id
|
||||
picked = -1
|
||||
|
||||
print(col(1) + "Starting IR camera check...\n" + col(0))
|
||||
|
||||
# If prompting has been disabled, skip camera check
|
||||
if "HOWDY_NO_PROMPT" in os.environ:
|
||||
print(col(2) + "AUTOMATED INSTALL, YOU WILL NOT BE ASKED FOR INPUT AND CHECKS WILL BE SKIPPED" + col(0))
|
||||
|
||||
with open("/tmp/howdy_picked_device", "w") as out_file:
|
||||
out_file.write("0")
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
# Get all devices
|
||||
devices = os.listdir("/dev")
|
||||
|
||||
# Loop though all devices
|
||||
for dev in devices:
|
||||
# Only use the video devices
|
||||
if (dev[:5] == "video"):
|
||||
time.sleep(.5)
|
||||
|
||||
# The full path to the device is the default name
|
||||
device_name = "/dev/" + dev
|
||||
# Get the udevadm details to try to get a better name
|
||||
udevadm = subprocess.check_output(["udevadm info -r --query=all -n " + device_name], shell=True).decode("utf-8")
|
||||
|
||||
# Loop though udevadm to search for a better name
|
||||
for line in udevadm.split("\n"):
|
||||
# Match it and encase it in quotes
|
||||
re_name = re.search('product.*=(.*)$', line, re.IGNORECASE)
|
||||
if re_name:
|
||||
device_name = '"' + re_name.group(1) + '"'
|
||||
|
||||
# Show what device we're using
|
||||
print("Trying " + device_name)
|
||||
|
||||
# Let fswebcam keep the camera open in the background
|
||||
sub = subprocess.Popen(["fswebcam -S 9999999999 -d /dev/" + dev + " /dev/null 2>/dev/null"], shell=True, preexec_fn=os.setsid)
|
||||
|
||||
try:
|
||||
# Ask the user if this is the right one
|
||||
print(col(2) + "One of your cameras should now be on." + col(0))
|
||||
ans = input("Did your IR emitters turn on? [y/N]: ")
|
||||
except KeyboardInterrupt:
|
||||
# Kill fswebcam if the user aborts
|
||||
os.killpg(os.getpgid(sub.pid), signal.SIGTERM)
|
||||
raise
|
||||
|
||||
# The user has answered, kill fswebcam
|
||||
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":
|
||||
picked = dev[5:]
|
||||
break
|
||||
else:
|
||||
print("Interpreting as a " + col(3) + "\"NO\"\n" + col(0))
|
||||
|
||||
# Abort if no camera was picked
|
||||
if picked == -1:
|
||||
print(col(3) + "No suitable IR camera found, aborting install." + col(0))
|
||||
sys.exit(23)
|
||||
|
||||
with open("/tmp/howdy_picked_device", "w") as out_file:
|
||||
out_file.write(str(picked))
|
||||
|
||||
print("")
|
19
debian/prerm
vendored
19
debian/prerm
vendored
|
@ -2,28 +2,27 @@
|
|||
# Executed on deinstallation
|
||||
# Completely remove howdy from the system
|
||||
|
||||
def col(id):
|
||||
if id == 1: return "\033[32m"
|
||||
if id == 2: return "\033[33m"
|
||||
if id == 3: return "\033[31m"
|
||||
return "\033[0m"
|
||||
|
||||
# Import required modules
|
||||
import subprocess
|
||||
|
||||
# Remove files and symlinks
|
||||
try:
|
||||
subprocess.call(["rm -rf /lib/security/howdy/"], shell=True)
|
||||
except e:
|
||||
pass
|
||||
try:
|
||||
subprocess.call(["rm /usr/share/bash-completion/completions/howdy"], shell=True)
|
||||
except e:
|
||||
print("Can't remove autocompletion script")
|
||||
pass
|
||||
|
||||
subprocess.call(["rm /usr/bin/howdy"], shell=True)
|
||||
|
||||
# Remove face_recognition and dlib
|
||||
subprocess.call(["pip3 uninstall face_recognition dlib -y --no-cache-dir"], shell=True)
|
||||
|
||||
# Print a tearbending message
|
||||
print("""
|
||||
Howdy has been uninstalled :'(
|
||||
|
||||
print(col(2) + """
|
||||
There are still lines in /etc/pam.d/common-auth that can't be removed automatically
|
||||
Run "nano /etc/pam.d/common-auth" to remove them by hand\
|
||||
""")
|
||||
""" + col(0))
|
||||
|
|
Loading…
Reference in a new issue