1 package Object::Remote::Connector::LocalSudo;
7 extends 'Object::Remote::Connector::Local';
9 has password_callback => (is => 'ro');
11 sub _sudo_perl_command {
12 my ($self, $stderr_fdno, $target_user) = @_;
14 'sudo', '-S', '-u', $target_user, '-p', "[sudo] password please\n",
15 'perl', '-MPOSIX=dup2',
16 '-e', 'print STDERR "GO\n"; dup2(shift(@ARGV), 2); exec(@ARGV);',
17 $stderr_fdno, $self->_perl_command($target_user);
22 open my $stderr_dup, '>&', \*STDERR or die "Couldn't dup STDERR: $!";
23 my $sudo_stderr = gensym;
28 $self->_sudo_perl_command(fileno($stderr_dup), @_)
29 ) or die "open3 failed: $!";
30 chomp(my $line = <$sudo_stderr>);
32 # started already, we're good
33 } elsif ($line =~ /\[sudo\]/) {
34 my $cb = $self->password_callback;
35 die "sudo sent ${line} but we have no password callback"
37 print $foreign_stdin $cb->($line, @_), "\n";
38 chomp($line = <$sudo_stderr>);
39 die "sent password but next line was ${line}"
42 die "Got inexplicable line ${line} trying to sudo";
44 return ($foreign_stdin, $foreign_stdout, $pid);
49 push @Object::Remote::Connection::Guess, sub {
51 # username followed by @
52 if (defined and !ref and /^ ([^\@]*?) \@ $/x) {
53 return __PACKAGE__->new->connect($1);