source: preprover/XMLRPC.pm @ 675cbea

abac0-leakabac0-meicompt_changesgec13mei-idmei-rt0-nmei_rt0mei_rt2mei_rt2_fix_1meiyap-rt1meiyap1rt2tvf-new-xml
Last change on this file since 675cbea was f7040d8, checked in by Mike Ryan <mikeryan@…>, 14 years ago

perl preprover

SSL key id differs from our (libabac) keyid

SSL: sha1(whole cert)
us: sha1(pub key)

  • Property mode set to 100644
File size: 2.4 KB
Line 
1package XMLRPC;
2
3use strict;
4use Carp;
5
6use HTTP::Daemon::SSL;
7use HTTP::Status qw(:constants);
8use RPC::XML::Server;
9use Net::SSLeay;
10
11sub new {
12    my ($class) = @_;
13
14    my $srv = RPC::XML::Server->new(no_http => 1);
15    return bless \$srv, $class;
16}
17
18sub add_method {
19    my $self = shift;
20    my $srv = $$self;
21    $srv->add_method(@_);
22}
23
24sub verify {
25    my ($ok, $store_ctx) = @_;
26
27    my $x = Net::SSLeay::X509_STORE_CTX_get_current_cert($store_ctx);
28    return $x ? 1 : 0;
29}
30
31sub run {
32    my ($self, $port) = @_;
33    croak "Must supply a port to run on" unless defined $port;
34
35    my $srv = $$self;
36
37    my $daemon = HTTP::Daemon::SSL->new(
38        LocalPort   => $port,
39        ReuseAddr   => 1,
40        SSL_verify_mode => 3,
41        SSL_ca_path => 'FAIL',  # if this isn't here, verify never gets called :D
42        SSL_verify_callback => \&verify,
43    ) or die "Can't start HTTP daemon: $!";
44
45    for ( ; ; ) {
46        while (my $client = $daemon->accept) {
47            my $pid = fork;
48            next if $pid;
49
50            my $peer_cert = $client->peer_certificate;
51            $srv->{peer_cert} = $peer_cert;
52
53            while (my $request = $client->get_request) {
54                # require an SSL certificate
55                if (!defined $srv->{peer_cert}) {
56                    my $response = HTTP::Response->new(HTTP_UNAUTHORIZED);
57                    $response->content("C'mon gimme a cert");
58                    $client->send_response($response);
59                    next;
60                }
61
62                # only handle POSTs to /RPC2
63                if ($request->method ne 'POST' || $request->url->path ne '/RPC2') {
64                    $client->send_error(HTTP_FORBIDDEN);
65                    next;
66                }
67
68                my $response;
69
70                eval {
71                    my $rpc_response = $srv->dispatch($request->content);
72                    my $content = $rpc_response->as_string;
73
74                    $response = HTTP::Response->new(HTTP_OK);
75                    $response->content($content);
76                };
77
78                # return an error on any kind of exception
79                if ($@) {
80                    $response = HTTP::Response->new(HTTP_BAD_REQUEST);
81                    $response->content('Are you even trying?');
82                }
83
84                $client->send_response($response);
85            }
86
87            exit;
88        }
89    }
90}
91
921;
Note: See TracBrowser for help on using the repository browser.