I'm trying to use mina sshd in a remote port forwarding scenario:
Client connects to Server on port 22
Traffic inbound to Server port 12345 gets forwarded to Client port 9876
I'm running into a problem where the connection to port 12345 on the server
gets refused. I've traced the issue to this line in TcpipServerChannel:
final ForwardingFilter filter =
getSession().getFactoryManager().getTcpipForwardingFilter();
if (address == null || filter == null || !filter.canConnect(address,
getSession())) {
the problem is that filer is winding up with a null value. The problem is that
I don't see any way to get that value set.
My client code:
SshClient client = SshClient.setUpDefaultClient();
client.start();
try{
ConnectFuture sessionFuture = client.connect("localhost", 22);
sessionFuture.await();
ClientSession session = sessionFuture.getSession();
AuthFuture authPassword = session.authPassword("user", "pass");
authPassword.await();
if(!authPassword.isSuccess()) throw new Error("Authentication failed");
SshdSocketAddress local = new SshdSocketAddress("localhost", 14722);
SshdSocketAddress remote = new SshdSocketAddress("localhost", 14730);
SshdSocketAddress remoteConnectInfo =
session.getTcpipForwarder().startRemotePortForwarding(remote, local);
System.out.println("Forwarding " + remoteConnectInfo + " to " + local);
and the server code:
SshServer sshd = SshServer.setUpDefaultServer();
sshd.setPort(22);
File keyFile = new File("devapphome/config/hostkey.ser").getAbsoluteFile();
sshd.setKeyPairProvider(new
SimpleGeneratorHostKeyProvider(keyFile.getAbsolutePath()));
sshd.setPasswordAuthenticator(new PasswordAuthenticator(){
@Override
public boolean authenticate(String username, String password, ServerSession
session) {
return "user".equals(username) && "pass".equals(password);
}
});
sshd.setTcpipForwardingFilter(new ForwardingFilter() {
@Override
public boolean canListen(SshdSocketAddress address, Session session) {
System.out.println("Listen request from " + address);
return true;
}
@Override
public boolean canForwardX11(Session session) {
return true;
}
@Override
public boolean canForwardAgent(Session session) {
return true;
}
@Override
public boolean canConnect(SshdSocketAddress address, Session session) {
System.out.println("Connection request from " + address);
return true;
}
});
try {
sshd.start();
System.out.println("sshd started - listening on port " + sshd.getPort());
synchronized (this) {
wait();
}
} catch (IOException | InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The problem is that sshd.setTcpipForwardingFilter sets the filter on the
SshServer side of things. In remote port forwarding mode, a totally different
(SshClient-side sub-class of AbstractChannel - AbstractClientChannel) Session
object is being created, and it doesn't look like it is inheriting the
TcpipForwardingFilter.
Am I missing something here? Do I need to be adding some sort of registration
to detect remote port forwarding requests and configure the
AbstractClientChannel somehow?
Thanks much,
- Kevin