pax_global_header00006660000000000000000000000064117215423370014517gustar00rootroot0000000000000052 comment=0b91d5d58fee989a662b4e39e3535c7a5046178b molly-guard-0.4.5/000077500000000000000000000000001172154233700137615ustar00rootroot00000000000000molly-guard-0.4.5/.gitignore000066400000000000000000000000771172154233700157550ustar00rootroot00000000000000/build-stamp /configure-stamp .*.sw? /molly-guard.8* /shutdown molly-guard-0.4.5/ChangeLog000066400000000000000000000046131172154233700155370ustar00rootroot000000000000002012-02-22 Ludovico Gardenghi Version 0.4.5 [ Martin F. Krafft] * Use tty tool to detect the tty of stdin, rather than /proc/*/fd/0, which is Linux-specificy. [ Ludovico Gardenghi ] * Check the process tree from the shell up to init and look for a 'sshd' process. 2008-06-19 martin f. krafft Version 0.4.4 * Fix argument passing to real commands. 2008-06-01 martin f. krafft Version 0.4.3 * Properly detects sshd sessions, even if ControlMaster is in use. 2008-05-31 martin f. krafft Version 0.4.2 * Improved checking for ALWAYS_QUERY_HOSTNAME 2008-05-31 martin f. krafft Version 0.4.1 * Improved installation routine 2008-04-19 martin f. krafft Version 0.4 * Checks are now done with run-parts to allow for easier extension. * Setting to simply always guard commands, bypassing checks. * Add ability to print custom warnings before the checks/prompt. 2008-03-16 martin f. krafft Version 0.3.2 * Don't fail if the SSH_CONNECTION variable is unset. 2008-03-12 martin f. krafft Version 0.3.1 * Pass --short option to hostname to prevent the user from having to type the whole FQDN at times. * Check for the $SSH_CONNECTION variable in addition to the pty checks. * Add a basic REAMDE file. 2007-05-26 martin f. krafft Version 0.3 * Shield shutdown -h; I am terribly sorry, Andrew! Now only shutdown -c and * --help are passed through regardless. * Added --help option, which now prints a short molly-guard help message followed by the actual command's help output. * Now should also work in su/sudo sessions because it now checks whether the creator of the current tty/pts is sshd, rather than the brittle check for the environment. Thanks to Craig Small and Don Armstrong for their sparks of brilliance. * Added --pretend-ssh option to facilitate testing. 2006-12-06 martin f. krafft Version 0.2.2 which also protects the poweroff command 2006-10-19 martin f. krafft Version 0.2.1 with improved shell quoting. 2006-10-19 martin f. krafft Version 0.2, which does better --help option handling. 2006-10-19 martin f. krafft Initial release, version 0.1 molly-guard-0.4.5/Makefile000066400000000000000000000023131172154233700154200ustar00rootroot00000000000000prefix?=/usr/local etc_prefix?=$(prefix) DST=$(DEST)$(prefix) ETCDIR=$(DEST)$(etc_prefix)/etc/molly-guard all: molly-guard.8.gz shutdown %.8: DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/manpages/docbook.xsl %.8: XP=xsltproc -''-nonet %.8: %.xml $(XP) $(DB2MAN) $< %.gz: % gzip -9 $< man: molly-guard.8 man -l $< .PHONY: man clean: rm -f shutdown rm -f molly-guard.8 molly-guard.8.gz .PHONY: clean shutdown: shutdown.in sed -e 's,@ETCDIR@,$(ETCDIR),g' $< > $@ install: shutdown molly-guard.8.gz mkdir -m755 --parent $(DST)/share/molly-guard install -m755 -oroot -oroot shutdown $(DST)/share/molly-guard mkdir -m755 --parent $(DST)/sbin ln -s ../share/molly-guard/shutdown $(DST)/sbin/poweroff ln -s ../share/molly-guard/shutdown $(DST)/sbin/halt ln -s ../share/molly-guard/shutdown $(DST)/sbin/reboot ln -s ../share/molly-guard/shutdown $(DST)/sbin/shutdown mkdir -m755 --parent $(ETCDIR) install -m644 -oroot -oroot rc $(ETCDIR) cp -r run.d $(ETCDIR) \ && chown root.root $(ETCDIR)/run.d && chmod 755 $(ETCDIR)/run.d mkdir -m755 --parent $(ETCDIR)/messages.d mkdir -m755 --parent $(DST)/share/man/man8 install -m644 -oroot -groot molly-guard.8.gz $(DST)/share/man/man8 .PHONY: install molly-guard-0.4.5/molly-guard.xml000066400000000000000000000220701172154233700167400ustar00rootroot00000000000000 .
will be generated. You may view the manual page with: nroff -man .
| less'. A typical entry in a Makefile or Makefile.am is: DB2MAN=/usr/share/sgml/docbook/stylesheet/xsl/nwalsh/\ manpages/docbook.xsl XP=xsltproc -''-nonet manpage.1: manpage.dbk $(XP) $(DB2MAN) $< The xsltproc binary is found in the xsltproc package. The XSL files are in docbook-xsl. Please remember that if you create the nroff version in one of the debian/rules file targets (such as build), you will need to include xsltproc and docbook-xsl in your Build-Depends control field. --> martin f."> krafft"> Apr 19, 2008"> 8"> madduck@madduck.net"> molly-guard"> molly-guard"> Debian"> GNU"> GPL"> ]>
&dhemail;
2008 &dhusername; &dhdate;
&dhucpackage; &dhsection; &dhcommand; guard against accidental shutdowns/reboots shutdown - -- script_options halt - -- script_options reboot - -- script_options poweroff - -- script_options DESCRIPTION &dhcommand; attempts to prevent you from accidentally shutting down or rebooting machines. It does this by injecting a couple of checks before the existing commands: halt, reboot, shutdown, and poweroff. This happens via scripts with the same names in /usr/sbin, so it only works if you have /usr/sbin before /sbin in your PATH! Before &dhcommand; invokes the real command, all scripts in /etc/molly-guard/run.d/ have to run and exit successfully; else, it aborts the command. run-parts(1) is used to process the directory. &dhcommand; passes any script_options to the scripts, and also populates the environment with the following variables: MOLLYGUARD_CMD - the actual command invoked by the user. MOLLYGUARD_DO_NOTHING - set to if this is a demo-run. MOLLYGUARD_SETTINGS - the path to a shell script snippet which scripts can source to obtain settings. &dhcommand; prints the contents of /etc/molly-guard/messages.d/COMMAND or /etc/molly-guard/messages.d/default to the console, if either exists. This is due to /etc/molly-guard/run.d/10-print-message. GUARDING SSH SESSIONS &dhcommand; was primarily designed to shield SSH connections. This functionality (which should arguably be provided by the openssh-server package) is implemented in /etc/molly-guard/run.d/30-query-hostname. This script first tests whether the command is being executed from a tty which has been created by sshd. It also checks whether the variable SSH_CONNECTION is defined. If any of these tests are successful, test script queries the user for the machine's hostname, which should be sufficient to prevent the user from doing something by accident. You can pass the script option to &dhcommand; to pretend that those tests succeeds. Alternatively, setting ALWAYS_QUERY_HOSTNAME in /etc/molly-guard/rc causes the script to always query. The following situations are still UNGUARDED. If you can think of ways to protect against those, please let me know! running sudo within screen or screen within sudo; sudo eats the SSH_CONNECTION variable, and screen creates a new pty. executing those command in a remote terminal window, that is a XTerm started on a remote machine but displaying on the local X server. You have been warned. You can use the switch to prevent anything from happening, e.g. halt --molly-guard-do-nothing. OPTIONS --molly-guard-do-nothing Cause &dhcommand; to print the command which would be executed, after processing all scripts, instead of executing it. -h --help Display usage information. -V --version Display version information. SEE ALSO shutdown 8 , halt 1 , reboot 8 , poweroff 8 . LEGALESE &dhpackage; is copyright by &dhusername;. Andrew Ruthven came up with the idea of using the scripts directory and submitted a patch, which I modified a bit. This manual page was written by &dhusername; &dhemail;. Permission is granted to copy, distribute and/or modify this document under the terms of the Artistic License 2.0
molly-guard-0.4.5/rc000066400000000000000000000003041172154233700143050ustar00rootroot00000000000000# molly-guard settings # # ALWAYS_QUERY_HOSTNAME # when set, causes the 30-query-hostname script to always ask for the # hostname, even if no SSH session was detected. #ALWAYS_QUERY_HOSTNAME=true molly-guard-0.4.5/run.d/000077500000000000000000000000001172154233700150075ustar00rootroot00000000000000molly-guard-0.4.5/run.d/10-print-message000077500000000000000000000011211172154233700177240ustar00rootroot00000000000000#!/bin/sh # # 10-print-message - print a (command-specific or default) message # # Copyright © Andrew Ruthven # Copyright © martin f. krafft # Released under the terms of the Artistic Licence 2.0 # # Prints either /etc/molly-guard/messages.d/$MOLLYGUARD_CMD # or /etc/molly-guard/messages.d/default # depending on whether the first exists. # set -eu MESSAGESDIR=/etc/molly-guard/messages.d for i in $MOLLYGUARD_CMD default; do if [ -f "$MESSAGESDIR/$i" ] && [ -r "$MESSAGESDIR/$i" ]; then cat $MESSAGESDIR/$i exit 0 fi done molly-guard-0.4.5/run.d/30-query-hostname000077500000000000000000000041041172154233700201350ustar00rootroot00000000000000#!/bin/sh # # 30-ask-hostname - request the user to type in the hostname of the local host # # Copyright © martin f. krafft # Released under the terms of the Artistic Licence 2.0 # set -eu ME=molly-guard # Walk up the process tree until PID 1 is reached or a process with 'sshd' in # its /proc//cmdline is met. Return success if such a process is found. is_child_of_sshd() { pid=$$ ppid=$PPID # Be a bit paranoid with the guard, should some horribly broken system # provide a strange process hierarchy. '[ $pid -ne 1 ]' should be enough for # sane systems. [ -z "$pid" ] || [ -z "$ppid" ] && return 2 while [ $pid -gt 1 ] && [ $pid -ne $ppid ]; do if grep -q sshd /proc/$ppid/cmdline; then return 0 fi pid=$ppid ppid=$(grep ^PPid: /proc/$pid/status | tr -dc 0-9) done return 1 } [ -f "$MOLLYGUARD_SETTINGS" ] && . "$MOLLYGUARD_SETTINGS" PRETEND_SSH=0 for arg in "$@"; do case "$arg" in (*-pretend-ssh) PRETEND_SSH=1;; esac done # require an interactive terminal connected to stdin test -t 0 || exit 0 # we've been asked to always protect this host case "${ALWAYS_QUERY_HOSTNAME:-0}" in 0|false|False|no|No|off|Off) # only run if we are being called over SSH, that is if the current terminal # was created by sshd. PTS=$(tty) if ! pgrep -f "^sshd.+${PTS#/dev/}\>" >/dev/null \ && [ -z "${SSH_CONNECTION:-}" ] \ && ! is_child_of_sshd; then if [ $PRETEND_SSH -eq 1 ]; then echo "I: $ME: this is not an SSH session, but --pretend-ssh was given..." >&2 else exit 0 fi else echo "W: $ME: SSH session detected!" >&2 fi ;; *) echo "I: $ME: $MOLLYGUARD_CMD is always molly-guarded on this system." >&2 ;; esac HOSTNAME="$(hostname --short)" sigh() { echo "Good thing I asked; I won't $MOLLYGUARD_CMD $HOSTNAME ..." >&2 exit 1 } trap 'echo;sigh' 1 2 3 9 10 12 15 echo -n "Please type in hostname of the machine to $MOLLYGUARD_CMD: " read HOSTNAME_USER || : [ "$HOSTNAME_USER" = "$HOSTNAME" ] || sigh trap - 1 2 3 9 10 12 15 exit 0 molly-guard-0.4.5/shutdown.in000077500000000000000000000047421172154233700161760ustar00rootroot00000000000000#!/bin/sh # # shutdown -- wrapper script to guard against accidental shutdowns # # Copyright © martin f. krafft # Released under the terms of the Artistic Licence 2.0 # set -eu ME=molly-guard VERSION=0.4 SCRIPTSDIR="@ETCDIR@/run.d" CMD="${0##*/}" EXEC="/sbin/$CMD" case "$CMD" in halt|reboot|shutdown|poweroff) if [ ! -f $EXEC ]; then echo "E: not a regular file: $EXEC" >&2 exit 4 fi if [ ! -x $EXEC ]; then echo "E: not an executable: $EXEC" >&2 exit 3 fi ;; *) echo "E: unsupported command: $CMD" >&2 exit 1 ;; esac usage() { cat <<-_eousage Usage: $ME [options] [-- script options] (shielding $EXEC) molly-guard's primary goal is to guard against accidental shutdowns/reboots. $ME will run all scripts in $SCRIPTSDIR and only invokes $EXEC if all scripts exited successfully. Specifying --molly-guard-do-nothing as argument to the command will make $ME echo the command it would execute rather than actually executing it. Options following the double hyphen will be passed unchanged to the scripts. Please see molly-guard(8) for more information. The actual command's help output follows: _eousage } CMDARGS= SCRIPTARGS= END_OF_ARGS=0 DO_NOTHING=0 for arg in "$@"; do case "$arg" in (*-molly-guard-do-nothing) DO_NOTHING=1;; (*-help) usage 2>&1 eval $EXEC --help 2>&1 exit 0 ;; --) END_OF_ARGS=1;; *) if [ $END_OF_ARGS -eq 0 ]; then CMDARGS="${CMDARGS:+$CMDARGS }$arg" else SCRIPTARGS="${SCRIPTARGS:+$SCRIPTARGS }--arg $arg" fi ;; esac done do_real_cmd() { if [ $DO_NOTHING -eq 1 ]; then echo "$ME: would run: $EXEC $CMDARGS" exit 0 else eval exec $EXEC "$CMDARGS" fi } if [ $DO_NOTHING -eq 1 ]; then echo "I: demo mode; $ME will not do anything due to --molly-guard-do-nothing." >&2 fi # pass through certain commands case "$CMD $CMDARGS" in (*shutdown\ *-c*) # allow canceling shutdowns echo "I: executing $CMD $CMDARGS regardless of check results." >&2 do_real_cmd ;; esac MOLLYGUARD_CMD=$CMD; export MOLLYGUARD_CMD MOLLYGUARD_DO_NOTHING=$DO_NOTHING; export MOLLYGUARD_DO_NOTHING MOLLYGUARD_SETTINGS="@ETCDIR@/rc"; export MOLLYGUARD_SETTINGS for script in $(run-parts --test $SCRIPTSDIR); do ret=0 eval $script $SCRIPTARGS || ret=$? if [ $ret -ne 0 ]; then echo "W: aborting $CMD due to ${script##*/} exiting with code $ret." >&2 exit $ret fi done do_real_cmd