Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

cvs wrapper with ssh-agent

by jacques (Priest)
on Sep 19, 2008 at 15:02 UTC ( #712535=sourcecode: print w/ replies, xml ) Need Help??

Category: Utility scripts
Author/Contact Info jacques
Description: I wrote this cvs wrapper because we were using cvs over ssh and I didn't want to keep logging in each time I invoked cvs. If you are doing the same thing, you might find it useful. One thing to note is that if someone has root, it is possible for them to get your password, since ssh-agent keeps it unencrypted in memory.
# Add the next 2 lines to bash_profile/bashrc file: 
#
#  eval `ssh-agent` > /dev/null
#  alias cvs='/path/to/cvs_wrapper.pl'
#
#!/usr/bin/perl

use strict;
use warnings;
use Expect;
#$Expect::Exp_Internal = 1;
#$Expect::Debug = 3;

my $testcommand = Expect->spawn("ssh-add -l");
$testcommand->log_stdout(0);

if ($testcommand->expect(1, '-re' => 'agent has')) {

    $testcommand->soft_close();

    print "CVS Wrapper\n===========\n\n";

    GET_PASSWD: {

        use Term::ReadKey;

        ReadMode 2;

        print "Enter cvs passwd:";

        my $passwd = <STDIN>;
        chomp $passwd;

        ReadMode 0;
        unless (length $passwd > 4) {
              print "\nBad password\n";
             redo GET_PASSWD;
        }

        my $user = $ENV{'USER'};
        my $home = $ENV{'HOME'};
        my $remoteserv = 'server.name.here';
        my $login = "$user" . '@' . "$remoteserv";

        unless (-e "$home/.ssh/id_dsa.pub") {
        # Set up private keys
        my $command = Expect->spawn("ssh-keygen -t dsa");
        $command->log_stdout(0);
        if ($command->expect(2, '-re' => 'Enter')) {
            print $command "\r"; 
        }
        if ($command->expect(2, '-re' => 'passphrase')) {
            print $command "$passwd\r"; 
        }

        if ($command->expect(2, '-re' => 'same')) {
            print $command "$passwd\r"; 
        }
        $command->soft_close();

        my $copy_command = Expect->spawn("scp ~/.ssh/id_dsa.pub $remot
+eserv:.ssh/authorized_keys2");
        $copy_command->log_stdout(0);
        if ($copy_command->expect(2, "password")) {
            print $copy_command "$passwd\r";
        }
        if ($copy_command->expect(3, '-re' => 'denied')) {
            $copy_command->hard_close();
            print "\nBad password\n";
            unlink "$home/.ssh/id_dsa.pub", "$home/.ssh/id_dsa";
            redo GET_PASSWD;
        }
        $copy_command->soft_close();

        }

        my $ssha_command = Expect->spawn("ssh-add");
        $ssha_command->log_stdout(0);
        if ($ssha_command->expect(2, "passphrase")) {
            print $ssha_command "$passwd\r";
        }
        if ($ssha_command->expect(1,'-re' =>'Bad')) {
            $ssha_command->hard_close();
            print "\nBad password\n";
            redo GET_PASSWD;
        }
        $ssha_command->soft_close();

        print "\nLogin successful\n";
    } #end GET_PASSWD
} else { $testcommand->soft_close(); }

open DATA, "/usr/bin/cvs @ARGV |" or die "Couldn't execute program: $!
+";
    while ( defined( my $line = <DATA> ) ) {
        chomp($line);
        print "$line\n";
    }
close DATA;

Comment on cvs wrapper with ssh-agent
Download Code
Re: cvs wrapper with ssh-agent
by blazar (Canon) on Sep 19, 2008 at 18:06 UTC
    open DATA, "/usr/bin/cvs @ARGV |" or die "Couldn't execute program: $! +";

    I personally believe that even if probably it doesn't do any harm here, you should avoid naming your filheandle DATA since it's a predefined perl one. Of course, had you used a lexical instead, there would have been no problem a priori.

    while ( defined( my $line = <DATA> ) ) {

    As a side note: perhaps you know (and perhaps you don't know) that defined is pleonastic there since perl will dwimmily assume it implicitly for you.

    chomp($line); print "$line\n"; } close DATA;

    Sorry, but I'm very tired and I may be missing something obvious. Anyway: why are you doing this? Line ending conversion? Since it's the very last part of your script, you may even be thinking -for once- of using exec instead, couldn't you?

    --
    If you can't understand the incipit, then please check the IPB Campaign.
      Originally I had did not have the open() there and had the last line as:
      print `/usr/bin/cvs @ARGV`;
      But this failed when there were double quotes in the @ARGV. For example if @ARGV contained: commit -m "message goes here" filename_to_commit

      So I used open() instead.

        I personally believe

        If you use open or exec (or system) you can "bypass" the shell by passing a list with more than one element, e.g.:

        open my $data, '-|', '/usr/bin/cvs' => @ARGV or die horribly;
        --
        If you can't understand the incipit, then please check the IPB Campaign.

Back to Code Catacombs

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://712535]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (17)
As of 2014-08-21 14:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The best computer themed movie is:











    Results (136 votes), past polls