1 package org
.argeo
.cms
.ssh
;
3 import java
.io
.IOException
;
4 import java
.nio
.file
.Files
;
5 import java
.nio
.file
.Path
;
6 import java
.util
.Collections
;
8 import org
.apache
.sshd
.common
.forward
.PortForwardingEventListener
;
9 import org
.apache
.sshd
.common
.session
.Session
;
10 import org
.apache
.sshd
.common
.util
.net
.SshdSocketAddress
;
11 import org
.apache
.sshd
.scp
.server
.ScpCommandFactory
;
12 import org
.apache
.sshd
.server
.SshServer
;
13 import org
.apache
.sshd
.server
.auth
.gss
.GSSAuthenticator
;
14 import org
.apache
.sshd
.server
.forward
.AcceptAllForwardingFilter
;
15 import org
.apache
.sshd
.server
.jaas
.JaasPasswordAuthenticator
;
16 import org
.apache
.sshd
.server
.keyprovider
.SimpleGeneratorHostKeyProvider
;
17 import org
.apache
.sshd
.server
.shell
.InteractiveProcessShellFactory
;
18 import org
.apache
.sshd
.sftp
.server
.SftpSubsystemFactory
;
19 import org
.argeo
.api
.cms
.CmsAuth
;
20 import org
.argeo
.api
.cms
.CmsConstants
;
21 import org
.argeo
.api
.cms
.CmsLog
;
22 import org
.argeo
.api
.cms
.CmsState
;
23 import org
.argeo
.cms
.CmsDeployProperty
;
24 import org
.argeo
.cms
.CmsSshd
;
26 public class CmsSshServer
implements CmsSshd
{
27 private final static CmsLog log
= CmsLog
.getLog(CmsSshServer
.class);
28 private static final String DEFAULT_SSH_HOST_KEY_PATH
= CmsConstants
.NODE
+ '/' + CmsConstants
.NODE
+ ".ser";
30 private CmsState cmsState
;
31 private SshServer sshd
= null;
37 String portStr
= cmsState
.getDeployProperty(CmsDeployProperty
.SSHD_PORT
.getProperty());
40 port
= Integer
.parseInt(portStr
);
42 host
= cmsState
.getDeployProperty(CmsDeployProperty
.HOST
.getProperty());
44 Path hostKeyPath
= cmsState
.getDataPath(DEFAULT_SSH_HOST_KEY_PATH
);
47 sshd
= SshServer
.setUpDefaultServer();
51 if (hostKeyPath
== null)
52 throw new IllegalStateException("An SSH server key must be set");
53 sshd
.setKeyPairProvider(new SimpleGeneratorHostKeyProvider(hostKeyPath
));
54 // sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i",
56 // String[] shellCommand = OS.LOCAL.getDefaultShellCommand();
57 // FIXME transfer args
58 // sshd.setShellFactory(new ProcessShellFactory(shellCommand));
59 sshd
.setShellFactory(InteractiveProcessShellFactory
.INSTANCE
);
60 sshd
.setCommandFactory(new ScpCommandFactory());
63 sshd
.setForwardingFilter(AcceptAllForwardingFilter
.INSTANCE
);
64 // sshd.setForwardingFilter(ForwardingFilter.asForwardingFilter(null, null,
65 // TcpForwardingFilter.DEFAULT));
66 // sshd.setForwarderFactory(DefaultForwarderFactory.INSTANCE);
67 // TcpForwardingFilter tcpForwardingFilter = sshd.getTcpForwardingFilter();
68 sshd
.addPortForwardingEventListener(new PortForwardingEventListener() {
71 public void establishingExplicitTunnel(Session session
, SshdSocketAddress local
,
72 SshdSocketAddress remote
, boolean localForwarding
) throws IOException
{
73 log
.debug("Establishing tunnel " + local
+ ", " + remote
);
77 public void establishedExplicitTunnel(Session session
, SshdSocketAddress local
,
78 SshdSocketAddress remote
, boolean localForwarding
, SshdSocketAddress boundAddress
,
79 Throwable reason
) throws IOException
{
80 log
.debug("Established tunnel " + local
+ ", " + remote
+ ", " + boundAddress
);
84 public void establishingDynamicTunnel(Session session
, SshdSocketAddress local
) throws IOException
{
85 log
.debug("Establishing dynamic tunnel " + local
);
89 public void establishedDynamicTunnel(Session session
, SshdSocketAddress local
,
90 SshdSocketAddress boundAddress
, Throwable reason
) throws IOException
{
91 log
.debug("Established dynamic tunnel " + local
);
97 // sshd.setPublickeyAuthenticator(new DefaultAuthorizedKeysAuthenticator(true));
98 sshd
.setPublickeyAuthenticator(null);
99 // sshd.setKeyboardInteractiveAuthenticator(null);
100 JaasPasswordAuthenticator jaasPasswordAuthenticator
= new JaasPasswordAuthenticator();
101 jaasPasswordAuthenticator
.setDomain(CmsAuth
.NODE
.getLoginContextName());
102 sshd
.setPasswordAuthenticator(jaasPasswordAuthenticator
);
104 Path krb5keyTab
= cmsState
.getDataPath("node/krb5.keytab");
105 if (Files
.exists(krb5keyTab
)) {
106 // FIXME experimental
107 GSSAuthenticator gssAuthenticator
= new GSSAuthenticator();
108 gssAuthenticator
.setKeytabFile(cmsState
.getDataPath("node/krb5.keytab").toString());
109 gssAuthenticator
.setServicePrincipalName("HTTP@" + host
);
110 sshd
.setGSSAuthenticator(gssAuthenticator
);
114 sshd
.setSubsystemFactories(Collections
.singletonList(new SftpSubsystemFactory()));
119 log
.debug(() -> "CMS SSH server started on port " + port
+ (host
!= null ?
" of host " + host
: ""));
120 } catch (IOException e
) {
121 throw new RuntimeException("Cannot start SSH server on port " + port
, e
);
131 log
.debug(() -> "CMS SSH server stopped on port " + port
+ (host
!= null ?
" of host " + host
: ""));
132 } catch (IOException e
) {
133 throw new RuntimeException("Cannot stop SSH server", e
);
138 public void setCmsState(CmsState cmsState
) {
139 this.cmsState
= cmsState
;