Skip to content

Commit

Permalink
Upgrade to SSHD 2.7.0 (#45)
Browse files Browse the repository at this point in the history
* bump to 2.7.0

* waiting for 2.7.0 version on the mvn repo

* use 2.7.0-SNAPSHOT until the release

* Update pom.xml

* Update pom.xml

* fix: update deprecated methods

* fix: update timeout setup

* fix: use ACL.as in the correct way

* chore: remove unused exports

* Update src/main/java/org/jenkinsci/main/modules/sshd/AsynchronousCommand.java

Co-authored-by: Jesse Glick <jglick@cloudbees.com>

* chore: add flushes to the catch block

* fix: missing import

* chore: refactor flush to a method

* chore: bump plugin version to 3.1.0

* chore: bump Jenkins Core to an LTS version

* Update pom.xml

Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com>

Co-authored-by: Jesse Glick <jglick@cloudbees.com>
Co-authored-by: Tim Jacomb <21194782+timja@users.noreply.github.com>
  • Loading branch information
3 people committed Jul 20, 2021
1 parent 7fc8037 commit 50f4033
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 33 deletions.
6 changes: 3 additions & 3 deletions pom.xml
Expand Up @@ -29,9 +29,9 @@
</licenses>

<properties>
<revision>3.0.5</revision>
<revision>3.1.0</revision>
<changelist>-SNAPSHOT</changelist>
<jenkins.version>2.282</jenkins.version> <!-- Current weekly -->
<jenkins.version>2.289.1</jenkins.version>
<java.level>8</java.level>
</properties>

Expand All @@ -51,7 +51,7 @@
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>2.5.1</version>
<version>2.7.0</version>
</dependency>
<dependency>
<groupId>net.i2p.crypto</groupId>
Expand Down
Expand Up @@ -2,14 +2,14 @@

import hudson.model.User;
import hudson.security.ACL;
import hudson.security.ACLContext;
import jenkins.model.Jenkins;
import org.acegisecurity.context.SecurityContextHolder;
import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.SessionAware;
import org.apache.sshd.server.session.ServerSession;
import org.apache.sshd.server.session.ServerSessionAware;
import org.jenkinsci.main.modules.sshd.SshCommandFactory.CommandLine;

import java.io.IOException;
Expand All @@ -19,16 +19,14 @@
import java.io.PrintWriter;
import java.nio.charset.Charset;

import org.acegisecurity.context.SecurityContext;

import javax.annotation.CheckForNull;

/**
* Partial {@link Command} implementation that uses a thread to run a command.
*
* @author Kohsuke Kawaguchi
*/
public abstract class AsynchronousCommand implements Command, SessionAware, Runnable {
public abstract class AsynchronousCommand implements Command, ServerSessionAware, Runnable {
private InputStream in;
private OutputStream out;
private OutputStream err;
Expand Down Expand Up @@ -112,32 +110,39 @@ public void start(Environment env) throws IOException {
public void run() {
try {
int i;

// run the command in the context of the authenticated user
SecurityContext old = SecurityContextHolder.getContext();
User user = getCurrentUser();
if (user!=null)
ACL.impersonate(user.impersonate());

try {
if (user != null) {
try (ACLContext ctx = ACL.as(user)) {
i = AsynchronousCommand.this.runCommand();
} finally {
out.flush(); // working around SSHD-154
err.flush();
SecurityContextHolder.setContext(old);
}
} else {
i = AsynchronousCommand.this.runCommand();
}
flushOutputs();
callback.onExit(i);
} catch (Exception e) {
// report the cause of the death to the client
//TODO: Consider switching to UTF-8
PrintWriter ps = new PrintWriter(new OutputStreamWriter(err, Charset.defaultCharset()));
e.printStackTrace(ps);
ps.flush();

flushOutputs();
callback.onExit(255,e.getMessage());
}
}

/**
* working around SSHD-154
*/
private void flushOutputs() {
try {
out.flush();
err.flush();
} catch (IOException ioException) {
//NOOP
}
}

@Override
public void destroy(ChannelSession channel) throws Exception {
destroy();
Expand Down
10 changes: 6 additions & 4 deletions src/main/java/org/jenkinsci/main/modules/sshd/IdleTimeout.java
@@ -1,7 +1,8 @@
package org.jenkinsci.main.modules.sshd;

import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.core.CoreModuleProperties;
import org.apache.sshd.server.SshServer;
import java.time.Duration;
import java.util.logging.Logger;

import org.kohsuke.accmod.Restricted;
Expand All @@ -15,6 +16,7 @@
public class IdleTimeout {

private static final Logger LOGGER = Logger.getLogger(IdleTimeout.class.getName());
public static final long ADDITIONAL_TIME_FOR_TIMEOUT = 60000;

private final Long timeoutInMilliseconds;

Expand Down Expand Up @@ -42,13 +44,13 @@ public void apply(SshServer sshd) {
return;
}

sshd.getProperties().put(ServerFactoryManager.IDLE_TIMEOUT, timeoutInMilliseconds);
CoreModuleProperties.IDLE_TIMEOUT.set(sshd, Duration.ofMillis(timeoutInMilliseconds));
// Read timeout must also be changed
long readTimeout = 0;
if (timeoutInMilliseconds != 0) {
readTimeout = ServerFactoryManager.DEFAULT_NIO2_READ_TIMEOUT - ServerFactoryManager.DEFAULT_IDLE_TIMEOUT + timeoutInMilliseconds;
readTimeout = ADDITIONAL_TIME_FOR_TIMEOUT + timeoutInMilliseconds;
}
sshd.getProperties().put(ServerFactoryManager.NIO2_READ_TIMEOUT, readTimeout);
CoreModuleProperties.NIO2_READ_TIMEOUT.set(sshd, Duration.ofSeconds(readTimeout));
}

}
@@ -1,7 +1,7 @@
package org.jenkinsci.main.modules.sshd;


import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.core.CoreModuleProperties;
import org.apache.sshd.server.SshServer;
import org.junit.Assert;
import org.junit.Before;
Expand Down Expand Up @@ -29,8 +29,8 @@ public void applyEmptyTimeout() {
idleTimeout.apply(sshd);

Map<String, Object> properties = sshd.getProperties();
Assert.assertFalse(properties.containsKey(ServerFactoryManager.IDLE_TIMEOUT));
Assert.assertFalse(properties.containsKey(ServerFactoryManager.NIO2_READ_TIMEOUT));
Assert.assertFalse(properties.containsKey(CoreModuleProperties.IDLE_TIMEOUT.getName()));
Assert.assertFalse(properties.containsKey(CoreModuleProperties.NIO2_READ_TIMEOUT.getName()));
}

@Test
Expand All @@ -40,10 +40,8 @@ public void apply24HoursTimeout() {

idleTimeout.apply(sshd);

Map<String, Object> properties = sshd.getProperties();
Assert.assertEquals(timeoutInMilliseconds, properties.get(ServerFactoryManager.IDLE_TIMEOUT));
Object readTimeout = properties.get(ServerFactoryManager.NIO2_READ_TIMEOUT);
Assert.assertTrue(readTimeout instanceof Long);
Assert.assertEquals(timeoutInMilliseconds, CoreModuleProperties.IDLE_TIMEOUT.get(sshd).get().toMillis());
Long readTimeout = CoreModuleProperties.NIO2_READ_TIMEOUT.get(sshd).get().toMillis();
Assert.assertTrue((Long) readTimeout > timeoutInMilliseconds);
}

Expand All @@ -54,8 +52,8 @@ public void applyFromAbsentSystemProperty() {
idleTimeout.apply(sshd);

Map<String, Object> properties = sshd.getProperties();
Assert.assertFalse(properties.containsKey(ServerFactoryManager.IDLE_TIMEOUT));
Assert.assertFalse(properties.containsKey(ServerFactoryManager.NIO2_READ_TIMEOUT));
Assert.assertFalse(properties.containsKey(CoreModuleProperties.IDLE_TIMEOUT.getName()));
Assert.assertFalse(properties.containsKey(CoreModuleProperties.NIO2_READ_TIMEOUT.getName()));
}

}

0 comments on commit 50f4033

Please sign in to comment.