App-Greple

 view release on metacpan or  search on metacpan

lib/App/Greple/PgpDecryptor.pm  view on Meta::CPAN

    my $passphrase = "";

    if (my $fd = $opt->{passphrase_fd}) {
	$obj->fh(_openfh($fd));
    }
    else {
	if (not defined $obj->fh) {
	    $obj->fh(_openfh());
	}
	if (defined $opt->{passphrase}) {
	    $passphrase = $opt->{passphrase};
	} else {
	    _readphrase(\$passphrase);
	}
	$obj->setphrase(\$passphrase);

	##
	## Destroy data as much as possible
	##
	$passphrase =~ s/./\0/g;
	$passphrase = "";
	undef $passphrase;
    }

    $obj;
}

sub setphrase {
    my $obj = shift;
    my $fh = $obj->fh;
    my $passphrase_r = shift;

    $obj->reset;
    $fh->syswrite($$passphrase_r, length($$passphrase_r));
    $obj->reset;
}

sub getphrase {
    my $obj = shift;
    my $fh = $obj->fh;

    $obj->reset;
    my $phrase = $fh->getline;
    $obj->reset;
    $phrase;
}

sub fh {
    my $obj = shift;
    @_ ? $obj->{FH} = shift
       : $obj->{FH};
}

sub pgppassfd {
    my $obj = shift;
    $obj->fh->fileno;
}

sub decrypt_command {
    my $obj = shift;
    my $command = "gpg";
    my @option = ( qw(--quiet --batch --decrypt) ,
		   qw(--no-tty --no-mdc-warning) );
    sprintf "$command @option --passphrase-fd %d", $obj->pgppassfd;
}

sub reset {
    my $obj = shift;
    defined $obj->fh or return;
    $obj->fh->sysseek(0, 0) or die $!;
}

sub _openfh {
    use Fcntl;
    use IO::File;

    my $fd = shift;
    my $fh;

    if (defined $fd) {
	$fh = IO::Handle->new;
	$fh->fdopen($fd, "w+");
    } else {
	$fh = new_tmpfile IO::File;
	defined $fh or die "new_tmpefile: $!";
    }

    $fh->fcntl(F_SETFD, 0) or die "fcntl F_SETFD failed: $!\n";

    return $fh;
}

my $noecho;
my $restore;
BEGIN {
    ($noecho, $restore) = eval {
	require Term::ReadKey;
	import  Term::ReadKey;
	(sub { ReadMode('noecho', @_) }, sub { ReadMode('restore', @_) });
    };
    if (not defined $noecho) {
	$noecho  = sub { system 'stty -echo < /dev/tty' };
	$restore = sub { system 'stty  echo < /dev/tty' };
    }
}

sub _readphrase {
    my $passphrase_r = shift;

    print STDERR "Enter PGP Passphrase> ";
    open my $tty, '<', '/dev/tty' or die;
    $noecho->($tty);
    if (defined (my $pass = ReadLine(0, $tty))) {
	chomp($$passphrase_r = $pass);
    }
    $restore->($tty);
    close $tty;
    print STDERR "\n";

    $passphrase_r;
}



( run in 0.771 second using v1.01-cache-2.11-cpan-e1769b4cff6 )