Skip to content

Commit

Permalink
Merge pull request #12925 from 8uurg/feature/GH-12880
Browse files Browse the repository at this point in the history
Allow for OpenSSH on Windows
  • Loading branch information
AliveDevil committed Feb 28, 2022
2 parents 2cec543 + dc6510e commit 52237d3
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 10 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Expand Up @@ -86,7 +86,7 @@
<httpclient-version>4.5.13</httpclient-version>
<google-http-client.version>1.41.4</google-http-client.version>

<ikvm-version>8.0.312.b07-2</ikvm-version>
<ikvm-version>8.0.312.b07-3</ikvm-version>
<java-native-dll>8u312b07</java-native-dll>
</properties>

Expand Down
6 changes: 4 additions & 2 deletions ssh/src/main/java/ch/cyberduck/core/sftp/SFTPSession.java
Expand Up @@ -286,11 +286,13 @@ private void authenticate(final SSHClient client, final Host host, final LoginCa
switch(Factory.Platform.getDefault()) {
case windows:
defaultMethods.add(new SFTPAgentAuthentication(client, new PageantAuthenticator()));

defaultMethods.add(new SFTPAgentAuthentication(client, new OpenSSHAgentAuthenticator(
new OpenSSHIdentityAgentConfigurator().getIdentityAgent(host.getHostname()), true)));
break;
default:
defaultMethods.add(new SFTPAgentAuthentication(client, new OpenSSHAgentAuthenticator(
new OpenSSHIdentityAgentConfigurator().getIdentityAgent(host.getHostname())
)));
new OpenSSHIdentityAgentConfigurator().getIdentityAgent(host.getHostname()), false)));
break;
}
}
Expand Down
Expand Up @@ -23,6 +23,9 @@
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.RandomAccessFile;
import java.io.EOFException;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
Expand All @@ -32,16 +35,58 @@
import com.jcraft.jsch.agentproxy.AgentProxyException;
import com.jcraft.jsch.agentproxy.Identity;
import com.jcraft.jsch.agentproxy.connector.SSHAgentConnector;
import com.jcraft.jsch.agentproxy.USocketFactory;
import com.jcraft.jsch.agentproxy.usocket.JNAUSocketFactory;

// Implements a wrapper around RandomAccessFile for use with jsch's
// SSH connector to support Windows' OpenSSH fork.
class RandomAccessFileSocketFactory implements USocketFactory
{
class WindowsSocket extends Socket
{
private RandomAccessFile raf;
WindowsSocket(String path) throws IOException
{
raf = new RandomAccessFile(path, "rw");
}

public int readFull(byte[] buf, int s, int len) throws IOException
{
try {
raf.readFully(buf, s, len);
} catch (EOFException e) {
return -1;
}
return len;
}
public void write(byte[] buf, int s, int len) throws IOException
{
raf.write(buf, s, len);
}
public void close() throws IOException
{
raf.close();
}
}

public Socket open(String path) throws IOException
{
return new WindowsSocket(path);
}
}

public class OpenSSHAgentAuthenticator extends AgentAuthenticator {
private static final Logger log = LogManager.getLogger(OpenSSHAgentAuthenticator.class);

private AgentProxy proxy;

public OpenSSHAgentAuthenticator(final String socket) {
public OpenSSHAgentAuthenticator(final String socket, final boolean windows) {
try {
proxy = new AgentProxy(new SSHAgentConnector(new JNAUSocketFactory(), socket));
if (windows) {
proxy = new AgentProxy(new SSHAgentConnector(new RandomAccessFileSocketFactory(), "\\\\.\\pipe\\openssh-ssh-agent"));
} else {
proxy = new AgentProxy(new SSHAgentConnector(new JNAUSocketFactory(), socket));
}
}
catch(AgentProxyException e) {
log.warn(String.format("Agent proxy %s failed with %s", this, e));
Expand All @@ -55,11 +100,8 @@ public AgentProxy getProxy() {

@Override
public Collection<Identity> getIdentities() {
if(!SSHAgentConnector.isConnectorAvailable()) {
log.warn(String.format("SSH agent %s is not running", this));
return Collections.emptyList();
}
if(null == proxy) {
log.warn(String.format("SSH agent %s is not running", this));
return Collections.emptyList();
}
if(log.isDebugEnabled()) {
Expand Down
Expand Up @@ -33,7 +33,7 @@ public class OpenSSHAgentAuthenticatorTest {
@Test
@Ignore
public void testGetIdentities() {
final OpenSSHAgentAuthenticator authenticator = new OpenSSHAgentAuthenticator(null);
final OpenSSHAgentAuthenticator authenticator = new OpenSSHAgentAuthenticator(null, false);
final Collection<Identity> identities = authenticator.getIdentities();
assertNotNull(authenticator.getProxy());
assertFalse(identities.isEmpty());
Expand Down

0 comments on commit 52237d3

Please sign in to comment.