>
Linedata Services (UK) Ltd Registered Office: Bishopsgate Court, 4-12 Norton Folgate, London, E1 6DB Registered in England and Wales No 3027851 VAT Reg No 778499447 -----Original Message----- > From: Giulio Troccoli > Sent: 08 December 2009 11:18 > To: us...@subversion.tigris.org; users@subversion.apache.org > Subject: Authentication with Perl bindings > > I'm desperately trying to write something in Perl to authenticate. > > The functionality I want to reproduce is: > - use the chached username and password if any > - if not, ask for a password for the current username > - if that fails, ask for a username and a password > > This is what the SVN client does, I think. But I'm not able > to do it in Perl. I'm using the following code, which I found > in the perldoc for SVN::Client > > use SVN::Client; > my $ctx = new SVN::Client( > auth => [ > SVN::Client::get_simple_provider(), > > SVN::Client::get_simple_prompt_provider(\&simple_prompt,2), > SVN::Client::get_username_provider() > ] > ); > > sub simple_prompt { > my $cred = shift; > my $realm = shift; > my $default_username = shift; > my $may_save = shift; > my $pool = shift; > > print "Enter authentication info for realm: $realm\n"; > print "Username: "; > my $username = <>; > chomp($username); > $cred->username($username); > print "Password: "; > my $password = <>; > chomp($password); > $cred->password($password); > } > > (I know the password is in clear, but I can fix that later). > > If the username and password are cached this works perfectly > well. When I comment out the get_simple_provider line (to > simulate authentication data not being cached) I am asked for > a username and password. If I enter the correct ones > everything works. Otherwise I am asked two more times, and > eventually the authentication fails. > > So, my questions are: > > 1) What is get_username_provider used for? When would I want > to get the chached username only? > > 2) How can I implement my second point "ask for a password > for the current username" ? I have tried changing > simple_prompt as follows > > print "Enter authentication info for realm: $realm\n"; > # print "Username: "; > my $username = $default_username; > # chomp($username); > $cred->username($username); > > And it works if I enter the correct password the first time. > But if the password is wrong, not only I'm not asked again > but I get a "Memory fault" error. I wasn't really expecting > to be asked for the username but at least for the password > for two more times. > > Anyone has done what I'm trying to do already? Anyone has any > hints or suggestions? > > Thanks in advance > Giulio > > P.S. I post this email to both mailing list @tigris and > @apache, just becuase the apache one doesn't seem to be very active. Well, after some experimentation I ahve found the solution, so I'm posting it here for future reference. The trick is to use two separate callback subroutines to get_simple_prompt_provider: one to use the default username (and to not retry) and one to ask for both username and password (with 1 retry, so a total of 3 attempts). I have also used the IO::Prompt package to mask the password. my $ctx = SVN::Client->new( auth => [ SVN::Client::get_simple_provider(), SVN::Client::get_simple_prompt_provider(\&ask_for_password,0), SVN::Client::get_simple_prompt_provider(\&ask_for_username_and_password,1), ] ); sub ask_for_password { my ($cred, $realm, $default_username, $may_save, $pool) = @_; print "Enter authentication info for realm: $realm\n"; $cred->username($default_username); my $password = IO::Prompt::prompt('Password: ', -le => '*'); chomp($password); $cred->password($password); } sub ask_for_username_and_password { my ($cred, $realm, $default_username, $may_save, $pool) = @_; print "Enter authentication info for realm: $realm\n"; print "Username: "; my $username = <>; chomp($username); $cred->username($username); my $password = IO::Prompt::prompt('Password: ', -le => '*'); chomp($password); $cred->password($password); }