Skip to content

Commit

Permalink
libs: use sshd-core 2.7.0
Browse files Browse the repository at this point in the history
Motivation:
The newer OSes disable by default unsecure ciphers and enforce the
stronger once.

Modification:
Update sshd-core to up-to-date version to make use of new ciphers.
Adjust code to match API changes.

Result:
better compatibility with new ssh clients

Acked-by:
Target: master
Require-book: no
Require-notes: yes
  • Loading branch information
kofemann committed Aug 24, 2021
1 parent 5b07905 commit f27c206
Show file tree
Hide file tree
Showing 11 changed files with 55 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package org.dcache.services.ssh2;

import org.apache.sshd.common.Factory;
import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.shell.ShellFactory;
import org.springframework.beans.factory.annotation.Required;

import java.io.File;
Expand All @@ -14,7 +15,7 @@
import org.dcache.cells.CellStub;
import org.dcache.util.list.ListDirectoryHandler;

public class ShellFactory implements Factory<Command>, CellMessageSender
public class AdminShellFactory implements ShellFactory, CellMessageSender
{
private CellEndpoint _endpoint;
private File _historyFile;
Expand Down Expand Up @@ -80,12 +81,12 @@ public void setCellEndpoint(CellEndpoint endpoint)
}

@Override
public Command create()
public Command createShell(ChannelSession channelSession)
{
return new ShellCommand(_historyFile, _historySize, _useColor, createShell());
return new ShellCommand(_historyFile, _historySize, _useColor, createAdminShell());
}

