Add SFTP tools with SCP fallback
This commit is contained in:
70
src/McpSsh.Server/Ssh/SshClientFactory.cs
Normal file
70
src/McpSsh.Server/Ssh/SshClientFactory.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
using Renci.SshNet;
|
||||
|
||||
namespace McpSsh.Server.Ssh;
|
||||
|
||||
public interface ISshClientFactory
|
||||
{
|
||||
SshClient CreateSshClient(SshConnectionRequest request);
|
||||
|
||||
SftpClient CreateSftpClient(SshConnectionRequest request);
|
||||
|
||||
ScpClient CreateScpClient(SshConnectionRequest request);
|
||||
}
|
||||
|
||||
public sealed record SshConnectionRequest(
|
||||
string Host,
|
||||
string Username,
|
||||
int Port,
|
||||
string? KeyPath,
|
||||
string? KeyPassphrase,
|
||||
TimeSpan? Timeout = null);
|
||||
|
||||
public sealed class SshNetClientFactory : ISshClientFactory
|
||||
{
|
||||
private readonly ISshKeyResolver _keyResolver;
|
||||
|
||||
public SshNetClientFactory(ISshKeyResolver keyResolver)
|
||||
{
|
||||
_keyResolver = keyResolver;
|
||||
}
|
||||
|
||||
public SshClient CreateSshClient(SshConnectionRequest request)
|
||||
{
|
||||
var client = new SshClient(CreateConnectionInfo(request));
|
||||
ApplyTimeout(client, request.Timeout);
|
||||
return client;
|
||||
}
|
||||
|
||||
public SftpClient CreateSftpClient(SshConnectionRequest request)
|
||||
{
|
||||
var client = new SftpClient(CreateConnectionInfo(request));
|
||||
ApplyTimeout(client, request.Timeout);
|
||||
return client;
|
||||
}
|
||||
|
||||
public ScpClient CreateScpClient(SshConnectionRequest request)
|
||||
{
|
||||
var client = new ScpClient(CreateConnectionInfo(request));
|
||||
ApplyTimeout(client, request.Timeout);
|
||||
return client;
|
||||
}
|
||||
|
||||
private ConnectionInfo CreateConnectionInfo(SshConnectionRequest request)
|
||||
{
|
||||
var keyPath = _keyResolver.ResolveKeyPath(request.KeyPath);
|
||||
var keyFile = string.IsNullOrEmpty(request.KeyPassphrase)
|
||||
? new PrivateKeyFile(keyPath)
|
||||
: new PrivateKeyFile(keyPath, request.KeyPassphrase);
|
||||
|
||||
var auth = new PrivateKeyAuthenticationMethod(request.Username, keyFile);
|
||||
return new ConnectionInfo(request.Host, request.Port, request.Username, auth);
|
||||
}
|
||||
|
||||
private static void ApplyTimeout(BaseClient client, TimeSpan? timeout)
|
||||
{
|
||||
if (timeout is { } value)
|
||||
{
|
||||
client.ConnectionInfo.Timeout = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user