Skip to content
Browse files
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 8a2ddf222f4463e2458e387121bf8d4c7840c37a
Showing 1 changed file with 34 additions and 10 deletions.
@@ -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);
@@ -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();
@@ -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");
@@ -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));
@@ -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();

0 comments on commit 8a2ddf2

Please sign in to comment.