From db1f07eeaa579c150171e94a5fd4385e72bb48be Mon Sep 17 00:00:00 2001 From: div0 Date: Sat, 3 Oct 2009 11:29:20 +0000 Subject: [PATCH] rcon.pl: IRC color output fixes from rcon2irc rcon2irc: rcon_secure 2 mode from rcon.pl git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8020 f962a42d-fe04-0410-a3ab-8c8b0445ebaa --- server/rcon.pl | 11 +++--- server/rcon2irc/rcon2irc-example.conf | 1 + server/rcon2irc/rcon2irc.pl | 48 +++++++++++++++++++++++++-- 3 files changed, 52 insertions(+), 8 deletions(-) diff --git a/server/rcon.pl b/server/rcon.pl index 66450c58f..80b651a05 100755 --- a/server/rcon.pl +++ b/server/rcon.pl @@ -200,10 +200,10 @@ sub color_dp2irc($) my $oldcolor = $color; $color = $color_dp2irc_table[$data]; - $color == $oldcolor ? '' : - $color < 0 ? "\017" : - $next eq ',' ? "\003$color\002\002" : - sprintf "\003%02d", $color; + $color == $oldcolor ? '' : + $color < 0 ? "\017" : + (index '0123456789,', $next) >= 0 ? "\003$color\002\002" : + "\003$color"; } : die "Invalid type"; } @@ -304,7 +304,7 @@ sub new($$) (length($local) ? (LocalAddr => $local) : ()), PeerAddr => $remote, PeerPort => $defaultport - ) or die "socket $proto/$local/$remote: $!"; + ) or die "socket $proto/$local/$remote/$defaultport: $!"; $sock->blocking(0); my $you = { # Mortal fool! Release me from this wretched tomb! I must be set free @@ -530,6 +530,7 @@ if(!length $server) print STDERR "Usage: rcon_address=SERVERIP:PORT rcon_password=PASSWORD $0 rconcommands...\n"; print STDERR "Optional: rcon_timeout=... (default: 5)\n"; print STDERR " rcon_timeout_inter=... (default: 0.2)\n"; + print STDERR " rcon_timeout_challenge=... (default: 5)\n"; print STDERR " rcon_colorcodes_raw=1 (to disable color codes translation)\n"; print STDERR " rcon_secure=0 (to allow connecting to older servers not supporting secure rcon)\n"; exit 0; diff --git a/server/rcon2irc/rcon2irc-example.conf b/server/rcon2irc/rcon2irc-example.conf index e9eac8d51..99db8f0ac 100644 --- a/server/rcon2irc/rcon2irc-example.conf +++ b/server/rcon2irc/rcon2irc-example.conf @@ -32,6 +32,7 @@ irc_channel = #Nexuiz-Pwayers # Tuning #dp_secure = 1 +#dp_secure_challengetimeout = 1 #dp_server_from_wan = #dp_listen = #dp_status_delay = 30 diff --git a/server/rcon2irc/rcon2irc.pl b/server/rcon2irc/rcon2irc.pl index f1f3bcb6a..3ddf42bb2 100755 --- a/server/rcon2irc/rcon2irc.pl +++ b/server/rcon2irc/rcon2irc.pl @@ -443,12 +443,13 @@ use Digest::MD4; # my $chan = new Channel::QW($connection, "password"); sub new($$$) { - my ($class, $conn, $password, $secure) = @_; + my ($class, $conn, $password, $secure, $timeout) = @_; my $you = { connector => $conn, password => $password, recvbuf => "", secure => $secure, + timeout => $timeout, }; return bless $you, 'Channel::QW'; @@ -464,7 +465,15 @@ sub join_commands($@) sub send($$$) { my ($self, $line, $nothrottle) = @_; - if($self->{secure}) + if($self->{secure} > 1) + { + $self->{connector}->send("\377\377\377\377getchallenge"); + my $c = $self->recvchallenge(); + return 0 if not defined $c; + my $key = Digest::HMAC::hmac("$c $line", $self->{password}, \&Digest::MD4::md4); + return $self->{connector}->send("\377\377\377\377srcon HMAC-MD4 CHALLENGE $key $c $line"); + } + elsif($self->{secure}) { my $t = sprintf "%ld.%06d", time(), int rand 1000000; my $key = Digest::HMAC::hmac("$t $line", $self->{password}, \&Digest::MD4::md4); @@ -486,6 +495,38 @@ sub quote($$) return $data; } +sub recvchallenge($) +{ + my ($self) = @_; + + my $sel = IO::Select->new($self->fds()); + my $endtime_max = Time::HiRes::time() + $self->{timeout}; + my $endtime = $endtime_max; + + while((my $dt = $endtime - Time::HiRes::time()) > 0) + { + if($sel->can_read($dt)) + { + for(;;) + { + my $s = $self->{connector}->recv(); + die "read error\n" + if not defined $s; + length $s + or last; + if($s =~ /^\377\377\377\377challenge (.*)$/s) + { + return $1; + } + next + if $s !~ /^\377\377\377\377n(.*)$/s; + $self->{recvbuf} .= $1; + } + } + } + return undef; +} + sub recv($) { my ($self) = @_; @@ -669,6 +710,7 @@ our %config = ( dp_server => undef, dp_secure => 1, + dp_secure_challengetimeout => 1, dp_listen => "", dp_password => undef, dp_status_delay => 30, @@ -750,7 +792,7 @@ $SIG{TERM} = sub { # Create the two channels to gateway between... $channels{irc} = new Channel::Line(new Connection::Socket(tcp => $config{irc_local} => $config{irc_server} => 6667)); -$channels{dp} = new Channel::QW(my $dpsock = new Connection::Socket(udp => $config{dp_listen} => $config{dp_server} => 26000), $config{dp_password}, $config{dp_secure}); +$channels{dp} = new Channel::QW(my $dpsock = new Connection::Socket(udp => $config{dp_listen} => $config{dp_server} => 26000), $config{dp_password}, $config{dp_secure}, $config{dp_secure_challengetimeout}); $config{dp_listen} = $dpsock->sockname(); print "Listening on $config{dp_listen}\n"; -- 2.39.2