Skip to content

Instantly share code, notes, and snippets.

@rmt
Last active October 8, 2021 14:50
Show Gist options
  • Select an option

  • Save rmt/c080dce48ec1e3241b5488c30278a59a to your computer and use it in GitHub Desktop.

Select an option

Save rmt/c080dce48ec1e3241b5488c30278a59a to your computer and use it in GitHub Desktop.
# Useful pam_exec program to do quick local sudo-auth.
# eg. add the following to /etc/pam.d/system-auth:
# auth sufficient pam_exec.so quiet stdout /usr/local/sbin/extra_sudo_auth
# Intention:
# Exit with 0 if right control & shift are held down simultaneously
# Fail immediately if left control or left shift are pressed
# Fail after a timeout
import asyncfile
import asyncdispatch
import os
import strutils
import times
# change this
let DEVICE = "/dev/input/by-id/usb-Metadot_-_Das_Keyboard_Das_Keyboard-event-kbd"
type timeval* = object
tv_sec*: int64
tv_usec*: int64
type input_event* = object
ev_timeval*: timeval
ev_type*: uint16
code*: uint16
value*: int32
proc timeout(fd: AsyncFD): bool =
quit("TIMEOUT")
proc main() {.async.} =
var lctrl = false
var lshift = false
var rctrl = false
var rshift = false
let time = now()
let waitPeriod = initDuration(seconds=5)
if getEnv("PAM_SERVICE") != "sudo":
quit("only used for sudo")
var fd: AsyncFile
try:
fd = openAsync(DEVICE)
except:
quit("could not open $1" % DEVICE)
addTimer(5000, true, timeout) # timeout after 5 seconds
echo("=== Authorization required ===")
var ev: input_event
while true:
if sizeof(ev) == await fd.readBuffer(cast[pointer](ev.addr), sizeof(ev)):
#echo "Event type=$1 / code=$2 / value=$3 (rshift=$4, rctrl=$5)" % [
# $ev.ev_type,
# $ev.code,
# $ev.value,
# $rshift,
# $rctrl]
if ev.ev_type == 0 or ev.ev_type == 4 or ev.value == 2:
continue
if ev.code == 97:
rctrl = (ev.value > 0)
elif ev.code == 54:
rshift = (ev.value > 0)
elif ev.code == 29:
lctrl = (ev.value > 0)
elif ev.code == 42:
lshift = (ev.value > 0)
#echo "lshift=$1, lctrl=$2, rshift=$3, rctrl=$4" % [
# $lshift,
# $lctrl,
# $rshift,
# $rctrl]
if rctrl and rshift:
echo "╱╱┏╮"
echo "╱╱┃┃ ACCESS"
echo "▉━╯┗━╮"
echo "▉┈┈┈┈┃ GRANTED"
echo "▉╮┈┈┈┃"
echo "╱╰━━━╯"
break
elif lctrl or lshift:
quit("ACCESS DENIED")
if (now() - time) > waitPeriod:
if (not rshift) and (not rctrl):
quit("TIMEOUT")
waitFor main()
@rmt
Copy link
Author

rmt commented Sep 6, 2021

$ sudo -i
=== Authorization required ===
╱╱┏╮
╱╱┃┃    ACCESS
▉━╯┗━╮
▉┈┈┈┈┃  GRANTED
▉╮┈┈┈┃
╱╰━━━╯
# 

and

$ sudo -i
=== Authorization required ===
ACCESS DENIED
[sudo] password for user:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment