/
flashpolicyd
executable file
·115 lines (97 loc) · 2.8 KB
/
flashpolicyd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#!/usr/bin/perl
# Standalone Flash policy server
# Jacob Elder <jacob.elder@gmail.com>
use strict;
use warnings;
use IO::Select;
use IO::Socket;
use Getopt::Long;
use English '-no_match_vars';
# file and port are optional on the command line.
my $file = '';
my $port = 843;
my $timeout = 3;
my $debug = 0;
my $pidfile = undef;
my $daemonize = 1;
sub help () {
print <<END;
Serves Flash socket policy requests using a quick select() interface.
--file File containing answer to policy requests.
--port TCP port, default is $port.
--timeout Timeout, default is $timeout.
--daemonize Daemonize, default is $daemonize.
--pidfile Write a PID to this file.
--debug Be verbose and don't daemonize.
If no arguments are specified, a ridiculously permissive policy file is served on port 843.
END
exit 75;
}
GetOptions(
'f|file=s' => \$file,
'p|port=s' => \$port,
'd|debug!' => \$debug,
'pidfile=s'=> \$pidfile,
'daemonize!' => \$daemonize,
) or help;
# $data will be from --file or the default after __END__
my $data = '';
if ($file) {
open FILE, $file or die "$file:$!";
$data .= $_ while (<FILE>);
close FILE;
} else {
$data .= $_ while (<DATA>);
}
my $listen = new IO::Socket::INET(
Listen => 2048,
LocalPort => $port,
Timeout => $timeout,
Reuse => 1
) or die $!;
# Drop privileges.
$EFFECTIVE_USER_ID = getpwnam('nobody') unless $UID;
printf("Listening on %s:%s\n",
$listen->sockhost(),
$listen->sockport())
if $debug;
my $select = new IO::Select( $listen )
or die $!;
# Daemonize
if ($daemonize and !$debug) {
exit if fork
}
# Write PID
if ($pidfile) {
open PIDFILE, ">$pidfile" or die "$pidfile:$!";
print PIDFILE $$;
close PIDFILE;
}
# Adobe's "protocol" says requests are null-terminated. Only <policy-file-request/> has been used so far, so assume that's all we'll ever see.
local $INPUT_RECORD_SEPARATOR = pack 'c', 0;
while (my @ready = $select->can_read) {
for my $fh (@ready) {
if ($fh == $listen) {
$select->add($listen->accept);
} else {
printf("%s:%s -> %s:%s",
$fh->peerhost(),
$fh->peerport(),
$fh->sockhost(),
$fh->sockport())
if $debug;
$fh->getline; # Don't need it, but wait for it anyway.
$fh->print($data);
$select->remove($fh);
$fh->close;
print "\n" if $debug;
}
}
}
__END__
<?xml version="1.0" encoding="UTF-8"?>
<cross-domain-policy xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.adobe.com/xml/schemas/PolicyFileSocket.xsd">
<site-control permitted-cross-domain-policies="all"/>
<allow-access-from domain="*" to-ports="*"/>
</cross-domain-policy>