RPI door alarm project for keks

Wazakindjes 8473fe3cd9 Support for custom ARP/ICMP target IPs, make sure any responses from known MACs use the proper protoc0l, support for both ICMP and ARP for the same MAC, also added some shit about Android being gay and responding to fuck all =] 10 months ago
ass 67f3d60192 Rotated muhdoor.jpg in photoshit cuz fuck EXIM rotation, also shrunk that and shitcable.jpg to like 25% their size xdxd 1 year ago
conf 8473fe3cd9 Support for custom ARP/ICMP target IPs, make sure any responses from known MACs use the proper protoc0l, support for both ICMP and ARP for the same MAC, also added some shit about Android being gay and responding to fuck all =] 10 months ago
include 8473fe3cd9 Support for custom ARP/ICMP target IPs, make sure any responses from known MACs use the proper protoc0l, support for both ICMP and ARP for the same MAC, also added some shit about Android being gay and responding to fuck all =] 10 months ago
src 8473fe3cd9 Support for custom ARP/ICMP target IPs, make sure any responses from known MACs use the proper protoc0l, support for both ICMP and ARP for the same MAC, also added some shit about Android being gay and responding to fuck all =] 10 months ago
tests 8473fe3cd9 Support for custom ARP/ICMP target IPs, make sure any responses from known MACs use the proper protoc0l, support for both ICMP and ARP for the same MAC, also added some shit about Android being gay and responding to fuck all =] 10 months ago
.gitignore bf9be31516 Make tests/*.c into their own bin folder and .gitignore that shit lol 10 months ago
LICENSE c8c983ebdf Initial commit 1 year ago
Makefile bf9be31516 Make tests/*.c into their own bin folder and .gitignore that shit lol 10 months ago
README.md 8473fe3cd9 Support for custom ARP/ICMP target IPs, make sure any responses from known MACs use the proper protoc0l, support for both ICMP and ARP for the same MAC, also added some shit about Android being gay and responding to fuck all =] 10 months ago
gdb.sh a61624d6f9 gdb.sh: Pass at least one arg to _not_ -ex run/continue (useful for setting breakpoints first etc) =] 1 year ago
keepalive.sh 36b4e9d64d Updated need-r00t strings for run.sh and keepalive.sh ;3 1 year ago
run.sh 36b4e9d64d Updated need-r00t strings for run.sh and keepalive.sh ;3 1 year ago

README.md

HamDoor

A (Raspberry Pi aimed) project involving a door alarm, for the keks obv. =] Shit's written in qt3.14 C and should run fien on Debian, Ubantnu and ne other *nix flav0urs fambi (currently only fully tested on Debian/OSMC tho tbh). I will prolly accept pull requests for other OSes (or at least incorporate the code one way or anotha). ;3

The idea is to have an alarm on muh door using magnetic contact switches and shit. ;] Keep in mind the notification stuff is a little basic, cuz decent speakers etc are kinda expensive and I cbf for na0. =]

Features etc:

  • Its main control channel is Telegram (yes, the message service thing).
  • You can optionally enable MAC address control, which will disarm shit when a whitelist of MAC addresses is in the vicinity (like a mobile phone using WiFi). It figures this out by watching DHCP broadcast packets. This means you'll need to have an actual DHCP server on your LAN that is not your wireless access point/router itself (as that will usually prevent the broadcast from ever happening lmao).
  • It's re-armed if the MAC addresses are no longer around on the LAN. It figures this out by sending specially crafted ARP and multicast (but actually unicast) ICMP echo requests to the listed MAC addys only. Apparently some phones don't respond to multicast-addressed ICMPs and OS X/leen0rx doesn't respond to ARPs for 0.0.0.0, so I implemented b0th. =] Which one to use is configurable per MAC obv.
  • If the alarm is [[ t r i g g e r e d ]] but the door is closed and reopened again before you "untrip" or disarm it, it will send a "retripped" notice too. xd
  • Now also has support for something audible (like a piezo buzzer lol).

It requires root to start up, bind to the DHCP port and initialise PCAP shit, but it will drop privileges laturd (see also config section bel0w).

Hardware/other requirements etc

  • Raspberry Pi w/ three free pins: GND, GPIO and 3v3 (or 3.3V if you prefer, same shit)
  • Door sensor: ADA-375 magnetic contact switch (100 mA, 200 VDC, 15mm max distance between contacts)
  • Also a 10k pull-up resistor to go between GPIO and 3v3 (and possibly a 1k one, see the Assembly section for m0ar on dat)
  • Piezo buzzer: small version should suffice
  • Probably something to solder that shit with (or use a breadboard lel) and dem heat shrinks
  • Double-sided tape to stickem contacts onto the door(frame)
  • libbsd, libcurl (w/ SSL/TLS supp0t), libpcap and libpthread dev packages (varies per OS/distro how2inst0ll, so look it up imo tbh)
  • A Telegram API key
  • A mobile phone that's not from the Flintstones era (i.e. can connect to WiFi and supports Telegram)
  • A DHCP server on your LAN that's not your router (see also above/3rd paragraph), mite b optional doe

Assembly/wiring/etc

Kkkk first of all: my rPI is on the "wrong" side of the door, so I'd have to drag the sensor cables across muh door and I cbf'd with that. As such, the switch is on the same side as the hinges and the code supports "reversing" open and closed values. In this scenario both parts do not make contact (high value) if the door's closed. That also means I had to be very precise with muh placement, as opening the door should bring them close enough together to make contact (low value) which in turn trips the alarm.

I encountered some contradicting wiring schemes but this is the one that worked for me (verify that your rPI's GPIO header pinout matches too), I even left out the 1k resistor on GPIO after the split point. ;3 It works just fine but if you're paranoid I suppose you can add that too. =] Now, I don't have (room for) a breadboard w/ a ribbon cable sort of thing like many others do, so I just hacked together a cable. It doesn't matter which of the 2 wires coming out of the switch you decide to use for GND, just FYI. ;]

As for the piezo buzzer: simply connect one wire to the GND pin and the other to GPIO, polarity doesn't matter for this thing and it's low-voltage enough to be powered from GPIO. =]

Config br0heme

Copy conf/muhconf.h.example to just conf/muhconf.h and edit that shit. There's no proper *.conf file cuz I'm lazy like that. ;]];];;]

// Global shit
#define VERBOSE 0
#define RUNUSER 100
#define RUNGROUP 100
#define RUNFILE "/home/kek/HamDoor/var/hamdoor.armed"
#define BIND_INTERFACE "eth0"
#define GPIO_PIN 18 // GPIO pin numba
#define GPIO_REVERSE 0 // When set to 1, GPIO value 1 means door's closed and 0 means it's open

// Speaker shit brohemio
#define SPEAKERLOL 0 // Global t0ggle ;]
#define SPEAKER_PIN 21 // GPIO pin etc
#define SPEAKER_DURATION 10 // How many microseconds to buzz for, 10 seems to be dank
#define SPEAKER_TIMEOUT 200 // How many milliseconds to wait between buzzes
#define SPEAKER_FREQ 5000 // Frequency obv, should prolly be between 2000 and 5000 cuz h00mans b most sansativ to that
#define SPEAKER_PAUSEEVERY 15 // Pause buzzing every X seconds to prevent 100% CPU =]
#define SPEAKER_PAUSEFOR 10 // Pause for this many seconds bro

// When set to 1, allow these MACs to disarm the alarm when seen using DHCP
// Also re-arms that shit if they're no longer around (using ARP and ICMP echo request packets)
#define MAC_CONTROL 1
#define MAC_CONTROL_ADDYS "" \
"I_BA:21:DC:43:FE:65," /* Lapterp, ICMP */ \
"A_AB:12:CD:34:EF:56," /* Ur phone lel, ARP maybe */ \
//"I_AB:12:CD:34:EF:56" /* Could also do ICMP kek */

