rcon.pl: IRC color output fixes from rcon2irc
authordiv0 <div0@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Sat, 3 Oct 2009 11:29:20 +0000 (11:29 +0000)
committerdiv0 <div0@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Sat, 3 Oct 2009 11:29:20 +0000 (11:29 +0000)
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
server/rcon2irc/rcon2irc-example.conf
server/rcon2irc/rcon2irc.pl

index 66450c5..80b651a 100755 (executable)
@@ -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;
index e9eac8d..99db8f0 100644 (file)
@@ -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
index f1f3bcb..3ddf42b 100755 (executable)
@@ -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";