summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xemergencyd.pl84
1 files changed, 50 insertions, 34 deletions
diff --git a/emergencyd.pl b/emergencyd.pl
index 1cb7536..e9bd8f3 100755
--- a/emergencyd.pl
+++ b/emergencyd.pl
@@ -8,38 +8,53 @@
#
# Commands are sent through UDP datagrams, normally addressed to port
# 911. Commands consist of three parts separated or terminated by '|'
-# or \n (but \r\n is also accepted). First part is the command
+# or \n (but \r\n is also accepted). First part is the command line
# proper. Second is a UTC timestamp in yyyy-mm-ddThh:mm:ssZ format
# (here 'T' and 'Z' are literal 'T' and 'Z'). Third is the
# HMAC-SHA256, in hexadecimal, of command|timestamp (separated by '|',
# even if they were separated differently in the input, and not
# terminated by anything), with a HMAC key shared by client and
-# server.
+# server. The command line consists of a four-letter command,
+# followed by an optional argument separated by whitespace. The
+# server response consists of one or more lines each terminated by \n;
+# the first is a four-character response similar in form to the
+# request. If the server cannot make sense of the request, it
+# responds !BAD.
#
-# The server response consists of one or more lines terminated by \n.
-# If the command is PING, the server responds PONG. If the command is
-# DATE, the server responds DATE followed by the current time and the
-# timestamp of the last authenticated command. Apart from PING and
-# DATE, all other commands are authenticated: if the HMAC does not
-# match what it should be, the server responds !MAC. If the timestamp
-# does not match the current date +/- 30 seconds, the server responds
-# !DAT; it also does so if the timestamp is not (strictly) greater
-# than the timestamp of the last request.
+# Apart from PING and DATE, all commands are authenticated: if the
+# HMAC does not match what it should be, the server responds !MAC. If
+# the timestamp does not match the current date +/- 30 seconds, the
+# server responds !DAT; it also does so if the timestamp is not
+# (strictly) greater than the timestamp of the last authenticated
+# request. If the command is unknown, the server responds !UNK. In
+# case of error, the server responds !ERR (normally followed by a more
+# human-readable error message on the next line).
#
-# The NOOP command does nothing (but must still be authenticated): the
-# server responds NOOP. The DPID command returns the daemon's PID:
-# the server responds DPID and then the PID itself (on a separate
-# line). The DIE! command causes the daemon to respond BYE! and then
-# quit. The RKEY command causes the daemon to reread its key file:
-# the server responds either DONE or !ERR in case of error, in which
-# case the next line in the response is a human-readable error line.
-# The LOGM command is followed by whitespace, an optional priority (as
-# in the LOG_* syslog macros: WARNING, DEBUG, etc.; again followed by
-# whitespace), and a message to be written to syslog: the server
-# responds DONE. The SYRQ command is followed by whitespace and then
-# by data to be written to /proc/sysrq-trigger: the server responds
-# either DONE or !ERR in case of error, in which case the next line in
-# the response is a human-readable error line.
+# The following commands are understood:
+#
+# * PING: the server responds PONG (this command is unauthenticated).
+#
+# * DATE: the server responds DATE, followed by two date lines, the
+# first being the current date, and the second being the timestamp
+# of the last authenticated command. (This command is
+# unauthenticated.)
+#
+# * NOOP: the server responds NOOP (this command is authenticated, and
+# is intended to serve as a manner to check authentication).
+#
+# * DPID: the server responds DPID followed by its PID on a separate
+# line.
+#
+# * RKEY: the server rereads its key file and responds with DONE.
+#
+# * LOGM: this command takes a mandatory argument; the server logs the
+# message to syslog and responds with DONE. The message can be
+# preceded by a priority to use (as in the LOG_* macros: WARNING,
+# DEBUG, etc.) followed by whitespace; otherwise, NOTICE is taken as
+# default.
+#
+# * SYRQ: this command takes a mandatory argument; the server writes
+# this argument to /proc/sysrq-trigger and responds with DONE.
# *** The emergency daemon itself ***
#
@@ -189,21 +204,22 @@ sub cmd_rkey {
}
sub cmd_logm {
- my $s = shift or die "Missing argument to LOGM\n";
- my $level = LOG_NOTICE;
- my %levels = ("EMERG"=>LOG_EMERG, "ALERT"=>LOG_ALERT,
- "CRIT"=>LOG_CRIT, "ERR"=>LOG_ERR, "WARNING"=>LOG_WARNING,
- "NOTICE"=>LOG_NOTICE, "INFO"=>LOG_INFO, "DEBUG"=>LOG_DEBUG);
- if ( $s =~ /^([A-Z0-9]*)\s+(.*)/ && exists($levels{$1}) ) {
- $level = $levels{$1};
+ my $s = shift or die [ "!BAD", "Missing argument to LOGM" ];
+ my $priority = LOG_NOTICE;
+ my %priorities = ("EMERG"=>LOG_EMERG, "ALERT"=>LOG_ALERT,
+ "CRIT"=>LOG_CRIT, "ERR"=>LOG_ERR,
+ "WARNING"=>LOG_WARNING, "NOTICE"=>LOG_NOTICE,
+ "INFO"=>LOG_INFO, "DEBUG"=>LOG_DEBUG);
+ if ( $s =~ /^([A-Z0-9]*)\s+(.*)/ && exists($priorities{$1}) ) {
+ $priority = $priorities{$1};
$s = $2;
}
- syslog $level, $s;
+ syslog $priority, $s;
return "DONE\n";
}
sub cmd_syrq {
- my $s = shift or die "Missing argument to SYRQ\n";
+ my $s = shift or die [ "!BAD", "Missing argument to SYRQ" ];
open my $sysrq_trigger, ">", "/proc/sysrq-trigger"
or die "Couldn't open /proc/sysrq-trigger for writing: $!";
print $sysrq_trigger $s