31 Commits

Author SHA1 Message Date
T
e2e5878630 Add API v2 2024-07-04 23:03:35 +02:00
T
5724fcad2a Code style and shellcheck 2024-06-07 22:17:06 +02:00
bb8be95468 Foodoor-Systemd-Service; Paketinstaller fragt nach oben/unten 2022-11-01 18:56:45 +01:00
0b34242781 v3.0.3 2022-07-13 19:18:55 +02:00
a4befbc911 Update-keydb with comments and better Algo check 2022-07-13 19:16:48 +02:00
949fc2e4fb v3.0.2 2022-07-02 15:16:15 +02:00
940af82f84 Get rid of Mac-Newlines 2022-07-02 15:06:11 +02:00
8c232699c3 Dependencies! 2022-04-16 18:32:47 +02:00
cb05047fed Script-Bugfixes, init.d 2022-04-15 18:49:40 +02:00
f0baee2d91 Have more information about the conf file 2022-04-15 18:24:03 +02:00
3eed323364 Debian-Packaging 2022-04-15 18:17:58 +02:00
ee44662cd3 I deleted too much!11!! 2022-04-11 19:29:50 +02:00
aacb9c9669 Coding-Style; First floor and basement are now the same with the
authentication user
2022-04-11 18:47:42 +02:00
aadce7fb1a Raspian 11 update; python3 2021-11-13 17:23:46 +01:00
5d475701e6 Update to Raspbian 11; using python3 2021-11-13 16:14:15 +01:00
ce451daef1 Intendation; foodoord_oben - right API™ 2021-11-13 14:27:33 +01:00
72b2276603 Merge branch 'master' of ssh://git.chaospott.de:2222/Chaospott/foodoord 2021-11-07 19:46:29 +01:00
b3e57e3b57 foodoor ist oben! 2021-11-07 19:46:13 +01:00
a104fbf913 Automatisches foo 2021-11-07 19:45:39 +01:00
897c3a442a fix den fix gefixed 2021-11-07 18:52:41 +01:00
3583fddb7b the same as above, now with changes 2021-11-07 18:49:54 +01:00
3995b4b289 some more fixes, reboot-safeness and default trigger response 2021-11-07 18:47:08 +01:00
ec75fc14e3 another bug bites the dust 2021-11-07 18:37:10 +01:00
3f59acbfb0 fixed buggy bugs 2021-11-07 18:31:48 +01:00
98f31f6965 changed repo path 2021-11-07 18:21:12 +01:00
deed2c6764 changed mode of files 2021-11-07 18:07:41 +01:00
30b027014e added support for operation via command instead of user 2021-11-07 18:02:14 +01:00
8bb7f10d84 New Config; foodoord for the basement/1st floor (_unten/_oben) 2021-01-19 18:47:19 +01:00
116ff5eba0 ed25519-Support 2020-05-24 20:27:22 +02:00
8856ba9cf4 New repo; Howto config 2020-05-21 12:12:28 +02:00
7326d8f70d Bugfix for invalid keys-check 2016-03-31 16:00:53 +02:00
26 changed files with 504 additions and 517 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
foodoord*.deb

View File

