0
0
Fork 0
mirror of https://github.com/boltgolt/howdy.git synced 2024-09-19 09:51:19 +02:00

Uninstaller working and comments in installer

This commit is contained in:
boltgolt 2018-02-13 23:59:23 +01:00
parent 818be92838
commit f084411861
3 changed files with 104 additions and 12 deletions

View file

@ -28,6 +28,10 @@ Any python errors get logged directly into the console and should indicate what
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.
### Uninstalling
There is an uninstaller available, run `sudo python3 /lib/security/howdy/uninstall.py` to remove Howdy from your system.
### 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.

View file

@ -1,3 +1,7 @@
# Installation script to install howdy
# Runs completely independent of the others
# Import required modules
import subprocess import subprocess
import time import time
import sys import sys
@ -8,87 +12,112 @@ import fileinput
import urllib.parse import urllib.parse
def log(text): def log(text):
"""Print a nicely formatted line to stdout"""
print("\n>>> \033[32m" + text + "\033[0m\n") print("\n>>> \033[32m" + text + "\033[0m\n")
def handleStatus(status): def handleStatus(status):
"""Abort if a command fails"""
if (status != 0): if (status != 0):
print("\033[31mError while running last command\033[0m") print("\033[31mError while running last command\033[0m")
sys.exit() sys.exit()
# Check if we're running as root
user = os.getenv("SUDO_USER") user = os.getenv("SUDO_USER")
if user is None: if user is None:
print("Please run this script as a sudo user") print("Please run this script as a sudo user")
sys.exit() sys.exit()
# Print some nice intro text
print("\n\033[33m HOWDY INSTALLER FOR UBUNTU\033[0m") print("\n\033[33m HOWDY INSTALLER FOR UBUNTU\033[0m")
print(" Version 1, 2016/02/05\n") print(" Version 1, 2016/02/05\n")
# Let it sink in
time.sleep(.5) time.sleep(.5)
log("Installing required apt packages") log("Installing required apt packages")
# Install packages though apt
handleStatus(subprocess.call(["apt", "install", "-y", "libpam-python", "fswebcam", "libopencv-dev", "python-opencv"])) handleStatus(subprocess.call(["apt", "install", "-y", "libpam-python", "fswebcam", "libopencv-dev", "python-opencv"]))
log("Starting camera check") log("Starting camera check")
# Get all devices
devices = os.listdir("/dev") devices = os.listdir("/dev")
# The picked video device id
picked = False picked = False
# Loop though all devices
for dev in devices: for dev in devices:
# Only use the video devices
if (dev[:5] == "video"): if (dev[:5] == "video"):
time.sleep(.5) time.sleep(.5)
# The full path to the device is the default name
device_name = "/dev/" + dev 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") 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"): for line in udevadm.split("\n"):
# Match it and encase it in quotes
re_name = re.search('product.*=(.*)$', line, re.IGNORECASE) re_name = re.search('product.*=(.*)$', line, re.IGNORECASE)
if re_name: if re_name:
device_name = '"' + re_name.group(1) + '"' device_name = '"' + re_name.group(1) + '"'
# Show what device we're using
print("Trying " + device_name) 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) sub = subprocess.Popen(["fswebcam -S 9999999999 -d /dev/" + dev + " /dev/null 2>/dev/null"], shell=True, preexec_fn=os.setsid)
# Ask the user if this is the right one
print("\033[33mOne of your cameras should now be on.\033[0m") print("\033[33mOne of your cameras should now be on.\033[0m")
ans = input("Did your IR emitters turn on? [y/N]: ") ans = input("Did your IR emitters turn on? [y/N]: ")
# The user has answered, kill fswebcam
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
if (ans.lower() == "y"): if (ans.lower() == "y"):
picked = dev[5:] picked = dev[5:]
break break
else: else:
print("Inerpeting as a \"NO\"\n") print("Inerpeting as a \"NO\"\n")
# Abort if no camera was picked
if (picked == False): if (picked == False):
print("\033[31mNo suitable IR camera found\033[0m") print("\033[31mNo suitable IR camera found\033[0m")
sys.exit() sys.exit()
log("Cloning dlib") log("Cloning dlib")
# Clone the git to /tmp
handleStatus(subprocess.call(["git", "clone", "https://github.com/davisking/dlib.git", "/tmp/dlib_clone"])) handleStatus(subprocess.call(["git", "clone", "https://github.com/davisking/dlib.git", "/tmp/dlib_clone"]))
log("Building dlib") log("Building dlib")
# Start the build without GPU
handleStatus(subprocess.call(["cd /tmp/dlib_clone/; python3 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA"], shell=True)) handleStatus(subprocess.call(["cd /tmp/dlib_clone/; python3 setup.py install --yes USE_AVX_INSTRUCTIONS --no DLIB_USE_CUDA"], shell=True))
log("Cleaning up dlib") log("Cleaning up dlib")
# Remove the no longer needed git clone
handleStatus(subprocess.call(["rm", "-rf", "/tmp/dlib_clone"])) handleStatus(subprocess.call(["rm", "-rf", "/tmp/dlib_clone"]))
log("Installing face_recognition") log("Installing face_recognition")
# Install face_recognition though pip
handleStatus(subprocess.call(["pip3", "install", "face_recognition"])) handleStatus(subprocess.call(["pip3", "install", "face_recognition"]))
log("Cloning howdy") log("Cloning howdy")
# Make sure /lib/security exists
if not os.path.exists("/lib/security"): if not os.path.exists("/lib/security"):
os.makedirs("/lib/security") os.makedirs("/lib/security")
# Clone howdy into it
handleStatus(subprocess.call(["git", "clone", "https://github.com/Boltgolt/howdy.git", "/lib/security/howdy"])) handleStatus(subprocess.call(["git", "clone", "https://github.com/Boltgolt/howdy.git", "/lib/security/howdy"]))
# Manually change the camera id to the one picked
for line in fileinput.input(["/lib/security/howdy/config.ini"], inplace = 1): for line in fileinput.input(["/lib/security/howdy/config.ini"], inplace = 1):
print(line.replace("device_id = 1", "device_id = " + picked), end="") print(line.replace("device_id = 1", "device_id = " + picked), end="")
@ -104,76 +133,103 @@ subprocess.call(["sudo cp /lib/security/howdy/autocomplete.sh /etc/bash_completi
log("Adding howdy as PAM module") log("Adding howdy as PAM module")
# Will be filled with the actual output lines
outlines = [] outlines = []
# Will be fillled with lines that contain coloring
printlines = [] printlines = []
# Track if the new lines have been insterted yet
inserted = False inserted = False
# Open the PAM config file
with open("/etc/pam.d/common-auth") as fp: with open("/etc/pam.d/common-auth") as fp:
# Read the first line
line = fp.readline() line = fp.readline()
cnt = 1
while line: while line:
# Add the line to the output directly, we're not deleting anything
outlines.append(line) outlines.append(line)
if line[:1] != "#": # Print the comments in gray and don't insert into comments
if line[:1] == "#":
printlines.append("\033[37m" + line + "\033[0m")
else:
printlines.append(line) printlines.append(line)
# If it's not a comment and we haven't inserted yet
if not inserted: if not inserted:
# Set both the comment and the linking line
line_comment = "# Howdy IR face recognition\n" line_comment = "# Howdy IR face recognition\n"
line_Link = "auth sufficient pam_python.so /lib/security/howdy/pam.py\n\n" line_link = "auth sufficient pam_python.so /lib/security/howdy/pam.py\n\n"
# Add them to the output without any markup
outlines.append(line_comment) outlines.append(line_comment)
outlines.append(line_Link) outlines.append(line_link)
# Make the print orange to make it clear what's being added
printlines.append("\033[33m" + line_comment + "\033[0m") printlines.append("\033[33m" + line_comment + "\033[0m")
printlines.append("\033[33m" + line_Link + "\033[0m") printlines.append("\033[33m" + line_link + "\033[0m")
# Mark as inserted
inserted = True inserted = True
else:
printlines.append("\033[37m" + line + "\033[0m")
# Go to the next line
line = fp.readline() line = fp.readline()
cnt += 1
# Print a file Header
print("\033[33m" + ">>> START OF /etc/pam.d/common-auth" + "\033[0m") print("\033[33m" + ">>> START OF /etc/pam.d/common-auth" + "\033[0m")
# Loop though all printing lines and use the enters from the file
for line in printlines: for line in printlines:
print(line, end="") print(line, end="")
# Print a footer
print("\033[33m" + ">>> END OF /etc/pam.d/common-auth" + "\033[0m" + "\n") print("\033[33m" + ">>> END OF /etc/pam.d/common-auth" + "\033[0m" + "\n")
# Ask the user if this change is okay
print("Lines will be insterted in /etc/pam.d/common-auth as shown above") print("Lines will be insterted in /etc/pam.d/common-auth as shown above")
ans = input("Apply this change? [y/N]: ") ans = input("Apply this change? [y/N]: ")
# Abort the whole thing if it's not
if (ans.lower() != "y"): if (ans.lower() != "y"):
print("Inerpeting as a \"NO\", aborting") print("Inerpeting as a \"NO\", aborting")
sys.exit() sys.exit()
print("Adding lines to PAM\n") print("Adding lines to PAM\n")
# Write to PAM
common_auth = open("/etc/pam.d/common-auth", "w") common_auth = open("/etc/pam.d/common-auth", "w")
common_auth.write("".join(outlines)) common_auth.write("".join(outlines))
common_auth.close() common_auth.close()
# From here onwards the installation is complete
# We want to gather more information about the types or IR camera's
# used though, and the following lines are data collection
# List all video devices
diag_out = "Video devices [IR=" + picked + "]\n" diag_out = "Video devices [IR=" + picked + "]\n"
diag_out += "```\n" diag_out += "```\n"
diag_out += subprocess.check_output(['ls /dev/ | grep video'], shell=True).decode("utf-8") diag_out += subprocess.check_output(['ls /dev/ | grep video'], shell=True).decode("utf-8")
diag_out += "```\n" diag_out += "```\n"
# Get some info from the USB kernel listings
diag_out += "Lsusb output\n" diag_out += "Lsusb output\n"
diag_out += "```\n" diag_out += "```\n"
diag_out += subprocess.check_output(['lsusb -vvvv | grep -i "Camera\|iFunction"'], shell=True).decode("utf-8") diag_out += subprocess.check_output(['lsusb -vvvv | grep -i "Camera\|iFunction"'], shell=True).decode("utf-8")
diag_out += "```\n" diag_out += "```\n"
# Get camera information from video4linux
diag_out += "Udevadm\n" diag_out += "Udevadm\n"
diag_out += "```\n" diag_out += "```\n"
diag_out += subprocess.check_output(['udevadm info -r --query=all -n /dev/video' + picked + ' | grep -i "ID_BUS\|ID_MODEL_ID\|ID_VENDOR_ID\|ID_V4L_PRODUCT\|ID_MODEL"'], shell=True).decode("utf-8") diag_out += subprocess.check_output(['udevadm info -r --query=all -n /dev/video' + picked + ' | grep -i "ID_BUS\|ID_MODEL_ID\|ID_VENDOR_ID\|ID_V4L_PRODUCT\|ID_MODEL"'], shell=True).decode("utf-8")
diag_out += "```" 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.") print("Installation complete.")
print("If you want to help the development, please use the link above to post some camera-related information to github") print("If you want to help the development, please use the link above to post some camera-related information to github")
# Remove the installer if downloaded to tmp # Remove the installer if it was downloaded to /tmp
if os.path.exists("/tmp/howdy_install.py"): if os.path.exists("/tmp/howdy_install.py"):
os.remove("/tmp/howdy_install.py") os.remove("/tmp/howdy_install.py")

View file

@ -1,4 +1,36 @@
import subprocess # Completely remove howdy from the system
# Import required modules
import subprocess
import sys
import os
# Check if we're running as root
user = os.getenv("SUDO_USER")
if user is None:
print("Please run the uninstaller as a sudo user")
sys.exit()
# Double check with the user for the last time
print("This will remove Howdy and all models generated with it")
ans = input("Do you want to continue? [y/N]: ")
# Abort if they don't say yes
if (ans.lower() != "y"):
sys.exit()
# Remove files and symlinks
subprocess.call(["rm -rf /lib/security/howdy/"], shell=True) subprocess.call(["rm -rf /lib/security/howdy/"], shell=True)
subprocess.call(["rm /usr/bin/howdy"], shell=True) subprocess.call(["rm /usr/bin/howdy"], shell=True)
subprocess.call(["rm /etc/bash_completion.d/howdy"], shell=True)
# Remove face_recognition and dlib
subprocess.call(["pip3 uninstall face_recognition dlib -y"], shell=True)
# Print a tearbending message
print("""
Howdy has been uninstalled :'(
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\
""")