aboutsummaryrefslogtreecommitdiff
path: root/lib/MasterServer/Core
diff options
context:
space:
mode:
Diffstat (limited to 'lib/MasterServer/Core')
-rwxr-xr-xlib/MasterServer/Core/Core.pm104
-rwxr-xr-xlib/MasterServer/Core/Logging.pm6
-rwxr-xr-xlib/MasterServer/Core/Secure.pm39
-rwxr-xr-xlib/MasterServer/Core/Util.pm6
-rwxr-xr-xlib/MasterServer/Core/Version.pm10
5 files changed, 62 insertions, 103 deletions
diff --git a/lib/MasterServer/Core/Core.pm b/lib/MasterServer/Core/Core.pm
index 02ec32a..e4e4836 100755
--- a/lib/MasterServer/Core/Core.pm
+++ b/lib/MasterServer/Core/Core.pm
@@ -5,36 +5,31 @@ use strict;
use warnings;
use AnyEvent;
use Exporter 'import';
-use Data::Dumper 'Dumper';
use DBI;
our @EXPORT = qw | halt main |;
-##
-## Halt
-## Handle shutting down the program for whatever reason.
+################################################################################
+## Handle shutting down the program in case a fatal error occurs.
+## TODO: lockfile!
+################################################################################
sub halt {
my $self = shift;
- # When other processes are still
- # running, set all other scopes
- # to null/undef?
-
# log shutdown
$self->log("stop", "Stopping the masterserver now.");
+ # clear all other timers, network servers, etc
+ $self->{dbh}->disconnect() if (defined $self->{dbh});
+ $self->{scope} = undef;
+
# and send signal to condition var
$self->{must_halt}->send;
-
- # allow everything to be written to the logs
- sleep(2);
-
- exit;
}
-##
-## Main
-## Initialize all processes and start them
+################################################################################
+## Initialize all processes and start various functions
+################################################################################
sub main {
my $self = shift;
@@ -47,21 +42,19 @@ sub main {
# keep several objects alive outside their original scope
$self->{scope} = ();
-
- # Startup procedure
+ # startup procedure information
$self->log("info", "333networks Master Server Application.");
$self->log("info", "Build: $self->{build_type}");
$self->log("info", "Version: $self->{build_version}");
- $self->log("info", " Written by $self->{build_author}");
+ $self->log("info", "Written by $self->{build_author}");
$self->log("info", "Logs are written to $self->{log_dir}");
-
# determine the type of database and load the appropriate module
- { # start db type
+ {
# read from login
my @db_type = split(':', $self->{dblogin}->[0]);
- # format supported (yet)?
+ # format supported?
if ( "Pg SQLite" =~ m/$db_type[1]/i) {
# inform us what DB we try to load
@@ -72,14 +65,16 @@ sub main {
# Connect to database
$self->{dbh} = $self->database_login();
+
+ # and test whether we succeeded.
+ $self->halt() unless (defined $self->{dbh});
}
else {
# raise error and halt
$self->log("fatal", "The masterserver could not determine the chosen database type.");
$self->halt();
}
- } # end db type
-
+ }
# start the listening service (listen for UDP beacons)
$self->{scope}->{beacon_catcher} = $self->beacon_catcher();
@@ -87,64 +82,19 @@ sub main {
# start the beacon checker service (query entries from the pending list)
$self->{scope}->{beacon_checker} = $self->beacon_checker() if ($self->{beacon_checker_enabled});
+ # query other masterserver applets to get more server addresses
+ $self->{scope}->{ucc_applet_query} = $self->ucc_applet_query_scheduler() if ($self->{master_applet_enabled});
- $self->log("info", "All modules loaded. Starting...");
-
-
-=pod
-
- ##############################################################################
- ##
- ## Initiate Scheduled tasks
- ##
- ## Main Tasks
- ## beacon_catcher (udp server)
- ## beacon_checker (udp client, timer)
- ## browser_server (tcp server)
- ##
- ## Synchronization
- ## ucc_applet_query (tcp client, timer)
- ## syncer_scheduler (tcp client, timer)
- ##
- ## 333networks website specific
- ## ut_server_query (udp client, timer)
- ##
- ## Core Functions
- ## maintenance (timer, dbi)
- ## statistics (timer, dbi)
- ##
- ## (store objects in hash to keep them alive outside their own scopes)
- ##############################################################################
- ## servers
- $ae{beacon_catcher} = $self->beacon_catcher();
- $ae{beacon_checker} = $self->beacon_checker_scheduler();
- $ae{browser_server} = $self->browser_server();
-
- # synchronizing
- $ae{ucc_applet_query} = $self->ucc_applet_query_scheduler();
- $ae{syncer_scheduler} = $self->syncer_scheduler();
-
- # status info for UT servers (333networks site)
- $ae{ut_server_scheduler} = $self->ut_server_scheduler();
-
- # maintenance
- $ae{maintenance_runner} = $self->maintenance_runner();
- $ae{stats_runner} = $self->stats_runner();
-=cut
-
-
-
-
-
-
-
-
-
+ # all modules loaded. Running...
+ $self->log("info", "All modules loaded. Masterserver is now running.");
# prevent main program from ending prematurely
$self->{must_halt}->recv;
- $self->log("stop", "Logging off. Enjoy your day.");
+ $self->log("stop", "Shutting down NOW!");
+
+ # time for a beer.
+ exit;
}
1;
diff --git a/lib/MasterServer/Core/Logging.pm b/lib/MasterServer/Core/Logging.pm
index 312a0f8..c503e1a 100755
--- a/lib/MasterServer/Core/Logging.pm
+++ b/lib/MasterServer/Core/Logging.pm
@@ -9,10 +9,8 @@ use Exporter 'import';
our @EXPORT = qw| log |;
################################################################################
-#
-# Log to file and print to screen.
-# args: $self, message_type, message
-#
+## Log to file and print to screen.
+## args: $self, message_type, message
################################################################################
sub log {
my ($self, $type, $msg) = @_;
diff --git a/lib/MasterServer/Core/Secure.pm b/lib/MasterServer/Core/Secure.pm
index dbe9c1f..3b85498 100755
--- a/lib/MasterServer/Core/Secure.pm
+++ b/lib/MasterServer/Core/Secure.pm
@@ -8,7 +8,10 @@ use Exporter 'import';
our @EXPORT = qw| secure_string validated_beacon validated_request validate_string charshift get_validate_string|;
-## generate a random string of 6 characters long for the \secure\ challenge
+################################################################################
+# generate a random string of 6 characters long for the \secure\ challenge
+# returns string
+################################################################################
sub secure_string {
# spit out a random string, only uppercase characters
my @c = ('A'..'Z');
@@ -19,7 +22,10 @@ sub secure_string {
return $s;
}
-## Check if beacon has a valid response.
+################################################################################
+# authenticate the \validate\ response for the \secure\ challenge.
+# returns 1 on valid response, 0 on invalid
+################################################################################
sub validated_beacon {
my ($self, $gamename, $secure, $enctype, $validate) = @_;
@@ -30,15 +36,18 @@ sub validated_beacon {
$enctype = 0 unless $enctype;
if ($self->{ignore_beacon_key} =~ m/$gamename/i){
- $self->log("secure", "Ignored beacon validation for $gamename.");
+ $self->log("secure", "ignored beacon validation for $gamename");
return 1;
}
- # compare received response with challenge
+ # compare received response with expected response
return ($self->validate_string($gamename, $secure, $enctype) eq $validate) || 0;
}
-## Check if request has valid response
+################################################################################
+# authenticate the \validate\ response for the \secure\ challenge.
+# returns 1 on valid response, 0 on invalid
+################################################################################
sub validated_request {
my ($self, $gamename, $secure, $enctype, $validate) = @_;
@@ -50,31 +59,29 @@ sub validated_request {
# ignore games and beacons that are listed
if ($self->{ignore_browser_key} =~ m/$gamename/i){
- $self->log("secure", "Ignored browser validation for $gamename.");
+ $self->log("secure", "ignored browser validation for $gamename");
return 1;
}
- # compare received response with challenge
+ # compare received response with expected response
return ($self->validate_string($gamename, $secure, $enctype) eq $validate) || 0;
}
################################################################################
-# calculate the \validate\ response for the \secure\ challenge.
-# args: gamename, secure_string, encryption type
+# process the validate string as a response to the secure challenge
# returns: validate string (usually 8 characters long)
-# !! requires cipher hash to be configured in config! (imported or else)
################################################################################
sub validate_string {
my ($self, $game, $sec, $enc) = @_;
# get cipher from gamename
- my $cip = $self->{game}->{$game}->{key} || "XXXXXX";
+ my $cip = $self->{game}->{$game}->{key} || "000000";
- # don't accept challenge longer than 16 characters -- usually h@xx0rs
+ # don't accept challenge longer than 16 characters (because vulnerable in UE)
if (length $sec > 16) {
- return "0"}
+ return "invalid!"}
- # check for valid encryption choises
+ # check for valid encryption choices
my $enc_val = (defined $enc && 0 <= $enc && $enc <= 2) ? $enc : 0;
# calculate and return validate string
@@ -98,7 +105,7 @@ sub charshift {
}
################################################################################
-# algorithm to calculate the response to the secure/validate query. processes
+# algorithm to process the response to the secure/validate query. processes
# the secure_string and returns the challenge_string with which GameSpy secure
# protocol authenticates games.
#
@@ -111,7 +118,7 @@ sub charshift {
#
# args: game cipher, 6-char challenge string, encryption type
# returns: validate string (usually 8 characters long)
-# !! requires cipher hash to be configured in config! (imported or else)
+# !! requires cipher hash to be configured in config! (imported or otherwise)
################################################################################
sub get_validate_string {
my ($self, $cipher_string, $secure_string, $enctype) = @_;
diff --git a/lib/MasterServer/Core/Util.pm b/lib/MasterServer/Core/Util.pm
index 001137d..eb4d509 100755
--- a/lib/MasterServer/Core/Util.pm
+++ b/lib/MasterServer/Core/Util.pm
@@ -9,15 +9,19 @@ use Exporter 'import';
our @EXPORT = qw| valid_address ip2country |;
+################################################################################
## return the abbreviated country based on IP
+################################################################################
sub ip2country {
my ($self, $ip) = @_;
my $reg = IP::Country::Fast->new();
return $reg->inet_atocc($ip);
}
+################################################################################
## Verify whether a given domain name or IP address and port are valid.
-## returns true/false if valid ip + port
+## returns 1/0 if valid/invalid ip + port
+################################################################################
sub valid_address {
my ($self, $a, $p) = @_;
diff --git a/lib/MasterServer/Core/Version.pm b/lib/MasterServer/Core/Version.pm
index 5bd3f1c..30972e4 100755
--- a/lib/MasterServer/Core/Version.pm
+++ b/lib/MasterServer/Core/Version.pm
@@ -9,9 +9,9 @@ our @EXPORT = qw| version |;
################################################################################
-#
-# Version information
-#
+##
+## Version information
+##
################################################################################
sub version {
my $self = shift;
@@ -29,10 +29,10 @@ sub version {
$self->{build_type} = "333networks Masterserver-Perl";
# version
- $self->{build_version} = "0.2";
+ $self->{build_version} = "2.0.4";
# date yyyy-mm-dd
- $self->{build_date} = "2015-01-31";
+ $self->{build_date} = "2015-02-11";
#author, email
$self->{build_author} = "Darkelarious, darkelarious\@333networks.com";