svnpw2simple.pl

#!/usr/bin/perl -w
#      /* Construct the basename of the creds file.  It's just the
#         realmstring converted into an md5 hex string.  */
#                      ... config_auth.c from subversion src
use strict;
use Pod::Usage;
use File::Basename;
use Digest::MD5 qw(md5_hex);

my $RCS_VERSION   = '$Id: svnpw2simple 6698 2010-05-07 08:50:40Z bonaccos $';
my $shell_heredoc = 0;
my $homedir       = ( getpwuid $< )[-2];
my $filename      = '';
my $template      = <<TEMPLATE;
K 8
passtype
V 6
simple
K 8
password
V %d
%s
K 15
svn:realmstring
V %d
%s
K 8
username
V %d
%s
END
TEMPLATE

sub get_svn_simple($$);
sub get_realm_string($);
sub heredoc_me($);
sub main;
main;

sub main() {
    if ( $ARGV[0] && $ARGV[0] eq '-s' ) {
        $shell_heredoc = 1;
        shift @ARGV;
    }
    my $repobase = shift @ARGV or pod2usage(1);
    my $getuser  = shift @ARGV or pod2usage(1);

    print heredoc_me( get_svn_simple( $repobase, $getuser ) ) and exit(0)
        if ( -d $repobase && $getuser =~ /[0-9a-zA-Z_]+/ && $shell_heredoc );

    print get_svn_simple( $repobase, $getuser )
        if ( -d $repobase && $getuser =~ /[0-9a-zA-Z_]+/ )
        or pod2usage(1);
}

sub get_svn_simple($$) {
    my $repo       = shift;
    my $username   = shift;
    my $passwdpath = "$repo/conf/passwd";
    my $password   = '';

    my $realmstr = get_realm_string($repo);

    open( P, '<', "$passwdpath" )
        or die "Unable to open SVN passwd file $passwdpath";
    while (<P>) { $password = $1 if /^$usernames+=s+(S+)/; }
    close P;
    die "SVN password for $username not found in $passwdpath"
        if ( $password eq '' );

    $filename = md5_hex($realmstr);

    print STDERR "## svn simple auth filename: $filenamen"
        if ( !$shell_heredoc );
    return sprintf $template, length($password), $password,
        length($realmstr), $realmstr,
        length($username), $username;
}

sub get_realm_string($) {
    my $repo     = shift;
    my $svnserve = "$repo/conf/svnserve.conf";
    my $realm    = '';

    if ( -r $svnserve ) {
        open( P, '<', "$svnserve" )
            or die "Unable to open SVN passwd file $svnserve";
        while (<P>) { $realm = $1 if /^realms+=s+(.*)/; }
        close P;
        return sprintf "<svn://svn.ee.ethz.ch:3690> %s", $realm
            if ( $realm ne '' );
    }    # else
    my $shortname = basename($repo);
    return sprintf "<svn://svn.ee.ethz.ch:3690> %s", $shortname;
}

sub heredoc_me($) {
    my $doc     = shift;
    my $ret     = '';
    my $destdir = "$homedir/.subversion/auth/svn.simple";
    $ret = "## svnpw2simple for $destdir/$filenamen";
    $ret .= "[ -d $destdir ] || mkdir -p $destdirn";
    $ret .= "cat - <<UNTILHERE > $destdir/$filenamen";
    $ret .= $doc;
    $ret .= "UNTILHEREn";
    $ret .= "chmod 700 $homedir/.subversionnn";
    return $ret;
}

__END__

=head1 NAME

svnpw2simple - Generate insecure SVN simple auth-cache files
by reading credentials on a repository server.

=head1 SYNOPSIS

B<svnpw2simple> I</path/to/myrepo> I<USERNAME>

B<svnpw2simple> -s I</path/to/myrepo> I<USERNAME>

B<perldoc> B<svnpw2simple>

=head1 DESCRIPTION

For a given SVN repository and user, given access to the
repo's conf/passwd file, svnpw2simple will provide the
contents that would reside in a user's .subversion/auth/simple
directory whenever that user chose to store that password
in that "simple" form.

Theoretically, any Keychain should be prefered over this
simple method. For automatic deployment purposes however,
this toy may help to cheat against yourself.

The -s option may be used to get a heredoc shell fragment.

=head1 COPYRIGHT

Copyright (c) 2010 by ETH Zurich. All rights reserved.

=head1 LICENSE

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

=head1 AUTHORS

S<Jan Hacker E<lt>[email protected]<gt>>
S<Salvatore Bonaccorso E<lt>[email protected]<gt>>

=head1 HISTORY

2010-05-07 jh Initial release

=cut

# Emacs Configuration
#
# Local Variables:
# mode: cperl
# eval: (cperl-set-style "PerlStyle")
# mode: flyspell
# mode: flyspell-prog
# End:
#
# vi: sw=4

你可能感兴趣的:(svnpw2simple.pl)