summaryrefslogtreecommitdiffstats
path: root/emergencyc.pl
diff options
context:
space:
mode:
authorDavid A. Madore <david.madore@ens.fr>2010-02-15 21:33:17 +0100
committerDavid A. Madore <david.madore@ens.fr>2010-02-15 21:33:17 +0100
commite80e7f3c2289a93955ffeda6cf1a2e8e47eb351a (patch)
treee0d87c6362735dc91508fc32345654e8e198ffeb /emergencyc.pl
downloademergency-e80e7f3c2289a93955ffeda6cf1a2e8e47eb351a.tar.gz
emergency-e80e7f3c2289a93955ffeda6cf1a2e8e47eb351a.tar.bz2
emergency-e80e7f3c2289a93955ffeda6cf1a2e8e47eb351a.zip
Initial creation of the emergency daemon, and a stupid client.
These don't do much for now.
Diffstat (limited to 'emergencyc.pl')
-rwxr-xr-xemergencyc.pl96
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;
+}