Annotation of embedaddon/strongswan/src/libcharon/plugins/vici/perl/Vici-Session/lib/Vici/Message.pm, revision 1.1.1.1
1.1 misho 1: package Vici::Message;
2:
3: our $VERSION = '0.9';
4:
5: use strict;
6: use Vici::Transport;
7:
8: use constant {
9: SECTION_START => 1, # Begin a new section having a name
10: SECTION_END => 2, # End a previously started section
11: KEY_VALUE => 3, # Define a value for a named key in the section
12: LIST_START => 4, # Begin a named list for list items
13: LIST_ITEM => 5, # Define an unnamed item value in the current list
14: LIST_END => 6, # End a previously started list
15: };
16:
17: sub new {
18: my $class = shift;
19: my $hash = shift;
20: my $self = {
21: Hash => $hash
22: };
23: bless($self, $class);
24: return $self;
25: }
26:
27: sub from_data {
28: my $class = shift;
29: my $data = shift;
30: my %hash = ();
31:
32: open my $data_fd, '<', \$data;
33: parse($data_fd, \%hash);
34: close $data_fd;
35:
36: my $self = {
37: Hash => \%hash
38: };
39: bless($self, $class);
40: return $self;
41: }
42:
43: sub hash {
44: my $self = shift;
45: return $self->{Hash};
46: }
47:
48: sub encode {
49: my $self = shift;
50: return encode_hash($self->{'Hash'});
51: }
52:
53: sub raw {
54: my $self = shift;
55: return '{' . raw_hash($self->{'Hash'}) . '}';
56: }
57:
58: sub result {
59: my $self = shift;
60: my $result = $self->{'Hash'};
61: return ($result->{'success'} eq 'yes', $result->{'errmsg'});
62: }
63:
64: # private functions
65:
66: sub parse {
67: my $fd = shift;
68: my $hash = shift;
69: my $data;
70:
71: until ( eof $fd )
72: {
73: my $type = unpack('C', read_data($fd, 1));
74:
75: if ( $type == SECTION_END )
76: {
77: return;
78: }
79:
80: my $key = read_len_data($fd, 1);
81:
82: if ( $type == KEY_VALUE )
83: {
84: my $value = read_len_data($fd, 2);
85: $hash->{$key} = $value;
86: }
87: elsif ( $type == SECTION_START )
88: {
89: my %section = ();
90: parse($fd, \%section);
91: $hash->{$key} = \%section;
92: }
93: elsif ( $type == LIST_START )
94: {
95: my @list = ();
96: my $more = 1;
97:
98: while ( !eof($fd) and $more )
99: {
100: my $type = unpack('C', read_data($fd, 1));
101:
102: if ( $type == LIST_ITEM )
103: {
104: my $value = read_len_data($fd, 2);
105: push(@list, $value);
106: }
107: elsif ( $type == LIST_END )
108: {
109: $more = 0;
110: $hash->{$key} = \@list;
111: }
112: else
113: {
114: die "message parsing error: ", $type, "\n"
115: }
116: }
117: }
118: else
119: {
120: die "message parsing error: ", $type, "\n"
121: }
122: }
123: }
124:
125: sub read_data {
126: my $fd = shift;
127: my $len = shift;
128: my $data;
129:
130: my $res = read $fd, $data, $len;
131: unless (defined $res and $res == $len)
132: {
133: die "message parsing error: unable to read ", $len, " bytes\n";
134: }
135: return $data;
136: }
137:
138: sub read_len_data {
139: my $fd = shift;
140: my $len = shift;
141:
142: $len = unpack($len == 1 ? 'C' : 'n', read_data($fd, $len));
143: return read_data($fd, $len);
144: }
145:
146: sub encode_hash {
147: my $hash = shift;
148: my $enc = '';
149:
150: while ( (my $key, my $value) = each %$hash )
151: {
152: if ( ref($value) eq 'HASH' )
153: {
154: $enc .= pack('CC/a*', SECTION_START, $key);
155: $enc .= encode_hash($value);
156: $enc .= pack('C', SECTION_END);
157: }
158: elsif ( ref($value) eq 'ARRAY' )
159: {
160: $enc .= pack('CC/a*', LIST_START, $key);
161:
162: foreach my $item (@$value)
163: {
164: $enc .= pack('Cn/a*', LIST_ITEM, $item);
165: }
166: $enc .= pack('C', LIST_END);
167: }
168: else
169: {
170: $enc .= pack('CC/a*n/a*', KEY_VALUE, $key, $value);
171: }
172: }
173: return $enc;
174: }
175:
176: sub raw_hash {
177: my $hash = shift;
178: my $raw = '';
179: my $first = 1;
180:
181: while ( (my $key, my $value) = each %$hash )
182: {
183: if ($first)
184: {
185: $first = 0;
186: }
187: else
188: {
189: $raw .= ' ';
190: }
191: $raw .= $key;
192:
193: if ( ref($value) eq 'HASH' )
194: {
195: $raw .= '{' . raw_hash($value) . '}';
196: }
197: elsif ( ref($value) eq 'ARRAY' )
198: {
199: my $first_item = 1;
200: $raw .= '[';
201:
202: foreach my $item (@$value)
203: {
204: if ($first_item)
205: {
206: $first_item = 0;
207: }
208: else
209: {
210: $raw .= ' ';
211: }
212: $raw .= $item;
213: }
214: $raw .= ']';
215: }
216: else
217: {
218: $raw .= '=' . $value;
219: }
220: }
221: return $raw;
222: }
223:
224: 1;
225: __END__
226: =head1 NAME
227:
228: Vici::Message - Perl extension for building and parsing strongSwan VICI messages
229:
230: =head1 SYNOPSIS
231:
232: use Vici::Message;
233:
234: =head1 DESCRIPTION
235:
236: The Vici::Message module is needed by the Vici::Session module to build and
237: parse messages used in the communication with the open source strongSwan IPsec
238: daemon (https://www.strongswan.com) via the documented Versatile IKE
239: Configuration Interface (VICI). VICI allows the configuration, management and
240: monitoring of multiple IPsec connections.
241:
242: =head2 EXPORT
243:
244: None by default.
245:
246: =head1 SEE ALSO
247:
248: strongSwan Wiki: https://wiki.strongswan.org/projects/strongswan/wiki/Vici
249:
250: strongSwan Mailing list: users@lists.strongswan.org
251:
252: =head1 AUTHOR
253:
254: Andreas Steffen, E<lt>andreas.steffen@strongswan.orgE<gt>
255:
256: =head1 COPYRIGHT AND LICENSE
257:
258: Copyright (C) 2015 by Andreas Steffen
259:
260: Permission is hereby granted, free of charge, to any person obtaining a copy
261: of this software and associated documentation files (the "Software"), to deal
262: in the Software without restriction, including without limitation the rights
263: to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
264: copies of the Software, and to permit persons to whom the Software is
265: furnished to do so, subject to the following conditions:
266:
267: The above copyright notice and this permission notice shall be included in
268: all copies or substantial portions of the Software.
269:
270: THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
271: IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
272: FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
273: AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
274: LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
275: OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
276: THE SOFTWARE.
277:
278: =cut
279:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>