Skip to content

Commit 9b6edc2

Browse files
JENKINS-42093 - fix quoting in askpass script
1 parent 10a2dff commit 9b6edc2

File tree

3 files changed

+127
-1
lines changed

3 files changed

+127
-1
lines changed

src/main/java/com/cloudbees/jenkins/plugins/sshagent/exec/ExecRemoteAgent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ private FilePath createAskpassScript() throws IOException, InterruptedException
163163
// suffix = ".bat";
164164
// script = "@ECHO %SSH_PASSPHRASE%\nDEL \"" + askpass.getAbsolutePath() + "\"\n";
165165

166-
FilePath askpass = temp.createTextTempFile("askpass_", ".sh", "#!/bin/sh\necho $SSH_PASSPHRASE\nrm $0\n");
166+
FilePath askpass = temp.createTextTempFile("askpass_", ".sh", "#!/bin/sh\necho \"$SSH_PASSPHRASE\"\nrm \"$0\"\n");
167167

168168
// executable only for a current user
169169
askpass.chmod(0700);

src/test/java/com/cloudbees/jenkins/plugins/sshagent/SSHAgentBase.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,68 @@ public String getPrivateKey() {
217217
+ "-----END RSA PRIVATE KEY-----\n";
218218
}
219219

220+
/**
221+
* Same key as getPrivateKey(), but encrypted with a different passphrase
222+
*
223+
* @return
224+
*/
225+
public String getPrivateKey2() {
226+
return "-----BEGIN RSA PRIVATE KEY-----\n"
227+
+ "Proc-Type: 4,ENCRYPTED\n"
228+
+ "DEK-Info: AES-128-CBC,4F1CC1FC8ABFF63F16459D0FD743235A\n"
229+
+ "\n"
230+
+ "5eKeY3ayrWVVrfx2aDpxB487t5NmykzZaLwlZ2YD97DA7mE4S87ywwBF3Dg8pG9e\n"
231+
+ "VCa03SfcjOITuXh6+Eh3dlAC5xC3Cg/gYfRKPUYrkNDkGOuAjuf/54iE+OVMS3Cm\n"
232+
+ "gc2ZSWHKS1VRsh/StcVGemGsGknx5Ij7vNjHTLLi7RlK290PNTFRjbzpGUziTYqE\n"
233+
+ "tYUfMtCUeAupZBxZTr+BLkA9wSLmDsA0K6J5kkGAvTZ4xM71u48QGjgOlOIiVkQK\n"
234+
+ "r+kdtyvN2M38mkH+abUWYBs/Cfk0ZjpCez83XmEM8bASEbH6BAg9JZ1JdJp/dSiW\n"
235+
+ "z267NfjGLKdUXreopgJhEj7OFIjxWsXcr1MVx9NrrdRYa+JPvooUtUu4AI4zG72E\n"
236+
+ "MOCEydUwS8rMVsm3f2nDowlCq8ZyVRPoTGtkJgIzolJYcnd9XpnhqQvK+9PLva4k\n"
237+
+ "3MIqIhyeyOoXl77ESZbl2VGwkqx9tR5HnSPr5mDXNJsSFLaxYkvfz8Zv97t4zAtb\n"
238+
+ "lLtxnlKFwXwYiSudlK0d249BAIj+pBQBz+gq7Teks1Er8Xr4TaCUG9DRer1j9wYM\n"
239+
+ "EhchnG/Vtvq6Lk8JN4GiAGpQNhk7Zxy71gljzidN79bMIPKpaF5xqJOLstUrxKGw\n"
240+
+ "yIrD6Pn2Mf7QbM5EK7bnWsWITN0LDzGej1FtnXSBQvJz/QEDK2v/MAgJd9bT3Unm\n"
241+
+ "cS0VbY0mi+UeIPcpvS5gc0k/6wXzr2IHKBDjre2Nh7fRZiII8dB60gg9GtzMeo9b\n"
242+
+ "JuOUGCMoXl0h6AG6mrF5tWRy58vs19JJYuwSS/tVbxVEiwWGaQ/oeaTDBnQ/HOhk\n"
243+
+ "ZssU5Ks0hQcRnnbV+3sikCx6k33Jf1vyfmzEKSyQdKL9GfWCmS/fBz7liPHaLtJu\n"
244+
+ "PNToqL2A0a6eMsk7ytttVy/HpfSCMDcbyYcBEL+lEhb3T6uL5+yyRRaXk+ZkXxUJ\n"
245+
+ "p/0vUBhNnwIlU4MYZsoU4R27ss7SDl3orra84GpfY1x+DdVUeDBnlH3fbvQzOT9w\n"
246+
+ "3RLxkTl6H3DbfiAwWeSJF3UZK88c2J69rl4lrwfV/g4UMuK50GDby3HNV8zuLFeI\n"
247+
+ "1pRyqfEqVRRAde9N1+uMa+fqZDujw3eH/hhh7nPa2NYawQN4klutLzpAj/lv6uU/\n"
248+
+ "ubeISASZbv4bBGHROvprsglx/GuJ93zIdcwbdtyBysqbZsjoZhL2mTV0kmvlxzL0\n"
249+
+ "oplngeaVcRzhnDEbFXNo6e9EthCCxUPe46xALsH+JBI7scgq+hTHtHTMrk3I/CU7\n"
250+
+ "RqjaqWG/0FhWMKpdIVghIHHHTL3ndsoFNiB3qXRd/3OOmXJP302MDX4Zj4SxBGB3\n"
251+
+ "YZeOj14yMZ51TJCR+NfqK7a7YSZHPU8ynOUtOf9XKfXwD2oyD42Zp0E6kY4INJ0k\n"
252+
+ "buxhmHH1f4cva1zEXwOTzziKMpk1TYW1oi+7YcbeLDRs2I3Fvz2KCMmUnxIpxT8Q\n"
253+
+ "ol1IyPxfKl6VD51gVKERNdEIyHLarHn+DiSHBto3JNj395H9vm68hdoFQDbalfPr\n"
254+
+ "X3iUnblOV+BwPz8IGRN90evksIA3r/PUFAFuwfDAmrPe7qUid3ur+nrVVxojLbgX\n"
255+
+ "JHN9BtDRQghkDt2igqgzuuwvShpyS1Yya5byA1Pbegrl4Yn1hERLie0kAhihZemB\n"
256+
+ "NRQDw2T4nuI0uRHL1Pold8phlK/xINh5aOhD40qOykz5LFYk2m3Eh+tdYEdexhYj\n"
257+
+ "x2HxCRL9jsCGdmifNqCT4WVLnj0YXuszeGIAKZE6wCyugQQ+2yFg1eVDE7HdS+ht\n"
258+
+ "U8zpyVNRD/r6rL/9D7ljHca9+c4QMtYK9sd/qh040CNkUxuPjUEVtPVUmap6gK/u\n"
259+
+ "zW7eUofNygSZrZ96NlKF8z2WGDA60RN8VimQZf6TiY87XhceHM1rS8jbtIkhzooH\n"
260+
+ "cDsX2HJCtBZMlvZZxNxmPMEVhmHYVvtCM/4MG5Ud8mQ41I1icreiAldpXAXD4Nua\n"
261+
+ "WhrgnHt4dsvkzVC8pVW5JMjNVGw55WmJutwnQPisqMCJLMpxu18Bi/NG1I3Syj9f\n"
262+
+ "Jyqp0X5i4CI1IS19a8+zRk093jbdC83N6fnFI58vwOeHlEQEgWptJe9LJ4YfhfQ9\n"
263+
+ "ha/XfGwshCs2/aTv0vIU/2pbkCA3kC9QLAc/r8QlgKV3/yqVlQ70BqxSbw0SsVVg\n"
264+
+ "gDNLx+BFRVq+bnohANvdfgjqF7OXtKPaYxj9ggQoC2vlb8uvCzB6eTi4eP68Flvx\n"
265+
+ "NC7zg1f8y1/Me6tFRCKzBEZg29NiEnmQaO4daCtVL92HhcFjdG43PSwKRL48Uc73\n"
266+
+ "9yZIm4hcImp71sS5QO7jsPxiTXNa6rWaAsd12Tii7/kNIT5NOACWVr4WxUAdTVMH\n"
267+
+ "leQueMk/8iGU6aM5Zr4SGezS934hOig3w8zlHOLSE+SadiexpXjPJe1RBb/9D8qG\n"
268+
+ "7nynZVMbONbXRYWHuCPal/DdrkN6YynD5yBqrFvxZ7svJJFIH+Mw6o5DI3fYPER/\n"
269+
+ "QB8TuBvdE5dSyuAPd3bHAugQyZMSn6usENWsHdquVvBGJZRnmVJxYBWPD5/XD5d3\n"
270+
+ "UXi6ctjwBGobJOMgg4XzO6AxH9hKg8yacAv67N921zydnEjYMvosErtBXq6E6HXI\n"
271+
+ "5ytVdR6q5vgG0vjXflpBsxRZm2I9uNOQuR6sjC0HDMmktQOESGWy+IwH5Z0vrs98\n"
272+
+ "Rk6StDVqHlwbW85sCOBzYeZs9w5C1e9fT76kMTsm/E28y5OduLXRTW/Eqnr0DeUf\n"
273+
+ "KgPw/bgJemOKNC0W6jZsqAFpArQ0PGuWikhsdoSIhRHXHjQnSqKv5qKzYiFZvPyV\n"
274+
+ "8P+u3DvYl5pRY9W2qyuFcrspWlgaunKV9VK5VJGyTmt0ezI+dSNvOmCSmOxv5nly\n"
275+
+ "+00Ilh9+VfudUq+WHAsUEC5VSL2NqLjHryBF/BZwCa+3Kdikh9qbEMC159Hw7rZs\n"
276+
+ "qrgr6SWapKNogPqDbeTRA6w9bptKzSUxm371pr6RefDcuPaab9jamqQPCg7rqnjs\n"
277+
+ "+2nKK8wY67JkilnYmWzqTykKUVGoKMqfSIv5COOTgWCGNtipIxhoMIqHpCuUp6uJ\n"
278+
+ "VZYF6iimsK8r3AqMCwXT7SyGPkbU7LaLpE39sdKiqQr7AV6xidR2fii/+oh+EECl\n"
279+
+ "-----END RSA PRIVATE KEY-----\n";
280+
}
281+
220282
/**
221283
* Returns a string with the authorized Public Key.
222284
*

src/test/java/com/cloudbees/jenkins/plugins/sshagent/SSHAgentBuildWrapperTest.java

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@
66
import com.cloudbees.plugins.credentials.CredentialsScope;
77
import com.cloudbees.plugins.credentials.SystemCredentialsProvider;
88
import hudson.model.Fingerprint;
9+
import hudson.model.FreeStyleBuild;
910
import hudson.model.FreeStyleProject;
1011
import hudson.model.Result;
1112
import hudson.tasks.Shell;
1213
import java.util.ArrayList;
1314
import java.util.List;
15+
import java.util.concurrent.Future;
1416
import org.junit.ClassRule;
1517
import org.junit.Rule;
1618
import org.junit.Test;
@@ -187,4 +189,66 @@ public void testTrackingOfCredential() throws Exception {
187189

188190
stopMockSSHServer();
189191
}
192+
193+
@Issue("JENKINS-42093")
194+
@Test
195+
public void sshAgentWithSpacesInWorkspacePath() throws Exception {
196+
startMockSSHServer();
197+
198+
List<String> credentialIds = new ArrayList<String>();
199+
credentialIds.add(CREDENTIAL_ID);
200+
201+
SSHUserPrivateKey key = new BasicSSHUserPrivateKey(CredentialsScope.GLOBAL, credentialIds.get(0), "cloudbees",
202+
new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource(getPrivateKey()), "cloudbees", "test");
203+
SystemCredentialsProvider.getInstance().getCredentials().add(key);
204+
SystemCredentialsProvider.getInstance().save();
205+
206+
FreeStyleProject job = r.createFreeStyleProject("name with spaces");
207+
job.setAssignedNode(r.createSlave());
208+
209+
SSHAgentBuildWrapper sshAgent = new SSHAgentBuildWrapper(credentialIds, false);
210+
job.getBuildWrappersList().add(sshAgent);
211+
212+
Shell shell = new Shell("set | grep SSH_AUTH_SOCK "
213+
+ "&& ssh-add -l "
214+
+ "&& ssh -o NoHostAuthenticationForLocalhost=yes -o StrictHostKeyChecking=no -p " + getAssignedPort()
215+
+ " -v -l cloudbees " + SSH_SERVER_HOST);
216+
job.getBuildersList().add(shell);
217+
218+
Future<? extends FreeStyleBuild> build = job.scheduleBuild2(0);
219+
r.assertBuildStatusSuccess(build);
220+
r.assertLogNotContains("rm: ", build.get());
221+
222+
stopMockSSHServer();
223+
}
224+
225+
@Test
226+
public void sshAgentWithTrickyPassphrase() throws Exception {
227+
startMockSSHServer();
228+
229+
List<String> credentialIds = new ArrayList<String>();
230+
credentialIds.add(CREDENTIAL_ID);
231+
232+
SSHUserPrivateKey key = new BasicSSHUserPrivateKey(CredentialsScope.GLOBAL, credentialIds.get(0), "cloudbees",
233+
new BasicSSHUserPrivateKey.DirectEntryPrivateKeySource(getPrivateKey2()), "* .*", "test");
234+
SystemCredentialsProvider.getInstance().getCredentials().add(key);
235+
SystemCredentialsProvider.getInstance().save();
236+
237+
FreeStyleProject job = r.createFreeStyleProject();
238+
job.setAssignedNode(r.createSlave());
239+
240+
SSHAgentBuildWrapper sshAgent = new SSHAgentBuildWrapper(credentialIds, false);
241+
job.getBuildWrappersList().add(sshAgent);
242+
243+
Shell shell = new Shell("set | grep SSH_AUTH_SOCK "
244+
+ "&& ssh-add -l "
245+
+ "&& ssh -o NoHostAuthenticationForLocalhost=yes -o StrictHostKeyChecking=no -p " + getAssignedPort()
246+
+ " -v -l cloudbees " + SSH_SERVER_HOST);
247+
job.getBuildersList().add(shell);
248+
249+
r.assertBuildStatusSuccess(job.scheduleBuild2(0));
250+
251+
stopMockSSHServer();
252+
}
253+
190254
}

0 commit comments

Comments
 (0)