add option to msva-query-agent to just return agent version info
[monkeysphere-validation-agent.git] / Crypt / Monkeysphere / MSVA / Client.pm
1 #----------------------------------------------------------------------
2 # Monkeysphere Validation Agent, Perl version
3 # Marginal User Interface for reasonable prompting
4 # Copyright © 2010 Daniel Kahn Gillmor <dkg@fifthhorseman.net>,
5 #                  Matthew James Goins <mjgoins@openflows.com>,
6 #                  Jameson Graef Rollins <jrollins@finestructure.net>,
7 #                  Elliot Winard <enw@caveteen.com>
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 # GNU General Public License for more details.
18 #
19 # You should have received a copy of the GNU General Public License
20 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
21 #
22 #----------------------------------------------------------------------
23
24 { package Crypt::Monkeysphere::MSVA::Client;
25
26   use strict;
27   use warnings;
28   use JSON;
29   use Crypt::Monkeysphere::MSVA::Logger;
30   use LWP::UserAgent;
31   use HTTP::Request;
32   use Module::Load::Conditional;
33
34   sub log {
35     my $self = shift;
36     $self->{logger}->log(@_);
37   }
38
39   sub agent_info {
40     my $self = shift;
41     my $requesturl = $self->{socket} . '/';
42     my $request = HTTP::Request->new('GET', $requesturl);
43     $self->log('debug', "Contacting MSVA at %s\n", $requesturl);
44     my $response = $self->{ua}->request($request);
45     my $status = $response->status_line;
46     my $ret;
47     if ($status eq '200 OK') {
48       $ret = from_json($response->content);
49     }
50     return $status, $ret;
51   }
52
53   sub query_agent {
54     my $self = shift;
55     my $context = shift;
56     my $peer = shift;
57     my $peertype = shift;
58     my $pkctype = shift;
59     my $pkcdata = shift;
60     my $keyserverpolicy = shift;
61
62     my $apd = $self->create_apd($context, $peer, $peertype, $pkctype, $pkcdata, $keyserverpolicy);
63
64     my $apdjson = to_json($apd);
65
66     my $headers = HTTP::Headers->new(
67         'Content-Type' => 'application/json',
68         'Content-Length' => length($apdjson),
69         'Connection' => 'close',
70         'Accept' => 'application/json',
71         );
72
73     my $requesturl = $self->{socket} . '/reviewcert';
74
75     my $request = HTTP::Request->new(
76         'POST',
77         $requesturl,
78         $headers,
79         $apdjson,
80         );
81
82     $self->log('debug', "Contacting MSVA at %s\n", $requesturl);
83     my $response = $self->{ua}->request($request);
84
85     my $status = $response->status_line;
86     my $ret;
87     if ($status eq '200 OK') {
88       $ret = from_json($response->content);
89     }
90
91     return $status, $ret;
92   }
93
94   sub create_apd {
95     my $self = shift;
96     my $context = shift;
97     my $peer = shift;
98     my $peertype = shift;
99     my $pkctype = shift;
100     my $pkcdata = shift;
101     my $keyserverpolicy = shift;
102
103     $self->log('debug', "context: %s\n", $context);
104     $self->log('debug', "peer: %s\n", $peer);
105     $self->log('debug', "pkctype: %s\n", $pkctype);
106
107     my $transformed_data;
108     if ($pkctype eq 'x509der') {
109       # remap raw der data into numeric array
110       $transformed_data = [map(ord, split(//,$pkcdata))];
111     } else {
112       $transformed_data = $pkcdata;
113     }
114
115     my $ret = {
116                context => $context,
117                peer => { name => $peer},
118                pkc => {
119                        type => $pkctype,
120                        data => $transformed_data,
121                       },
122               };
123     $ret->{peer}->{type} = $peertype
124       if (defined $peertype);
125     $ret->{keyserverpolicy} = $keyserverpolicy
126       if (defined $keyserverpolicy);
127
128     return $ret;
129   };
130
131
132   sub new {
133     my $class = shift;
134     my %args = @_;
135     my $self = {};
136
137     $self->{logger} = Crypt::Monkeysphere::MSVA::Logger->new($args{log_level});
138     $self->{socket} = $args{socket};
139     $self->{socket} = 'http://localhost:8901'
140       if (! defined $self->{socket} or $self->{socket} eq '');
141
142     # create the user agent
143     $self->{ua} = LWP::UserAgent->new;
144
145     bless ($self,$class);
146     return $self;
147   }
148
149   1;
150 }