[pm-h] Overriding package subroutines (the hard way)

Paul Archer tigger at io.com
Fri Jul 6 06:57:20 PDT 2007


You could take a different approach and used the forced-command feature of 
ssh on the server side--or change the login shell on the account they're 
going to to a wrapper that runs 'script' for logging and then whatever you 
want post-logout.
That makes the assumption you want the logging on the server side, which may 
or may not be a good thing, depending on your situation.

Paul


8:19am, Todd Rinaldo wrote:

> I went a little crazy yesterday (I was already partially there) trying to
> figure this out. I thought I'd throw this out on the list and see if there
> are other ways to do it.
>
> We want to log a user's session to a priveliged account from start to stop.
> We also need to do some pre-qual and some post processing once they're done.
> We want to use Net::SSH::Perl to do this. Here's my problem: Net::SSH::Perl
> has an interactive mode that would meet this need, except it does not
> provide any obvious hooks to do additional logging.
>
> The bad way: Go re-write the appropriate pm file (Net::SSH::Pel::SSH2). I
> refuse to use this option.
>
> The evil way: Use Sub::Override to re-write the subroutine I want to hack.
> The problem is it looks like this below. Search for ### in the override
> code.
>
> The problem with this code is it's not very adaptable to change if the CPAN
> module changes. It'd be better if I could insert a hook and then have it
> resume the original subroutine. I don't think I can with the Sub::Override
> module. I've also got a problem with my use of main::LOG, but see no more
> elegant way pull this off.
>
> Is there a better way?
>
> ---------------------------------------------------------------------
>
> #!perl
>
> use strict;
> use warnings;
> use Net::SSH::Perl
>
> package Net::SSH::Perl::SSH2;
> use Sub::Override;
> my $override = Sub::Override->new()
>
> $override->replace (shell => sub {
>    my $ssh = shift;
>    my $cmgr = $ssh->channel_mgr;
>    my $channel = $ssh->_session_channel;
>    $channel->open;
>
>    $channel->register_handler(SSH2_MSG_CHANNEL_OPEN_CONFIRMATION, sub {
>        my($channel, $packet) = @_;
>        my $r_packet = $channel->request_start('pty-req', 0);
>        my($term) = $ENV{TERM} =~ /(\w+)/;
>        $r_packet->put_str($term);
>        $r_packet->put_int32(0) for 1..4;
>        $r_packet->put_str("");
>        $r_packet->send;
>        $channel->{ssh}->debug("Requesting shell.");
>        $channel->request("shell", 0);
>    });
>
>    my($exit);
>    $channel->register_handler(SSH2_MSG_CHANNEL_REQUEST,
>        _make_input_channel_req(\$exit));
>
>    $channel->register_handler("_output_buffer", sub {
>        syswrite STDOUT, $_[1]->bytes;
>
> 	  ############# Inserting custom TODD code.
> 	  my $output = $_[1]->bytes;
> 	  print main::LOG $output;
>    });
>    $channel->register_handler("_extended_buffer", sub {
>        syswrite STDERR, $_[1]->bytes;
>    });
>
>    $ssh->debug("Entering interactive session.");
>    $ssh->client_loop;
> });
> 1;
>
> # Must use package main to be able to write code after a package definition?
> package main;
>
> open (LOG, ">", "ssh.$$.log") or die;
>
> use Net::SSH::Perl;
> my $host = "host";
> my $user = "username";
> my $password = "passhere";
>
> my $ssh = Net::SSH::Perl->new($host);
> $ssh->login($user, $pass);
>
> use Term::ReadKey;
> ReadMode('raw');
> $ssh->shell;
> ReadMode('restore');
>
> exit;
>
> _______________________________________________
> Houston mailing list
> Houston at pm.org
> http://mail.pm.org/mailman/listinfo/houston
> Website: http://houston.pm.org/
>
>



-------------------------------------------
SYSTEM ADMINISTRATOR: A person whose job it
is to do everything that isn't his job.
-------------------------------------------


More information about the Houston mailing list