| 1 |
95b003ff
|
Origo
|
#!/usr/bin/perl
|
| 2 |
|
|
|
| 3 |
|
|
# All rights reserved and Copyright (c) 2020 Origo Systems ApS.
|
| 4 |
|
|
# This file is provided with no warranty, and is subject to the terms and conditions defined in the license file LICENSE.md.
|
| 5 |
|
|
# The license file is part of this source code package and its content is also available at:
|
| 6 |
|
|
# https://www.origo.io/info/stabiledocs/licensing/stabile-open-source-license
|
| 7 |
|
|
|
| 8 |
|
|
use CGI ':standard';
|
| 9 |
|
|
use JSON;
|
| 10 |
|
|
use URI::Escape;
|
| 11 |
|
|
use Tie::DBI;
|
| 12 |
|
|
use Error qw(:try);
|
| 13 |
|
|
use Sys::Syslog qw( :DEFAULT setlogsock);
|
| 14 |
|
|
use ConfigReader::Simple;
|
| 15 |
|
|
use Data::Dumper;
|
| 16 |
|
|
use Time::HiRes qw(usleep);
|
| 17 |
|
|
|
| 18 |
|
|
$ENV{PATH} = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin';
|
| 19 |
|
|
delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
|
| 20 |
|
|
|
| 21 |
|
|
$SIG{'INT'} = sub { handle_signal('INT'); };
|
| 22 |
|
|
$SIG{'PIPE'} = sub { handle_signal('PIPE'); };
|
| 23 |
|
|
$SIG{'HUP'} = sub { handle_signal('HUP'); };
|
| 24 |
|
|
$SIG{'TERM'} = sub { handle_signal('TERM'); };
|
| 25 |
|
|
|
| 26 |
|
|
$q = new CGI;
|
| 27 |
|
|
%params = $q->Vars;
|
| 28 |
|
|
|
| 29 |
|
|
$user = $ENV{'REMOTE_USER'};
|
| 30 |
|
|
$user = $1 if ($user =~ /(.+)/); #untaint
|
| 31 |
|
|
$account = $q->cookie('steamaccount'); # User is using another account
|
| 32 |
|
|
$account = $user unless ($account);
|
| 33 |
|
|
$account = $1 if ($account =~ /(.+)/); #untaint
|
| 34 |
|
|
|
| 35 |
|
|
|
| 36 |
|
|
$naptime = 2;
|
| 37 |
|
|
$tied;
|
| 38 |
|
|
$session;
|
| 39 |
|
|
$i = 0;
|
| 40 |
|
|
|
| 41 |
|
|
my $config = ConfigReader::Simple->new("/etc/stabile/config.cfg",
|
| 42 |
|
|
[qw(STORAGE_BACKUPDIR
|
| 43 |
|
|
DBI_USER DBI_PASSWD ENGINEID
|
| 44 |
|
|
)]);
|
| 45 |
|
|
my $dbiuser = $config->get('DBI_USER') || "irigo";
|
| 46 |
|
|
my $dbipasswd = $config->get('DBI_PASSWD') || "";
|
| 47 |
|
|
my $tktname = 'auth_tkt';
|
| 48 |
|
|
$tktname = ('auth_' . substr($config->get('ENGINEID'), 0, 8) ) if ($config->get('ENGINEID'));
|
| 49 |
|
|
|
| 50 |
|
|
if (!is_user()) { # User not authenticated
|
| 51 |
|
|
print header('text/html', '401 Unauthorized');
|
| 52 |
|
|
print "User: $0 : $user not allowed\n";
|
| 53 |
|
|
|
| 54 |
|
|
} elsif (!$params{'s'}) { # Set up a new session
|
| 55 |
|
|
|
| 56 |
|
|
$privileges = getPrivileges($user);
|
| 57 |
|
|
|
| 58 |
|
|
if ($account ne $user) { # Check privileges
|
| 59 |
|
|
$account = checkAccount($user, $account); # this also sets global $privileges
|
| 60 |
|
|
}
|
| 61 |
|
|
my $isadmin = index($privileges,"a")!=-1;
|
| 62 |
|
|
|
| 63 |
|
|
if (!$account || index($privileges,"d")!=-1) {
|
| 64 |
|
|
print header('text/html', '401 Unauthorized');
|
| 65 |
|
|
exit 0;
|
| 66 |
|
|
}
|
| 67 |
|
|
|
| 68 |
|
|
my $tkt = $q->cookie($tktname);
|
| 69 |
|
|
$session = substr($tkt, 0, 6);
|
| 70 |
|
|
$session = "A-" . $session if ($isadmin);
|
| 71 |
|
|
$session =~ /(.+)/; $session = $1; #untaint
|
| 72 |
|
|
my $i = 1;
|
| 73 |
|
|
while (-e "/tmp/$account~$session.$i.tasks") {$i++;};
|
| 74 |
|
|
$session = "$session.$i";
|
| 75 |
|
|
|
| 76 |
|
|
$account = $1 if ($account =~ /(.+)/);
|
| 77 |
|
|
|
| 78 |
|
|
print header('application/json; charset=UTF8');
|
| 79 |
|
|
|
| 80 |
|
|
# system(qq[/usr/bin/pkill -f "$account~ui_update" &]); # Remove lingering ui_update.cgi's if reloading or changing account
|
| 81 |
|
|
`pkill -f "$account~ui_update.cgi"`; # Remove lingering ui_update.cgi's if reloading or changing account
|
| 82 |
|
|
|
| 83 |
|
|
if ($session ) {
|
| 84 |
|
|
my $tasks = qq|{"type": "session", "session": "$session", "url": "/stabile/ui_update/$account~ui_update?s=$session"}|;
|
| 85 |
|
|
print "[$tasks]\n";
|
| 86 |
|
|
} else {
|
| 87 |
|
|
sleep $naptime;
|
| 88 |
|
|
}
|
| 89 |
|
|
} else { # Wait and read input from operations
|
| 90 |
|
|
print header('application/json; charset=UTF8');
|
| 91 |
|
|
|
| 92 |
|
|
$session = $params{'s'};
|
| 93 |
|
|
$session =~ /(.+)/; $session = $1; #untaint
|
| 94 |
|
|
# if (-e "/tmp/$account~$session.tasks") {
|
| 95 |
|
|
my $r = substr rand(),2,4;
|
| 96 |
|
|
my $update = qq|{"type": "serial", "serial": "$r"}|;
|
| 97 |
|
|
my $tasks;
|
| 98 |
|
|
if (-e "/tmp/$account.tasks") {
|
| 99 |
|
|
$update = qq|{"type": "serial", "serial": "$r", "orphan": true}|;
|
| 100 |
|
|
# Orphaned tasks found - read them
|
| 101 |
|
|
$tasks = `/bin/cat < /tmp/$account.tasks`; # Read session tasks from pipe
|
| 102 |
|
|
# unlink ("/tmp/$account.tasks");
|
| 103 |
|
|
`rm "/tmp/$account.tasks"`;
|
| 104 |
|
|
} else {
|
| 105 |
|
|
$update = qq|{"type": "serial", "serial": "$r"}|;
|
| 106 |
|
|
# This is where we block and wait for news...
|
| 107 |
04c16f26
|
hq
|
`/usr/bin/mkfifo -m666 /tmp/$account~$session.tasks`;# unless (-e "/tmp/$account~$session.tasks");
|
| 108 |
95b003ff
|
Origo
|
$tasks = `/bin/cat < /tmp/$account~$session.tasks`; # Read session tasks from pipe
|
| 109 |
|
|
}
|
| 110 |
|
|
chomp $tasks;
|
| 111 |
|
|
$tasks = substr($tasks, 0, -2) if ($tasks =~ /(, )$/); # Remove last comma and space
|
| 112 |
|
|
if ($tasks && $tasks ne "--") {
|
| 113 |
|
|
$update .= qq|, $tasks|;
|
| 114 |
|
|
}
|
| 115 |
|
|
print "[$update]\n";
|
| 116 |
|
|
unlink "/tmp/$account~$session.tasks";
|
| 117 |
|
|
# } else {
|
| 118 |
|
|
# my $tasks = qq|{"type":"logout", "message":"Logged out"}| ;
|
| 119 |
|
|
# print "[$tasks]\n";
|
| 120 |
|
|
# }
|
| 121 |
|
|
}
|
| 122 |
|
|
|
| 123 |
|
|
sub handle_signal {
|
| 124 |
|
|
my $sig = shift;
|
| 125 |
|
|
return 0 if ($sig eq 'PIPE');
|
| 126 |
|
|
# unlink "/tmp/$account~$session.tasks"; # unless ($hupped);
|
| 127 |
|
|
# `/bin/rm /tmp/$account~$session.tasks`; # unless ($hupped);
|
| 128 |
|
|
# `/usr/bin/touch /tmp/$account~$session.tasks` if (-e "/tmp/$account~$session.tasks");
|
| 129 |
|
|
# Remove old session files
|
| 130 |
|
|
# `/usr/bin/find /tmp/* -maxdepth 0 -name "*.tasks" ! -name "$account~$session.tasks" -mmin +1 -exec rm '{}' \\;`;
|
| 131 |
|
|
# print header('application/json; charset=UTF8');
|
| 132 |
|
|
print qq|{"signal":"$sig"}\n|;
|
| 133 |
|
|
my $t = time;
|
| 134 |
|
|
unlink "/tmp/$account~$session.tasks";
|
| 135 |
|
|
`pkill -f "/bin/cat < /tmp/$account~$session.tasks"`;
|
| 136 |
|
|
exit 0;
|
| 137 |
|
|
# die;
|
| 138 |
|
|
}
|
| 139 |
|
|
|
| 140 |
|
|
sub is_user {
|
| 141 |
|
|
# $0 contains the name of the script e.g. jakob@cabo.dk~ui_update.cgi
|
| 142 |
|
|
$0 =~ /.+\/(.+)~+.+/;
|
| 143 |
|
|
if ($1 eq $user || $1 eq $account) {return 1;}
|
| 144 |
|
|
else {return 0;}
|
| 145 |
|
|
}
|
| 146 |
|
|
|
| 147 |
|
|
sub getPrivileges {
|
| 148 |
|
|
my $u = shift;
|
| 149 |
|
|
unless (tie %userreg,'Tie::DBI', {
|
| 150 |
|
|
db=>'mysql:steamregister',
|
| 151 |
|
|
table=>'users',
|
| 152 |
|
|
key=>'username',
|
| 153 |
|
|
autocommit=>0,
|
| 154 |
|
|
CLOBBER=>1,
|
| 155 |
|
|
user=>$dbiuser,
|
| 156 |
|
|
password=>$dbipasswd}) {return ""};
|
| 157 |
|
|
my $privs = $userreg{$u}->{'privileges'};
|
| 158 |
|
|
untie %userreg;
|
| 159 |
|
|
return $privs;
|
| 160 |
|
|
}
|
| 161 |
|
|
|
| 162 |
|
|
sub checkAccount {
|
| 163 |
|
|
my ($user, $account) = @_;
|
| 164 |
|
|
unless (tie %userreg,'Tie::DBI', {
|
| 165 |
|
|
db=>'mysql:steamregister',
|
| 166 |
|
|
table=>'users',
|
| 167 |
|
|
key=>'username',
|
| 168 |
|
|
autocommit=>0,
|
| 169 |
|
|
CLOBBER=>1,
|
| 170 |
|
|
user=>$dbiuser,
|
| 171 |
|
|
password=>$dbipasswd}) {return 0};
|
| 172 |
|
|
|
| 173 |
|
|
my %ahash;
|
| 174 |
|
|
my @accounts = split(',', $userreg{$user}->{'accounts'});
|
| 175 |
|
|
my @accountsprivs = split(',', $userreg{$user}->{'accountsprivileges'});
|
| 176 |
|
|
for my $i (0 .. $#accounts)
|
| 177 |
|
|
{ $ahash{$accounts[$i]} = $accountsprivs[$i] || 'r'; }
|
| 178 |
|
|
|
| 179 |
|
|
if ($ahash{$account}) {
|
| 180 |
|
|
$user = $account;
|
| 181 |
|
|
$privileges = $ahash{$account};
|
| 182 |
|
|
unless ($userreg{$user}->{'username'}) {
|
| 183 |
|
|
return 0;
|
| 184 |
|
|
};
|
| 185 |
|
|
if (index($privileges,"d")!=-1) {
|
| 186 |
|
|
return 0;
|
| 187 |
|
|
};
|
| 188 |
|
|
}
|
| 189 |
|
|
untie %userreg;
|
| 190 |
|
|
return $user;
|
| 191 |
|
|
}
|