diff options
Diffstat (limited to 'emergencyc.pl')
-rwxr-xr-x | emergencyc.pl | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/emergencyc.pl b/emergencyc.pl new file mode 100755 index 0000000..a7d55d2 --- /dev/null +++ b/emergencyc.pl @@ -0,0 +1,96 @@ +#! /usr/local/bin/perl -w + +# The Emergency Client - send commands to the emergency daemon + +# David A. Madore <URL: http://www.madore.org/~david/ > - Public Domain + +# This is a stupid client which just sends a command verbatim to the +# emergency daemon. All it takes care of is to put a valid timestamp +# and MAC. + +# Options recognized: +# +# -K <key> specifies the key to use; or -k <filename> specifies a +# keyfile (the client will use the first line as key). +# +# -h <hostname> and -p <number> specifies the host and port to connect +# to. +# +# -t <timestamp> specifies an explicit timestamp to use. +# +# The command follows the options. + +use strict; +use warnings; +use Digest::SHA qw(hmac_sha256_hex); +use Socket; +use Socket6; +use Getopt::Std; + +use constant { + DEFAULT_PORT => 911 +}; + +my %opts; + +getopts("K:k:h:p:t:", \%opts); + +my $key; +if ( defined($opts{K}) ) { + $key = $opts{K}; +} elsif ( defined($opts{k}) ) { + open my $keyfile, "<", $opts{k} or die "Cannot open key file $opts{k}: $!"; + $key = <$keyfile>; + chomp $key; + close $keyfile; +} +die "No key specified (use -K or -k option)" unless defined($key); + +my $host; +if ( defined($opts{h}) ) { + $host = $opts{h}; +} else { + $host = "localhost"; +} +my $port; +if ( defined($opts{p}) ) { + $port = $opts{p}; +} else { + $port = DEFAULT_PORT; +} + +my @res = getaddrinfo($host, $port, AF_UNSPEC, SOCK_DGRAM) + or die "Cannot resolve host $host port $port"; +my ($family, $socktype, $proto, $haddr) = @res; + +my $socket; +socket $socket, $family, $socktype, $proto or die "Can't create socket: $!"; +bind $socket, sockaddr_in6(0, in6addr_any); + +sub curtime { + my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time); + return sprintf("%04d-%02d-%02dT%02d:%02d:%02dZ",$year+1900,$mon+1,$mday,$hour,$min,$sec); +} + +my $command = $ARGV[0]; +$command = "PING" unless defined($command); +my $timestamp = $opts{t}; +$timestamp = curtime unless defined($timestamp); +my $validate = "$command|$timestamp"; +my $maccheck = hmac_sha256_hex($validate, $key); +send $socket, "$command|$timestamp|$maccheck", 0, $haddr; + +my $buf; +my $sender; +eval { + local $SIG{ALRM} = sub { die "alarm\n" }; + alarm 5; + do { + $sender = recv($socket, $buf, 16384, 0); + } while ( $sender ne $haddr ); +}; +if ( $@ ) { + printf "timeout\n"; +} else { + printf "%s", $buf; +} |