#define MAC_REARM_TIMEOUT 1 // After how many minutes we should rearm if MACs r no longer ar0und
#define MAC_PRINT_DHCPPACKET 0 // Print hexadecimal DHCP packets (for debugging etc)
#define HEX_ROWSIZE 16 // When dumping DHCP packets, place newlines after every this many bytez

#define ARP_ICMP_RETRY 4 // Max number of packets to send in one round (one at a time obv)
#define ARP_ICMP_PACKET_TIMEOUT 1000 // Retry sending to the same host after this many milliseconds
#define ARP_ICMP_RESPONSE_TIMEOUT 20 // How many seconds to wait between rounds

#define ARP_ADDY "0.0.0.0" // What IP to request ;]
#define ICMP_ADDY "224.0.0.1" // What IP to ping =]

// Required for dis(arm)ing thru Telegram and receiving notifications
#define TELEGRAM_KEY "111111111:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" // API key
#define TELEGRAM_ID "111111111" // Your personal "chat ID", see below for details
#define TELEGRAM_URLBASE "https://api.telegram.org/bot" // Base URL for API calls, current URL should b gucci (key is appended to it)
#define TELEGRAM_INTERVAL 5 // Telegram don't like 1 req/sec so let's wait for X seconds ;];]

Shit should be pretty clear imo tbh, but watch MAC_CONTROL_ADDYS closely and you'll see that every MAC addy ends with a comma (and the actual line ends with \). It's parsed by strtok() so make sure the full list ends up to be comma-separated etc.