@ -1,81 +1,103 @@
#foodoord # foodoord
Das Schließsystem läuft auf einem RaspberryPi mit der Erweiterungsplatine "PiFaceDigitalIO". Das Schließsystem läuft auf einem RaspberryPi mit der Erweiterungsplatine "PiFaceDigitalIO".
##Software##
###Installation### ## Konfiguration
<code>apt-get install python-pifacedigitalio </code>
Um das Paket zu installieren muss die */etc/apt/sources.list* angepasst werden. Falls `/etc/foodoord.conf` nicht vorhanden ist:
<code>deb http://archive.raspbian.org/raspbian wheezy main contrib non-free rpi</code> * `mv /etc/foodoord.conf_example /etc/foodoord.conf`
<code>deb-src http://archive.raspbian.org/raspbian wheezy main contrib non-free rpi</code> 1. Trage dort die API-Config für den Türstatus ein.
2. Falls nicht schon beim Paketinstall geschehen, mit `systemctl enable --now foodoord@oben` oder `systemctl enable --now foodoord@unten` enablen und starten.
Wer apt-get benutzt, kann den Raspbian Pubkey zum keyring hinzufügen.
<code>wget http://archive.raspbian.org/raspbian.public.key -O - | sudo apt-key add -</code>
###Dateiliste### ## Software
Der Deamon besteht aus folgenden Dateien.
### Dateiliste
Der Daemon besteht aus folgenden Dateien.
* foodoor * foodoor
* foodoord * foodoord
* foodoord.conf * foodoord.conf
* foodoord_initd
* foodoor-ssh-wrapper
* foodoor-update-keydb * foodoor-update-keydb
* foodoord@.service
##Schüssel Zusätzlich sollte für das git-repo eine Config angelegt werden:
###Schlüsselupdate /root/.ssh/config
<pre><code>foodoor-update-keydb ```
</code></pre> Host git.chaospott.de
Aktualisiert die die Schlüssel auf der Tür und baut die *Authorized_Keys* für die User *open* und *close*. Keys die nicht dem OpenSSH-Format mit 4096 bit entsprechen, werden ignoriert. Wenn das Script von Hand aufgerufen wird, werden die betroffenen Keys angezeigt. Über einen Cronjob werden die Keys alle **5 Min aktualisiert**. User git
Port 2222
IdentityFile ~/.ssh/id_chaospott
```
Das IdentityFile ist der Deploy-SSH-Key, der im [Repo](https://git.chaospott.de/Chaospott/foodoor-keys) hinterlegt ist.
## Schüssel
### Schlüsselupdate
`foodoor-update-keydb`
Aktualisiert die Schlüssel auf der Tür und baut die *Authorized_Keys* für die User *open* und *close*. Keys die nicht dem OpenSSH-Format mit 4096 bit entsprechen, werden ignoriert. Wenn das Script von Hand aufgerufen wird, werden die betroffenen Keys angezeigt. Über einen Cronjob werden die Keys alle **5 Min aktualisiert**.
### Schlüsselformate
###Schlüsselformate###
Der foodoord akzeptiert nur Pub-Keys im *OpenSSH2-Format*. Keys lassen sich unter anderem mit OpenSSH oder PuTTygen erzeugen. Der foodoord akzeptiert nur Pub-Keys im *OpenSSH2-Format*. Keys lassen sich unter anderem mit OpenSSH oder PuTTygen erzeugen.
###OpenSSH#### ### OpenSSH
####Keys generieren#### #### Keys generieren
* Mit <code>ssh-keygen -b 4096 </code> lassen sich Keys generieren.
* <code>ssh-add $Pfad_zum_Key</code> fügt den Key dem ssh-Agent hinzu. Die Option <code>ssh-add -l</code> zeigt geladene Keys an.
* <code>ssh-kegen -l -f $Pfad_zum_Key </code> gibt den Fingerprint und andere Informationen zurück.
####Keys konvertieren(PuTTy>OpenSSH):#### * Mit `ssh-keygen -b 4096` lassen sich Keys generieren.
* <code>ssh-keygen -i $Pfad_zum_Key > $Pfad_neuer_Pfad.pub</code> liest ssh2-kompatible Keys(RFC 4716) ein und speichert diese im OpenSSH-Format. * `ssh-add $Pfad_zum_Key` fügt den Key dem ssh-Agent hinzu. Die Option `ssh-add -l` zeigt geladene Keys an.
* `ssh-kegen -l -f $Pfad_zum_Key` gibt den Fingerprint und andere Informationen zurück.
#### Keys konvertieren (PuTTy > OpenSSH):
* `ssh-keygen -i $Pfad_zum_Key > $Pfad_neuer_Pfad.pub<` liest ssh2-kompatible Keys (RFC 4716) ein und speichert diese im OpenSSH-Format.
### PuTTy
###PuTTy###
Da die Tür nur Keys im OpenSSH-Format verträgt, dürfen auch mit Putty nur OpenSSH-Keys genutzt werden. Da die Tür nur Keys im OpenSSH-Format verträgt, dürfen auch mit Putty nur OpenSSH-Keys genutzt werden.
###Keys generieren (OpenSSH-Format mit PuttyGen):### #### Keys generieren (OpenSSH-Format mit PuttyGen):
1. PuTTYgen öffnen 1. PuTTYgen öffnen
2. Unten "Number of Bits in a generated Key:" 4096 eintippen 2. Unten "Number of Bits in a generated Key:" 4096 eintippen
3. "Generate" klicken um Key zu generieren 3. "Generate" klicken um Key zu generieren
4. Nach dem generieren oben im Menu "Conversions" > "Export OpenSSH-Key" 4. Nach dem Generieren oben im Menu "Conversions" > "Export OpenSSH-Key"
5. Speichern 5. Speichern
Es ist zu beachten, dass Putty den PrivateKey im Putty-Format benötigt! Das heißt, falls der generierte Key vor dem Export nicht gespeichert wurde, muss der private Key noch konvertiert werden, siehe nächster Punkt! Es ist zu beachten, dass Putty den PrivateKey im Putty-Format benötigt! Das heißt, falls der generierte Key vor dem Export nicht gespeichert wurde, muss der private Key noch konvertiert werden, siehe nächster Punkt!
###Keys konvertieren(OpenSSH>PuTTy):###
#### Keys konvertieren (OpenSSH > PuTTy):
1. PuTTYgen öffnen 1. PuTTYgen öffnen
2. "Load" drücken 2. "Load" drücken
3. OpenSSH-Key auswählen 3. OpenSSH-Key auswählen
4. "Save Private-Key" drücken 4. "Save Private-Key" drücken
5. Speichern 5. Speichern
##Hardware
## Hardware
### Input: ### Input:
* ssh-login * ssh-login
* Klingel * Klingel
* Statustaster * Statustaster
### Output: ### Output:
* Status LEDs * Status LEDs
* Summer * Summer
* Keymatic * Keymatic

3
build-package Executable file
View File

@ -0,0 +1,3 @@
#!/bin/bash
VERSION=3.2.0
dpkg-deb --root-owner-group -b debian "foodoord_${VERSION}_all.deb"

6
debian/DEBIAN/control vendored Executable file
View File

@ -0,0 +1,6 @@
Package: foodoord
Version: 3.2.0
Maintainer: Bandie <bandie@chaospott.de>
Architecture: all
Description: Control the doors of the club, ja!
Depends: dash, git, python3, pip, tmux

36
debian/DEBIAN/postinst vendored Executable file
View File

@ -0,0 +1,36 @@
#!/bin/bash
echo "Creating group and users.."
groupadd foodoor
useradd -M -d /var/lib/foodoor/close -G foodoor -s /bin/sh close
useradd -M -d /var/lib/foodoor/open -G foodoor -s /bin/sh open
useradd -M -d /var/lib/foodoor/door -G foodoor -s /bin/sh door
echo "Chown homes"
for u in close open door; do
groupadd ${u}
chown ${u}:${u} /var/lib/foodoor/${u}
done
echo "Chmod foodoor"
chmod 755 /var/lib/foodoor
echo "Create /state"
touch /state
chown root:foodoor /state
chmod 664 /state
echo "##################"
while [ "$prompt" != "oben" ] && [ "$prompt" != "unten" ]; do
read -r -p "Sind wir oben oder unten? (oben, unten): " prompt
done
echo "##################"
echo "Installing dependencies via pip: pifacecommon pifacedigitalio"
pip install pifacecommon pifacedigitalio
echo "Enabling and starting systemd-Services"
systemctl daemon-reload
systemctl enable "foodoord@$prompt"
systemctl restart "foodoord@$prompt"
systemctl status "foodoord@$prompt"

11
debian/changelog vendored
View File

@ -1,11 +0,0 @@
foodoord (2-1~foobar1) UNRELEASED; urgency=medium
* New upstream release.
-- Hauro <hauro@chaospott.de> Fri, 17 Jul 2015 20:10:27 +0200
foodoord (1-1~foobar1) unstable; urgency=low
* Initial release.
-- gammlaa <gammlaa@chaospott.de> Sat, 04 Apr 2015 16:19:46 +0100

1
debian/compat vendored
View File

@ -1 +0,0 @@
9

15
debian/control vendored
View File

@ -1,15 +0,0 @@
Source: foodoord
Section: net
Priority: optional
Maintainer: gammlaa <gammlaa@chaospott.de>
Build-Depends: debhelper (>= 9), dh-python, python
Standards-Version: 3.9.6
Homepage: https://github.com/c3e/foodoord
Package: foodoord
Architecture: all
X-Python-Version: any
Depends: ${misc:Depends}, adduser, python-pifacedigitalio
Description: Türschließsystem des foobar e.V.
Simsalabim!

38
debian/copyright vendored
View File

@ -1,38 +0,0 @@
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: foodoord
Source: <url://example.com>
Files: *
Copyright: <years> <put author's name and email here>
<years> <likewise for another author>
License: <special license>
<Put the license of the package here indented by 1 space>
<This follows the format of Description: lines in control file>
.
<Including paragraphs>
# If you want to use GPL v2 or later for the /debian/* files use
# the following clauses, or change it to suit. Delete these two lines
Files: debian/*
Copyright: 2014 gammlaa <gammlaa@chaospott.de>
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".
# Please also look if there are files or directories which have a
# different copyright/license attached and list them here.
# Please avoid to pick license terms that are more restrictive than the
# packaged work, as it may make Debian's contributions unacceptable upstream.

0
debian/foodoord.cron.d → debian/etc/cron.d/foodoord vendored Normal file → Executable file
View File

9
debian/etc/foodoord.conf_example vendored Executable file
View File

@ -0,0 +1,9 @@
[doorstatus]
status_url =
key =
secret =
[doorstatusv2]
status_url =
key =
secret =

13
debian/etc/systemd/system/foodoord@.service vendored Executable file
View File

@ -0,0 +1,13 @@
[Unit]
Description=foodoord %i
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
Type=simple
ExecStart=/usr/sbin/foodoord_%i
Restart=on-failure
RestartSec=5s
[Install]
WantedBy=multi-user.target

View File

@ -1,5 +0,0 @@
foodoord.conf etc
foodoor usr/sbin
foodoord usr/sbin
foodoor-ssh-wrapper usr/sbin
foodoor-update-keydb usr/sbin

View File

@ -1,38 +0,0 @@
#!/bin/sh
# preinst script for foodoord
#
# see: dh_installdeb(1)
set -e
# summary of how this script can be called:
# * <new-preinst> `install'
# * <new-preinst> `install' <old-version>
# * <new-preinst> `upgrade' <old-version>
# * <old-preinst> `abort-upgrade' <new-version>
# for details, see http://www.debian.org/doc/debian-policy/ or
# the debian-policy package
case "$1" in
install|upgrade)
addgroup --system foodoor
adduser --system --ingroup foodoor --home /var/lib/foodoor/open --disabled-password --disabled-login open
adduser --system --ingroup foodoor --home /var/lib/foodoor/close --disabled-password --disabled-login close
;;
abort-upgrade)
;;
*)
echo "preinst called with unknown argument \`$1'" >&2
exit 1
;;
esac
# dh_installdeb will replace this with shell code automatically
# generated by other debhelper scripts.
#DEBHELPER#
exit 0

12
debian/rules vendored
View File

@ -1,12 +0,0 @@
#!/usr/bin/make -f
# See debhelper(7) (uncomment to enable)
# output every command that modifies files on the build system.
#DH_VERBOSE = 1
%:
dh $@ --with=python2
override_dh_installinit:
mkdir debian/foodoord/etc/init.d
cp foodoord_initd debian/foodoord/etc/init.d/foodoord
dh_installinit --onlyscripts

View File

@ -1 +0,0 @@
3.0 (quilt)

34
debian/usr/sbin/foodoor vendored Executable file
View File

@ -0,0 +1,34 @@
#!/bin/sh
set -e
PIPE_PATH=/var/run/foodoord.pipe
if [ ! -e $PIPE_PATH ]; then
echo "Pipe missing. Check daemon status."
exit 1
fi
action=$1
isTriggerActivated=0
if [ -z "$action" ]; then
action=$SSH_ORIGINAL_COMMAND
isTriggerActivated=1
fi
case $action in
close | open)
echo "$action" | tee "$PIPE_PATH" | sed 's/open/UNLOCKED/;s/close/LOCKED/' > /state
;;
status) ;;
*)
echo "Usage: $(basename "$0") { close, open, status }"
exit 1
;;
esac
if [ $isTriggerActivated -eq 1 ]; then
cat /state
sleep 2
fi

54
debian/usr/sbin/foodoor-update-keydb vendored Executable file
View File

@ -0,0 +1,54 @@
#!/bin/bash
set -e
export PATH="/usr/bin:/bin:/usr/sbin:/sbin"
dest=/var/run/foodoor-keys
temp_outfile=$dest.tmp
if [ ! -e "$dest/.git/config" ]; then
#echo "Repo does not exist, trying to clone..."
git -C "$dest" clone --quiet --single-branch --depth=1 ssh://git.chaospott.de/Keyverwaltung/foodoor-keys.git "$dest"
else
#echo "Repo exists, updating..."
git -C "$dest" fetch --quiet && git -C "$dest" merge --quiet origin/master master
fi
rm -f "$temp_outfile"
find "$dest/keys" -type f -name '*.pub' | sort |
while read -r keyfile; do
if ssh-keygen -l -f "$keyfile" &> /dev/null; then
keyinfo=$(ssh-keygen -l -f "$keyfile") # The whole key information
crypto=$(echo "$keyinfo" | sed 's/.*(\(.*\))/\1/') # Looks like "RSA" or "ED25519"
key_length=$(echo "$keyinfo" | cut -d" " -f1)
if [ "$crypto" == "RSA" ]; then
if [ "$key_length" -lt 4096 ]; then
echo "Key size of key $keyfile less than 4096. Not adding it to key database." >&2
continue
fi
# valid
elif [ "$crypto" == "ED25519" ]; then
: # valid
else
continue
fi
echo "command=\"/usr/sbin/foodoor \$action \",no-port-forwarding,no-X11-forwarding,no-agent-forwarding $(sed 's/\r//g' "$keyfile") $keyfile" >> $temp_outfile
fi
done
for appendix in open close door; do
action=$appendix
if [ "$appendix" = "door" ]; then
action=""
fi
export action
outfile=$dest/authorized_keys.$appendix
envsubst < "$temp_outfile" > "$outfile"
# Oben und unten
install -d -o "$appendix" -g nogroup -m 0700 "/var/lib/foodoor/$appendix/.ssh"
install -b -S .last -o "$appendix" -g nogroup -m 0600 "$outfile" "/var/lib/foodoor/$appendix/.ssh/authorized_keys"
done

165
debian/usr/sbin/foodoord_oben vendored Executable file
View File

@ -0,0 +1,165 @@
#!/usr/bin/env python3
# vim: ts=2 sw=2 et
import grp
import json
import os
import signal
import stat
import subprocess
import sys
import time
from configparser import ConfigParser
from dataclasses import dataclass
import pifacedigitalio
# Definitions for output
LED_RED = 6
LED_GREEN = 7
RELAYS_LOCK = 0
RELAYS_UNLOCK = 1
# Definitions for input
DOOR_BELL = 0
REED_RELAYS = 1 # not implemented yet
# Definitions for LED color
RED = 1
GREEN = 2
ORANGE = 3
# Read config
parser = ConfigParser()
parser.read('/etc/foodoord.conf')
@dataclass
class API:
api_url: str
consumer_key: str
consumer_secret: str
APIv1 = API(
parser.get('doorstatus', 'status_url'),
parser.get('doorstatus', 'key'),
parser.get('doorstatus', 'secret'),
)
APIv2 = API(
parser.get('doorstatusv2', 'status_url'),
parser.get('doorstatusv2', 'key'),
parser.get('doorstatusv2', 'secret'),
)
def update_api(locked):
try:
# API v1
subprocess.check_call([
"/usr/bin/curl", "-XPOST",
"--header", "Content-Type: application/json",
"--data",
json.dumps({"consumer_key": APIv1.consumer_key, "consumer_secret": APIv1.consumer_secret, "aerie": locked}),
APIv1.api_url
])
except:
pass
try:
# API v2
subprocess.check_call([
"/usr/bin/curl", "-XPOST",
"--header", "Content-Type: application/json",
"--data",
json.dumps({"consumer_key": APIv2.consumer_key, "consumer_secret": APIv2.consumer_secret, "aerie": locked}),
APIv2.api_url
])
except:
pass
def set_led(color):
if color == RED:
pifacedigital.leds[LED_RED].turn_on()
pifacedigital.leds[LED_GREEN].turn_off()
elif color == GREEN:
pifacedigital.leds[LED_GREEN].turn_on()
pifacedigital.leds[LED_RED].turn_off()
elif color == ORANGE:
pifacedigital.leds[LED_RED].turn_on()
pifacedigital.leds[LED_GREEN].turn_on()
class Foodoord:
def __init__(self):
self.status_open = False
self.listener = pifacedigitalio.InputEventListener()
self.listener.register(0, pifacedigitalio.IODIR_RISING_EDGE, self.doorbell, settle_time=10)
self.listener.register(1, pifacedigitalio.IODIR_RISING_EDGE, self.close_button, settle_time=5)
def signal_handler(self, _signal, _frame):
self.listener.deactivate()
os.remove("/var/run/foodoord.pipe")
update_api(True)
set_led(RED)
sys.exit(0)
def doorbell(self, event):
if self.status_open:
pifacedigital.relays[RELAYS_UNLOCK].toggle()
time.sleep(2)
pifacedigital.relays[RELAYS_UNLOCK].toggle()
def close_button(self, _event):
self.status_open = False
update_api(True)
set_led(RED)
def main(self):
self.listener.activate()
pifacedigital = pifacedigitalio.PiFaceDigital()
signal.signal(signal.SIGTERM, self.signal_handler)
# Start settings
pifacedigital.leds[LED_RED].turn_on()
# Setting up FiFo to get sshd-output
try:
os.mkfifo("/var/run/foodoord.pipe")
os.chown("/var/run/foodoord.pipe", -1, grp.getgrnam('foodoor')[2])
os.chmod("/var/run/foodoord.pipe", stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP)
except OSError:
pass
ssh_input = open("/var/run/foodoord.pipe", "r")
while True:
# Read sshd-output from pipe
pipe_cmd = ssh_input.readline().strip()
if pipe_cmd == "close" and self.status_open:
pifacedigital.relays[RELAYS_LOCK].toggle()
time.sleep(1)
pifacedigital.relays[RELAYS_LOCK].toggle()
self.status_open = False
update_api(True)
set_led(RED)
elif pipe_cmd == "open":
pifacedigital.relays[RELAYS_UNLOCK].toggle()
time.sleep(2)
pifacedigital.relays[RELAYS_UNLOCK].toggle()
if not self.status_open:
update_api(False)
self.status_open = True
set_led(GREEN)
time.sleep(0.1)
if __name__ == "__main__":
Foodoord().main()

128
debian/usr/sbin/foodoord_unten vendored Executable file
View File

@ -0,0 +1,128 @@
#!/usr/bin/env python3
# vim: ts=2 sw=2 et
import grp
import json
import os
import stat
import subprocess
import time
from configparser import ConfigParser
from dataclasses import dataclass
import RPi.GPIO as gpio
# Definitions for output
LED_RED = 6
LED_GREEN = 7
RELAYS_LOCK = 0
RELAYS_UNLOCK = 1
PIN_OPEN = 24
PIN_CLOSE = 27
# Definitions for input
DOOR_BELL = 0
REED_RELAYS = 1 # not implemented yet
# Definitions for LED color
RED = 1
GREEN = 2
ORANGE = 3
# Read config
parser = ConfigParser()
parser.read('/etc/foodoord.conf')
@dataclass
class API:
api_url: str
consumer_key: str
consumer_secret: str
APIv1 = API(
parser.get('doorstatus', 'status_url'),
parser.get('doorstatus', 'key'),
parser.get('doorstatus', 'secret'),
)
APIv2 = API(
parser.get('doorstatusv2', 'status_url'),
parser.get('doorstatusv2', 'key'),
parser.get('doorstatusv2', 'secret'),
)
def write_state(state):
try:
with open("/tmp/door_state", "w") as handle:
handle.write(state)
except:
pass
def update_api(locked):
try:
# API v1
subprocess.check_call([
"/usr/bin/curl", "-XPOST",
"--header", "Content-Type: application/json",
"--data",
json.dumps({"consumer_key": APIv1.consumer_key, "consumer_secret": APIv1.consumer_secret, "cellar": locked}),
APIv1.api_url
])
except:
pass
try:
# API v2
subprocess.check_call([
"/usr/bin/curl", "-XPOST",
"--header", "Content-Type: application/json",
"--data",
json.dumps({"consumer_key": APIv2.consumer_key, "consumer_secret": APIv2.consumer_secret, "cellar": locked}),
APIv2.api_url
])
except:
pass
def main():
# Start settings
gpio.setmode(gpio.BCM)
gpio.setup(PIN_OPEN, gpio.OUT)
gpio.setup(PIN_CLOSE, gpio.OUT)
# Setting up FiFo to get sshd-output
try:
os.mkfifo("/var/run/foodoord.pipe")
os.chown("/var/run/foodoord.pipe", -1, grp.getgrnam('foodoor')[2])
os.chmod("/var/run/foodoord.pipe", stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP)
except OSError:
pass
ssh_input = open("/var/run/foodoord.pipe", "r")
while True:
# Read sshd output from pipe
pipe_cmd = ssh_input.readline().strip()
if pipe_cmd == "close":
gpio.output(PIN_CLOSE, 1)
time.sleep(1)
gpio.output(PIN_CLOSE, 0)
write_state("closed")
update_api(True)
elif pipe_cmd == "open":
# Locking
gpio.output(PIN_OPEN, 1)
time.sleep(1)
gpio.output(PIN_OPEN, 0)
write_state("open") # Save State
update_api(False) # Status Update
time.sleep(0.2)
if __name__ == "__main__":
main()

23
foodoor
View File

@ -1,23 +0,0 @@
#!/bin/sh
set -e
PIPE_PATH=/var/run/foodoord.pipe
if [ ! -e $PIPE_PATH ]
then
echo "Pipe missing. Check daemon status."
exit 1
fi
case $1 in
close)
echo close > $PIPE_PATH
;;
open)
echo open > $PIPE_PATH
;;
*)
echo "Usage: $(basename $0) { close, open}"
exit 1
;;
esac

View File

@ -1,2 +0,0 @@
#!/bin/sh
ssh -i /root/.ssh/id_rsa_gitlab_deploy $1 $2

View File

@ -1,38 +0,0 @@
#!/bin/sh
set -e
export PATH="/usr/bin:/bin:/usr/sbin:/sbin"
export GIT_SSH="/usr/sbin/foodoor-ssh-wrapper"
dest=/var/run/foodoor-keys
if [ ! -e "${dest}/.git/config" ]
then
#echo "Repo does not exist, trying to clone..."
( cd /var/run && git clone --quiet --single-branch --depth=1 luftschleuse@nordstern.chaospott.de:/home/luftschleuse/foodoor-keys "${dest}" )
else
#echo "Repo exists, updating..."
( cd "${dest}" && git fetch --quiet && git merge --quiet origin/master master )
fi
for action in open close
do
outfile="${dest}/authorized_keys.${action}"
rm -f ${outfile}
find "${dest}/keys" -name '*.pub' | sort | \
while read keyfile
do
valid_key=$(ssh-keygen -l -f ${keyfile})
if [ "$?" -eq "0" ]; then
if [ $(echo "${valid_key}" | cut -d" " -f1) -lt "4096" ]; then
echo "Size of key ${keyfile} is less than 4096. Not adding it to key database." >&2
continue
fi
fi
printf "command=\"/usr/sbin/foodoor ${action}\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding " >> ${outfile}
cat "${keyfile}" >> ${outfile}
echo >> ${outfile}
done
install -d -o ${action} -g nogroup -m 0700 /var/lib/foodoor/${action}/.ssh
install -b -S .last -o ${action} -g nogroup -m 0600 ${outfile} /var/lib/foodoor/${action}/.ssh/authorized_keys
done

140
foodoord
View File

@ -1,140 +0,0 @@
#!/usr/bin/env python2
import os
import stat
import time
import pifacedigitalio
import urllib2
import signal
import sys
import grp
from ConfigParser import SafeConfigParser
#Read config
parser = SafeConfigParser()
parser.read('/etc/foodoord.conf')
url = parser.get('door_firstlevel', 'status_url')
old_api = parser.get('door_firstlevel_old', 'status_url')
#Definitions for output
LED_RED=6
LED_GREEN=7
RELAYS_LOCK=0
RELAYS_UNLOCK=1
#Definitions for input
DOOR_BELL=0
REED_RELAYS=1 #not implementet yet
#Definitions for LEDcolor
RED=1
GREEN=2
ORANGE=3
if __name__ == "__main__":
def doorbell(event):
if (STATUS):
pifacedigital.relays[RELAYS_UNLOCK].toggle()
time.sleep(2)
pifacedigital.relays[RELAYS_UNLOCK].toggle()
#print 'got doorbell'
def close_button(event):
global STATUS
STATUS = False
try:
urllib2.urlopen(url+'&door=aerie&locked=1', timeout=2)
urllib2.urlopen(old_api+'&status=closed', timeout=2)
except:
pass
set_led(RED)
listener = pifacedigitalio.InputEventListener()
listener.register(0, pifacedigitalio.IODIR_RISING_EDGE, doorbell, settle_time=10)
listener.register(1, pifacedigitalio.IODIR_RISING_EDGE, close_button, settle_time=5)
listener.activate()
def signal_handler(signal, frame):
listener.deactivate()
os.remove("/var/run/foodoord.pipe")
try:
urllib2.urlopen(url+'&door=aerie&locked=1', timeout=2)
urllib2.urlopen(old_api+'&status=closed', timeout=2)
except:
pass
set_led(RED)
sys.exit(0)
def set_led(color):
if (color==RED):
pifacedigital.leds[LED_RED].turn_on()
pifacedigital.leds[LED_GREEN].turn_off()
elif (color==GREEN):
pifacedigital.leds[LED_GREEN].turn_on()
pifacedigital.leds[LED_RED].turn_off()
elif (color==ORANGE):
pifacedigital.leds[LED_RED].turn_on()
pifacedigital.leds[LED_GREEN].turn_on()
pifacedigital = pifacedigitalio.PiFaceDigital()
signal.signal(signal.SIGTERM, signal_handler)
#Startsettings
STATUS = False
pifacedigital.leds[LED_RED].turn_on()
#Setting up FiFo to get sshd-output
try:
os.mkfifo("/var/run/foodoord.pipe")
os.chown("/var/run/foodoord.pipe", -1, grp.getgrnam('foodoor')[2])
os.chmod("/var/run/foodoord.pipe", stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP)
except OSError:
pass
with open("/var/run/foodoord.pipe", "r") as ssh_input:
while 1:
#Read sshd-output from pipe
Pipe = ssh_input.readline()[:-1]
if (Pipe == "close" and STATUS):
pifacedigital.relays[RELAYS_LOCK].toggle()
time.sleep(1)
pifacedigital.relays[RELAYS_LOCK].toggle()
STATUS = False
try:
urllib2.urlopen(url+'&door=aerie&locked=1', timeout=2)
urllib2.urlopen(old_api+'&status=closed', timeout=2)
except:
pass
set_led(RED)
elif (Pipe == "open"):
pifacedigital.relays[RELAYS_UNLOCK].toggle()
time.sleep(2)
pifacedigital.relays[RELAYS_UNLOCK].toggle()
if (STATUS==False):
try:
urllib2.urlopen(url+'&door=aerie&locked=0', timeout=2)
urllib2.urlopen(old_api+'&status=open', timeout=2)
except:
pass
STATUS = True
set_led(GREEN)
time.sleep(0.1)

View File

@ -1,5 +0,0 @@
[door_firstlevel_old]
status_url =
[door_firstlevel]
status_url =

View File

@ -1,155 +0,0 @@
#! /bin/sh
### BEGIN INIT INFO
# Provides: foodoor
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: foodoor initscript
# Description: Daemon to lock and unlock the foodoor
### END INIT INFO
# Author: gammlaa <gammlaa@die-foobar.de>
# Do NOT "set -e"
# PATH should only include /usr/* if it runs after the mountnfs.sh script
PATH=/sbin:/usr/sbin:/bin:/usr/bin
DESC="foodoor daemon"
NAME=foodoord
DAEMON=/usr/sbin/$NAME
#DAEMON_ARGS="--options args"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
# Exit if the package is not installed
[ -x "$DAEMON" ] || exit 0
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
# Define LSB log_* functions.
# Depend on lsb-base (>= 3.2-14) to ensure that this file is present
# and status_of_proc is working.
. /lib/lsb/init-functions
#
# Function that starts the daemon/service
#
do_start()
{
# Return
# 0 if daemon has been started
# 1 if daemon was already running
# 2 if daemon could not be started
start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \
|| return 1
start-stop-daemon --start --quiet --background --make-pidfile --pidfile $PIDFILE --exec $DAEMON -- \
$DAEMON_ARGS \
|| return 2
# Add code here, if necessary, that waits for the process to be ready
# to handle requests from services started subsequently which depend
# on this one. As a last resort, sleep for some time.
}
#
# Function that stops the daemon/service
#
do_stop()
{
# Return
# 0 if daemon has been stopped
# 1 if daemon was already stopped
# 2 if daemon could not be stopped
# other if a failure occurred
start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name python2
RETVAL="$?"
[ "$RETVAL" = 2 ] && return 2
# Wait for children to finish too if this is a daemon that forks
# and if the daemon is only ever run from this initscript.
# If the above conditions are not satisfied then add some other code
# that waits for the process to drop all resources that could be
# needed by services started subsequently. A last resort is to
# sleep for some time.
start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --pidfile $PIDFILE --exec $DAEMON
[ "$?" = 2 ] && return 2
# Many daemons don't delete their pidfiles when they exit.
rm -f $PIDFILE
return "$RETVAL"
}
#
# Function that sends a SIGHUP to the daemon/service
#
do_reload() {
#
# If the daemon can reload its configuration without
# restarting (for example, when it is sent a SIGHUP),
# then implement that here.
#
start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
return 0
}
case "$1" in
start)
[ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
do_start
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
stop)
[ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
do_stop
case "$?" in
0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
esac
;;
status)
status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
;;
#reload|force-reload)
#
# If do_reload() is not implemented then leave this commented out
# and leave 'force-reload' as an alias for 'restart'.
#
#log_daemon_msg "Reloading $DESC" "$NAME"
#do_reload
#log_end_msg $?
#;;
restart|force-reload)
#
# If the "reload" option is implemented then remove the
# 'force-reload' alias
#
log_daemon_msg "Restarting $DESC" "$NAME"
do_stop
case "$?" in
0|1)
do_start
case "$?" in
0) log_end_msg 0 ;;
1) log_end_msg 1 ;; # Old process is still running
*) log_end_msg 1 ;; # Failed to start
esac
;;
*)
# Failed to stop
log_end_msg 1
;;
esac
;;
*)
#echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
exit 3
;;
esac
: