RemoteSshdConfig.cs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. using Renci.SshNet.TestTools.OpenSSH;
  2. namespace Renci.SshNet.IntegrationTests
  3. {
  4. internal sealed class RemoteSshdConfig
  5. {
  6. private const string SshdConfigFilePath = "/etc/ssh/sshd_config";
  7. private static readonly Encoding Utf8NoBom = new UTF8Encoding(false, true);
  8. private readonly RemoteSshd _remoteSshd;
  9. private readonly IConnectionInfoFactory _connectionInfoFactory;
  10. private readonly SshdConfig _config;
  11. public RemoteSshdConfig(RemoteSshd remoteSshd, IConnectionInfoFactory connectionInfoFactory)
  12. {
  13. _remoteSshd = remoteSshd;
  14. _connectionInfoFactory = connectionInfoFactory;
  15. using (var client = new ScpClient(_connectionInfoFactory.Create()))
  16. {
  17. client.Connect();
  18. using (var memoryStream = new MemoryStream())
  19. {
  20. client.Download(SshdConfigFilePath, memoryStream);
  21. memoryStream.Position = 0;
  22. _config = SshdConfig.LoadFrom(memoryStream, Encoding.UTF8);
  23. }
  24. }
  25. }
  26. /// <summary>
  27. /// Specifies whether challenge-response authentication is allowed.
  28. /// </summary>
  29. /// <param name="value"><see langword="true"/> to allow challenge-response authentication.</param>
  30. /// <returns>
  31. /// The current <see cref="RemoteSshdConfig"/> instance.
  32. /// </returns>
  33. public RemoteSshdConfig WithChallengeResponseAuthentication(bool? value)
  34. {
  35. _config.ChallengeResponseAuthentication = value;
  36. return this;
  37. }
  38. /// <summary>
  39. /// Specifies whether to allow keyboard-interactive authentication.
  40. /// </summary>
  41. /// <param name="value"><see langword="true"/> to allow keyboard-interactive authentication.</param>
  42. /// <returns>
  43. /// The current <see cref="RemoteSshdConfig"/> instance.
  44. /// </returns>
  45. public RemoteSshdConfig WithKeyboardInteractiveAuthentication(bool value)
  46. {
  47. _config.KeyboardInteractiveAuthentication = value;
  48. return this;
  49. }
  50. /// <summary>
  51. /// Specifies whether <c>sshd</c> should print /etc/motd when a user logs in interactively.
  52. /// </summary>
  53. /// <param name="value"><see langword="true"/> if <c>sshd</c> should print /etc/motd when a user logs in interactively.</param>
  54. /// <returns>
  55. /// The current <see cref="RemoteSshdConfig"/> instance.
  56. /// </returns>
  57. public RemoteSshdConfig PrintMotd(bool? value = true)
  58. {
  59. _config.PrintMotd = value;
  60. return this;
  61. }
  62. /// <summary>
  63. /// Specifies whether TCP forwarding is permitted.
  64. /// </summary>
  65. /// <param name="value"><see langword="true"/> to allow TCP forwarding.</param>
  66. /// <returns>
  67. /// The current <see cref="RemoteSshdConfig"/> instance.
  68. /// </returns>
  69. public RemoteSshdConfig AllowTcpForwarding(bool? value = true)
  70. {
  71. _config.AllowTcpForwarding = value;
  72. return this;
  73. }
  74. public RemoteSshdConfig WithAuthenticationMethods(string user, string authenticationMethods)
  75. {
  76. var sshNetMatch = _config.Matches.Find(m => m.Users.Contains(user));
  77. if (sshNetMatch is null)
  78. {
  79. sshNetMatch = new Match(new[] { user }, Array.Empty<string>());
  80. _config.Matches.Add(sshNetMatch);
  81. }
  82. sshNetMatch.AuthenticationMethods = authenticationMethods;
  83. return this;
  84. }
  85. public RemoteSshdConfig ClearCiphers()
  86. {
  87. _config.Ciphers.Clear();
  88. return this;
  89. }
  90. public RemoteSshdConfig AddCipher(Cipher cipher)
  91. {
  92. _config.Ciphers.Add(cipher);
  93. return this;
  94. }
  95. public RemoteSshdConfig ClearKeyExchangeAlgorithms()
  96. {
  97. _config.KeyExchangeAlgorithms.Clear();
  98. return this;
  99. }
  100. public RemoteSshdConfig AddKeyExchangeAlgorithm(KeyExchangeAlgorithm keyExchangeAlgorithm)
  101. {
  102. _config.KeyExchangeAlgorithms.Add(keyExchangeAlgorithm);
  103. return this;
  104. }
  105. public RemoteSshdConfig ClearPublicKeyAcceptedAlgorithms()
  106. {
  107. _config.PublicKeyAcceptedAlgorithms.Clear();
  108. return this;
  109. }
  110. public RemoteSshdConfig AddPublicKeyAcceptedAlgorithm(PublicKeyAlgorithm publicKeyAlgorithm)
  111. {
  112. _config.PublicKeyAcceptedAlgorithms.Add(publicKeyAlgorithm);
  113. return this;
  114. }
  115. public RemoteSshdConfig ClearMessageAuthenticationCodeAlgorithms()
  116. {
  117. _config.MessageAuthenticationCodeAlgorithms.Clear();
  118. return this;
  119. }
  120. public RemoteSshdConfig AddMessageAuthenticationCodeAlgorithm(MessageAuthenticationCodeAlgorithm messageAuthenticationCodeAlgorithm)
  121. {
  122. _config.MessageAuthenticationCodeAlgorithms.Add(messageAuthenticationCodeAlgorithm);
  123. return this;
  124. }
  125. public RemoteSshdConfig ClearHostKeyAlgorithms()
  126. {
  127. _config.HostKeyAlgorithms.Clear();
  128. return this;
  129. }
  130. public RemoteSshdConfig AddHostKeyAlgorithm(HostKeyAlgorithm hostKeyAlgorithm)
  131. {
  132. _config.HostKeyAlgorithms.Add(hostKeyAlgorithm);
  133. return this;
  134. }
  135. public RemoteSshdConfig ClearSubsystems()
  136. {
  137. _config.Subsystems.Clear();
  138. return this;
  139. }
  140. public RemoteSshdConfig AddSubsystem(Subsystem subsystem)
  141. {
  142. _config.Subsystems.Add(subsystem);
  143. return this;
  144. }
  145. public RemoteSshdConfig WithLogLevel(LogLevel logLevel)
  146. {
  147. _config.LogLevel = logLevel;
  148. return this;
  149. }
  150. public RemoteSshdConfig WithUsePAM(bool usePAM)
  151. {
  152. _config.UsePAM = usePAM;
  153. return this;
  154. }
  155. public RemoteSshdConfig ClearHostKeyFiles()
  156. {
  157. _config.HostKeyFiles.Clear();
  158. return this;
  159. }
  160. public RemoteSshdConfig AddHostKeyFile(string hostKeyFile)
  161. {
  162. _config.HostKeyFiles.Add(hostKeyFile);
  163. return this;
  164. }
  165. public RemoteSshd Update()
  166. {
  167. using (var client = new ScpClient(_connectionInfoFactory.Create()))
  168. {
  169. client.Connect();
  170. using (var memoryStream = new MemoryStream())
  171. using (var sw = new StreamWriter(memoryStream, Utf8NoBom))
  172. {
  173. sw.NewLine = "\n";
  174. _config.SaveTo(sw);
  175. sw.Flush();
  176. memoryStream.Position = 0;
  177. client.Upload(memoryStream, SshdConfigFilePath);
  178. }
  179. }
  180. return _remoteSshd;
  181. }
  182. }
  183. }