Project

General

Profile

Download (6.16 KB) Statistics
| Branch: | Revision:
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
}