File Coverage

blib/lib/NET/MitM.pm
Criterion Covered Total %
statement 280 315 88.8
branch 110 170 64.7
condition 23 34 67.6
subroutine 41 45 91.1
pod 24 24 100.0
total 478 588 81.2


line stmt bran cond sub pod time code
1             package NET::MitM;
2              
3             =head1 NAME
4              
5             NET::MitM - Man in the Middle - connects a client and a server, giving visibility of and control over messages passed.
6              
7             =head1 VERSION
8              
9             Version 0.02
10              
11             =cut
12              
13             our $VERSION = '0.02';
14              
15             =head1 SYNOPSIS
16              
17             NET::MitM is designed to be inserted between a client and a server. It proxies all traffic through verbatum, and also copies that same data to a log file and/or a callback function, allowing a data session to be monitored, recorded, even altered on the fly.
18              
19             MitM acts as a 'man in the middle', sitting between the client and server. To the client, MitM looks like the server. To the server, MitM looks like the client.
20              
21             MitM cannot be used to covertly operate on unsuspecting client/server sessions - it requires that you control either the client or the server. If you control the client, you can tell it to connect via your MitM. If you control the server, you can move it to a different port, and put a MitM in its place.
22              
23             When started, MitM opens a socket and listens for connections. When that socket is connected to, MitM opens another connection to the server. Messages from either client or server are passed to the other, and a copy of each message is, potentially, logged. Alternately, callback methods may be used to add business logic, including potentially altering the messages being passed.
24              
25             MitM can also be used as a proxy to allow two processes on machines that cannot 'see' each other to communicate via an intermediary machine that is visible to both.
26              
27             There is an (as yet unreleased) sister module L that allows a MitM session to be replayed.
28              
29             =head3 Usage
30              
31             Assume the following script is running on the local machine:
32              
33             use NET::MitM;
34             my $MitM = NET::MitM->new("cpan.org", 80, 10080);
35             $MitM->log_file("MitM.log");
36             $MitM->go();
37              
38             A browser connecting to L will now cause MitM to open a connection to cpan.org, and messages sent by either end will be passed to the other end, and logged to MitM.log.
39              
40             For another example, see samples/mitm.pl in the MitM distribution.
41              
42             =head3 Modifying messages on the fly.
43              
44             However you deploy MitM, it will be virtually identical to having the client and server talk directly. The difference will be that either the client and/or server will be at an address other than the one its counterpart believes it to be at. Most programs ignore this, but sometimes it matters.
45              
46             For example, HTTP browsers pass a number of parameters, one of which is "Host", the host to which the browser believes it is connecting. Often, this parameter is unused. But sometimes, a single HTTP server will be serving content for more than one website. Such a server generally relies on the Host parameter to know what it is to return. If the MitM is not on the same host as the HTTP server, the host parameter that the browser passes will cause the HTTP server to fail to serve the desired pages.
47              
48             Further, HTTP servers typically return URLs containing the host address. If the browser navigates to a returned URL, it will from that point onwards connect directly to the server in the URL instead of communicating via MitM.
49              
50             Both of these problems can be worked around by modifying the messages being passed.
51              
52             For example, assume the following script is running on the local machine:
53              
54             use NET::MitM;
55             sub send_($) {$_[0] =~ s/Host: .*:\d+/Host: cpan.org/;}
56             sub receive($) {$_[0] =~ s/cpan.org:\d+/localhost:10080/g;}
57             my $MitM = NET::MitM->new("cpan.org", 80, 10080);
58             $MitM->client_to_server_callback(\&send);
59             $MitM->server_to_client_callback(\&receive);
60             $MitM->log_file("http_MitM.log");
61             $MitM->go();
62              
63             The send callback tells the server that it is to serve cpan.org pages, instead of some other set of pages, while the receive callback tells the browser to access cpan.org URLs via the MitM process, not directly. The HTTP server will now respond properly, even though the browser sent the wrong hostname, and the browser will now behave as desired and direct future requests via the MitM.
64              
65             For another example, see samples/http_mitm.pl in the MitM distribution.
66              
67             A more difficult problem is security aware processes, such as those that use HTTPS based protocols. They are actively hostname aware. Precisely to defend against a man-in-the-middle attack, they check their counterpart's reported hostname (but not normally the port) against the actual hostname. Unless client, server and MitM are all on the same host, either the client or the server will notice that the remote hostname is not what it should be, and will abort the connection.
68             There is no good workaround for this, unless you can run an instance of MitM on the server, and another on the client - but even if you do, you still have to deal with the communication being encrypted.
69              
70             =head1 SUBROUTINES/METHODS
71              
72             =cut
73              
74             # #######
75             # Globals
76             # #######
77              
78 8     8   220085 use 5.002;
  8         39  
  8         388  
79 8     8   47 use warnings FATAL => 'all';
  8         16  
  8         363  
80 8     8   9905 use Socket;
  8         38991  
  8         5449  
81 8     8   8250 use FileHandle;
  8         139412  
  8         84  
82 8     8   3301 use IO::Handle;
  8         66  
  8         253  
83 8     8   41 use Carp;
  8         16  
  8         532  
84 8     8   54 use strict;
  8         10  
  8         346  
85 8     8   13448 eval {use Time::HiRes qw(time)}; # only needed for high precision time_interval - will still work fine even if missing
  8         18449  
  8         39  
