using Renci.SshNet.TestTools.OpenSSH;
namespace Renci.SshNet.IntegrationTests
{
internal sealed class RemoteSshdConfig
{
private const string SshdConfigFilePath = "/etc/ssh/sshd_config";
private static readonly Encoding Utf8NoBom = new UTF8Encoding(false, true);
private readonly RemoteSshd _remoteSshd;
private readonly IConnectionInfoFactory _connectionInfoFactory;
private readonly SshdConfig _config;
public RemoteSshdConfig(RemoteSshd remoteSshd, IConnectionInfoFactory connectionInfoFactory)
{
_remoteSshd = remoteSshd;
_connectionInfoFactory = connectionInfoFactory;
using (var client = new ScpClient(_connectionInfoFactory.Create()))
{
client.Connect();
using (var memoryStream = new MemoryStream())
{
client.Download(SshdConfigFilePath, memoryStream);
memoryStream.Position = 0;
_config = SshdConfig.LoadFrom(memoryStream, Encoding.UTF8);
}
}
}
///
/// Specifies whether challenge-response authentication is allowed.
///
/// to allow challenge-response authentication.
///
/// The current instance.
///
public RemoteSshdConfig WithChallengeResponseAuthentication(bool? value)
{
_config.ChallengeResponseAuthentication = value;
return this;
}
///
/// Specifies whether to allow keyboard-interactive authentication.
///
/// to allow keyboard-interactive authentication.
///
/// The current instance.
///
public RemoteSshdConfig WithKeyboardInteractiveAuthentication(bool value)
{
_config.KeyboardInteractiveAuthentication = value;
return this;
}
///
/// Specifies whether sshd should print /etc/motd when a user logs in interactively.
///
/// if sshd should print /etc/motd when a user logs in interactively.
///
/// The current instance.
///
public RemoteSshdConfig PrintMotd(bool? value = true)
{
_config.PrintMotd = value;
return this;
}
///
/// Specifies whether TCP forwarding is permitted.
///
/// to allow TCP forwarding.
///
/// The current instance.
///
public RemoteSshdConfig AllowTcpForwarding(bool? value = true)
{
_config.AllowTcpForwarding = value;
return this;
}
public RemoteSshdConfig WithAuthenticationMethods(string user, string authenticationMethods)
{
var sshNetMatch = _config.Matches.Find(m => m.Users.Contains(user));
if (sshNetMatch is null)
{
sshNetMatch = new Match(new[] { user }, Array.Empty());
_config.Matches.Add(sshNetMatch);
}
sshNetMatch.AuthenticationMethods = authenticationMethods;
return this;
}
public RemoteSshdConfig ClearCiphers()
{
_config.Ciphers.Clear();
return this;
}
public RemoteSshdConfig AddCipher(Cipher cipher)
{
_config.Ciphers.Add(cipher);
return this;
}
public RemoteSshdConfig ClearKeyExchangeAlgorithms()
{
_config.KeyExchangeAlgorithms.Clear();
return this;
}
public RemoteSshdConfig AddKeyExchangeAlgorithm(KeyExchangeAlgorithm keyExchangeAlgorithm)
{
_config.KeyExchangeAlgorithms.Add(keyExchangeAlgorithm);
return this;
}
public RemoteSshdConfig ClearPublicKeyAcceptedAlgorithms()
{
_config.PublicKeyAcceptedAlgorithms.Clear();
return this;
}
public RemoteSshdConfig AddPublicKeyAcceptedAlgorithm(PublicKeyAlgorithm publicKeyAlgorithm)
{
_config.PublicKeyAcceptedAlgorithms.Add(publicKeyAlgorithm);
return this;
}
public RemoteSshdConfig ClearMessageAuthenticationCodeAlgorithms()
{
_config.MessageAuthenticationCodeAlgorithms.Clear();
return this;
}
public RemoteSshdConfig AddMessageAuthenticationCodeAlgorithm(MessageAuthenticationCodeAlgorithm messageAuthenticationCodeAlgorithm)
{
_config.MessageAuthenticationCodeAlgorithms.Add(messageAuthenticationCodeAlgorithm);
return this;
}
public RemoteSshdConfig ClearHostKeyAlgorithms()
{
_config.HostKeyAlgorithms.Clear();
return this;
}
public RemoteSshdConfig AddHostKeyAlgorithm(HostKeyAlgorithm hostKeyAlgorithm)
{
_config.HostKeyAlgorithms.Add(hostKeyAlgorithm);
return this;
}
public RemoteSshdConfig ClearSubsystems()
{
_config.Subsystems.Clear();
return this;
}
public RemoteSshdConfig AddSubsystem(Subsystem subsystem)
{
_config.Subsystems.Add(subsystem);
return this;
}
public RemoteSshdConfig WithLogLevel(LogLevel logLevel)
{
_config.LogLevel = logLevel;
return this;
}
public RemoteSshdConfig WithUsePAM(bool usePAM)
{
_config.UsePAM = usePAM;
return this;
}
public RemoteSshdConfig ClearHostKeyFiles()
{
_config.HostKeyFiles.Clear();
return this;
}
public RemoteSshdConfig AddHostKeyFile(string hostKeyFile)
{
_config.HostKeyFiles.Add(hostKeyFile);
return this;
}
public RemoteSshd Update()
{
using (var client = new ScpClient(_connectionInfoFactory.Create()))
{
client.Connect();
using (var memoryStream = new MemoryStream())
using (var sw = new StreamWriter(memoryStream, Utf8NoBom))
{
sw.NewLine = "\n";
_config.SaveTo(sw);
sw.Flush();
memoryStream.Position = 0;
client.Upload(memoryStream, SshdConfigFilePath);
}
}
return _remoteSshd;
}
}
}