| line | stmt | bran | cond | sub | pod | time | code | 
| 1 |  |  |  |  |  |  | package POE::Component::Server::NSCA; | 
| 2 |  |  |  |  |  |  | $POE::Component::Server::NSCA::VERSION = '0.10'; | 
| 3 |  |  |  |  |  |  | #ABSTRACT: a POE Component that implements NSCA daemon functionality | 
| 4 |  |  |  |  |  |  |  | 
| 5 | 3 |  |  | 3 |  | 40894 | use strict; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 71 |  | 
| 6 | 3 |  |  | 3 |  | 12 | use warnings; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 62 |  | 
| 7 | 3 |  |  | 3 |  | 1273 | use Socket; | 
|  | 3 |  |  |  |  | 9769 |  | 
|  | 3 |  |  |  |  | 1087 |  | 
| 8 | 3 |  |  | 3 |  | 20 | use Carp; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 111 |  | 
| 9 | 3 |  |  | 3 |  | 1071 | use Net::Netmask; | 
|  | 3 |  |  |  |  | 34155 |  | 
|  | 3 |  |  |  |  | 240 |  | 
| 10 | 3 |  |  | 3 |  | 1269 | use Math::Random; | 
|  | 3 |  |  |  |  | 12408 |  | 
|  | 3 |  |  |  |  | 212 |  | 
| 11 | 3 |  |  | 3 |  | 1193 | use POE qw(Wheel::SocketFactory Wheel::ReadWrite Filter::Stream); | 
|  | 3 |  |  |  |  | 64988 |  | 
|  | 3 |  |  |  |  | 20 |  | 
| 12 |  |  |  |  |  |  |  | 
| 13 | 3 |  |  | 3 |  | 171490 | use constant MAX_INPUT_BUFFER =>        2048    ; # /* max size of most buffers we use */ | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 197 |  | 
| 14 | 3 |  |  | 3 |  | 18 | use constant MAX_HOST_ADDRESS_LENGTH => 256     ; # /* max size of a host address */ | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 112 |  | 
| 15 | 3 |  |  | 3 |  | 33 | use constant MAX_HOSTNAME_LENGTH =>     64      ; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 99 |  | 
| 16 | 3 |  |  | 3 |  | 15 | use constant MAX_DESCRIPTION_LENGTH =>  128; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 93 |  | 
| 17 | 3 |  |  | 3 |  | 15 | use constant OLD_PLUGINOUTPUT_LENGTH => 512; | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 90 |  | 
| 18 | 3 |  |  | 3 |  | 14 | use constant MAX_PLUGINOUTPUT_LENGTH => 4096; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 93 |  | 
| 19 | 3 |  |  | 3 |  | 14 | use constant MAX_PASSWORD_LENGTH =>     512; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 94 |  | 
| 20 | 3 |  |  | 3 |  | 13 | use constant TRANSMITTED_IV_SIZE =>     128; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 106 |  | 
| 21 | 3 |  |  | 3 |  | 14 | use constant SIZEOF_U_INT32_T   => 4; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 101 |  | 
| 22 | 3 |  |  | 3 |  | 14 | use constant SIZEOF_INT16_T     => 2; | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 146 |  | 
| 23 | 3 |  |  | 3 |  | 22 | use constant SIZEOF_INIT_PACKET => TRANSMITTED_IV_SIZE + SIZEOF_U_INT32_T; | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 100 |  | 
| 24 |  |  |  |  |  |  |  | 
| 25 | 3 |  |  | 3 |  | 15 | use constant PROBABLY_ALIGNMENT_ISSUE => 4; | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 150 |  | 
| 26 |  |  |  |  |  |  |  | 
| 27 | 3 |  |  | 3 |  | 15 | use constant SIZEOF_DATA_PACKET => SIZEOF_INT16_T + SIZEOF_U_INT32_T + SIZEOF_U_INT32_T + SIZEOF_INT16_T + MAX_HOSTNAME_LENGTH + MAX_DESCRIPTION_LENGTH + MAX_PLUGINOUTPUT_LENGTH + PROBABLY_ALIGNMENT_ISSUE; | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 138 |  | 
| 28 | 3 |  |  | 3 |  | 15 | use constant SIZEOF_OLD_PACKET  => SIZEOF_INT16_T + SIZEOF_U_INT32_T + SIZEOF_U_INT32_T + SIZEOF_INT16_T + MAX_HOSTNAME_LENGTH + MAX_DESCRIPTION_LENGTH + OLD_PLUGINOUTPUT_LENGTH + PROBABLY_ALIGNMENT_ISSUE; | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 96 |  | 
| 29 |  |  |  |  |  |  |  | 
| 30 | 3 |  |  | 3 |  | 15 | use constant ENCRYPT_NONE =>            0       ; # /* no encryption */ | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 98 |  | 
| 31 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_XOR =>             1       ; # /* not really encrypted, just obfuscated */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 94 |  | 
| 32 | 3 |  |  | 3 |  | 13 | use constant ENCRYPT_DES =>             2       ; # /* DES */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 106 |  | 
| 33 | 3 |  |  | 3 |  | 19 | use constant ENCRYPT_3DES =>            3       ; # /* 3DES or Triple DES */ | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 132 |  | 
| 34 | 3 |  |  | 3 |  | 19 | use constant ENCRYPT_CAST128 =>         4       ; # /* CAST-128 */ | 
|  | 3 |  |  |  |  | 28 |  | 
|  | 3 |  |  |  |  | 105 |  | 
| 35 | 3 |  |  | 3 |  | 15 | use constant ENCRYPT_CAST256 =>         5       ; # /* CAST-256 */ | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 107 |  | 
| 36 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_XTEA =>            6       ; # /* xTEA */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 94 |  | 
| 37 | 3 |  |  | 3 |  | 13 | use constant ENCRYPT_3WAY =>            7       ; # /* 3-WAY */ | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 98 |  | 
| 38 | 3 |  |  | 3 |  | 16 | use constant ENCRYPT_BLOWFISH =>        8       ; # /* SKIPJACK */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 119 |  | 
| 39 | 3 |  |  | 3 |  | 17 | use constant ENCRYPT_TWOFISH =>         9       ; # /* TWOFISH */ | 
|  | 3 |  |  |  |  | 31 |  | 
|  | 3 |  |  |  |  | 145 |  | 
| 40 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_LOKI97 =>          10      ; # /* LOKI97 */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 102 |  | 
| 41 | 3 |  |  | 3 |  | 13 | use constant ENCRYPT_RC2 =>             11      ; # /* RC2 */ | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 87 |  | 
| 42 | 3 |  |  | 3 |  | 21 | use constant ENCRYPT_ARCFOUR =>         12      ; # /* RC4 */ | 
|  | 3 |  |  |  |  | 9 |  | 
|  | 3 |  |  |  |  | 102 |  | 
| 43 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_RC6 =>             13      ; # /* RC6 */            ; # /* UNUSED */ | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 95 |  | 
| 44 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_RIJNDAEL128 =>     14      ; # /* RIJNDAEL-128 */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 93 |  | 
| 45 | 3 |  |  | 3 |  | 13 | use constant ENCRYPT_RIJNDAEL192 =>     15      ; # /* RIJNDAEL-192 */ | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 99 |  | 
| 46 | 3 |  |  | 3 |  | 15 | use constant ENCRYPT_RIJNDAEL256 =>     16      ; # /* RIJNDAEL-256 */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 92 |  | 
| 47 | 3 |  |  | 3 |  | 13 | use constant ENCRYPT_MARS =>            17      ; # /* MARS */           ; # /* UNUSED */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 107 |  | 
| 48 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_PANAMA =>          18      ; # /* PANAMA */         ; # /* UNUSED */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 97 |  | 
| 49 | 3 |  |  | 3 |  | 13 | use constant ENCRYPT_WAKE =>            19      ; # /* WAKE */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 95 |  | 
| 50 | 3 |  |  | 3 |  | 65 | use constant ENCRYPT_SERPENT =>         20      ; # /* SERPENT */ | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 117 |  | 
| 51 | 3 |  |  | 3 |  | 13 | use constant ENCRYPT_IDEA =>            21      ; # /* IDEA */           ; # /* UNUSED */ | 
|  | 3 |  |  |  |  | 7 |  | 
|  | 3 |  |  |  |  | 101 |  | 
| 52 | 3 |  |  | 3 |  | 18 | use constant ENCRYPT_ENIGMA =>          22      ; # /* ENIGMA (Unix crypt) */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 108 |  | 
| 53 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_GOST =>            23      ; # /* GOST */ | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 105 |  | 
| 54 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_SAFER64 =>         24      ; # /* SAFER-sk64 */ | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 111 |  | 
| 55 | 3 |  |  | 3 |  | 13 | use constant ENCRYPT_SAFER128 =>        25      ; # /* SAFER-sk128 */ | 
|  | 3 |  |  |  |  | 6 |  | 
|  | 3 |  |  |  |  | 100 |  | 
| 56 | 3 |  |  | 3 |  | 14 | use constant ENCRYPT_SAFERPLUS =>       26      ; # /* SAFER+ */ | 
|  | 3 |  |  |  |  | 5 |  | 
|  | 3 |  |  |  |  | 5911 |  | 
| 57 |  |  |  |  |  |  |  | 
| 58 |  |  |  |  |  |  | my $HAVE_MCRYPT = 0; | 
| 59 |  |  |  |  |  |  | eval { | 
| 60 |  |  |  |  |  |  | require Mcrypt; | 
| 61 |  |  |  |  |  |  | $HAVE_MCRYPT++; | 
| 62 |  |  |  |  |  |  | }; | 
| 63 |  |  |  |  |  |  |  | 
| 64 |  |  |  |  |  |  | # Lookups for loading. | 
| 65 |  |  |  |  |  |  | my %mcrypts =   (       ENCRYPT_NONE,		"none", | 
| 66 |  |  |  |  |  |  | ENCRYPT_XOR,		"xor", | 
| 67 |  |  |  |  |  |  | ENCRYPT_DES,            "DES", | 
| 68 |  |  |  |  |  |  | ENCRYPT_3DES,           "3DES", | 
| 69 |  |  |  |  |  |  | ENCRYPT_CAST128,        "CAST_128", | 
| 70 |  |  |  |  |  |  | ENCRYPT_CAST256,        "CAST-256", | 
| 71 |  |  |  |  |  |  | ENCRYPT_XTEA,           "XTEA", | 
| 72 |  |  |  |  |  |  | ENCRYPT_3WAY,           "THREEWAY", | 
| 73 |  |  |  |  |  |  | ENCRYPT_BLOWFISH,       "BLOWFISH", | 
| 74 |  |  |  |  |  |  | ENCRYPT_TWOFISH,        "TWOFISH", | 
| 75 |  |  |  |  |  |  | ENCRYPT_LOKI97,         "LOKI97", | 
| 76 |  |  |  |  |  |  | ENCRYPT_RC2,            "RC2", | 
| 77 |  |  |  |  |  |  | ENCRYPT_ARCFOUR,        "ARCFOUR", | 
| 78 |  |  |  |  |  |  | ENCRYPT_RC6,            "RC6", | 
| 79 |  |  |  |  |  |  | ENCRYPT_RIJNDAEL128,    "RIJNDAEL_128", | 
| 80 |  |  |  |  |  |  | ENCRYPT_RIJNDAEL192,    "RIJNDAEL_192", | 
| 81 |  |  |  |  |  |  | ENCRYPT_RIJNDAEL256,    "RIJNDAEL_256", | 
| 82 |  |  |  |  |  |  | ENCRYPT_MARS,           "MARS", | 
| 83 |  |  |  |  |  |  | ENCRYPT_PANAMA,         "PANAMA", | 
| 84 |  |  |  |  |  |  | ENCRYPT_WAKE,           "WAKE", | 
| 85 |  |  |  |  |  |  | ENCRYPT_SERPENT,        "SERPENT", | 
| 86 |  |  |  |  |  |  | ENCRYPT_IDEA,           "IDEA", | 
| 87 |  |  |  |  |  |  | ENCRYPT_ENIGMA,         "ENGIMA", | 
| 88 |  |  |  |  |  |  | ENCRYPT_GOST,           "GOST", | 
| 89 |  |  |  |  |  |  | ENCRYPT_SAFER64,        "SAFER_SK64", | 
| 90 |  |  |  |  |  |  | ENCRYPT_SAFER128,       "SAFER_SK128", | 
| 91 |  |  |  |  |  |  | ENCRYPT_SAFERPLUS,      "SAFERPLUS", | 
| 92 |  |  |  |  |  |  | ); | 
| 93 |  |  |  |  |  |  |  | 
| 94 |  |  |  |  |  |  | sub spawn { | 
| 95 | 3 |  |  | 3 | 1 | 46 | my $package = shift; | 
| 96 | 3 |  |  |  |  | 25 | my %opts = @_; | 
| 97 | 3 |  |  |  |  | 33 | $opts{lc $_} = delete $opts{$_} for keys %opts; | 
| 98 |  |  |  |  |  |  | croak "$package requires a 'password' argument\n" | 
| 99 | 3 | 50 |  |  |  | 16 | unless $opts{password}; | 
| 100 |  |  |  |  |  |  | croak "$package requires an 'encryption' argument\n" | 
| 101 | 3 | 50 |  |  |  | 14 | unless defined $opts{encryption}; | 
| 102 |  |  |  |  |  |  | croak "'encryption' argument must be a valid numeric\n" | 
| 103 | 3 | 50 |  |  |  | 20 | unless defined $mcrypts{ $opts{encryption} }; | 
| 104 | 3 |  |  |  |  | 11 | my $options = delete $opts{options}; | 
| 105 | 3 |  | 50 |  |  | 37 | my $access = delete $opts{access} || [ Net::Netmask->new('any') ]; | 
| 106 | 3 | 50 |  |  |  | 333 | $access = [ ] unless ref $access eq 'ARRAY'; | 
| 107 | 3 |  |  |  |  | 12 | foreach my $acl ( @$access ) { | 
| 108 | 3 | 50 |  |  |  | 32 | next unless $acl->isa('Net::Netmask'); | 
| 109 | 3 |  |  |  |  | 8 | push @{ $opts{access} }, $acl; | 
|  | 3 |  |  |  |  | 14 |  | 
| 110 |  |  |  |  |  |  | } | 
| 111 | 3 |  |  |  |  | 11 | my $self = bless \%opts, $package; | 
| 112 | 3 | 100 |  |  |  | 61 | $self->{session_id} = POE::Session->create( | 
| 113 |  |  |  |  |  |  | object_states => [ | 
| 114 |  |  |  |  |  |  | $self => { shutdown       => '_shutdown', | 
| 115 |  |  |  |  |  |  | }, | 
| 116 |  |  |  |  |  |  | $self => [qw( | 
| 117 |  |  |  |  |  |  | _start | 
| 118 |  |  |  |  |  |  | _accept_client | 
| 119 |  |  |  |  |  |  | _accept_failed | 
| 120 |  |  |  |  |  |  | _conn_input | 
| 121 |  |  |  |  |  |  | _conn_error | 
| 122 |  |  |  |  |  |  | _conn_alarm | 
| 123 |  |  |  |  |  |  | register | 
| 124 |  |  |  |  |  |  | unregister | 
| 125 |  |  |  |  |  |  | )], | 
| 126 |  |  |  |  |  |  | ], | 
| 127 |  |  |  |  |  |  | heap => $self, | 
| 128 |  |  |  |  |  |  | ( ref($options) eq 'HASH' ? ( options => $options ) : () ), | 
| 129 |  |  |  |  |  |  | )->ID(); | 
| 130 | 3 |  |  |  |  | 586 | return $self; | 
| 131 |  |  |  |  |  |  | } | 
| 132 |  |  |  |  |  |  |  | 
| 133 |  |  |  |  |  |  | sub shutdown { | 
| 134 | 3 |  |  | 3 | 1 | 6939 | my $self = shift; | 
| 135 | 3 |  |  |  |  | 19 | $poe_kernel->post( $self->{session_id}, 'shutdown' ); | 
| 136 |  |  |  |  |  |  | } | 
| 137 |  |  |  |  |  |  |  | 
| 138 |  |  |  |  |  |  | sub session_id { | 
| 139 | 2 |  |  | 2 | 1 | 56 | return $_[0]->{session_id}; | 
| 140 |  |  |  |  |  |  | } | 
| 141 |  |  |  |  |  |  |  | 
| 142 |  |  |  |  |  |  | sub getsockname { | 
| 143 | 3 | 50 |  | 3 | 1 | 2681 | return unless $_[0]->{listener}; | 
| 144 | 3 |  |  |  |  | 26 | return $_[0]->{listener}->getsockname(); | 
| 145 |  |  |  |  |  |  | } | 
| 146 |  |  |  |  |  |  |  | 
| 147 |  |  |  |  |  |  | sub _start { | 
| 148 | 3 |  |  | 3 |  | 1132 | my ($kernel,$self,$sender) = @_[KERNEL,OBJECT,SENDER]; | 
| 149 | 3 |  |  |  |  | 14 | $self->{session_id} = $_[SESSION]->ID(); | 
| 150 | 3 | 50 |  |  |  | 22 | if ( $self->{alias} ) { | 
| 151 | 0 |  |  |  |  | 0 | $kernel->alias_set( $self->{alias} ); | 
| 152 |  |  |  |  |  |  | } | 
| 153 |  |  |  |  |  |  | else { | 
| 154 | 3 |  |  |  |  | 17 | $kernel->refcount_increment( $self->{session_id} => __PACKAGE__ ); | 
| 155 |  |  |  |  |  |  | } | 
| 156 |  |  |  |  |  |  | #$self->{filter} = POE::Filter::Block->new( BlockSize => SIZEOF_DATA_PACKET ); | 
| 157 | 3 |  |  |  |  | 158 | $self->{filter} = POE::Filter::Stream->new(); | 
| 158 |  |  |  |  |  |  | $self->{listener} = POE::Wheel::SocketFactory->new( | 
| 159 |  |  |  |  |  |  | ( defined $self->{address} ? ( BindAddress => $self->{address} ) : () ), | 
| 160 | 3 | 50 |  |  |  | 73 | ( defined $self->{port} ? ( BindPort => $self->{port} ) : ( BindPort => 5667 ) ), | 
|  |  | 50 |  |  |  |  |  | 
| 161 |  |  |  |  |  |  | SuccessEvent   => '_accept_client', | 
| 162 |  |  |  |  |  |  | FailureEvent   => '_accept_failed', | 
| 163 |  |  |  |  |  |  | SocketDomain   => AF_INET,             # Sets the socket() domain | 
| 164 |  |  |  |  |  |  | SocketType     => SOCK_STREAM,         # Sets the socket() type | 
| 165 |  |  |  |  |  |  | SocketProtocol => 'tcp',               # Sets the socket() protocol | 
| 166 |  |  |  |  |  |  | Reuse          => 'on',                # Lets the port be reused | 
| 167 |  |  |  |  |  |  | ); | 
| 168 | 3 |  |  |  |  | 1676 | return; | 
| 169 |  |  |  |  |  |  | } | 
| 170 |  |  |  |  |  |  |  | 
| 171 |  |  |  |  |  |  | sub register { | 
| 172 | 2 |  |  | 2 | 1 | 168 | my ($kernel,$self,$sender) = @_[KERNEL,OBJECT,SENDER]; | 
| 173 | 2 |  |  |  |  | 8 | my $sender_id = $sender->ID(); | 
| 174 | 2 |  |  |  |  | 9 | my %args; | 
| 175 | 2 | 50 |  |  |  | 9 | if ( ref $_[ARG0] eq 'HASH' ) { | 
|  |  | 0 |  |  |  |  |  | 
| 176 | 2 |  |  |  |  | 5 | %args = %{ $_[ARG0] }; | 
|  | 2 |  |  |  |  | 11 |  | 
| 177 |  |  |  |  |  |  | } | 
| 178 |  |  |  |  |  |  | elsif ( ref $_[ARG0] eq 'ARRAY' ) { | 
| 179 | 0 |  |  |  |  | 0 | %args = @{ $_[ARG0] }; | 
|  | 0 |  |  |  |  | 0 |  | 
| 180 |  |  |  |  |  |  | } | 
| 181 |  |  |  |  |  |  | else { | 
| 182 | 0 |  |  |  |  | 0 | %args = @_[ARG0..$#_]; | 
| 183 |  |  |  |  |  |  | } | 
| 184 | 2 |  |  |  |  | 14 | $args{lc $_} = delete $args{$_} for keys %args; | 
| 185 | 2 | 50 |  |  |  | 12 | unless ( $args{event} ) { | 
| 186 | 0 |  |  |  |  | 0 | warn "No 'event' argument supplied\n"; | 
| 187 | 0 |  |  |  |  | 0 | return; | 
| 188 |  |  |  |  |  |  | } | 
| 189 | 2 | 50 |  |  |  | 13 | if ( defined $self->{sessions}->{ $sender_id } ) { | 
| 190 | 0 |  |  |  |  | 0 | $self->{sessions}->{ $sender_id } = \%args; | 
| 191 |  |  |  |  |  |  | } | 
| 192 |  |  |  |  |  |  | else { | 
| 193 | 2 |  |  |  |  | 10 | $self->{sessions}->{ $sender_id } = \%args; | 
| 194 | 2 |  |  |  |  | 44 | $kernel->refcount_increment( $sender_id, __PACKAGE__ ); | 
| 195 |  |  |  |  |  |  | } | 
| 196 | 2 |  |  |  |  | 67 | return; | 
| 197 |  |  |  |  |  |  | } | 
| 198 |  |  |  |  |  |  |  | 
| 199 |  |  |  |  |  |  | sub unregister { | 
| 200 | 0 |  |  | 0 | 1 | 0 | my ($kernel,$self,$sender) = @_[KERNEL,OBJECT,SENDER]; | 
| 201 | 0 |  |  |  |  | 0 | my $sender_id = $sender->ID(); | 
| 202 | 0 |  |  |  |  | 0 | my %args; | 
| 203 | 0 | 0 |  |  |  | 0 | if ( ref $_[ARG0] eq 'HASH' ) { | 
|  |  | 0 |  |  |  |  |  | 
| 204 | 0 |  |  |  |  | 0 | %args = %{ $_[ARG0] }; | 
|  | 0 |  |  |  |  | 0 |  | 
| 205 |  |  |  |  |  |  | } | 
| 206 |  |  |  |  |  |  | elsif ( ref $_[ARG0] eq 'ARRAY' ) { | 
| 207 | 0 |  |  |  |  | 0 | %args = @{ $_[ARG0] }; | 
|  | 0 |  |  |  |  | 0 |  | 
| 208 |  |  |  |  |  |  | } | 
| 209 |  |  |  |  |  |  | else { | 
| 210 | 0 |  |  |  |  | 0 | %args = @_[ARG0..$#_]; | 
| 211 |  |  |  |  |  |  | } | 
| 212 | 0 |  |  |  |  | 0 | $args{lc $_} = delete $args{$_} for keys %args; | 
| 213 | 0 |  |  |  |  | 0 | my $data = delete $self->{sessions}->{ $sender_id }; | 
| 214 | 0 | 0 |  |  |  | 0 | $kernel->refcount_decrement( $sender_id, __PACKAGE__ ) if $data; | 
| 215 | 0 |  |  |  |  | 0 | return; | 
| 216 |  |  |  |  |  |  | } | 
| 217 |  |  |  |  |  |  |  | 
| 218 |  |  |  |  |  |  | sub _shutdown { | 
| 219 | 3 |  |  | 3 |  | 933 | my ($kernel,$self) = @_[KERNEL,OBJECT]; | 
| 220 | 3 |  |  |  |  | 23 | delete $self->{listener}; | 
| 221 | 3 |  |  |  |  | 676 | delete $self->{clients}; | 
| 222 | 3 |  |  |  |  | 8 | $kernel->refcount_decrement( $_, __PACKAGE__ ) for keys %{ $self->{sessions} }; | 
|  | 3 |  |  |  |  | 19 |  | 
| 223 | 3 |  |  |  |  | 121 | $kernel->alarm_remove_all(); | 
| 224 | 3 |  |  |  |  | 134 | $kernel->alias_remove( $_ ) for $kernel->alias_list(); | 
| 225 | 3 | 50 |  |  |  | 116 | $kernel->refcount_decrement( $self->{session_id} => __PACKAGE__ ) unless $self->{alias}; | 
| 226 | 3 |  |  |  |  | 145 | return; | 
| 227 |  |  |  |  |  |  | } | 
| 228 |  |  |  |  |  |  |  | 
| 229 |  |  |  |  |  |  | sub _accept_failed { | 
| 230 | 0 |  |  | 0 |  | 0 | my ($kernel,$self,$operation,$errnum,$errstr,$wheel_id) = @_[KERNEL,OBJECT,ARG0..ARG3]; | 
| 231 | 0 |  |  |  |  | 0 | warn "Listener: $wheel_id generated $operation error $errnum: $errstr\n"; | 
| 232 | 0 |  |  |  |  | 0 | delete $self->{listener}; | 
| 233 | 0 |  |  |  |  | 0 | $kernel->yield( '_shutdown' ); | 
| 234 | 0 |  |  |  |  | 0 | return; | 
| 235 |  |  |  |  |  |  | } | 
| 236 |  |  |  |  |  |  |  | 
| 237 |  |  |  |  |  |  | sub _accept_client { | 
| 238 | 3 |  |  | 3 |  | 4787 | my ($kernel,$self,$socket,$peeraddr,$peerport) = @_[KERNEL,OBJECT,ARG0..ARG2]; | 
| 239 | 3 |  |  |  |  | 52 | my $sockaddr = inet_ntoa( ( unpack_sockaddr_in ( CORE::getsockname $socket ) )[1] ); | 
| 240 | 3 |  |  |  |  | 17 | my $sockport = ( unpack_sockaddr_in ( CORE::getsockname $socket ) )[0]; | 
| 241 | 3 |  |  |  |  | 15 | $peeraddr = inet_ntoa( $peeraddr ); | 
| 242 |  |  |  |  |  |  |  | 
| 243 | 3 | 50 |  |  |  | 6 | return unless grep { $_->match( $peeraddr ) } @{ $self->{access} }; | 
|  | 3 |  |  |  |  | 19 |  | 
|  | 3 |  |  |  |  | 14 |  | 
| 244 |  |  |  |  |  |  |  | 
| 245 |  |  |  |  |  |  | my $wheel = POE::Wheel::ReadWrite->new( | 
| 246 |  |  |  |  |  |  | Handle => $socket, | 
| 247 |  |  |  |  |  |  | Filter => $self->{filter}, | 
| 248 | 3 |  |  |  |  | 262 | InputEvent => '_conn_input', | 
| 249 |  |  |  |  |  |  | ErrorEvent => '_conn_error', | 
| 250 |  |  |  |  |  |  | FlushedEvent => '_conn_flushed', | 
| 251 |  |  |  |  |  |  | ); | 
| 252 |  |  |  |  |  |  |  | 
| 253 | 3 | 50 |  |  |  | 1123 | return unless $wheel; | 
| 254 |  |  |  |  |  |  |  | 
| 255 | 3 |  |  |  |  | 15 | my $id = $wheel->ID(); | 
| 256 | 3 |  |  |  |  | 24 | my $time = time(); | 
| 257 | 3 |  |  |  |  | 37 | my $iv = join '', random_uniform_integer(128,0,9); | 
| 258 | 3 |  |  |  |  | 698 | my $init_packet = $iv . pack 'N', $time; | 
| 259 | 3 |  |  |  |  | 26 | $self->{clients}->{ $id } = | 
| 260 |  |  |  |  |  |  | { | 
| 261 |  |  |  |  |  |  | wheel    => $wheel, | 
| 262 |  |  |  |  |  |  | peeraddr => $peeraddr, | 
| 263 |  |  |  |  |  |  | peerport => $peerport, | 
| 264 |  |  |  |  |  |  | sockaddr => $sockaddr, | 
| 265 |  |  |  |  |  |  | sockport => $sockport, | 
| 266 |  |  |  |  |  |  | ts       => $time, | 
| 267 |  |  |  |  |  |  | iv	 => $iv, | 
| 268 |  |  |  |  |  |  | }; | 
| 269 | 3 |  | 50 |  |  | 24 | $self->{clients}->{ $id }->{alarm} = $kernel->delay_set( '_conn_alarm', $self->{time_out} || 60, $id ); | 
| 270 | 3 |  |  |  |  | 244 | $wheel->put( $init_packet ); | 
| 271 | 3 |  |  |  |  | 266 | return; | 
| 272 |  |  |  |  |  |  | } | 
| 273 |  |  |  |  |  |  |  | 
| 274 |  |  |  |  |  |  | sub _conn_exists { | 
| 275 | 5 |  |  | 5 |  | 15 | my ($self,$wheel_id) = @_; | 
| 276 | 5 | 50 | 33 |  |  | 47 | return 0 unless $wheel_id and defined $self->{clients}->{ $wheel_id }; | 
| 277 | 5 |  |  |  |  | 22 | return 1; | 
| 278 |  |  |  |  |  |  | } | 
| 279 |  |  |  |  |  |  |  | 
| 280 |  |  |  |  |  |  | sub _conn_error { | 
| 281 | 2 |  |  | 2 |  | 1275 | my ($self,$errstr,$id) = @_[OBJECT,ARG2,ARG3]; | 
| 282 | 2 | 50 |  |  |  | 10 | return unless $self->_conn_exists( $id ); | 
| 283 | 2 |  |  |  |  | 13 | delete $self->{clients}->{ $id }; | 
| 284 | 2 |  |  |  |  | 564 | return; | 
| 285 |  |  |  |  |  |  | } | 
| 286 |  |  |  |  |  |  |  | 
| 287 |  |  |  |  |  |  | sub _conn_alarm { | 
| 288 | 1 |  |  | 1 |  | 10010103 | my ($kernel,$self,$id) = @_[KERNEL,OBJECT,ARG0]; | 
| 289 | 1 | 50 |  |  |  | 7 | return unless $self->_conn_exists( $id ); | 
| 290 | 1 |  |  |  |  | 15 | delete $self->{clients}->{ $id }; | 
| 291 | 1 |  |  |  |  | 518 | return; | 
| 292 |  |  |  |  |  |  | } | 
| 293 |  |  |  |  |  |  |  | 
| 294 |  |  |  |  |  |  | sub _conn_input { | 
| 295 | 2 |  |  | 2 |  | 26586 | my ($kernel,$self,$packet,$id) = @_[KERNEL,OBJECT,ARG0,ARG1]; | 
| 296 | 2 | 50 |  |  |  | 10 | return unless $self->_conn_exists( $id ); | 
| 297 | 2 |  |  |  |  | 6 | my $client = $self->{clients}->{ $id }; | 
| 298 | 2 |  |  |  |  | 23 | $kernel->alarm_remove( delete $client->{alarm} ); | 
| 299 | 2 |  |  |  |  | 203 | my $data_packet_length = SIZEOF_DATA_PACKET; | 
| 300 | 2 | 50 |  |  |  | 17 | if ( length( $packet ) == SIZEOF_OLD_PACKET ) { | 
| 301 | 2 |  |  |  |  | 6 | $data_packet_length = SIZEOF_OLD_PACKET; | 
| 302 |  |  |  |  |  |  | } | 
| 303 | 2 |  |  |  |  | 10 | my $input = _decrypt( $packet, $self->{encryption}, $client->{iv}, $self->{password}, $data_packet_length ); | 
| 304 | 2 | 50 |  |  |  | 9 | return unless $input; # something wrong with the decryption | 
| 305 | 2 |  |  |  |  | 13 | my $version = unpack 'n', substr $input, 0, 4; | 
| 306 | 2 | 0 | 33 |  |  | 13 | return unless $version == 3 or $client->{version_already_checked}; # Wrong version received | 
| 307 | 2 |  |  |  |  | 7 | $client->{version_already_checked} = 1; | 
| 308 | 2 |  |  |  |  | 7 | my $crc32 = unpack 'N', substr $input, 4, 4; | 
| 309 | 2 |  |  |  |  | 5 | my $ts = unpack 'N', substr $input, 8, 4; | 
| 310 | 2 |  |  |  |  | 6 | my $rc = unpack 'n', substr $input, 12, 2; | 
| 311 | 2 |  |  |  |  | 6 | my $firstbit = substr $input, 0, 4; | 
| 312 | 2 |  |  |  |  | 5 | my $secondbit = substr $input, 8; | 
| 313 | 2 |  |  |  |  | 9 | my $checksum = _calculate_crc32( $firstbit . pack('N', 0) . $secondbit ); | 
| 314 | 2 |  |  |  |  | 23 | my @data = unpack 'a[64]a[128]a[512]', substr $input, 14; | 
| 315 | 2 |  |  |  |  | 38 | s/\000.*$// for @data; | 
| 316 | 2 |  |  |  |  | 18 | my $result = { | 
| 317 |  |  |  |  |  |  | version      => $version, | 
| 318 |  |  |  |  |  |  | crc32        => $crc32, | 
| 319 |  |  |  |  |  |  | checksum     => $checksum, | 
| 320 |  |  |  |  |  |  | return_code  => $rc, | 
| 321 |  |  |  |  |  |  | timestamp    => $ts, | 
| 322 |  |  |  |  |  |  | }; | 
| 323 | 2 |  |  |  |  | 20 | $result->{$_} = shift @data for qw(host_name svc_description plugin_output); | 
| 324 | 2 |  |  |  |  | 19 | $result->{$_} = $client->{$_} for qw(peeraddr peerport sockaddr sockport ts iv); | 
| 325 |  |  |  |  |  |  | $kernel->post( $_, $self->{sessions}->{$_}->{event}, $result, $self->{sessions}->{$_}->{context} ) | 
| 326 | 2 |  |  |  |  | 13 | for keys %{ $self->{sessions} }; | 
|  | 2 |  |  |  |  | 51 |  | 
| 327 | 2 |  |  |  |  | 311 | return; | 
| 328 |  |  |  |  |  |  | } | 
| 329 |  |  |  |  |  |  |  | 
| 330 |  |  |  |  |  |  | #/* calculates the CRC 32 value for a buffer */ | 
| 331 |  |  |  |  |  |  | sub _calculate_crc32 { | 
| 332 | 2 |  |  | 2 |  | 6 | my $string = shift; | 
| 333 |  |  |  |  |  |  |  | 
| 334 | 2 |  |  |  |  | 6 | my $crc32_table = _generate_crc32_table(); | 
| 335 | 2 |  |  |  |  | 6 | my $crc = 0xFFFFFFFF; | 
| 336 |  |  |  |  |  |  |  | 
| 337 | 2 |  |  |  |  | 130 | foreach my $tchar (split(//, $string)) { | 
| 338 | 1440 |  |  |  |  | 1982 | my $char = ord($tchar); | 
| 339 | 1440 |  |  |  |  | 2377 | $crc = (($crc >> 8) & 0x00FFFFFF) ^ $crc32_table->[($crc ^ $char) & 0xFF]; | 
| 340 |  |  |  |  |  |  | } | 
| 341 |  |  |  |  |  |  |  | 
| 342 | 2 |  |  |  |  | 63 | return ($crc ^ 0xFFFFFFFF); | 
| 343 |  |  |  |  |  |  | } | 
| 344 |  |  |  |  |  |  |  | 
| 345 |  |  |  |  |  |  | #/* build the crc table - must be called before calculating the crc value */ | 
| 346 |  |  |  |  |  |  | sub _generate_crc32_table { | 
| 347 | 2 |  |  | 2 |  | 5 | my $crc32_table = []; | 
| 348 | 2 |  |  |  |  | 5 | my $poly = 0xEDB88320; | 
| 349 |  |  |  |  |  |  |  | 
| 350 | 2 |  |  |  |  | 11 | for (my $i = 0; $i < 256; $i++){ | 
| 351 | 512 |  |  |  |  | 707 | my $crc = $i; | 
| 352 | 512 |  |  |  |  | 997 | for (my $j = 8; $j > 0; $j--) { | 
| 353 | 4096 | 100 |  |  |  | 6748 | if ($crc & 1) { | 
| 354 | 2048 |  |  |  |  | 4189 | $crc = ($crc >> 1) ^ $poly; | 
| 355 |  |  |  |  |  |  | } | 
| 356 |  |  |  |  |  |  | else { | 
| 357 | 2048 |  |  |  |  | 4032 | $crc = ($crc >> 1); | 
| 358 |  |  |  |  |  |  | } | 
| 359 |  |  |  |  |  |  | } | 
| 360 | 512 |  |  |  |  | 1067 | $crc32_table->[$i] = $crc; | 
| 361 |  |  |  |  |  |  | } | 
| 362 | 2 |  |  |  |  | 9 | return $crc32_table; | 
| 363 |  |  |  |  |  |  | } | 
| 364 |  |  |  |  |  |  |  | 
| 365 |  |  |  |  |  |  | # central switchboard for encryption methods. | 
| 366 |  |  |  |  |  |  | sub _decrypt { | 
| 367 | 2 |  |  | 2 |  | 9 | my ($data_packet_string, $encryption_method, $iv_salt, $password, $data_packet_length) = @_; | 
| 368 |  |  |  |  |  |  |  | 
| 369 | 2 |  |  |  |  | 5 | my $crypted; | 
| 370 | 2 | 100 |  |  |  | 12 | if ($encryption_method == ENCRYPT_NONE) { | 
|  |  | 50 |  |  |  |  |  | 
| 371 | 1 |  |  |  |  | 2 | $crypted = $data_packet_string; | 
| 372 |  |  |  |  |  |  | } | 
| 373 |  |  |  |  |  |  | elsif ($encryption_method == ENCRYPT_XOR) { | 
| 374 | 1 |  |  |  |  | 4 | $crypted = _decrypt_xor($data_packet_string, $iv_salt, $password, $data_packet_length); | 
| 375 |  |  |  |  |  |  | } | 
| 376 |  |  |  |  |  |  | else { | 
| 377 | 0 |  |  |  |  | 0 | $crypted = _decrypt_mcrypt( $data_packet_string, $encryption_method, $iv_salt, $password ); | 
| 378 |  |  |  |  |  |  | } | 
| 379 | 2 |  |  |  |  | 8 | return $crypted; | 
| 380 |  |  |  |  |  |  | } | 
| 381 |  |  |  |  |  |  |  | 
| 382 |  |  |  |  |  |  | sub _decrypt_xor { | 
| 383 | 1 |  |  | 1 |  | 4 | my ($data_packet_string, $iv_salt, $password, $data_packet_length) = @_; | 
| 384 |  |  |  |  |  |  |  | 
| 385 | 1 |  |  |  |  | 66 | my @out = split(//, $data_packet_string); | 
| 386 | 1 |  |  |  |  | 19 | my @salt_iv = split(//, $iv_salt); | 
| 387 | 1 |  |  |  |  | 4 | my @salt_pw = split(//, $password); | 
| 388 |  |  |  |  |  |  |  | 
| 389 | 1 |  |  |  |  | 2 | my $y = 0; | 
| 390 | 1 |  |  |  |  | 3 | my $x = 0; | 
| 391 |  |  |  |  |  |  |  | 
| 392 |  |  |  |  |  |  | #/* rotate over IV we received from the server... */ | 
| 393 | 1 |  |  |  |  | 4 | while ($y < $data_packet_length) { | 
| 394 |  |  |  |  |  |  | #/* keep rotating over IV */ | 
| 395 | 720 |  |  |  |  | 1133 | $out[$y] = $out[$y] ^ $salt_iv[$x % scalar(@salt_iv)]; | 
| 396 |  |  |  |  |  |  |  | 
| 397 | 720 |  |  |  |  | 963 | $y++; | 
| 398 | 720 |  |  |  |  | 1343 | $x++; | 
| 399 |  |  |  |  |  |  | } | 
| 400 |  |  |  |  |  |  |  | 
| 401 |  |  |  |  |  |  | #/* rotate over password... */ | 
| 402 | 1 |  |  |  |  | 3 | $y=0; | 
| 403 | 1 |  |  |  |  | 3 | $x=0; | 
| 404 | 1 |  |  |  |  | 5 | while ($y < $data_packet_length){ | 
| 405 |  |  |  |  |  |  | #/* keep rotating over password */ | 
| 406 | 720 |  |  |  |  | 1108 | $out[$y] = $out[$y] ^ $salt_pw[$x % scalar(@salt_pw)]; | 
| 407 |  |  |  |  |  |  |  | 
| 408 | 720 |  |  |  |  | 976 | $y++; | 
| 409 | 720 |  |  |  |  | 1342 | $x++; | 
| 410 |  |  |  |  |  |  | } | 
| 411 | 1 |  |  |  |  | 57 | return join '', @out; | 
| 412 |  |  |  |  |  |  | } | 
| 413 |  |  |  |  |  |  |  | 
| 414 |  |  |  |  |  |  | sub _decrypt_mcrypt { | 
| 415 | 0 |  |  | 0 |  |  | my ( $data_packet_string, $encryption_method, $iv_salt, $password ) = @_; | 
| 416 | 0 |  |  |  |  |  | my $crypted; | 
| 417 | 0 |  |  |  |  |  | my $evalok = 0; | 
| 418 | 0 | 0 |  |  |  |  | if( $HAVE_MCRYPT ){ | 
| 419 |  |  |  |  |  |  | # Initialise the routine | 
| 420 | 0 | 0 |  |  |  |  | if( defined( $mcrypts{$encryption_method} ) ){ | 
| 421 |  |  |  |  |  |  | # Load the routine. | 
| 422 | 0 |  |  |  |  |  | my $routine = $mcrypts{$encryption_method}; | 
| 423 | 0 |  |  |  |  |  | eval { | 
| 424 |  |  |  |  |  |  | # This sometimes dies with 'mcrypt is not of type MCRYPT'. | 
| 425 | 0 |  |  |  |  |  | my $td = Mcrypt->new( algorithm => &{\&{"Mcrypt::".$routine}}(), mode => Mcrypt::CFB(), verbose => 0 ); | 
|  | 0 |  |  |  |  |  |  | 
|  | 0 |  |  |  |  |  |  | 
| 426 | 0 |  |  |  |  |  | my $key = $password; | 
| 427 | 0 |  |  |  |  |  | my $iv = substr $iv_salt, 0, $td->{IV_SIZE}; | 
| 428 | 0 | 0 |  |  |  |  | if( defined( $td ) ){ | 
| 429 | 0 |  |  |  |  |  | $td->init($key, $iv); | 
| 430 | 0 |  |  |  |  |  | for (my $i = 0; $i < length( $data_packet_string ); $i++ ) { | 
| 431 | 0 |  |  |  |  |  | $crypted .= $td->decrypt( substr $data_packet_string, 0+$i, 1 ); | 
| 432 |  |  |  |  |  |  | } | 
| 433 | 0 |  |  |  |  |  | $td->end(); | 
| 434 |  |  |  |  |  |  | } | 
| 435 | 0 |  |  |  |  |  | $evalok++; | 
| 436 |  |  |  |  |  |  | }; | 
| 437 | 0 | 0 |  |  |  |  | warn "$@\n" if $@; | 
| 438 |  |  |  |  |  |  | } | 
| 439 |  |  |  |  |  |  | } else { | 
| 440 | 0 |  |  |  |  |  | warn "Mcrypt module missing\n"; | 
| 441 |  |  |  |  |  |  | } | 
| 442 | 0 |  |  |  |  |  | return $crypted; | 
| 443 |  |  |  |  |  |  | } | 
| 444 |  |  |  |  |  |  |  | 
| 445 |  |  |  |  |  |  | 'Hon beiriant goes at hun ar ddeg'; | 
| 446 |  |  |  |  |  |  |  | 
| 447 |  |  |  |  |  |  | __END__ |