Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix special characters bugs in credentials workspace path
JENKINS-44041 - Windows authenticated git checkout fails if '(' or ')' in path to workspace
JENKINS-43931 - Windows authenticated git checkout fails if ' ' in path to workspace
JENKINS-44127 - Authenticated git checkout fails if '%' in path to workspace (Windows & Linux)

Also safeguards against use for "`" (grave) in a workspace path.
Jenkins already guards against that, but the added safety check is low
cost and passes the credentials tests.
  • Loading branch information
MarkEWaite committed May 18, 2017
1 parent 5c74414 commit 8a2ddf2
Showing 1 changed file with 34 additions and 10 deletions.
44 changes: 34 additions & 10 deletions src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java
Expand Up @@ -1425,11 +1425,26 @@ private File createTempFileInSystemDir(String prefix, String suffix) throws IOEx
return Files.createTempFile(prefix, suffix, fileAttribute).toFile();
}

/**
* Create temporary file that is aware of the specific limitations
* of command line git.
*
* For example, no temporary file name (Windows or Unix) may
* include a percent sign in its path because ssh uses the percent
* sign character as the start of token indicator for token
* expansion.
*
* As another example, windows temporary files may not contain a
* space, an open parenthesis, or a close parenthesis anywhere in
* their path, otherwise they break ssh argument passing through
* the GIT_SSH or SSH_ASKPASS environment variable.
*
* @param prefix file name prefix for the generated temporary file
* @param suffix file name suffix for the generated temporary file
* @return temporary file
* @throws IOException on error
*/
private File createTempFile(String prefix, String suffix) throws IOException {
return createTempFile(prefix, suffix, false);
}

private File createTempFile(String prefix, String suffix, boolean spacesForbiddenInPath) throws IOException {
if (workspace == null) {
return createTempFileInSystemDir(prefix, suffix);
}
Expand All @@ -1440,16 +1455,25 @@ private File createTempFile(String prefix, String suffix, boolean spacesForbidde
}
}
Path tmpPath = Paths.get(workspaceTmp.getAbsolutePath());
if (workspaceTmp.getAbsolutePath().contains("%")) {
// Avoid ssh token expansion on all platforms
return createTempFileInSystemDir(prefix, suffix);
}
if (isWindows()) {
/* Windows git fails its call to GIT_SSH if its absolute
* path contains a space. Use system temp dir if path to
* workspace tmp dir contains a space.
* path contains a space or parenthesis or pipe or question mark or asterisk.
* Use system temp dir instead of workspace temp dir.
*/
if (spacesForbiddenInPath && workspaceTmp.getAbsolutePath().contains(" ")) {
if (workspaceTmp.getAbsolutePath().matches(".*[ ()|?*].*")) {
return createTempFileInSystemDir(prefix, suffix);
}
return Files.createTempFile(tmpPath, prefix, suffix).toFile();
}
// Unix specific
if (workspaceTmp.getAbsolutePath().contains("`")) {
// Avoid backquote shell expansion
return createTempFileInSystemDir(prefix, suffix);
}
Set<PosixFilePermission> ownerOnly = PosixFilePermissions.fromString("rw-------");
FileAttribute fileAttribute = PosixFilePermissions.asFileAttribute(ownerOnly);
return Files.createTempFile(tmpPath, prefix, suffix, fileAttribute).toFile();
Expand Down Expand Up @@ -1641,7 +1665,7 @@ private String quoteUnixCredentials(String str) {
}

private File createWindowsSshAskpass(SSHUserPrivateKey sshUser) throws IOException {
File ssh = createTempFile("pass", ".bat", true);
File ssh = createTempFile("pass", ".bat");
try (PrintWriter w = new PrintWriter(ssh, Charset.defaultCharset().toString())) {
// avoid echoing command as part of the password
w.println("@echo off");
Expand All @@ -1665,7 +1689,7 @@ private File createUnixSshAskpass(SSHUserPrivateKey sshUser) throws IOException

/* Package protected for testability */
File createWindowsBatFile(String userName, String password) throws IOException {
File askpass = createTempFile("pass", ".bat", true);
File askpass = createTempFile("pass", ".bat");
try (PrintWriter w = new PrintWriter(askpass, Charset.defaultCharset().toString())) {
w.println("@set arg=%~1");
w.println("@if (%arg:~0,8%)==(Username) echo " + escapeWindowsCharsForUnquotedString(userName));
Expand Down Expand Up @@ -1810,7 +1834,7 @@ private File getSSHExeFromGitExeParentDir(String userGitExe) {
}

private File createWindowsGitSSH(File key, String user) throws IOException {
File ssh = createTempFile("ssh", ".bat", true);
File ssh = createTempFile("ssh", ".bat");

File sshexe = getSSHExecutable();

Expand Down

0 comments on commit 8a2ddf2

Please sign in to comment.