You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

99 lines
2.8 KiB

#!/usr/bin/env perl
##
## flashpolicyd.pl -- Adobe Flash Policy File Server
## Copyright (c) 2005 Adobe Systems Incorporated
## Copyright (c) 2009 Ralf S. Engelschall <rse@engelschall.com>
##
use strict;
use Socket;
my $NULLBYTE = pack('c', 0);
my $uid = 65534;
my $gid = 65534;
my $host = "0.0.0.0";
my $port = 843;
my $cfgfile;
my $logfile;
my $content;
while (my $arg = shift @ARGV) {
if ($arg =~ m/^--host=(\d+)$/) {
$host = $1;
}
elsif ($arg =~ m/^--port=(\d+)$/) {
$port = $1;
}
elsif ($arg =~ m/^--cfg=(.*)/) {
$cfgfile = $1;
}
elsif ($arg =~ m/^--log=(.*)/) {
$logfile = $1;
}
elsif ($arg =~ m/^--uid=(.*)/) {
$uid = $1;
}
elsif ($arg =~ m/^--gid=(.*)/) {
$gid = $1;
}
}
unless ($cfgfile) {
die "Usage: flashpolicyd [--host=IP] [--port=N] --cfg=FILE [--log=FILE] [--uid=N] [--gid=N]\n";
}
-f $cfgfile or die "No such file: '$cfgfile'\n";
-s $cfgfile < 10_000 or die "File probably too large to be a policy file: '$cfgfile'\n";
local $/ = undef;
open POLICYFILE, "<$cfgfile" or die "Can't open '$cfgfile': $!\n";
$content = <POLICYFILE>;
close POLICYFILE;
$content =~ m/cross-domain-policy/ or die "Not a valid policy file: '$cfgfile'\n";
socket(LISTENSOCK, PF_INET, SOCK_STREAM, getprotobyname('tcp')) or die "socket() error: $!";
setsockopt(LISTENSOCK, SOL_SOCKET, SO_REUSEADDR, pack('l', 1)) or die "setsockopt() error: $!";
bind(LISTENSOCK, sockaddr_in($port, $host eq "0.0.0.0" ? INADDR_ANY : inet_aton($host))) or die "bind() error: $!";
listen(LISTENSOCK, SOMAXCONN) or die "listen() error: $!";
$< = $uid;
$( = $gid;
$> = $<;
$) = $(;
umask(022);
sub logbook {
my ($msg) = @_;
my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime(time());
open LOGFILE, ">>$logfile" or die "Can't open '$logfile': $!\n";
printf(LOGFILE "[%04d-%02d-%02dT%02d:%02d:%02d] %s\n", 1900+$year, $mon, $mday, $hour, $min, $sec, $msg);
close LOGFILE
}
logbook("startup (listening at $host:$port, running under $uid/$gid)");
while (my $clientAddr = accept(CONNSOCK, LISTENSOCK)) {
my ($clientPort, $clientIp) = sockaddr_in($clientAddr);
my $clientIpStr = inet_ntoa($clientIp);
logbook("[$clientIpStr:$clientPort] connection opened");
local $/ = $NULLBYTE;
my $request = <CONNSOCK>;
chomp $request;
if ($request ne '<policy-file-request/>') {
$request =~ s/([^a-zA-Z0-9<>\/]+)/sprintf("\\x%02x", ord($1))/sge;
logbook("[$clientIpStr:$clientPort] unrecognized request: \"$request\"");
close CONNSOCK;
next;
}
logbook("[$clientIpStr:$clientPort] send response");
print CONNSOCK $content;
print CONNSOCK $NULLBYTE;
close CONNSOCK;
logbook("[$clientIpStr:$clientPort] connection closed");
}