86              
87             my $protocol = getprotobyname('tcp'); # TODO: make dynamic?
88              
89             =head2 new( remote_ip_address, local_port_num, remote_port_num )
90              
91             Creates a new MitM
92              
93             =head4 Parameters
94              
95             =over
96              
97             =item * remote_ip_address - the remote hostname/IP address of the server
98              
99             =item * remote_port_num - the remote port number of the server
100              
101             =item * local_port_num - the port number to listen on
102              
103             =item * Returns - a new MitM object
104              
105             =back
106              
107             =head4 Usage
108              
109             To keep a record of all messages sent:
110              
111             use NET::MitM;
112             my $MitM = NET::MitM->new("www.cpan.org", 80, 10080);
113             $MitM->log_file("MitM.log");
114             $MitM->go();
115              
116             =cut
117              
118             sub hhmmss();
119              
120             my $mitm_count=0;
121              
122             sub _new(){
123 111     111   248 my %this;
124 111         704 $this{verbose} = 1;
125 111         326 $this{parallel} = 0;
126 111         419 $this{mydate} = \&hhmmss;
127 111         938 $this{name} = "MitM".++$mitm_count;
128 111         470 return \%this;
129             }
130              
131             sub new($$;$$$) {
132 7     7 1 570032 my $class=shift;
133 7         804 my $this=_new();
134 7 50       20794 $this->{remote_ip_address} = shift or croak "remote hostname/ip address missing";
135 7 50       553 $this->{remote_port_num} = shift or croak "remote port number missing";
136 7   33     124 $this->{local_port_num} = shift || $this->{remote_port_num};
137 7         156 return bless($this, $class);
138             }
139              
140             =head2 go( )
141              
142             Listen on local_port, accept incoming connections, and forwards messages back and forth.
143              
144             =head4 Parameters
145              
146             =over
147              
148             =item * --none--
149              
150             =item * Returns --none--
151              
152             =back
153              
154             =head4 Usage
155              
156             When a connection on local_port is received a connect to remote_ip_address:remote_port is created and messages from the client are passed to the server and vice-versa.
157              
158             If parallel() was set, which is not the default, there will be a new process created for each such session.
159              
160             If any callback functions have been set, they will be called before each message is passed.
161             If logging is on, messages will be logged.
162              
163             go() does not return. You may want to L before calling it. There is no way to stop it from outside except using a signal to interrupt it. This will probably change in a future release of MitM.
164              
165             If new_server() was used instead of new(), messages from client are instead passed to the server callback function.
166              
167             =cut
168              
169             # Convenience function - intentionally not exposed. If you really want to call it, you can of course. But if you are going to violate encapsulation, why not go directly to the variables?
170              
171             sub _set($;$) {
172 125     125   215 my $this=shift;
173 125 50       711 my $key=shift or confess "missing mandatory parameter";
174 125         207 my $value=shift;
175 125 100       434 if(defined $value){
176 112         304 $this->{$key} = $value;
177             }
178 125         365 return $this->{$key};
179             }
180              
181             =head2 name( [name] )
182              
183             Names the object - will be reported back in logging/debug
184              
185             =head4 Parameters
186              
187             =over
188              
189             =item * name - the new name (default is MitM1, MitM2, ...)
190              
191             =item * Returns - the current or new setting
192              
193             =back
194              
195             =head4 Usage
196              
197             For a minimal MitM:
198              
199             use NET::MitM;
200             my $MitM = NET::MitM->new("www.cpan.org", 80, 10080);
201             $MitM->go();
202              
203             =cut
204              
205             sub name(;$) {
206 97     97 1 793 my $this=shift;
207 97         3733 my $value=shift;
208 97         317 return $this->_set("name", $value);
209             }
210              
211             =head2 verbose( [level] )
212              
213             Turns on/off reporting to stdout.
214              
215             =head4 Parameters
216              
217             =over
218              
219             =item * level - how verbose to be. 0=nothing, 1=normal, 2=debug. The default is 1.
220              
221             =item * Returns - the current or new setting
222              
223             =back
224              
225             =head4 Usage
226              
227             Setting verbose changes the amount of information printed to stdout.
228              
229             =cut
230              
231             sub verbose(;$) {
232 1     1 1 8 my $this=shift;
233 1         3 my $verbose=shift;
234             #warn "verbose->(",$verbose||"--undef--",")\n";
235 1         5 return $this->_set("verbose", $verbose);
236             }
237              
238             =head2 client_to_server_callback( callback )
239              
240             Set a callback function to monitor/modify each message sent to server
241              
242             =head4 Parameters
243              
244             =over
245              
246             =item * callback - a reference to a function to be called for each message sent to server
247              
248             =item * Returns - the current or new setting
249              
250             =back
251              
252             =head4 Usage
253              
254             If client_to_server_callback is set, it will be called with a copy of each message to the server before it is sent. Whatever the callback returns will be sent.
255              
256             For example, to modify messages:
257              
258             use NET::MitM;
259             sub send_($) {$_[0] =~ s/Host: .*:\d+/Host: cpan.org/;}
260             sub receive($) {$_[0] =~ s/www.cpan.org(:\d+)?/localhost:10080/g;}
261             my $MitM = NET::MitM->new("www.cpan.org", 80, 10080);
262             $MitM->client_to_server_callback(\&send);
263             $MitM->server_to_client_callback(\&receive);
264             $MitM->go();
265              
266             If the callback is readonly, it should either return a copy of the original message, or undef. Be careful not to accidentally return something else - remember that perl methods implicitly returns the value of the last command executed.
267              
268             For example, to write messages to a log:
269              
270             sub peek($) {my $msg = shift; print LOG; return $msg;}
271             my $MitM = NET::MitM->new("www.cpan.org", 80, 10080);
272             $MitM->client_to_server_callback(\&peek);
273             $MitM->server_to_client_callback(\&peek);
274             $MitM->go();
275              
276             This would also work:
277             sub peek($) {my $msg = shift; print LOG; return undef;}
278             ...
279              
280             But this is unlikely to do what you would want:
281             sub peek($) {my $msg = shift; print LOG}
282             ...
283              
284             =cut
285              
286             sub client_to_server_callback(;$) {
287 4     4 1 114 my $this=shift;
288 4         23 my $callback=shift;
289 4         99 return $this->_set("client_to_server_callback", $callback);
290             }
291              
292             =head2 server_to_client_callback( [callback] )
293              
294             Set a callback function to monitor/modify each message received from server
295              
296             =head4 Parameters
297              
298             =over
299              
300             =item * callback - a reference to a function to be called for each inward message
301              
302             =item * Returns - the current or new setting
303              
304             =back
305              
306             =head4 Usage
307              
308             If server_to_client_callback is set, it will be called with a copy of each message received from the server before it is sent to the client. Whatever the callback returns will be sent.
309              
310             If the callback is readonly, it should either return a copy of the original message, or undef. Be careful not to accidentally return something else - remember that perl methods implicitly returns the value of the last command executed.
311              
312             =cut
313              
314             sub server_to_client_callback(;$) {
315 5     5 1 56 my $this=shift;
316 5         56 my $callback=shift;
317 5         64 return $this->_set("server_to_client_callback", $callback);
318             }
319              
320             =head2 timer_callback( [interval, callback] )
321              
322             Set a callback function to be called at regular intervals
323              
324             =head4 Parameters
325              
326             =over
327              
328             =item * interval - how often the callback function is to be called - must be > 0 seconds, may be fractional
329             =item * callback - a reference to a function to be called every interval seconds
330              
331             =item * Returns - the current or new setting, as an array
332              
333             =back
334              
335             =head4 Usage
336              
337             If the callback is set, it will be called every interval seconds. Interval must be > 0 seconds. It may be fractional. If interval is passed as 0 it will be reset to 1 second. This is to prevent accidental spin-wait. If you really want to spin-wait, pass an extremely small but non-zero interval.
338              
339             If the callback returns false, mainloop will exit and return control to the caller.
340              
341             The time spent in callbacks is not additional to the specified interval - the timer callback will be called every interval seconds, or as close as possible to every interval seconds.
342              
343             Please remember that if you have called fork before calling go() that the timer_callback method will be executed in a different process to the parent - the two processes will need to use some form of L to communicate.
344              
345             =cut
346              
347             sub timer_callback(;$) {
348 8     8 1 5707 my $this=shift;
349 8         15 my $interval=shift;
350 8         12 my $callback=shift;
351 8 100 100     56 if(defined $interval && $interval==0){
352 1         8 $interval=1;
353             }
354 8         26 $interval=$this->_set("timer_interval", $interval);
355 8         25 $callback=$this->_set("timer_callback", $callback);
356 8         22 return ($interval, $callback);
357             }
358              
359             =head2 parallel( [level] )
360              
361             Turns on/off running in parallel.
362              
363             =head4 Parameters
364              
365             =over
366              
367             =item * level - 0=serial, 1=parallel. Default is 0 (run in serial).
368              
369             =item * Returns - the current or new setting
370              
371             =back
372              
373             =head4 Usage
374              
375             If running in parallel, MitM starts a new process for each new connection using L.
376              
377             Running in serial still allows multiple clients to run concurrently, as so long as none of them have long-running callbacks. If they do, they will block other clients from sending/recieving.
378              
379             =cut
380              
381             sub parallel(;$) {
382 2     2 1 16 my $this=shift;
383 2         4 my $parallel=shift;
384 2 50       26 if($parallel){
385 2         90 $SIG{CLD} = "IGNORE";
386             }
387 2         8 return $this->_set("parallel", $parallel);
388             }
389              
390             =head2 serial( [level] )
391              
392             Turns on/off running in serial
393              
394             =head4 Parameters
395              
396             =over
397              
398             =item * level - 0=parallel, 1=serial. Default is 1, i.e. run in serial.
399              
400             =item * Returns - the current or new setting
401              
402             =back
403              
404             =head4 Usage
405              
406             Calling this function with level=$l is exactly equivalent to calling parallel with level=!$l.
407              
408             If running in parallel, MitM starts a new process for each new connection using L.
409              
410             Running in serial, which is the default, still allows multiple clients to run concurrently, as so long as none of them have long-running callbacks. If they do, they will block other clients from sending/recieving.
411              
412             =cut
413              
414             sub serial(;$) {
415 0     0 1 0 my $this=shift;
416 0         0 my $level=shift;
417 0 0       0 my $parallel = $this->parallel(defined $level ? ! $level : undef);
418 0 0       0 return $parallel ? 0 : 1;
419             }
420              
421             =head2 log_file( [log_file_name] ] )
422              
423             log_file() sets, or clears, a log file.
424              
425             =head4 Parameters
426              
427             =over
428              
429             =item * log_file_name - the name of the log file to be appended to. Passing "" disables logging. Passing nothing, or undef, returns the current log filename without change.
430              
431             =item * Returns - log file name
432              
433             =back
434              
435             =head4 Usage
436              
437             The log file contains a record of connects and disconnects and messages as sent back and forwards. Log entries are timestamped. If the log file already exists, it is appended to.
438              
439             The default timestamp is "hh:mm:ss", eg 19:49:43 - see mydate() and hhmmss().
440              
441             =cut
442              
443             sub log_file(;$) {
444 1     1 1 56 my $this=shift;
445 1         22 my $new_log_file=shift;
446 1 50       31 if(defined $new_log_file){
447 1 50       43 if(!$new_log_file){
448 0 0       0 if($this->{LOGFILE}){
449 0         0 close($this->{LOGFILE});
450 0         0 $this->{log_file}=$this->{LOGFILE}=undef;
451 0 0       0 print "Logging turned off\n" if $this->{verbose};
452             }
453             }else{
454 1         11 my $LOGFILE;
455 1 50       1690 if( open($LOGFILE, ">>$new_log_file") ) {
456 1         1138 binmode($LOGFILE);
457 1         375 $LOGFILE->autoflush(1); # TODO make this configurable?
458 1         550 $this->{log_file}=$new_log_file;
459 1         17 $this->{LOGFILE}=$LOGFILE;
460             }
461             else {
462 0 0       0 print "Failed to open $new_log_file for logging: $!" if $this->{verbose};
463             }
464 1 50 33     2063 print "Logging to $this->{log_file}\n" if $this->{verbose} && $this->{log_file};
465             }
466             }
467 1         28 return $this->{log_file};
468             }
469              
470             =head2 defrag_delay( [delay] )
471              
472             Use a small delay to defragment messages
473              
474             =head4 Parameters
475              
476             =over
477              
478             =item * Delay - seconds to wait - fractions of a second are OK
479              
480             =item * Returns - the current setting.
481              
482             =back
483              
484             =head4 Usage
485              
486             Under TCPIP, there is always a risk that large messages will be fragmented in transit, and that messages sent close together may be concatenated.
487              
488             Client/Server programs have to know how to turn a stream of bytes into the messages they care about, either by repeatedly reading until they see an end-of-message (defragmenting), or by splitting the bytes read into multiple messages (deconcatenating).
489              
490             For our purposes, fragmentation and concatenation can make our logs harder to read.
491              
492             Without knowning the protocol, it's not possible to tell for sure if a message has been fragmented or concatenated.
493              
494             A small delay can be used as a way of defragmenting messages, although it increases the risk that separate messages may be concatenated.
495              
496             Eg:
497             $MitM->defrag_delay( 0.1 );
498              
499             =cut
500              
501             sub defrag_delay(;$) {
502 0     0 1 0 my $this=shift;
503 0         0 my $defrag_delay=shift;
504 0         0 return $this->_set("defrag_delays",$defrag_delay);
505             }
506              
507             =head1 SUPPORTING SUBROUTINES/METHODS
508              
509             The remaining functions are supplimentary. new_server() and new_client() provide a simple client and a simple server that may be useful in some circumstances. The other methods are only likely to be useful if you choose to bypass go() in order to, for example, have more control over messages being received and sent.
510              
511             =head2 new_server( local_port_num, callback_function )
512              
513             Returns a very simple server, adequate for simple tasks.
514              
515             =head4 Parameters
516              
517             =over
518              
519             =item * local_port_num - the Port number to listen on
520              
521             =item * callback_function - a reference to a function to be called when a message arrives - must return a response which will be returned to the client
522              
523             =item * Returns - a new server
524              
525             =back
526              
527             =head4 Usage
528              
529             sub do_something($){
530             my $in = shift;
531             my $out = ...
532             return $out;
533             }
534              
535             my $server = NET::MitM::new_server(8080,\&do_something) || die;
536             $server->go();
537            
538             The server returned by new_server has a method, go(), which tells it to start receiving messages (arbitrary strings). Each string is passed to the callback_function, which is expected to return a single string, being the response to be returned to caller. If the callback returns undef, the original message will be echoed back to the client.
539              
540             go() does not return. You may want to L before calling it.
541              
542             See, for another example, samples/echo_server.pl in the MitM distribution.
543              
544             =cut
545              
546             sub new_server($%) {
547 8     8 1 18474 my $class=shift;
548 8         85 my $this=_new();
549 8 50       80 $this->{local_port_num} = shift or croak "no port number passed";
550 8 50       50 $this->{server_callback} = shift or croak "no callback passed";
551 8         43 return bless $this;
552             }
553              
554             =head2 new_client( remote_host, local_port_num )
555              
556             new client returns a very simple client, adequate for simple tasks
557              
558             The server returned has a method, send_and_receive(), which sends a message and receives a response.
559              
560             Alternately, send_to_server() may be used to send a message, and read_from_server() may be used to receive a message.
561              
562             Explicitly calling connect_to_server() is optional, but may be useful if you want to be sure the server is reachable. If you don't call it explicitly, it will be called the first time a message is sent.
563              
564             =head4 Parameters
565              
566             =over
567              
568             =item * remote_ip_address - the hostname/IP address of the server
569              
570             =item * remote_port_num - the Port number of the server
571              
572             =item * Returns - a new client object
573              
574             =back
575              
576             =head4 Usage
577              
578             my $client = NET::MitM::new_client("localhost", 8080) || die("failed to start test client: $!");
579             $client->connect_to_server();
580             my $resp = $client->send_and_receive("hello");
581             ...
582              
583             See, for example, samples/client.pl or samples/clients.pl in the MitM distribution.
584              
585             =cut
586              
587             sub new_client($%) {
588 74     74 1 2963610 my $class=shift;
589 74         489 my $this=_new();
590 74 50       451 $this->{remote_ip_address} = shift or croak "remote hostname/ip address missing";
591 74 50       381 $this->{remote_port_num} = shift or croak "remote port number missing";
592 74         373 return bless $this;
593             }
594              
595             =head2 log( string )
596              
597             log is a convenience function that prefixes output with a timestamp and PID information then writes to log_file.
598              
599             =head4 Parameters
600              
601             =over
602              
603             =item * string(s) - one or more strings to be logged
604              
605             =item * Returns --none--
606              
607             =back
608              
609             =head4 Usage
610              
611             log is a convenience function that prefixes output with a timestamp and PID information then writes to log_file.
612              
613             log() does nothing unless log_file is set, which by default, it is not.
614              
615             =cut
616              
617             sub log($@)
618             {
619 459     459 1 1605 my $this=shift;
620 459 100       2182 printf {$this->{LOGFILE}} "%u/%s %s\n", $$, $this->{mydate}(), "@_" if $this->{LOGFILE};
  81         259  
621 459         3114 return undef;
622             }
623              
624             =head2 echo( string(s) )
625              
626             Prints to stdout and/or the logfile
627              
628             =head4 Parameters
629              
630             =over
631              
632             =item * string(s) - one or more strings to be echoed (printed)
633              
634             =item * Returns --none--
635              
636             =back
637              
638             =head4 Usage
639              
640             echo() is a convenience function that prefixes output with a timestamp and PID information and prints it to standard out if verbose is set and, if log_file() has been set, logs it to the log file.
641              
642             =cut
643              
644             sub echo($@)
645             {
646 256     256 1 443 my $this=shift;
647 256         1257 $this->log("@_");
648 256 50       777 return if !$this->{verbose};
649 256 50       613 confess "Did not expect not to have a name" if !$this->{name};
650 256 100       38611 if($_[0] =~ m/^[<>]{3}$/){
651 109         181 my $prefix=shift;
652 109         227 my $msg=join "", @_;
653 109         371 printf("%s: %u/%s %s %d bytes\n", $this->{name}, $$, $this->{mydate}(), $prefix, length($msg));
654             }else{
655 147         593 printf("%s: %u/%s\n", $this->{name}, $$, join(" ", $this->{mydate}(), @_));
656             }
657 256         749 return undef;
658             }
659              
660             =head2 send_to_server( string(s) )
661              
662             send_to_server() sends a message to the server
663              
664             =head4 Parameters
665              
666             =over
667              
668             =item * string(s) - one or more strings to be sent
669              
670             =item * Return: true if successful
671              
672             =back
673              
674             =head4 Usage
675              
676             If a callback is set, it will be called before the message is sent.
677              
678             send_to_server() may 'die' if it detects a failure to send.
679              
680             =cut
681              
682             sub _do_callback($$)
683             {
684 109     109   1028 my $callback = shift;
685 109         174 my $msg = shift;
686 109 100       379 if($callback){
687 11         116 my $new_msg = $callback->($msg);
688 11 100       306 $msg = $new_msg unless !defined $new_msg;
689             }
690 109         298 return $msg;
691             }
692              
693             sub _logmsg
694             {
695 109     109   185 my $this = shift;
696 109         148 my $direction = shift;
697 109         164 my $msg = shift;
698 109 50       306 if($this->{verbose}>1){
699 0         0 $this->echo($direction,"(".length($msg)." bytes) {$msg}\n");
700             }else{
701             # don't print the whole message by default, in case it is either binary &/or long
702 109         452 $this->echo($direction,"(".length($msg)." bytes)\n");
703 109         806 $this->log($direction," {{{$msg}}}\n");
704             }
705             }
706              
707             sub send_to_server($@)
708             {
709 85     85 1 484 my $this = shift;
710 85         222 my $msg = shift;
711 85         559 $this->connect_to_server();
712 85 50 66     404 $this->log("calling server callback ($msg)\n") if $this->{client_to_server_callback} && $this->{verbose}>1;
713 85         677 $msg = _do_callback( $this->{client_to_server_callback}, $msg );
714 85         418 $this->_logmsg(">>>",$msg);
715 85 50       296 confess "SERVER being null was unexpected" if !$this->{SERVER};
716 85   50     152 return print({$this->{SERVER}} $msg) || die "Can't send to server: $?";
717             }
718              
719             =head2 send_to_client( string(s) )
720              
721             Sends a message to the client
722              
723             =head4 Parameters
724              
725             =over
726              
727             =item * string(s) - one or more strings to be sent
728              
729             =item * Return: true if successful
730              
731             =back
732              
733             =head4 Usage
734              
735             If a callback is set, it will be called before the message is sent.
736              
737             =cut
738              
739             sub send_to_client($@)
740             {
741 24     24 1 147 my $this = shift;
742 24         46 my $msg = shift;
743 24 50 66     128 $this->echo("calling client callback ($msg)\n") if $this->{server_to_client_callback} && $this->{verbose}>1;
744 24         116 $msg = _do_callback( $this->{server_to_client_callback}, $msg );
745 24         94 $this->_logmsg("<<<",$msg);
746 24         40 return print({$this->{CLIENT}} $msg);
  24         3301  
747             }
748              
749             =head2 read_from_server( )
750              
751             Reads a message from the server
752              
753             =head4 Parameters
754              
755             =over
756              
757             =item * --none--
758              
759             =item * Returns - the message read, or undef if the server disconnected.
760              
761             =back
762              
763             =head4 Usage
764              
765             Blocks until a message is received.
766              
767             =cut
768              
769             sub read_from_server()
770             {
771 85     85 1 4581 my $this=shift;
772 85         101 my $msg;
773 85         273724 sysread($this->{SERVER},$msg,100000);
774 85 50       564 if(length($msg) == 0)
775             {
776 0         0 $this->echo("Server disconnected\n");
777 0         0 return undef;
778             }
779 85         609 return $msg;
780             }
781              
782             =head2 send_and_receive( )
783              
784             Sends a message to the server and receives a response
785              
786             =head4 Parameters
787              
788             =over
789              
790             =item * the message(s) to be sent
791              
792             =item * Returns - message read, or undef if the server disconnected.
793              
794             =back
795              
796             =head4 Usage
797              
798             Blocks until a message is received. If the server does not always return exactly one message for each message it receives, send_and_receive() will either concatenate messages or block forever.
799              
800             =cut
801              
802             sub send_and_receive($)
803             {
804 77     77 1 13757 my $this=shift;
805 77         410 $this->send_to_server(@_);
806 77         356 return $this->read_from_server(@_);
807             }
808              
809             =head2 connect_to_server( )
810              
811             Connects to the server
812              
813             =head4 Parameters
814              
815             =over
816              
817             =item * --none--
818              
819             =item * Returns --none--
820              
821             =back
822              
823             =head4 Usage
824              
825             This method is automatically called when needed. It only needs to be called directly if you want to be sure that the connection to server succeeds before proceeding.
826              
827             =cut
828              
829             sub connect_to_server()
830             {
831 91     91 1 130 my $this=shift;
832 91 100       410 return if $this->{SERVER};
833 80 50       13973 socket($this->{SERVER}, PF_INET, SOCK_STREAM, $protocol) or die "Can't create socket: $!";
834 80 50       231 confess "remote_ip_address unexpectedly not known" if !$this->{remote_ip_address};
835 80 50       22274 my $remote_ip_aton = inet_aton( $this->{remote_ip_address} ) or croak "Fatal: Cannot resolve internet address: '$this->{remote_ip_address}'\n";
836 80 50       661 my $remote_port_address = sockaddr_in($this->{remote_port_num}, $remote_ip_aton ) or die "Fatal: Can't get port address: $!"; # TODO Is die the way to go here? Not sure it isn't. Not sure it is.
837 80         1469 $this->echo("Connecting to $this->{remote_ip_address}\:$this->{remote_port_num} [verbose=$this->{verbose}]\n");
838 80 50       51673 connect($this->{SERVER}, $remote_port_address) or confess "Fatal: Can't connect to $this->{remote_ip_address}:$this->{remote_port_num} using $this->{SERVER}. $!"; # TODO Is die the way to go here? Not sure it isn't. Not sure it is. TODO document error handling, one way or the other.
839 80         966 $this->{SERVER}->autoflush(1);
840 80         5341 binmode($this->{SERVER});
841 80         201 return undef;
842             }
843              
844             =head2 disconnect_from_server( )
845              
846             Disconnects from the server
847              
848             =head4 Parameters
849              
850             =over
851              
852             =item * --none--
853              
854             =item * Returns --none--
855              
856             =back
857              
858             =head4 Usage
859              
860             Disconnection is normally triggered by the other party disconnecting, not by us. disconnect_from_server() is only useful with new_client(), and not otherwise supported.
861              
862             =cut
863              
864             sub disconnect_from_server()
865             {
866 73     73 1 22777 my $this=shift;
867 73         156 $this->log("initiating disconnect");
868 73         633 $this->_destroy();
869 73         169 return undef;
870             }
871              
872             sub _pause($){
873 0     0   0 select undef,undef,undef,shift;
874 0         0 return undef;
875             }
876              
877             sub _message_from_client_to_server(){ # TODO Too many too similar sub names, some of which maybe should be public
878 44     44   72 my $this=shift;
879             # optional sleep to reduce risk of split messages
880 44 50       318 _pause($this->{defrag_delay}) if $this->{defrag_delay};
881             # It would be possible to be more agressive by repeatedly waiting until there is a break, but that would probably err too much towards concatenating seperate messages - especially under load.
882 44         68 my $msg;
883 44         742 sysread($this->{CLIENT},$msg,10000);
884             # (0 length message means connection closed)
885 44 100       242 if(length($msg) == 0) {
886 20         219 $this->echo("Client disconnected\n");
887 20         90 $this->_destroy();
888 20         50 return;
889             }
890             # Send message to server, if any. Else 'send' to callback function and return result to client.
891 24 100       146 if($this->{SERVER}){
    50          
892 7         144 $this->send_to_server($msg);
893             }elsif($this->{server_callback}){
894 17         94 $this->send_to_client( $this->{server_callback}($msg) );
895             }else{
896 0         0 confess "$this->{name}: Did not expect to have neither a connection to a SERVER nor a server_callback";
897             }
898 24         687 return undef;
899             }
900              
901             sub _message_from_server_to_client(){ # TODO Too many too similar sub names
902 7     7   16 my $this=shift;
903             # sleep to avoid splitting messages
904 7 50       62 _pause($this->{defrag_delay}) if $this->{defrag_delay};
905             # Read from SERVER and copy to CLIENT
906 7         66 my $msg = $this->read_from_server();
907 7 50       42 if(!defined $msg){
908 0         0 $this->echo("Server disconnected\n");
909 0         0 $this->_destroy();
910 0         0 return;
911             }
912 7         37 $this->send_to_client($msg);
913 7         18 return undef;
914             }
915              
916             sub _cull_child()
917             {
918 19 50   19   69 my $this=shift or die;
919 19 50       62 my $child=shift or die;
920 19         29 for my $i (0 .. @{$this->{children}}){
  19         118  
921 19 50       67 if($child==$this->{children}[$i]){
922 19 50       58 $this->echo("Child $child->{name} is done, cleaning it up") if $this->{verbose}>1;
923 19         292 splice @{$this->{children}}, $i,1;
  19         88  
924 19         41 return;
925             }
926             }
927 0         0 confess "Child $child->{name} is finished, but I can't find it to clean it up";
928             }
929              
930             # _main_loop is called by listeners and by their 'leave-home' children both. When called by listeners, it also includes stay at home children
931              
932             sub _main_loop()
933             {
934 11     11   32 my $this=shift;
935 11         26 my $last_time;
936             my $target_time;
937 11 100 66     101 if($this->{timer_interval}&&$this->{timer_callback}){
938 4         16 $last_time=time();
939 4         8 $target_time=$last_time+$this->{timer_interval};
940             }
941             # Main Loop
942 11         2692 mainloop: while(1)
943             {
944             # Build file descriptor list for select call
945 94         279 my $rin = "";
946 94 100       405 if($this->{LISTEN}){
947 89 50       356 confess "LISTEN is unexpectedly not a filehandle" if !fileno($this->{LISTEN});
948 89         3946 vec($rin, fileno($this->{LISTEN}), 1) = 1;
949             }
950 94         1081 foreach my $each ($this, @{$this->{children}}) {
  94         710  
951 277 100       1305 vec($rin, fileno($each->{CLIENT}), 1) = 1 if $each->{CLIENT}; # TODO if no client, child should probably be dead
952 277 100       958 vec($rin, fileno($each->{SERVER}), 1) = 1 if $each->{SERVER};
953             }
954             # and listen...
955 94         202 my $rout = $rin;
956 94         121 my $delay;
957 94 100       313 if($this->{timer_interval}){
958 21 100       130 if(time() > $target_time){
959 13 100       121 $this->{timer_callback}() or last;
960 9         914586 $last_time=$target_time;
961 9         48 $target_time+=$this->{timer_interval};
962             }
963 17         84 $delay=$target_time-time();
964 17 50       67 $delay=0 if($delay<0);
965 17 100       269 $this->echo("delay=$delay") if $this->{verbose} > 1;
966             }else{
967 73         116 $delay=undef;
968             }
969 90         9712263 select( $rout, "", "", $delay );
970 90 100 100     2155 if( $this->{LISTEN} && vec($rout,fileno($this->{LISTEN}),1) ) {
971 21         132 my $child = $this->_spawn_child();
972 20 100       169 push @{$this->{children}}, $child if $child;
  19         276  
973 20         53 next;
974             }
975 64         154 foreach my $each($this, @{$this->{children}}) {
  64         281  
976 156 50 66     724 confess "We have a child with no CLIENT\n" if !$each->{CLIENT} && $each!=$this;
977 156 100 100     724 if($each->{CLIENT} && vec($rout,fileno($each->{CLIENT}),1) ) {
978 44         237 $each->_message_from_client_to_server(); # TODO Too many too similar sub names
979 44 100       168 if(!$each->{CLIENT}){
980             # client has disconnected
981 20 100       80 if($each==$this){
982             # we are the child - OK to exit
983 1         4 return; #might be better to die or exit at this point instead?
984             }else{
985             # we are the parent - clean up child and keep going
986 19         80 $this->_cull_child($each);
987 19         110 last; # _cull_child impacts the children array - not safe to continue without regenerating rout
988             }
989             }
990             }
991 136 100 100     783 if($each->{SERVER} && vec($rout,fileno($each->{SERVER}),1) ) {
992 7         61 $each->_message_from_server_to_client(); # TODO Too many too similar sub names
993 7 50       60 if(!$each->{SERVER}){
994             # client has disconnected
995 0 0       0 if($each==$this){
996             # we are the child - OK to exit
997 0         0 return; #might be better to die or exit at this point instead?
998             }else{
999 0         0 $this->_cull_child($each);
1000 0         0 last; # _cull_child impacts the children array - not safe to continue without regenerating rout
1001             }
1002             }
1003             }
1004             }
1005             }
1006 4         411 return undef;
1007             }
1008              
1009             =head2 hhmmss( )
1010              
1011             The default timestamp function - returns localtime in hh:mm:ss format
1012              
1013             =head4 Parameters
1014              
1015             =over
1016              
1017             =item * --none--
1018              
1019             =item * Returns - current time in hh:mm:ss format
1020              
1021             =back
1022              
1023             =head4 Usage
1024              
1025             This function is, by default, called when a message is written to the log file.
1026              
1027             It may be overridden by calling mydate().
1028              
1029             =cut
1030              
1031             sub hhmmss()
1032             {
1033 337     337 1 18027 my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
1034 337         82735 return sprintf "%02d:%02d:%02d",$hour,$min,$sec;
1035             }
1036              
1037             =head2 mydate( )
1038              
1039             Override the standard hh:mm:ss datestamp
1040              
1041             =head4 Parameters
1042              
1043             =over
1044              
1045             =item * datestamp_callback - a reference to a function that returns a datestamp
1046              
1047             =item * Returns - a reference to the current or updated callback function
1048              
1049             =back
1050              
1051             =head4 Usage
1052              
1053             For example:
1054              
1055             sub yymmddhhmmss {
1056             my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime();
1057             return sprintf "%02d/%02d/%02d %02d:%02d:%02d",
1058             $year+1900,$mon+1,$mday,$hour,$min,$sec;
1059             }
1060             mydate(\&yymmddhhmmss);
1061              
1062             =cut
1063              
1064             sub mydate(;$)
1065             {
1066 0     0 1 0 my $this=shift;
1067 0   0     0 my $mydate=shift||undef;
1068 0 0       0 if(defined $mydate){
1069 0         0 $this->{mydate} = $mydate;
1070             }
1071 0         0 return $this->{mydate};
1072             }
1073              
1074             =head2 listen( )
1075              
1076             Listen on local_port and prepare to accept incoming connections
1077              
1078             =head4 Parameters
1079              
1080             =over
1081              
1082             =item * --none--
1083              
1084             =item * Return --none--
1085              
1086             =back
1087              
1088             =head4 Usage
1089              
1090             This method is called by go(). It only needs to be called directly if go() is being bypassed for some reason.
1091              
1092             =cut
1093              
1094             sub listen()
1095             {
1096 11     11 1 30 my $this=shift;
1097 11 100       2384 return if $this->{LISTEN};
1098 8 100       284 $this->echo(sprintf "Server %u listening on port %d (%s)\n",$$,$this->{local_port_num},$this->{parallel}?"parallel":"serial");
1099             # open tcp/ip socket - see blue camel book pg 349
1100 8 50       1475 socket($this->{LISTEN}, PF_INET, SOCK_STREAM, $protocol) or die "Fatal: Can't create socket: $!";
1101 8 50       385 bind($this->{LISTEN}, sockaddr_in($this->{local_port_num}, INADDR_ANY)) or die "Fatal: Can't bind socket $this->{local_port_num}: $!";
1102 8 50       1210 listen($this->{LISTEN},1) or die "Fatal: Can't listen to socket: $!";
1103 8         313 $this->echo("Waiting on port $this->{local_port_num}\n");
1104 8         19 return undef;
1105             }
1106              
1107             sub _accept($)
1108             {
1109             # Accept a new connection
1110 21     21   38 my $this=shift;
1111 21         38 my $LISTEN=shift;
1112 21         1059 my $client_paddr = accept($this->{CLIENT}, $LISTEN);
1113 21         977 $this->{CLIENT}->autoflush(1);
1114 21         3463 binmode($this->{CLIENT});
1115 21         112 my ($client_port, $client_iaddr) = sockaddr_in( $client_paddr );
1116 21         2802 $this->log("Connection accepted from", inet_ntoa($client_iaddr).":$client_port\n");
1117 21 100       168 $this->connect_to_server() if $this->{remote_ip_address};
1118 21         46 return undef;
1119             }
1120              
1121             sub _new_child(){
1122 22     22   91 my $parent=shift;
1123 22         151 my $child=_new();
1124 22         46 my $all_good=1;
1125 22         44 foreach my $key (keys %{$parent}){
  22         255  
1126 237 100       11371 if($key=~m/^(LISTEN|children|connections|name|timer_interval|timer_callback)$/){
    100          
    50          
1127             # do nothing - these parameters are not inherited
1128             }elsif($key =~ m/^(parallel|log_file|verbose|mydate|.*callback|(local|remote)_(port_num|ip_address))$/){
1129 141         2345 $child->{$key}=$parent->{$key};
1130             }elsif($key eq "LOGFILE"){
1131             # TODO might want to have a different logfile for each child, or at least, an option to do so.
1132 16         52 $child->{$key}=$parent->{$key};
1133             }else{
1134 0         0 warn "internal error - unexpected attribute: $key = {$parent->$key}\n";
1135 0         0 $all_good=0;
1136             }
1137             }
1138 22 50       125 die "Internal error in _new_child()" unless $all_good;
1139 22         63 return bless $child;
1140             }
1141              
1142             sub _spawn_child(){
1143 21     21   51 my $this=shift;
1144 21         252 my $child = $this->_new_child();
1145 21         119 $child->_accept($this->{LISTEN});
1146 21 50       337 confess "We have a child with no CLIENT\n" if !$child->{CLIENT};
1147             # hand-off the connection
1148 21         175 $this->echo("starting connection:",++$this->{connections});
1149 21 100       86 if(!$this->{parallel}){
1150 19         77 return $child;
1151             }
1152 2         10999 my $pid = fork();
1153 2 50       266 if(!defined $pid){
    100          
1154             # Error
1155 0         0 $this->echo("Cannot fork!: $!\nNew connection will run in the current thread\n");
1156 0         0 return $child;
1157             }elsif(!$pid){
1158             # This is the child process
1159 1 50       46 $child->echo(sprintf"Running %u",$$) if $child->{verbose}>1;
1160 1 50       19 confess "We have a child with no CLIENT\n" if !$child->{CLIENT};
1161             # The active instanct of the parent is in a different process
1162             # Ideally, we would have the parent go out of scope, but all we can do is clean up the bits that matter
1163 1         98 close $this->{LISTEN};
1164 1         74 $child->_main_loop();
1165 1 50       6 $child->echo(sprintf"Exiting %u",$$) if $child->{verbose}>1;
1166 1         623 exit;
1167             }else{
1168             # This is the parent process. The active child instance is in its own process, we clean up what we can
1169 1         67 $child->_destroy();
1170 1         148 return undef;
1171             }
1172             }
1173              
1174             sub go()
1175             {
1176 10     10 1 2420 my $this=shift;
1177 10         580 $this->listen();
1178 10         163 $this->_main_loop();
1179 4         14 return undef;
1180             }
1181              
1182             sub _destroy()
1183             {
1184 96     96   19844 my $this=shift;
1185 96 100       20665 close $this->{CLIENT} if($this->{CLIENT});
1186 96 100       72287 close $this->{SERVER} if($this->{SERVER});
1187 96         613 $this->{SERVER}=$this->{CLIENT}=undef;
1188 96         626 return undef;
1189             }
1190              
1191             =head1 Exports
1192              
1193             MitM does not export any functions or variables.
1194             If parallel() is turned on, which by default it is not, MitM sets SIGCHD to IGNORE, and as advertised, it calls fork() once for each new connection.
1195              
1196             =head1 AUTHOR
1197              
1198             Ben AVELING, C<< >>
1199              
1200             =head1 BUGS
1201              
1202             Please report any bugs or feature requests to C, or through
1203             the web interface at L. I will be notified, and then you'll
1204             automatically be notified of progress on your bug as I make changes.
1205              
1206             =head1 SUPPORT
1207              
1208             You can find documentation for this module with the perldoc command.
1209              
1210             perldoc NET::MitM
1211              
1212             You can also look for information at:
1213              
1214             =over
1215              
1216             =item * RT: CPAN's request tracker (report bugs here)
1217              
1218             L
1219              
1220             =item * AnnoCPAN: Annotated CPAN documentation
1221              
1222             L
1223              
1224             =item * CPAN Ratings
1225              
1226             L
1227              
1228             =item * Search CPAN
1229              
1230             L
1231              
1232             =back
1233              
1234             =head1 ACKNOWLEDGEMENTS
1235              
1236             I'd like to acknowledge W. Richard Steven's and his fantastic introduction to TCPIP: "TCP/IP Illustrated, Volume 1: The Protocols", Addison-Wesley, 1994. (L).
1237             It got me started. Recommend. RIP.
1238             The Blue Camel Book is also pretty useful, and Langworth & chromatic's "Perl Testing, A Developer's Notebook" is also worth a hat tip.
1239              
1240             =head1 ALTERNATIVES
1241              
1242             If what you want is a pure proxy, especially if you want an ssh proxy or support for firewalls, you might want to evaluate Philippe "BooK" Bruhat's L.
1243              
1244             And if you want a full "portable multitasking and networking framework for any event loop", you may be looking for L.
1245              
1246             =head1 LICENSE AND COPYRIGHT
1247              
1248             Copyleft 2013 Ben AVELING.
1249              
1250             This program is free software; you can redistribute it and/or modify it
1251             under the terms of the the Artistic License (2.0). You may obtain a
1252             copy of the full license at:
1253              
1254             L
1255              
1256             Any use, modification, and distribution of the Standard or Modified
1257             Versions is governed by this Artistic License. By using, modifying or
1258             distributing the Package, you accept this license. Do not use, modify,
1259             or distribute the Package, if you do not accept this license.
1260              
1261             If your Modified Version has been derived from a Modified Version made
1262             by someone other than you, you are nevertheless required to ensure that
1263             your Modified Version complies with the requirements of this license.
1264              
1265             This license does not grant you the right to use any trademark, service
1266             mark, tradename, or logo of the Copyright Holder.
1267              
1268             This license includes the non-exclusive, worldwide, free-of-charge
1269             patent license to make, have made, have, hold and cherish,
1270             use, offer to use, sell, offer to sell, import and
1271             otherwise transfer the Package with respect to any patent claims
1272             licensable by the Copyright Holder that are necessarily infringed by the
1273             Package. If you institute patent litigation (including a cross-claim or
1274             counterclaim) against any party alleging that the Package constitutes
1275             direct or contributory patent infringement, then this Artistic License
1276             to you shall terminate on the date that such litigation is filed.
1277              
1278             Disclaimer of Warranty: THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER
1279             AND CONTRIBUTORS "AS IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES.
1280             THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
1281             PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY
1282             YOUR LOCAL LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR
1283             CONTRIBUTOR WILL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR
1284             CONSEQUENTIAL DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE,
1285             EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. SO THERE.
1286              
1287             =cut
1288              
1289             1; # End of NET::MitM