Skip to content
Permalink
Browse files

Merge pull request #11 from jglick/temp-dir-JENKINS-27152

[JENKINS-27152] Use a standardized directory for $SSH_AUTH_SOCK
  • Loading branch information
jglick committed Mar 4, 2016
2 parents 12f6ff0 + 361a072 commit f96025a616f9e5407befea51d76619ec5b266026
80 pom.xml
@@ -29,7 +29,7 @@
<parent>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>plugin</artifactId>
<version>1.609.1</version>
<version>2.3</version>
</parent>

<artifactId>ssh-agent</artifactId>
@@ -65,11 +65,8 @@
</scm>

<properties>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<project.build.outputEncoding>UTF-8</project.build.outputEncoding>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<findbugs-maven-plugin.version>3.0.1</findbugs-maven-plugin.version>
<findbugs.failOnError>true</findbugs.failOnError>
<jenkins.version>1.609.3</jenkins.version>
<java.level>7</java.level> <!-- sshd-core is 7+ -->
<workflow-jenkins-plugin.version>1.9</workflow-jenkins-plugin.version>
</properties>

@@ -120,12 +117,6 @@
<artifactId>jnr-unixsocket-nodep</artifactId>
<version>0.3.1</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>annotations</artifactId>
<version>3.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-step-api</artifactId>
@@ -176,43 +167,23 @@
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
<dependency> <!-- TODO Jenkins sshd (1.6) depends on sshd-core 0.8, which is incompatible with 1.0 -->
<groupId>org.jenkins-ci.main</groupId>
<artifactId>jenkins-war</artifactId>
<version>${jenkins.version}</version>
<classifier>war-for-test</classifier>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.jenkins-ci.modules</groupId>
<artifactId>sshd</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>

<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.0.1</version>
<executions>
<execution>
<id>enforce-maven</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireMavenVersion>
<version>(,2.1.0),(2.1.0,2.2.0),(2.2.0,)</version>
<message>Maven 2.1.0 and 2.2.0 produce incorrect GPG signatures and checksums respectively.
</message>
</requireMavenVersion>
<requireMavenVersion>
<version>(,3.0),[3.0.4,)</version>
<message>Maven 3.0 through 3.0.3 inclusive do not pass correct settings.xml to Maven Release Plugin</message>
</requireMavenVersion>
</rules>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.1</version>
</plugin>
<plugin>
<groupId>org.jenkins-ci.tools</groupId>
<artifactId>maven-hpi-plugin</artifactId>
@@ -222,25 +193,6 @@
<compatibleSinceVersion>1.5</compatibleSinceVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>${findbugs-maven-plugin.version}</version>
<configuration>
<excludeFilterFile>src/findbugs/excludesFilter.xml</excludeFilterFile>
<failOnError>${findbugs.failOnError}</failOnError>
<xmlOutput>true</xmlOutput>
<findbugsXmlWithMessages>true</findbugsXmlWithMessages>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

This file was deleted.

@@ -25,8 +25,11 @@
package com.cloudbees.jenkins.plugins.sshagent;

import hudson.ExtensionPoint;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.model.TaskListener;
import javax.annotation.CheckForNull;

/**
* Extension point for ssh-agent providers.
@@ -48,13 +51,25 @@
*/
public abstract boolean isSupported(Launcher launcher, TaskListener listener);

@Deprecated
public RemoteAgent start(Launcher launcher, TaskListener listener) throws Throwable {
return start(launcher, listener, null);
}

