From 2152c0a7f0f4732fb1d352cb5dbc14e7b0fe8320 Mon Sep 17 00:00:00 2001 From: "David A. Madore" Date: Mon, 22 Feb 2010 16:52:08 +0100 Subject: Rewrite description of protocol (and reply !BAD in case of missing argument). --- emergencyd.pl | 84 +++++++++++++++++++++++++++++++++++------------------------ 1 file 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 -- cgit v1.2.3