2
0

SshMessageFactoryTest.cs 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423
  1. using System;
  2. using System.Globalization;
  3. using System.Linq;
  4. using Microsoft.VisualStudio.TestTools.UnitTesting;
  5. using Renci.SshNet.Common;
  6. using Renci.SshNet.Messages.Authentication;
  7. using Renci.SshNet.Messages.Transport;
  8. namespace Renci.SshNet.Tests.Classes
  9. {
  10. [TestClass]
  11. public class SshMessageFactoryTest
  12. {
  13. private SshMessageFactory _sshMessageFactory;
  14. [TestInitialize]
  15. public void SetUp()
  16. {
  17. _sshMessageFactory = new SshMessageFactory();
  18. }
  19. [TestMethod]
  20. public void CreateShouldThrowSshExceptionWhenMessageIsNotEnabled()
  21. {
  22. const byte messageNumber = 60;
  23. try
  24. {
  25. _sshMessageFactory.Create(messageNumber);
  26. Assert.Fail();
  27. }
  28. catch (SshException ex)
  29. {
  30. Assert.IsNull(ex.InnerException);
  31. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);
  32. }
  33. }
  34. [TestMethod]
  35. public void CreateShouldThrowSshExceptionWhenMessageDoesNotExist_OutsideOfMessageNumberRange()
  36. {
  37. const byte messageNumber = 255;
  38. try
  39. {
  40. _sshMessageFactory.Create(messageNumber);
  41. Assert.Fail();
  42. }
  43. catch (SshException ex)
  44. {
  45. Assert.IsNull(ex.InnerException);
  46. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not supported.", messageNumber), ex.Message);
  47. }
  48. }
  49. [TestMethod]
  50. public void CreateShouldThrowSshExceptionWhenMessageDoesNotExist_WithinMessageNumberRange()
  51. {
  52. const byte messageNumber = 5;
  53. try
  54. {
  55. _sshMessageFactory.Create(messageNumber);
  56. Assert.Fail();
  57. }
  58. catch (SshException ex)
  59. {
  60. Assert.IsNull(ex.InnerException);
  61. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not supported.", messageNumber), ex.Message);
  62. }
  63. }
  64. [TestMethod]
  65. public void CreateShouldThrowSshExceptionWhenMessageIsNotActivated()
  66. {
  67. const byte messageNumber = 60;
  68. const string messageName = "SSH_MSG_USERAUTH_PASSWD_CHANGEREQ";
  69. _sshMessageFactory.EnableAndActivateMessage(messageName);
  70. _sshMessageFactory.DisableAndDeactivateMessage(messageName);
  71. try
  72. {
  73. _sshMessageFactory.Create(messageNumber);
  74. Assert.Fail();
  75. }
  76. catch (SshException ex)
  77. {
  78. Assert.IsNull(ex.InnerException);
  79. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);
  80. }
  81. }
  82. [TestMethod]
  83. public void CreateShouldReturnMessageInstanceCorrespondingToMessageNumberWhenMessageIsEnabledAndActivated()
  84. {
  85. const byte messageNumber = 60;
  86. const string messageName = "SSH_MSG_USERAUTH_PASSWD_CHANGEREQ";
  87. _sshMessageFactory.EnableAndActivateMessage(messageName);
  88. var actual = _sshMessageFactory.Create(messageNumber);
  89. Assert.IsNotNull(actual);
  90. Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());
  91. _sshMessageFactory.DisableAndDeactivateMessage(messageName);
  92. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
  93. actual = _sshMessageFactory.Create(messageNumber);
  94. Assert.IsNotNull(actual);
  95. Assert.AreEqual(typeof(InformationRequestMessage), actual.GetType());
  96. }
  97. [TestMethod]
  98. public void DisableAndDeactivateMessageShouldThrowSshExceptionWhenAnotherMessageWithSameMessageNumberIsEnabled()
  99. {
  100. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  101. try
  102. {
  103. _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
  104. Assert.Fail();
  105. }
  106. catch (SshException ex)
  107. {
  108. Assert.IsNull(ex.InnerException);
  109. Assert.AreEqual("Cannot enable message 'SSH_MSG_USERAUTH_INFO_REQUEST'. Message type 60 is already enabled for 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'.", ex.Message);
  110. }
  111. // verify that the original message remains enabled
  112. var actual = _sshMessageFactory.Create(60);
  113. Assert.IsNotNull(actual);
  114. Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());
  115. }
  116. [TestMethod]
  117. public void DisableAndDeactivateMessageShouldNotThrowExceptionWhenMessageIsAlreadyDisabled()
  118. {
  119. const byte messageNumber = 60;
  120. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  121. _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  122. _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  123. // verify that message remains disabled
  124. try
  125. {
  126. _sshMessageFactory.Create(messageNumber);
  127. Assert.Fail();
  128. }
  129. catch (SshException ex)
  130. {
  131. Assert.IsNull(ex.InnerException);
  132. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);
  133. }
  134. }
  135. [TestMethod]
  136. public void DisableAndDeactivateMessageShouldNotThrowExceptionWhenMessageWasNeverEnabled()
  137. {
  138. const byte messageNumber = 60;
  139. _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  140. // verify that message is disabled
  141. try
  142. {
  143. _sshMessageFactory.Create(messageNumber);
  144. Assert.Fail();
  145. }
  146. catch (SshException ex)
  147. {
  148. Assert.IsNull(ex.InnerException);
  149. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);
  150. }
  151. }
  152. [TestMethod]
  153. public void DisableAndDeactivateMessageShouldThrowSshExceptionWhenMessageIsNotSupported()
  154. {
  155. const string messageName = "WHATEVER";
  156. try
  157. {
  158. _sshMessageFactory.DisableAndDeactivateMessage("WHATEVER");
  159. Assert.Fail();
  160. }
  161. catch (SshException ex)
  162. {
  163. Assert.IsNull(ex.InnerException);
  164. Assert.AreEqual(string.Format("Message '{0}' is not supported.", messageName), ex.Message);
  165. }
  166. }
  167. [TestMethod]
  168. public void DisableAndDeactivateMessageShouldThrowArgumentNullExceptionWhenMessageNameIsNull()
  169. {
  170. const string messageName = null;
  171. try
  172. {
  173. _sshMessageFactory.DisableAndDeactivateMessage(messageName);
  174. Assert.Fail();
  175. }
  176. catch (ArgumentNullException ex)
  177. {
  178. Assert.IsNull(ex.InnerException);
  179. Assert.AreEqual("messageName", ex.ParamName);
  180. }
  181. }
  182. [TestMethod]
  183. public void EnableAndActivateMessageShouldThrowSshExceptionWhenAnotherMessageWithSameMessageNumberIsAlreadyEnabled()
  184. {
  185. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  186. try
  187. {
  188. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
  189. Assert.Fail();
  190. }
  191. catch (SshException ex)
  192. {
  193. Assert.IsNull(ex.InnerException);
  194. Assert.AreEqual("Cannot enable message 'SSH_MSG_USERAUTH_INFO_REQUEST'. Message type 60 is already enabled for 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'.", ex.Message);
  195. }
  196. // verify that the original message remains enabled
  197. var actual = _sshMessageFactory.Create(60);
  198. Assert.IsNotNull(actual);
  199. Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());
  200. }
  201. [TestMethod]
  202. public void EnableAndActivateMessageShouldNotThrowExceptionWhenMessageIsAlreadyEnabled()
  203. {
  204. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  205. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  206. var actual = _sshMessageFactory.Create(60);
  207. Assert.IsNotNull(actual);
  208. Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());
  209. }
  210. [TestMethod]
  211. public void EnableAndActivateMessageShouldThrowSshExceptionWhenMessageIsNotSupported()
  212. {
  213. const string messageName = "WHATEVER";
  214. try
  215. {
  216. _sshMessageFactory.EnableAndActivateMessage("WHATEVER");
  217. Assert.Fail();
  218. }
  219. catch (SshException ex)
  220. {
  221. Assert.IsNull(ex.InnerException);
  222. Assert.AreEqual(string.Format("Message '{0}' is not supported.", messageName), ex.Message);
  223. }
  224. }
  225. [TestMethod]
  226. public void EnableAndActivateMessageShouldThrowArgumentNullExceptionWhenMessageNameIsNull()
  227. {
  228. const string messageName = null;
  229. try
  230. {
  231. _sshMessageFactory.EnableAndActivateMessage(messageName);
  232. Assert.Fail();
  233. }
  234. catch (ArgumentNullException ex)
  235. {
  236. Assert.IsNull(ex.InnerException);
  237. Assert.AreEqual("messageName", ex.ParamName);
  238. }
  239. }
  240. [TestMethod]
  241. public void DisableNonKeyExchangeMessagesShouldDisableNonKeyExchangeMessages()
  242. {
  243. const byte messageNumber = 60;
  244. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  245. _sshMessageFactory.DisableNonKeyExchangeMessages(strict: false);
  246. // verify that message is disabled
  247. try
  248. {
  249. _sshMessageFactory.Create(messageNumber);
  250. Assert.Fail();
  251. }
  252. catch (SshException ex)
  253. {
  254. Assert.IsNull(ex.InnerException);
  255. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);
  256. }
  257. }
  258. [TestMethod]
  259. public void DisableNonKeyExchangeMessagesShouldNotDisableKeyExchangeMessages()
  260. {
  261. const byte messageNumber = 21;
  262. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_NEWKEYS");
  263. _sshMessageFactory.DisableNonKeyExchangeMessages(strict: false);
  264. // verify that message remains enabled
  265. var actual = _sshMessageFactory.Create(messageNumber);
  266. Assert.IsNotNull(actual);
  267. Assert.AreEqual(typeof(NewKeysMessage), actual.GetType());
  268. }
  269. [TestMethod]
  270. public void EnableActivatedMessagesShouldEnableMessagesThatWereEnabledPriorToInvokingDisableNonKeyExchangeMessages()
  271. {
  272. const byte messageNumber = 60;
  273. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  274. _sshMessageFactory.DisableNonKeyExchangeMessages(strict: false);
  275. _sshMessageFactory.EnableActivatedMessages();
  276. var actual = _sshMessageFactory.Create(messageNumber);
  277. Assert.IsNotNull(actual);
  278. Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());
  279. }
  280. [TestMethod]
  281. public void EnableActivatedMessagesShouldNotEnableMessagesThatWereDisabledPriorToInvokingDisableNonKeyExchangeMessages()
  282. {
  283. const byte messageNumber = 60;
  284. _sshMessageFactory.DisableNonKeyExchangeMessages(strict: false);
  285. _sshMessageFactory.EnableActivatedMessages();
  286. try
  287. {
  288. _sshMessageFactory.Create(messageNumber);
  289. Assert.Fail();
  290. }
  291. catch (SshException ex)
  292. {
  293. Assert.IsNull(ex.InnerException);
  294. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);
  295. }
  296. }
  297. [TestMethod]
  298. public void EnableActivatedMessagesShouldNotEnableMessagesThatWereDisabledAfterInvokingDisableNonKeyExchangeMessages()
  299. {
  300. const byte messageNumber = 60;
  301. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  302. _sshMessageFactory.DisableNonKeyExchangeMessages(strict: false);
  303. _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  304. _sshMessageFactory.EnableActivatedMessages();
  305. try
  306. {
  307. _sshMessageFactory.Create(messageNumber);
  308. Assert.Fail();
  309. }
  310. catch (SshException ex)
  311. {
  312. Assert.IsNull(ex.InnerException);
  313. Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);
  314. }
  315. }
  316. [TestMethod]
  317. public void EnableActivatedMessagesShouldThrowSshExceptionWhenAnothersMessageWithSameMessageNumberWasEnabledAfterInvokingDisableNonKeyExchangeMessages()
  318. {
  319. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  320. _sshMessageFactory.DisableNonKeyExchangeMessages(strict: false);
  321. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_INFO_REQUEST");
  322. try
  323. {
  324. _sshMessageFactory.EnableActivatedMessages();
  325. Assert.Fail();
  326. }
  327. catch (SshException ex)
  328. {
  329. Assert.IsNull(ex.InnerException);
  330. Assert.AreEqual("Cannot enable message 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'. Message type 60 is already enabled for 'SSH_MSG_USERAUTH_INFO_REQUEST'.", ex.Message);
  331. }
  332. }
  333. [TestMethod]
  334. public void EnableActivatedMessagesShouldLeaveMessagesEnabledThatWereEnabledAfterInvokingDisableNonKeyExchangeMessages()
  335. {
  336. const byte messageNumber = 60;
  337. _sshMessageFactory.DisableNonKeyExchangeMessages(strict: false);
  338. _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");
  339. _sshMessageFactory.EnableActivatedMessages();
  340. var actual = _sshMessageFactory.Create(messageNumber);
  341. Assert.IsNotNull(actual);
  342. Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());
  343. }
  344. [TestMethod]
  345. public void HighestMessageNumberShouldCorrespondWithHighestSupportedMessageNumber()
  346. {
  347. var highestSupportMessageNumber = SshMessageFactory.AllMessages.Max(m => m.Number);
  348. Assert.AreEqual(highestSupportMessageNumber, SshMessageFactory.HighestMessageNumber);
  349. }
  350. [TestMethod]
  351. public void TotalMessageCountShouldBeTotalNumberOfSupportedMessages()
  352. {
  353. var totalNumberOfSupportedMessages = SshMessageFactory.AllMessages.Length;
  354. Assert.AreEqual(totalNumberOfSupportedMessages, SshMessageFactory.TotalMessageCount);
  355. }
  356. }
  357. }