/**
* Start a ssh-agent on the specified launcher.
*
* @param launcher the launcher on which to start a ssh-agent.
* @param listener a listener for any diagnostics.
* @param temp a temporary directory to use; null if unspecified
* @return the agent.
* @throws Throwable if the agent cannot be started.
*/
public abstract RemoteAgent start(Launcher launcher, TaskListener listener) throws Throwable;
public /*abstract*/ RemoteAgent start(Launcher launcher, TaskListener listener, @CheckForNull FilePath temp) throws Throwable {
if (Util.isOverridden(RemoteAgentFactory.class, getClass(), "start", Launcher.class, TaskListener.class)) {
return start(launcher, listener);
} else {
throw new AbstractMethodError("you must implement the start method");
}
}
}
@@ -32,6 +32,7 @@
import edu.umd.cs.findbugs.annotations.NonNull;
import edu.umd.cs.findbugs.annotations.Nullable;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.Util;
import hudson.model.AbstractBuild;
@@ -56,6 +57,7 @@
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
@@ -243,7 +245,7 @@ public Environment setUp(AbstractBuild build, final Launcher launcher, BuildList
private SSHAgentEnvironment createSSHAgentEnvironment(AbstractBuild build, Launcher launcher, BuildListener listener)
throws IOException, InterruptedException {
try {
return new SSHAgentEnvironment(launcher, listener);
return new SSHAgentEnvironment(launcher, listener, build.getWorkspace());
} catch (IOException e) {
throw new IOException2(Messages.SSHAgentBuildWrapper_CouldNotStartAgent(), e);
} catch (InterruptedException e) {
@@ -334,6 +336,11 @@ public SSHAgentEnvironment(Launcher launcher, final BuildListener listener,
}
}

@Deprecated
public SSHAgentEnvironment(Launcher launcher, final BuildListener listener) throws Throwable {
this(launcher, listener, (FilePath) null);
}

/**
* Construct the environment and initialize on the remote node.
*
@@ -342,15 +349,15 @@ public SSHAgentEnvironment(Launcher launcher, final BuildListener listener,
* @throws Throwable if things go wrong.
* @since 1.9
*/
public SSHAgentEnvironment(Launcher launcher, final BuildListener listener) throws Throwable {
public SSHAgentEnvironment(Launcher launcher, BuildListener listener, @CheckForNull FilePath workspace) throws Throwable {
RemoteAgent agent = null;
listener.getLogger().println("[ssh-agent] Looking for ssh-agent implementation...");
Map<String, Throwable> faults = new LinkedHashMap<String, Throwable>();
for (RemoteAgentFactory factory : Jenkins.getActiveInstance().getExtensionList(RemoteAgentFactory.class)) {
if (factory.isSupported(launcher, listener)) {
try {
listener.getLogger().println("[ssh-agent] " + factory.getDisplayName());
agent = factory.start(launcher, listener);
agent = factory.start(launcher, listener, workspace != null ? SSHAgentStepExecution.tempDir(workspace) : null);
break;
} catch (Throwable t) {
faults.put(factory.getDisplayName(), t);
@@ -4,9 +4,11 @@
import com.cloudbees.plugins.credentials.CredentialsProvider;
import com.google.inject.Inject;
import hudson.EnvVars;
import hudson.FilePath;
import hudson.Launcher;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.slaves.WorkspaceList;
import hudson.util.Secret;
import jenkins.model.Jenkins;
import org.apache.commons.lang.StringUtils;
@@ -32,6 +34,9 @@
@StepContextParameter
private transient Launcher launcher;

@StepContextParameter
private transient FilePath workspace;

@Inject(optional = true)
private SSHAgentStep step;

@@ -82,6 +87,11 @@ public void onResume() {
}
}

// TODO use 1.652 use WorkspaceList.tempDir
static FilePath tempDir(FilePath ws) {
return ws.sibling(ws.getName() + System.getProperty(WorkspaceList.class.getName(), "@") + "tmp");
}

private static class Callback extends BodyExecutionCallback {

private static final long serialVersionUID = 1L;
@@ -149,7 +159,7 @@ private void initRemoteAgent() throws IOException {
if (factory.isSupported(launcher, listener)) {
try {
listener.getLogger().println("[ssh-agent] " + factory.getDisplayName());
agent = factory.start(launcher, listener);
agent = factory.start(launcher, listener, tempDir(workspace));
break;
} catch (Throwable t) {
faults.put(factory.getDisplayName(), t);
@@ -18,8 +18,7 @@
*/
package com.cloudbees.jenkins.plugins.sshagent.jna;

import java.security.PublicKey;
import java.util.List;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import jnr.enxio.channels.NativeSelectorProvider;
import jnr.posix.POSIXFactory;
import jnr.unixsocket.UnixServerSocket;
@@ -41,12 +40,10 @@
import java.util.Iterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.sshd.common.util.Pair;
import javax.annotation.CheckForNull;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;

import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_REQUEST_IDENTITIES;
import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENT_IDENTITIES_ANSWER;


/**
@@ -62,13 +59,15 @@
private UnixServerSocket socket;
private Selector selector;
private volatile boolean selectable = true;
private final @CheckForNull File temp;

public AgentServer() {
this(new AgentImpl());
public AgentServer(File temp) {
this(new AgentImpl(), temp);
}

public AgentServer(SshAgent agent) {
public AgentServer(SshAgent agent, File temp) {
this.agent = agent;
this.temp = temp;
}

public SshAgent getAgent() {
@@ -87,6 +86,9 @@ public String start() throws Exception {
channel.register(selector, SelectionKey.OP_ACCEPT, new SshAgentServerSocketHandler());

POSIXFactory.getPOSIX().chmod(authSocket, 0600);
if (!new File(authSocket).exists()) {
throw new IllegalStateException("failed to create " + authSocket + " of length " + authSocket.length() + " (check UNIX_PATH_MAX)");
}

thread = new Thread(new AgentSocketAcceptor(), "SSH Agent socket acceptor " + authSocket);
thread.setDaemon(true);
@@ -130,14 +132,22 @@ public void run() {
}
}

static String createLocalSocketAddress() throws IOException {
@SuppressFBWarnings(value="RV_RETURN_VALUE_IGNORED_BAD_PRACTICE", justification="createTempFile will fail anyway if there is a problem with mkdirs")
private String createLocalSocketAddress() throws IOException {
String name;
if (temp != null) {
temp.mkdirs();
}
if (OsUtils.isUNIX()) {
File socket = File.createTempFile("jenkins", ".jnr");
File socket = File.createTempFile("ssh", "", temp);
if (socket.getAbsolutePath().length() >= /*UNIX_PATH_MAX*/108) {
LOGGER.log(Level.WARNING, "Cannot use {0} due to UNIX_PATH_MAX; falling back to system temp dir", socket);
socket = File.createTempFile("ssh", "");
}
FileUtils.deleteQuietly(socket);
name = socket.getAbsolutePath();
} else {
File socket = File.createTempFile("jenkins", ".jnr");
File socket = File.createTempFile("ssh", "", temp);
FileUtils.deleteQuietly(socket);
name = "\\\\.\\pipe\\" + socket.getName();
}
@@ -27,6 +27,7 @@
import com.cloudbees.jenkins.plugins.sshagent.Messages;
import com.cloudbees.jenkins.plugins.sshagent.RemoteAgent;
import hudson.model.TaskListener;
import java.io.File;
import org.apache.sshd.common.util.SecurityUtils;
import org.bouncycastle.openssl.PEMKeyPair;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
@@ -38,6 +39,7 @@
import java.io.IOException;
import java.io.StringReader;
import java.security.KeyPair;
import javax.annotation.CheckForNull;

/**
* An implementation that uses Apache SSH to provide the Agent over JNR's UnixSocket implementation.
@@ -62,9 +64,9 @@
* @param listener the listener.
* @throws Exception if the agent could not start.
*/
public JNRRemoteAgent(TaskListener listener) throws Exception {
public JNRRemoteAgent(TaskListener listener, @CheckForNull File temp) throws Exception {
this.listener = listener;
agent = new AgentServer();
agent = new AgentServer(temp);
socket = agent.start();
}

0 comments on commit f96025a

Please sign in to comment.
You can’t perform that action at this time.