Skip to content

Commit

Permalink
[SCM-763] Password masking for svnexe does not handle all cases
Browse files Browse the repository at this point in the history
  • Loading branch information
michael-o committed Apr 29, 2018
1 parent 5eb6ba7 commit 60d9884
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,25 +107,25 @@ else if ( !StringUtils.isEmpty( SvnUtil.getSettings().getConfigDirectory() ) )
cl.createArg().setValue( SvnUtil.getSettings().getConfigDirectory() );
}

boolean hasAuthInfo = false;
boolean hasAuthInfo = false;
if ( repository != null && !StringUtils.isEmpty( repository.getUser() ) )
{
hasAuthInfo = true;
hasAuthInfo = true;
cl.createArg().setValue( "--username" );
cl.createArg().setValue( repository.getUser() );
}

if ( repository != null && !StringUtils.isEmpty( repository.getPassword() ) )
{
hasAuthInfo = true;
hasAuthInfo = true;
cl.createArg().setValue( "--password" );
cl.createArg().setValue( repository.getPassword() );
}

// [by Lenik] don't overwrite existing auth cache by default.
if ( hasAuthInfo && !SvnUtil.getSettings().isUseAuthCache() )
// [by Lenik] don't overwrite existing auth cache by default.
if ( hasAuthInfo && !SvnUtil.getSettings().isUseAuthCache() )
{
cl.createArg().setValue( "--no-auth-cache" );
cl.createArg().setValue( "--no-auth-cache" );
}

if ( SvnUtil.getSettings().isUseNonInteractive() )
Expand Down Expand Up @@ -222,21 +222,48 @@ public static String cryptPassword( Commandline cl )
{
String clString = cl.toString();

int pos = clString.indexOf( "--password" );
final String passwordArg = "--password ";
String quoteChar;
String escapedQuoteChar;
String cryptedPassword;

int pos = clString.indexOf( passwordArg );

if ( pos > 0 )
{
String beforePassword = clString.substring( 0, pos + "--password ".length() );
String afterPassword = clString.substring( pos + "--password ".length() );
afterPassword = afterPassword.substring( afterPassword.indexOf( ' ' ) );
String beforePassword = clString.substring( 0, pos + passwordArg.length() );
String afterPassword = clString.substring( pos + passwordArg.length() );

if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
{
clString = beforePassword + "*****" + afterPassword;
quoteChar = "\"";
escapedQuoteChar = "\"\"";
cryptedPassword = "*****";
}
else
{
quoteChar = "'";
escapedQuoteChar = "'\\''";
cryptedPassword = "'*****'";
}

if ( afterPassword.startsWith( quoteChar ) )
{
pos = 1;
while ( afterPassword.indexOf( escapedQuoteChar, pos ) != -1 )
{
pos = afterPassword.indexOf( escapedQuoteChar, pos ) + escapedQuoteChar.length();
}
afterPassword = afterPassword.substring ( afterPassword.indexOf( quoteChar, pos )
+ quoteChar.length() );
}
else
{
clString = beforePassword + "'*****'" + afterPassword;
afterPassword = afterPassword.substring( afterPassword.indexOf( ' ' ) );
}

clString = beforePassword + cryptedPassword + afterPassword;

}

return clString;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@

import org.apache.maven.scm.ScmTestCase;
import org.apache.maven.scm.provider.svn.repository.SvnScmProviderRepository;
import org.codehaus.plexus.util.Os;
import org.codehaus.plexus.util.cli.Commandline;

import static org.junit.Assert.assertNotEquals;

import java.io.File;

/**
Expand All @@ -35,6 +38,9 @@ public class SvnCommandLineUtilsTest
public void testCryptPassword()
throws Exception
{
/* FIXME Plexus does not quote the crypted password on Windows which is actually incorrect at the moment
* it would cause wildcard expansion with cmd: https://github.com/codehaus-plexus/plexus-utils/issues/37.
*/
SvnScmProviderRepository repo =
new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", "password" );
String clString =
Expand All @@ -48,5 +54,72 @@ public void testCryptPassword()
SvnCommandLineUtils.cryptPassword( SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
assertCommandLine( "svn --username username --no-auth-cache --non-interactive", new File( "." ),
SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );

repo = new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", "password with spaces" );
clString =
SvnCommandLineUtils.cryptPassword( SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
expectedCmd = new Commandline( "svn --username username --password ***** --no-auth-cache --non-interactive" );
expectedCmd.setWorkingDirectory( new File( "." ).getAbsolutePath() );
assertEquals( expectedCmd.toString(), clString );

repo = new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", "password'with'single'quotes" );
clString =
SvnCommandLineUtils.cryptPassword( SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
expectedCmd = new Commandline( "svn --username username --password ***** --no-auth-cache --non-interactive" );
expectedCmd.setWorkingDirectory( new File( "." ).getAbsolutePath() );
assertEquals( expectedCmd.toString(), clString );

repo = new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", "password'with'single'quotes and spaces" );
clString =
SvnCommandLineUtils.cryptPassword( SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
expectedCmd = new Commandline( "svn --username username --password ***** --no-auth-cache --non-interactive" );
expectedCmd.setWorkingDirectory( new File( "." ).getAbsolutePath() );
assertEquals( expectedCmd.toString(), clString );

repo = new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", "password\"with\"double\"quotes" );
clString =
SvnCommandLineUtils.cryptPassword( SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
expectedCmd = new Commandline( "svn --username username --password ***** --no-auth-cache --non-interactive" );
expectedCmd.setWorkingDirectory( new File( "." ).getAbsolutePath() );
assertEquals( expectedCmd.toString(), clString );

repo = new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", "password\"with\"double\"quotes and spaces" );
clString =
SvnCommandLineUtils.cryptPassword( SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
expectedCmd = new Commandline( "svn --username username --password ***** --no-auth-cache --non-interactive" );
expectedCmd.setWorkingDirectory( new File( "." ).getAbsolutePath() );
// FIXME https://github.com/codehaus-plexus/plexus-utils/issues/36
if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
{
assertNotEquals( expectedCmd.toString(), clString );
}
else {
assertEquals( expectedCmd.toString(), clString );
}

repo = new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", "password\"with\"double\"quotes'and'single'quotes" );
clString =
SvnCommandLineUtils.cryptPassword( SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
expectedCmd = new Commandline( "svn --username username --password ***** --no-auth-cache --non-interactive" );
expectedCmd.setWorkingDirectory( new File( "." ).getAbsolutePath() );
assertEquals( expectedCmd.toString(), clString );

repo = new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", "password\"with\"double\"quotes'and'single'quotes and spaces" );
clString =
SvnCommandLineUtils.cryptPassword( SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
expectedCmd = new Commandline( "svn --username username --password ***** --no-auth-cache --non-interactive" );
expectedCmd.setWorkingDirectory( new File( "." ).getAbsolutePath() );
// FIXME https://github.com/codehaus-plexus/plexus-utils/issues/36
if ( Os.isFamily( Os.FAMILY_WINDOWS ) )
{
assertNotEquals( expectedCmd.toString(), clString );
}
else {
assertEquals( expectedCmd.toString(), clString );
}

repo = new SvnScmProviderRepository( "https://svn.apache.org/repos/asf/maven/scm/trunk", "username", null );
assertCommandLine( "svn --username username --no-auth-cache --non-interactive", new File( "." ),
SvnCommandLineUtils.getBaseSvnCommandLine( new File( "." ), repo ) );
}
}

0 comments on commit 60d9884

Please sign in to comment.