Rename option to disable ssh agent

This commit is contained in:
Kenneth Skovhede
2025-06-03 06:23:45 +02:00
parent 2b4cf848a9
commit 1420bed3c5
3 changed files with 61 additions and 34 deletions
@@ -11,6 +11,7 @@
<ItemGroup>
<PackageReference Include="SSH.NET" Version="2024.2.0" />
<PackageReference Include="SSH.NET.Agent" Version="2024.2.0" />
</ItemGroup>
<ItemGroup>
+55 -31
View File
@@ -25,8 +25,9 @@ using Duplicati.Library.Interface;
using Duplicati.Library.SourceProvider;
using Duplicati.Library.Utility;
using Duplicati.Library.Utility.Options;
using Renci.SshNet;
using Renci.SshNet.Common;
using Renci.SshNet;
using Renci.SshNet.Agent;
using Renci.SshNet.Common;
using System.Globalization;
using System.Runtime.CompilerServices;
@@ -41,7 +42,8 @@ namespace Duplicati.Library.Backend
private const string SSH_FINGERPRINT_ACCEPT_ANY_OPTION = "ssh-accept-any-fingerprints";
public const string KEYFILE_URI = "sshkey://";
private const string SSH_TIMEOUT_OPTION = "ssh-operation-timeout";
private const string SSH_KEEPALIVE_OPTION = "ssh-keepalive";
private const string SSH_KEEPALIVE_OPTION = "ssh-keepalive";
private const string SSH_DISABLE_AGENT_OPTION = "ssh-disable-agent";
readonly Dictionary<string, string?> m_options;
@@ -55,21 +57,23 @@ namespace Duplicati.Library.Backend
private readonly TimeSpan m_keepaliveinterval;
private readonly int m_port = 22;
private readonly bool m_useRelativePath;
private readonly TimeoutOptionsHelper.Timeouts m_timeouts;
private readonly bool m_useRelativePath;
private readonly bool m_useAgent;
private readonly TimeoutOptionsHelper.Timeouts m_timeouts;
private string? m_initialDirectory;
private SftpClient? m_con;
public SSHv2()
{
m_server = null!;
m_path = null!;
m_username = null!;
m_options = null!;
m_timeouts = null!;
m_con = null!;
}
public SSHv2()
{
m_server = null!;
m_path = null!;
m_username = null!;
m_options = null!;
m_timeouts = null!;
m_con = null!;
m_useAgent = true;
}
public SSHv2(string url, Dictionary<string, string?> options)
{
@@ -85,8 +89,9 @@ namespace Duplicati.Library.Backend
m_password = auth.Password;
m_fingerprint = options.GetValueOrDefault(SSH_FINGERPRINT_OPTION);
m_fingerprintallowall = Utility.Utility.ParseBoolOption(options, SSH_FINGERPRINT_ACCEPT_ANY_OPTION);
m_useRelativePath = Utility.Utility.ParseBoolOption(options, SSH_RELATIVE_PATH_OPTION);
m_timeouts = TimeoutOptionsHelper.Parse(options);
m_useRelativePath = Utility.Utility.ParseBoolOption(options, SSH_RELATIVE_PATH_OPTION);
m_useAgent = !Utility.Utility.ParseBoolOption(options, SSH_DISABLE_AGENT_OPTION);
m_timeouts = TimeoutOptionsHelper.Parse(options);
m_path = uri.Path;
@@ -191,12 +196,15 @@ namespace Duplicati.Library.Backend
new CommandLineArgument(SSH_TIMEOUT_OPTION, CommandLineArgument.ArgumentType.Timespan,
Strings.SSHv2Backend.DescriptionSshtimeoutShort, Strings.SSHv2Backend.DescriptionSshtimeoutLong,
"0", null,null, Strings.SSHv2Backend.TimeoutDeprecated(SSH_TIMEOUT_OPTION, TimeoutOptionsHelper.ShortTimeoutOption, TimeoutOptionsHelper.ListTimeoutOption, TimeoutOptionsHelper.ReadWriteTimeoutOption)),
new CommandLineArgument(SSH_KEEPALIVE_OPTION, CommandLineArgument.ArgumentType.Timespan,
Strings.SSHv2Backend.DescriptionSshkeepaliveShort,
Strings.SSHv2Backend.DescriptionSshkeepaliveLong, "0"),
new CommandLineArgument(SSH_RELATIVE_PATH_OPTION, CommandLineArgument.ArgumentType.Boolean,
Strings.SSHv2Backend.DescriptionRelativePathShort,
Strings.SSHv2Backend.DescriptionRelativePathLong),
new CommandLineArgument(SSH_KEEPALIVE_OPTION, CommandLineArgument.ArgumentType.Timespan,
Strings.SSHv2Backend.DescriptionSshkeepaliveShort,
Strings.SSHv2Backend.DescriptionSshkeepaliveLong, "0"),
new CommandLineArgument(SSH_DISABLE_AGENT_OPTION, CommandLineArgument.ArgumentType.Boolean,
Strings.SSHv2Backend.DescriptionDisableAgentShort,
Strings.SSHv2Backend.DescriptionDisableAgentLong),
new CommandLineArgument(SSH_RELATIVE_PATH_OPTION, CommandLineArgument.ArgumentType.Boolean,
Strings.SSHv2Backend.DescriptionRelativePathShort,
Strings.SSHv2Backend.DescriptionRelativePathLong),
.. TimeoutOptionsHelper.GetOptions(),
];
@@ -293,15 +301,31 @@ namespace Duplicati.Library.Backend
return m_con;
}
SftpClient con;
m_options.TryGetValue(SSH_KEYFILE_OPTION, out var keyFile);
m_options.TryGetValue(SSH_KEYFILE_INLINE, out var keyInline);
if (!string.IsNullOrWhiteSpace(keyFile) || !string.IsNullOrWhiteSpace(keyInline))
con = new SftpClient(m_server, m_port, m_username, ValidateKeyFile(keyFile, keyInline, m_password));
else
con = new SftpClient(m_server, m_port, m_username, m_password ?? string.Empty);
SftpClient con;
m_options.TryGetValue(SSH_KEYFILE_OPTION, out var keyFile);
m_options.TryGetValue(SSH_KEYFILE_INLINE, out var keyInline);
if (!string.IsNullOrWhiteSpace(keyFile) || !string.IsNullOrWhiteSpace(keyInline))
{
con = new SftpClient(m_server, m_port, m_username, ValidateKeyFile(keyFile, keyInline, m_password));
}
else if (!string.IsNullOrWhiteSpace(m_password))
{
con = new SftpClient(m_server, m_port, m_username, m_password);
}
else if (m_useAgent)
{
var connectionInfo = new ConnectionInfo(m_server, m_port, m_username, new AuthenticationMethod[]
{
new AgentAuthenticationMethod(m_username)
});
con = new SftpClient(connectionInfo);
}
else
{
con = new SftpClient(m_server, m_port, m_username, string.Empty);
}
con.HostKeyReceived += (sender, e) =>
{
+5 -3
View File
@@ -57,9 +57,11 @@ namespace Duplicati.Library.Backend.Strings
public static string DescriptionSshkeyShort => LC.L(@"Use a SSH private key to authenticate");
public static string DescriptionSshtimeoutLong => LC.L(@"Use this option to manage the internal timeout for SSH operations. If the value is set to zero, the operations will not time out.");
public static string DescriptionSshtimeoutShort => LC.L(@"Set the operation timeout value");
public static string DescriptionSshkeepaliveLong => LC.L(@"Use this option to enable the keep-alive interval for the SSH connection. If the connection is idle, aggressive firewalls might close the connection. Using keep-alive will keep the connection open in this scenario. If this value is set to zero, the keep-alive is disabled.");
public static string DescriptionSshkeepaliveShort => LC.L(@"Set a keepalive value");
public static string DescriptionRelativePathShort => LC.L(@"Treat source path as relative to the initial path");
public static string DescriptionSshkeepaliveLong => LC.L(@"Use this option to enable the keep-alive interval for the SSH connection. If the connection is idle, aggressive firewalls might close the connection. Using keep-alive will keep the connection open in this scenario. If this value is set to zero, the keep-alive is disabled.");
public static string DescriptionSshkeepaliveShort => LC.L(@"Set a keepalive value");
public static string DescriptionDisableAgentShort => LC.L(@"Disable ssh-agent authentication");
public static string DescriptionDisableAgentLong => LC.L(@"Prevent using ssh-agent for authentication. When not set and no password or keyfile is supplied, the agent will be used.");
public static string DescriptionRelativePathShort => LC.L(@"Treat source path as relative to the initial path");
public static string DescriptionRelativePathLong => LC.L(@"Use this option to treat the source path as relative to the initial path. This is useful when the full path of the system is not known.");
public static string FolderNotFoundManagedError(string foldername, string message) { return LC.L(@"Unable to set folder to {0}, error message: {1}", foldername, message); }
public static string FingerprintNotMatchManagedError(string fingerprint) { return LC.L(@"Validation of server fingerprint failed. Server returned fingerprint ""{0}"". Cause of this message is either not correct configuration or Man-in-the-middle attack!", fingerprint); }