private UserAdminShell createShell()
private UserAdminShell createAdminShell()
{
UserAdminShell shell = new UserAdminShell(_prompt);
shell.setCellEndpoint(_endpoint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jline.console.history.FileHistory;
import jline.console.history.MemoryHistory;
import jline.console.history.PersistentHistory;
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;
Expand Down Expand Up @@ -78,7 +79,7 @@ public AnsiTerminalCommand(File historyFile, int historySize, boolean useColor,
}

@Override
public void destroy() {
public void destroy(ChannelSession channelSession) {
Thread thread = _pipeThread;
if (thread != null) {
thread.interrupt();
Expand Down Expand Up @@ -109,7 +110,7 @@ public void setOutputStream(OutputStream out) {
}

@Override
public void start(Environment env) throws IOException {
public void start(ChannelSession channelSession, Environment env) throws IOException {
_pipedOut = new PipedOutputStream();
_pipedIn = new PipedInputStream(_pipedOut);
_userAdminShell.setUser(env.getEnv().get(Environment.ENV_USER));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,10 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
*/
package org.dcache.services.ssh2;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -97,7 +96,7 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
*
* @author litvinse
*/
public class DirectCommand implements Command, Runnable, SessionAware
public class DirectCommand implements Command, Runnable
{
private static final Logger LOGGER =
LoggerFactory.getLogger(DirectCommand.class);
Expand Down Expand Up @@ -128,7 +127,7 @@ public class DirectCommand implements Command, Runnable, SessionAware
}

@Override
public void destroy() {
public void destroy(ChannelSession channelSession) {
shellThread.interrupt();
}

Expand All @@ -153,9 +152,13 @@ public void setOutputStream(OutputStream out) {
}

@Override
public void start(Environment env) {
public void start(ChannelSession channelSession, Environment env) {

sessionId = Sessions.connectionId(channelSession.getServerSession());

try (CDC ignored = new CDC()) {
CDC.setSession(sessionId);
shell.setSession(sessionId);
shell.setUser(env.getEnv().get(Environment.ENV_USER));
CDC cdc = new CDC();
shellThread = new Thread(() -> cdc.execute(this));
Expand Down Expand Up @@ -230,11 +233,4 @@ private void executeCommands() {
}
}
}

@Override
public void setSession(ServerSession session)
{
sessionId = Sessions.connectionId(session);
shell.setSession(sessionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
*/
package org.dcache.services.ssh2;

import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.command.CommandFactory;
import org.springframework.beans.factory.annotation.Required;
Expand Down Expand Up @@ -127,7 +128,7 @@ public void setCellEndpoint(CellEndpoint endpoint)
}

@Override
public Command createCommand(String command) {
public Command createCommand(ChannelSession channelSession, String command) {
checkArgument(command != null, "No command");
return new DirectCommand(Arrays.asList(command.split(COMMAND_SEPARATOR)),
endpoint,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jline.console.history.FileHistory;
import jline.console.history.MemoryHistory;
import jline.console.history.PersistentHistory;
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;
Expand Down Expand Up @@ -69,7 +70,7 @@ public LegacyAdminShellCommand(CellEndpoint endpoint, File historyFile, int hist
}

@Override
public void destroy() {
public void destroy(ChannelSession channelSession) {
if (_adminShellThread != null) {
_adminShellThread.interrupt();
}
Expand All @@ -96,7 +97,7 @@ public void setOutputStream(OutputStream out) {
}

@Override
public void start(Environment env) throws IOException {
public void start(ChannelSession channelSession, Environment env) throws IOException {
String user = env.getEnv().get(Environment.ENV_USER);
_shell = new LegacyAdminShell(user, _endpoint, _prompt);
_console = new ConsoleReader(_in, _out, new ConsoleReaderTerminal(env)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
package org.dcache.services.ssh2;

import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.server.channel.ChannelSession;
import org.apache.sshd.server.command.Command;
import org.apache.sshd.server.subsystem.SubsystemFactory;
import org.springframework.beans.factory.annotation.Required;

import java.io.File;
import java.io.IOException;

import dmg.cells.nucleus.CellEndpoint;
import dmg.cells.nucleus.CellMessageSender;

public class LegacySubsystemFactory implements NamedFactory<Command>, CellMessageSender
public class LegacySubsystemFactory implements SubsystemFactory, CellMessageSender
{
private CellEndpoint _endpoint;

Expand Down Expand Up @@ -53,8 +55,7 @@ public String getName()
}

@Override
public Command create()
{
public Command createSubsystem(ChannelSession channelSession) throws IOException {
return new LegacyAdminShellCommand(_endpoint, _historyFile, _historySize, _prompt, _useColor);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package org.dcache.services.ssh2;

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;
Expand Down Expand Up @@ -45,7 +46,7 @@ public NoTerminalCommand(UserAdminShell shell)
}

@Override
public void destroy() {
public void destroy(ChannelSession channelSession) {
}

@Override
Expand All @@ -69,7 +70,7 @@ public void setOutputStream(OutputStream out) {
}

@Override
public void start(Environment env) throws IOException {
public void start(ChannelSession channelSession, Environment env) throws IOException {
_userAdminShell.setUser(env.getEnv().get(Environment.ENV_USER));
CDC cdc = new CDC();
_adminShellThread = new Thread(() -> cdc.execute(this));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* dCache - http://www.dcache.org/
*
* Copyright (C) 2015 Deutsches Elektronen-Synchrotron
* Copyright (C) 2015 - 2021 Deutsches Elektronen-Synchrotron
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
Expand All @@ -17,11 +17,10 @@
*/
package org.dcache.services.ssh2;

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 java.io.File;
import java.io.IOException;
Expand All @@ -32,7 +31,7 @@

import dmg.cells.nucleus.CDC;

public class ShellCommand implements Command, SessionAware
public class ShellCommand implements Command
{
private final File historyFile;
private final int historySize;
Expand Down Expand Up @@ -79,9 +78,11 @@ public void setExitCallback(ExitCallback callback)
}

@Override
public void start(Environment env) throws IOException
public void start(ChannelSession channelSession, Environment env) throws IOException
{
try (CDC ignored = new CDC()) {
sessionId = Sessions.connectionId(channelSession.getServerSession());
shell.setSession(sessionId);
CDC.setSession(sessionId);
if (env.getEnv().get(Environment.ENV_TERM) != null) {
delegate = new AnsiTerminalCommand(historyFile, historySize, useColor, shell);
Expand All @@ -92,22 +93,15 @@ public void start(Environment env) throws IOException
delegate.setOutputStream(out);
delegate.setErrorStream(err);
delegate.setExitCallback(callback);
delegate.start(env);
delegate.start(channelSession, env);
}
}

@Override
public void destroy() throws Exception
public void destroy(ChannelSession channelSession) throws Exception
{
if (delegate != null) {
delegate.destroy();
delegate.destroy(channelSession);
}
}

@Override
public void setSession(ServerSession session)
{
sessionId = Sessions.connectionId(session);
shell.setSession(sessionId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,23 @@
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Iterables;
import org.apache.sshd.common.Factory;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.config.keys.AuthorizedKeyEntry;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.keyprovider.FileKeyPairProvider;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.util.security.SecurityUtils;
import org.apache.sshd.server.command.Command;
import org.apache.sshd.core.CoreModuleProperties;
import org.apache.sshd.server.command.CommandFactory;
import org.apache.sshd.server.SshServer;
import org.apache.sshd.server.auth.gss.GSSAuthenticator;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;

import org.apache.sshd.server.shell.ShellFactory;
import org.apache.sshd.server.subsystem.SubsystemFactory;
import org.dcache.auth.LoginNamePrincipal;
import org.dcache.auth.LoginReply;
import org.dcache.auth.LoginStrategy;
Expand All @@ -47,6 +46,7 @@
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.PublicKey;
import java.time.Duration;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List;
Expand Down Expand Up @@ -151,7 +151,7 @@ public void setAuthorizedKeyList(File authorizedKeyList) {
}

@Required
public void setShellFactory(Factory<Command> shellCommand) {
public void setShellFactory(ShellFactory shellCommand) {
_server.setShellFactory(shellCommand);
}

Expand All @@ -161,7 +161,7 @@ public void setCommandFactory(CommandFactory commandFactory) {
}

@Required
public void setSubsystemFactories(List<NamedFactory<Command>> subsystemFactories)
public void setSubsystemFactories(List<SubsystemFactory> subsystemFactories)
{
_server.setSubsystemFactories(subsystemFactories);
}
Expand Down Expand Up @@ -223,15 +223,16 @@ public void beforeStop() {
}

private void configureKeyFiles() {
KeyPairProvider keyPair = SecurityUtils.createGeneratorHostKeyProvider(_hostKey);
KeyPairProvider keyPair = new FileKeyPairProvider(_hostKey);
_server.setKeyPairProvider(keyPair);
}

private void startServer() {
long effectiveTimeout = _idleTimeoutUnit.toMillis(_idleTimeout);
PropertyResolverUtils.updateProperty(_server, FactoryManager.IDLE_TIMEOUT, effectiveTimeout);
// esure, that read timeout is longer than idle timeout
PropertyResolverUtils.updateProperty(_server, FactoryManager.NIO2_READ_TIMEOUT, effectiveTimeout*2);
// Duration#of is picky about overflows
Duration effectiveTimeout = Duration.ofMillis(_idleTimeoutUnit.toMillis(_idleTimeout));
CoreModuleProperties.IDLE_TIMEOUT.set(_server, effectiveTimeout);
// ensure, that read timeout is longer than idle timeout
CoreModuleProperties.NIO2_READ_TIMEOUT.set(_server, effectiveTimeout);

_server.setPort(_port);
_server.setHost(_host);
Expand Down Expand Up @@ -335,7 +336,7 @@ public boolean authenticate(String userName, PublicKey key,
userName, key);
try {
for(AuthorizedKeyEntry ke: AuthorizedKeyEntry.readAuthorizedKeys(_authorizedKeyList.toPath())) {
PublicKey publicKey = ke.resolvePublicKey(null);
PublicKey publicKey = ke.resolvePublicKey(null, null);

String hostspec = ke.getLoginOptions().getOrDefault("from", "");
if (!isValidHost(hostspec, session)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
<property name="cellStub" ref="gplazma"/>
</bean>

<bean id="shell-factory" class="org.dcache.services.ssh2.ShellFactory">
<bean id="shell-factory" class="org.dcache.services.ssh2.AdminShellFactory">
<property name="historyFile" value="${admin.paths.history}"/>
<property name="historySize" value="${admin.history.size}"/>
<property name="useColor" value="${admin.enable.colors}"/>
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@
<dependency>
<groupId>org.apache.sshd</groupId>
<artifactId>sshd-core</artifactId>
<version>2.1.0</version>
<version>2.7.0</version>
</dependency>
<dependency>
<!-- Newer versions have two problems. A performance regression causes it to block on non-responding network
Expand Down

0 comments on commit f27c206

Please sign in to comment.