File Coverage

blib/lib/XAS/Lib/SSH/Server.pm
Criterion Covered Total %
statement 12 96 12.5
branch 0 6 0.0
condition n/a
subroutine 4 19 21.0
pod 7 7 100.0
total 23 128 17.9


line stmt bran cond sub pod time code
1             package XAS::Lib::SSH::Server;
2              
3             our $VERSION = '0.01';
4              
5 1     1   609 use POE;
  1         2  
  1         6  
6 1     1   237 use POE::Filter::Line;
  1         2  
  1         15  
7 1     1   3 use POE::Wheel::ReadWrite;
  1         1  
  1         49  
8              
9             use XAS::Class
10 1         12 debug => 0,
11             version => $VERSION,
12             base => 'XAS::Lib::POE::Session',
13             accessors => 'client peerhost peerport',
14             utils => ':validation trim',
15             vars => {
16             PARAMS => {
17             -filter => { optional => 1, default => undef },
18             -eol => { optional => 1, default => "\015\012" },
19             }
20             }
21 1     1   4 ;
  1         1  
22              
23             #use Data::Dumper;
24              
25             # ----------------------------------------------------------------------
26             # Public Methods
27             # ----------------------------------------------------------------------
28              
29             sub session_initialize {
30 0     0 1   my $self = shift;
31              
32 0           my $alias = $self->alias;
33              
34 0           $self->log->debug("$alias: entering session_initialize()");
35              
36             # public events
37              
38             # private events
39              
40 0           $poe_kernel->state('client_error', $self, '_client_error');
41 0           $poe_kernel->state('client_input', $self, '_client_input');
42 0           $poe_kernel->state('client_output', $self, '_client_output');
43 0           $poe_kernel->state('client_connection', $self, '_client_connection');
44              
45 0           $poe_kernel->state('process_errors', $self, '_process_errors');
46 0           $poe_kernel->state('process_request', $self, '_process_request');
47 0           $poe_kernel->state('process_response', $self, '_process_response');
48 0           $poe_kernel->state('handle_connection', $self, '_handle_connection');
49              
50             # Find the remote host and port.
51              
52 0           my ($rhost, $rport, $lhost, $lport) = split(' ', $ENV{'SSH_CONNECTION'});
53              
54 0           $self->{'peerhost'} = $rhost;
55 0           $self->{'peerport'} = $rport;
56              
57             # walk the chain
58              
59 0           $self->SUPER::session_initialize();
60              
61 0           $self->log->debug("$alias: leaving session_initialize()");
62              
63             }
64              
65             sub session_startup {
66 0     0 1   my $self = shift;
67              
68 0           my $alias = $self->alias;
69              
70             # start listening for connections
71              
72 0           $self->log->debug("$alias: entering session_startup()");
73              
74 0           $poe_kernel->post($alias, 'client_connection');
75              
76             # walk the chain
77              
78 0           $self->SUPER::session_startup();
79              
80 0           $self->log->debug("$alias: leaving session_startup()");
81              
82             }
83              
84             sub process_request {
85 0     0 1   my $self = shift;
86 0           my ($input, $ctx) = validate_params(\@_, [1,1]);
87              
88 0           return $input;
89              
90             }
91              
92             sub process_response {
93 0     0 1   my $self = shift;
94 0           my ($output, $ctx) = validate_params(\@_, [1,1]);
95              
96 0           return $output;
97              
98             }
99              
100             sub process_errors {
101 0     0 1   my $self = shift;
102 0           my ($output, $ctx) = validate_params(\@_, [1,1]);
103              
104 0           return $output;
105              
106             }
107              
108             sub handle_connection {
109 0     0 1   my $self = shift;
110 0           my ($wheel) = validate_params(\@_, [1]);
111              
112             }
113              
114             # ----------------------------------------------------------------------
115             # Public Events
116             # ----------------------------------------------------------------------
117              
118             # ----------------------------------------------------------------------
119             # Private Events
120             # ----------------------------------------------------------------------
121              
122             sub _process_request {
123 0     0     my ($self, $input, $ctx) = @_[OBJECT,ARG0,ARG1];
124              
125 0           my $alias = $self->alias;
126 0           my $data = $self->process_request($input, $ctx);
127              
128 0           $self->log->debug("$alias: process_request()");
129 0           $poe_kernel->post($alias, 'process_response', $data, $ctx);
130              
131             }
132              
133             sub _process_response {
134 0     0     my ($self, $output, $ctx) = @_[OBJECT,ARG0,ARG1];
135              
136 0           my $alias = $self->alias;
137 0           my $data = $self->process_response($output, $ctx);
138              
139 0           $self->log->debug("$alias: process_response()");
140 0           $poe_kernel->post($alias, 'client_output', $data, $ctx);
141              
142             }
143              
144             sub _process_errors {
145 0     0     my ($self, $output, $ctx) = @_[OBJECT,ARG0,ARG1];
146              
147 0           my $alias = $self->alias;
148 0           my $data = $self->process_errors($output, $ctx);
149              
150 0           $self->log->debug("$alias: process_errors()");
151 0           $poe_kernel->post($alias, 'client_output', $data, $ctx);
152              
153             }
154              
155             sub _handle_connection {
156 0     0     my ($self, $wheel) = @_[OBJECT,ARG0];
157            
158 0           my $alias = $self->alias;
159              
160 0           $self->log->debug("$alias: handle_connection()");
161 0           $self->handle_connection($wheel);
162              
163             }
164              
165             sub _client_connection {
166 0     0     my ($self) = $_[OBJECT];
167              
168 0           my $alias = $self->alias;
169              
170 0           $self->log->debug("$alias: _client_connection()");
171              
172             # Start listening on stdin.
173              
174 0           $self->{'client'} = POE::Wheel::ReadWrite->new(
175             InputHandle => \*STDIN,
176             OutputHandle => \*STDOUT,
177             Filter => $self->filter,
178             InputEvent => 'client_input',
179             ErrorEvent => 'client_error'
180             );
181              
182 0           $poe_kernel->post($alias, 'handle_connection', $self->client->ID);
183              
184             }
185              
186             sub _client_input {
187 0     0     my ($self, $input, $wheel) = @_[OBJECT,ARG0,ARG1];
188              
189 0           my $alias = $self->alias;
190 0           my $ctx = {
191             wheel => $wheel
192             };
193              
194 0           $self->log->debug("$alias: _client_input()");
195              
196 0           $poe_kernel->post($alias, 'process_request', $input, $ctx);
197              
198             }
199              
200             sub _client_output {
201 0     0     my ($self, $output, $ctx) = @_[OBJECT,ARG0,ARG1];
202              
203 0           my @buffer;
204 0           my $alias = $self->alias;
205              
206 0           $self->log->debug("$alias: _client_output()");
207              
208 0 0         if (my $wheel = $self->client) {
209              
210 0           push(@buffer, $output);
211 0           $wheel->put(@buffer);
212              
213             } else {
214              
215 0           $self->log->error_msg('net_server_nowheel', $alias);
216              
217             }
218              
219             }
220              
221             sub _client_error {
222 0     0     my ($self, $syscall, $errnum, $errstr, $wheel) = @_[OBJECT,ARG0 .. ARG3];
223              
224 0           my $alias = $self->alias;
225              
226 0           $self->log->debug("$alias: _client_error()");
227 0           $self->log->debug(sprintf("%s: syscall: %s, errnum: %s, errstr: %s", $alias, $syscall, $errnum, $errstr));
228              
229 0 0         if ($errnum == 0) {
230              
231             # EOF detected.
232              
233 0           $self->log->info_msg('net_server_disconnect', $alias, $self->peerhost, $self->peerport);
234              
235 0           delete $self->{'client'};
236 0           $poe_kernel->post($alias, 'session_shutdown');
237              
238             } else {
239              
240 0           $self->log->error_msg('net_server_error', $alias, $errnum, $errstr);
241              
242             }
243              
244             }
245              
246             # ----------------------------------------------------------------------
247             # Private Methods
248             # ----------------------------------------------------------------------
249              
250             sub init {
251 0     0 1   my $class = shift;
252              
253 0           my $self = $class->SUPER::init(@_);
254              
255 0 0         unless (defined($self->filter)) {
256              
257 0           $self->{'filter'} = POE::Filter::Line->new(
258             InputLiteral => $self->eol,
259             OutputLiteral => $self->eol
260             );
261              
262             }
263              
264 0           return $self;
265              
266             }
267              
268             1;
269              
270             __END__