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>