Ain't gettin' no response?

It's possibru yo Android phone (or any l00nerx-based device such as a Ubuntu desktop) ain't responding to neither ARPs nor ICMPs (which happened for muh new phone). There's a possible fix but you'll need rewt in both cases. I'd imagine since iOS was written by Apple too and OSX responds just fine, you won't need to do anything specia there. =]

Just get into a shell (adb shell or just SSH) and run sysctl net.ipv4.icmp_echo_ignore_broadcasts. If it returns 1 then broadcast ICMPs will be dropped, which also applies to multicast which is what HamDoor's using by default. ;] Sooooooo get r00t status and run sysctl net.ipv4.icmp_echo_ignore_broadcasts=0 to turn it off temporarily. If that makes it respond properly then we gotta make it permament.

For anything but Android:
You should have a file sysctl.conf somewhere under /etc. Open it in whatever editor you want and attempt to find a line that already specifies the option and change 1 to 0. If there's none just slam it in there: net.ipv4.icmp_echo_ignore_broadcasts = 0

For Android:
You're prolly using MagiskSU so place the following script inside /magisk/.core/post-fs-data.d (name can be anything y0):

#!/system/bin/sh
echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts

Finally make sure it has the proper permissions: chmod 755 skrip.sh
Now Magisk will run it after mounting filesystems, which is p early in ze boot pr0cess. =]

Finding TELEGRAM_ID

Kkkk so this is p ez fam, send a message to the bot first. Then just concatenate TELEGRAM_URLBASE, TELEGRAM_KEY and /getUpdates and call the resulting URL in ur browser (so like https://api.telegram.org/bot111111111:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/getUpdates). You'll get some JSON shyte, just look for a variable called id inside a parent hash from (e.g. "from":{"id":123456789). Copy the ID and slam it in the config. This ID is used to tell the Telegram API where to send messages, as well as verify that only you can use the below commands.

Usage

The code uses /sys/class/gpio/export to initialise the GPIO stuff and tries to clean it up when quits (/sys/class/gpio/unexport), but as it dropped privileges it probably won't succeed. xd You can just do shit like echo -n 18 > /sys/class/gpio/unexport as root if you want to stop using HamDoor and/or GPIO pin 18. Same goes for the speaker pin if you're using it. =]

I recommend you use run.sh while testing since it runs make to refresh the config and checks if you have the privs to bind to the DHCP server port (if not, runs that shit w/ sudo). When done testing you can make it run as a daemon yoself or just use keepalive.sh in a screen sesh or something. =]]

Telegram commands

All commands give feedback if it would result in a change. ;]

  • a, arm => shud b obvi0us
  • c, continue => unpause/resume monitoring (if paused obv)
  • d, dis, disarm => ditt0 (automatically untrips shit too)
  • h, halp, help => shits out built-in halp string
  • p, pause => toggle pausing of monitoring (resume if paused and vice versa etc) -- makes it skip DHCP packet parsing and sending/listening for ARP/ICMP
  • ping, hi => say hiiiiiiiii (check if still connected etc)
  • t, trip, test => simulate unauth0rised entray (so you don't have to open the door every goddamn time while testing lmao)
  • u, un, untrip, r, res, reset => if alarm was armed and someone tripped it, have to untrip (does not automatically disarm)