| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982 | using System;using System.Collections.Generic;using System.Diagnostics;using System.Globalization;using System.Linq;using Renci.SshNet.Common;using Renci.SshNet.Messages;using Renci.SshNet.Messages.Authentication;using Renci.SshNet.Messages.Connection;using Renci.SshNet.Messages.Transport;using Microsoft.VisualStudio.TestTools.UnitTesting;namespace Renci.SshNet.Tests{    [TestClass]    public class SshMessageFactoryTest    {        private SshMessageFactory _sshMessageFactory;        private SshMessageFactoryOriginal _sshMessageFactoryOriginal;        [TestInitialize]        public void SetUp()        {            _sshMessageFactory = new SshMessageFactory();            _sshMessageFactoryOriginal = new SshMessageFactoryOriginal();        }        [TestMethod]        public void CreateShouldThrowSshExceptionWhenMessageIsNotEnabled()        {            const byte messageNumber = 60;            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);            }        }        [TestMethod]        public void CreateShouldThrowSshExceptionWhenMessageDoesNotExist_OutsideOfMessageNumberRange()        {            const byte messageNumber = 255;            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not supported.", messageNumber), ex.Message);            }        }        [TestMethod]        public void CreateShouldThrowSshExceptionWhenMessageDoesNotExist_WithinMessageNumberRange()        {            const byte messageNumber = 5;            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not supported.", messageNumber), ex.Message);            }        }        [TestMethod]        public void CreateShouldThrowSshExceptionWhenMessageIsNotActivated()        {            const byte messageNumber = 60;            const string messageName = "SSH_MSG_USERAUTH_PASSWD_CHANGEREQ";            _sshMessageFactory.EnableAndActivateMessage(messageName);            _sshMessageFactory.DisableAndDeactivateMessage(messageName);            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);            }        }        [TestMethod]        public void CreateShouldReturnMessageInstanceCorrespondingToMessageNumberWhenMessageIsEnabledAndActivated()        {            const byte messageNumber = 60;            const string messageName = "SSH_MSG_USERAUTH_PASSWD_CHANGEREQ";            _sshMessageFactory.EnableAndActivateMessage(messageName);            var actual = _sshMessageFactory.Create(messageNumber);            Assert.IsNotNull(actual);            Assert.AreEqual(typeof (PasswordChangeRequiredMessage), actual.GetType());            _sshMessageFactory.DisableAndDeactivateMessage(messageName);            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_INFO_REQUEST");            actual = _sshMessageFactory.Create(messageNumber);            Assert.IsNotNull(actual);            Assert.AreEqual(typeof(InformationRequestMessage), actual.GetType());        }        [TestMethod]        public void DisableAndDeactivateMessageShouldThrowSshExceptionWhenAnotherMessageWithSameMessageNumberIsEnabled()        {            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            try            {                _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_INFO_REQUEST");                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual("Cannot enable message 'SSH_MSG_USERAUTH_INFO_REQUEST'. Message type 60 is already enabled for 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'.", ex.Message);            }            // verify that the original message remains enabled            var actual = _sshMessageFactory.Create(60);            Assert.IsNotNull(actual);            Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());        }        [TestMethod]        public void DisableAndDeactivateMessageShouldNotThrowExceptionWhenMessageIsAlreadyDisabled()        {            const byte messageNumber = 60;            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            // verify that message remains disabled            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);            }        }        [TestMethod]        public void DisableAndDeactivateMessageShouldNotThrowExceptionWhenMessageWasNeverEnabled()        {            const byte messageNumber = 60;            _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            // verify that message is disabled            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);            }        }        [TestMethod]        public void DisableAndDeactivateMessageShouldThrowSshExceptionWhenMessageIsNotSupported()        {            const string messageName = "WHATEVER";            try            {                _sshMessageFactory.DisableAndDeactivateMessage("WHATEVER");                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format("Message '{0}' is not supported.", messageName), ex.Message);            }        }        [TestMethod]        public void DisableAndDeactivateMessageShouldThrowArgumentNullExceptionWhenMessageNameIsNull()        {            const string messageName = null;            try            {                _sshMessageFactory.DisableAndDeactivateMessage(messageName);                Assert.Fail();            }            catch (ArgumentNullException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual("messageName", ex.ParamName);            }        }        [TestMethod]        public void EnableAndActivateMessageShouldThrowSshExceptionWhenAnotherMessageWithSameMessageNumberIsAlreadyEnabled()        {            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            try            {                _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_INFO_REQUEST");                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual("Cannot enable message 'SSH_MSG_USERAUTH_INFO_REQUEST'. Message type 60 is already enabled for 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'.", ex.Message);            }            // verify that the original message remains enabled            var actual = _sshMessageFactory.Create(60);            Assert.IsNotNull(actual);            Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());        }        [TestMethod]        public void EnableAndActivateMessageShouldNotThrowExceptionWhenMessageIsAlreadyEnabled()        {            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            var actual = _sshMessageFactory.Create(60);            Assert.IsNotNull(actual);            Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());        }        [TestMethod]        public void EnableAndActivateMessageShouldThrowSshExceptionWhenMessageIsNotSupported()        {            const string messageName = "WHATEVER";            try            {                _sshMessageFactory.EnableAndActivateMessage("WHATEVER");                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format("Message '{0}' is not supported.", messageName), ex.Message);            }        }        [TestMethod]        public void EnableAndActivateMessageShouldThrowArgumentNullExceptionWhenMessageNameIsNull()        {            const string messageName = null;            try            {                _sshMessageFactory.EnableAndActivateMessage(messageName);                Assert.Fail();            }            catch (ArgumentNullException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual("messageName", ex.ParamName);            }        }        [TestMethod]        public void DisableNonKeyExchangeMessagesShouldDisableNonKeyExchangeMessages()        {            const byte messageNumber = 60;            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.DisableNonKeyExchangeMessages();            // verify that message is disabled            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);            }        }        [TestMethod]        public void DisableNonKeyExchangeMessagesShouldNotDisableKeyExchangeMessages()        {            const byte messageNumber = 21;            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_NEWKEYS");            _sshMessageFactory.DisableNonKeyExchangeMessages();            // verify that message remains enabled            var actual = _sshMessageFactory.Create(messageNumber);            Assert.IsNotNull(actual);            Assert.AreEqual(typeof (NewKeysMessage), actual.GetType());        }        [TestMethod]        public void EnableActivatedMessagesShouldEnableMessagesThatWereEnabledPriorToInvokingDisableNonKeyExchangeMessages()        {            const byte messageNumber = 60;            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.DisableNonKeyExchangeMessages();            _sshMessageFactory.EnableActivatedMessages();            var actual = _sshMessageFactory.Create(messageNumber);            Assert.IsNotNull(actual);            Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());        }        [TestMethod]        public void EnableActivatedMessagesShouldNotEnableMessagesThatWereDisabledPriorToInvokingDisableNonKeyExchangeMessages()        {            const byte messageNumber = 60;            _sshMessageFactory.DisableNonKeyExchangeMessages();            _sshMessageFactory.EnableActivatedMessages();            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);            }        }        [TestMethod]        public void EnableActivatedMessagesShouldNotEnableMessagesThatWereDisabledAfterInvokingDisableNonKeyExchangeMessages()        {            const byte messageNumber = 60;            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.DisableNonKeyExchangeMessages();            _sshMessageFactory.DisableAndDeactivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.EnableActivatedMessages();            try            {                _sshMessageFactory.Create(messageNumber);                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid in the current context.", messageNumber), ex.Message);            }        }        [TestMethod]        public void EnableActivatedMessagesShouldThrowSshExceptionWhenAnothersMessageWithSameMessageNumberWasEnabledAfterInvokingDisableNonKeyExchangeMessages()        {            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.DisableNonKeyExchangeMessages();            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_INFO_REQUEST");            try            {                _sshMessageFactory.EnableActivatedMessages();                Assert.Fail();            }            catch (SshException ex)            {                Assert.IsNull(ex.InnerException);                Assert.AreEqual("Cannot enable message 'SSH_MSG_USERAUTH_PASSWD_CHANGEREQ'. Message type 60 is already enabled for 'SSH_MSG_USERAUTH_INFO_REQUEST'.", ex.Message);            }        }        [TestMethod]        public void EnableActivatedMessagesShouldLeaveMessagesEnabledThatWereEnabledAfterInvokingDisableNonKeyExchangeMessages()        {            const byte messageNumber = 60;            _sshMessageFactory.DisableNonKeyExchangeMessages();            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_PASSWD_CHANGEREQ");            _sshMessageFactory.EnableActivatedMessages();            var actual = _sshMessageFactory.Create(messageNumber);            Assert.IsNotNull(actual);            Assert.AreEqual(typeof(PasswordChangeRequiredMessage), actual.GetType());        }        [TestMethod]        public void HighestMessageNumberShouldCorrespondWithHighestSupportedMessageNumber()        {            var highestSupportMessageNumber = SshMessageFactory.AllMessages.Max(m => m.Number);            Assert.AreEqual(highestSupportMessageNumber, SshMessageFactory.HighestMessageNumber);        }        [TestMethod]        public void TotalMessageCountShouldBeTotalNumberOfSupportedMessages()        {            var totalNumberOfSupportedMessages = SshMessageFactory.AllMessages.Length;            Assert.AreEqual(totalNumberOfSupportedMessages, SshMessageFactory.TotalMessageCount);        }        [TestMethod]        [TestCategory("Performance")]        public void Performance_Ctor()        {            const int runCount = 100000;            // warm-up            for (var i = 0; i < 3; i++)            {                var sshMessageFactory = new SshMessageFactory();                var sshMessageFactoryOriginal = new SshMessageFactoryOriginal();            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            var stopwatch = new Stopwatch();            stopwatch.Start();            for (var i = 0; i < runCount; i++)            {                var sshMessageFactory = new SshMessageFactory();            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);            stopwatch.Reset();            stopwatch.Start();            for (var i = 0; i < runCount; i++)            {                var sshMessageFactory = new SshMessageFactoryOriginal();            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);        }        [TestMethod]        [TestCategory("LongRunning")]        [TestCategory("Performance")]        public void Performance_Create()        {            const int runCount = 10000000;            const string messageName = "SSH_MSG_CHANNEL_CLOSE";            _sshMessageFactory.EnableAndActivateMessage(messageName);            _sshMessageFactoryOriginal.EnableAndActivateMessage(messageName);            // warm-up            for (var i = 0; i < 3; i++)            {                _sshMessageFactory.Create(97);                _sshMessageFactoryOriginal.Create(97);            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            var stopwatch = new Stopwatch();            stopwatch.Start();            for (var i = 0; i < runCount; i++)            {                var msg = _sshMessageFactory.Create(97);                if (msg == null)                    Console.WriteLine();            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);            stopwatch.Reset();            stopwatch.Start();            for (var i = 0; i < runCount; i++)            {                var msg = _sshMessageFactoryOriginal.Create(97);                if (msg == null)                    Console.WriteLine();            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);        }        [TestMethod]        [TestCategory("LongRunning")]        [TestCategory("Performance")]        public void Performance_EnableAndActivateMessage()        {            const int runCount = 1000000;            const string messageName = "SSH_MSG_CHANNEL_CLOSE";            // warm-up            for (var i = 0; i < 3; i++)            {                _sshMessageFactory.EnableAndActivateMessage(messageName);                _sshMessageFactoryOriginal.EnableAndActivateMessage(messageName);            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            var stopwatch = new Stopwatch();            stopwatch.Start();            for (var i = 0; i < runCount; i++)                _sshMessageFactory.EnableAndActivateMessage(messageName);            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);            stopwatch.Reset();            stopwatch.Start();            for (var i = 0; i < runCount; i++)                _sshMessageFactoryOriginal.EnableAndActivateMessage(messageName);            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);        }        [TestMethod]        [TestCategory("LongRunning")]        [TestCategory("Performance")]        public void Performance_DisableAndDeactivateMessage()        {            const int runCount = 1000000;            const string messageName = "SSH_MSG_CHANNEL_CLOSE";            // warm-up            for (var i = 0; i < 3; i++)            {                _sshMessageFactory.DisableAndDeactivateMessage(messageName);                _sshMessageFactoryOriginal.DisableAndDeactivateMessage(messageName);            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            var stopwatch = new Stopwatch();            stopwatch.Start();            for (var i = 0; i < runCount; i++)                _sshMessageFactory.DisableAndDeactivateMessage(messageName);            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);            stopwatch.Reset();            stopwatch.Start();            for (var i = 0; i < runCount; i++)                _sshMessageFactoryOriginal.DisableAndDeactivateMessage(messageName);            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);        }        [TestMethod]        [TestCategory("LongRunning")]        [TestCategory("Performance")]        public void Performance_DisableNonKeyExchangeMessages()        {            const int runCount = 1000000;            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_USERAUTH_BANNER");            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_DEBUG");            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_UNIMPLEMENTED");            _sshMessageFactory.EnableAndActivateMessage("SSH_MSG_SERVICE_ACCEPT");            _sshMessageFactoryOriginal.EnableAndActivateMessage("SSH_MSG_USERAUTH_BANNER");            _sshMessageFactoryOriginal.EnableAndActivateMessage("SSH_MSG_DEBUG");            _sshMessageFactoryOriginal.EnableAndActivateMessage("SSH_MSG_UNIMPLEMENTED");            _sshMessageFactoryOriginal.EnableAndActivateMessage("SSH_MSG_SERVICE_ACCEPT");            // warm-up            for (var i = 0; i < 3; i++)            {                _sshMessageFactory.DisableNonKeyExchangeMessages();                _sshMessageFactory.EnableActivatedMessages();                _sshMessageFactoryOriginal.DisableNonKeyExchangeMessages();                _sshMessageFactoryOriginal.EnableActivatedMessages();            }            //Console.WriteLine("Starting test");            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            var stopwatch = new Stopwatch();            stopwatch.Start();            for (var i = 0; i < runCount; i++)            {                _sshMessageFactory.DisableNonKeyExchangeMessages();                _sshMessageFactory.EnableActivatedMessages();            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);            stopwatch.Reset();            stopwatch.Start();            for (var i = 0; i < runCount; i++)            {                _sshMessageFactoryOriginal.DisableNonKeyExchangeMessages();                _sshMessageFactoryOriginal.EnableActivatedMessages();            }            GC.Collect();            GC.WaitForPendingFinalizers();            GC.Collect();            stopwatch.Stop();            Console.WriteLine(stopwatch.ElapsedMilliseconds);        }        internal class SshMessageFactoryOriginal        {            private readonly IEnumerable<MessageMetadata> _messagesMetadata;            public SshMessageFactoryOriginal()            {                _messagesMetadata = new[]                {                    new MessageMetadata {Name = "SSH_MSG_NEWKEYS", Number = 21, Type = typeof(NewKeysMessage)},                    new MessageMetadata                    {                        Name = "SSH_MSG_REQUEST_FAILURE",                        Number = 82,                        Type = typeof(RequestFailureMessage)                    },                    new MessageMetadata {Name = "SSH_MSG_KEXINIT", Number = 20, Type = typeof(KeyExchangeInitMessage)},                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_OPEN_FAILURE",                        Number = 92,                        Type = typeof(ChannelOpenFailureMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_FAILURE",                        Number = 100,                        Type = typeof(ChannelFailureMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_EXTENDED_DATA",                        Number = 95,                        Type = typeof(ChannelExtendedDataMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_DATA",                        Number = 94,                        Type = typeof(ChannelDataMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_USERAUTH_REQUEST",                        Number = 50,                        Type = typeof(RequestMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_REQUEST",                        Number = 98,                        Type = typeof(ChannelRequestMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_USERAUTH_BANNER",                        Number = 53,                        Type = typeof(BannerMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_USERAUTH_INFO_RESPONSE",                        Number = 61,                        Type = typeof(InformationResponseMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_USERAUTH_FAILURE",                        Number = 51,                        Type = typeof(FailureMessage)                    },                    new MessageMetadata {Name = "SSH_MSG_DEBUG", Number = 4, Type = typeof(DebugMessage),},                    new MessageMetadata                    {                        Name = "SSH_MSG_KEXDH_INIT",                        Number = 30,                        Type = typeof(KeyExchangeDhInitMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_GLOBAL_REQUEST",                        Number = 80,                        Type = typeof(GlobalRequestMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_OPEN",                        Number = 90,                        Type = typeof(ChannelOpenMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_OPEN_CONFIRMATION",                        Number = 91,                        Type = typeof(ChannelOpenConfirmationMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_USERAUTH_INFO_REQUEST",                        Number = 60,                        Type = typeof(InformationRequestMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_UNIMPLEMENTED",                        Number = 3,                        Type = typeof(UnimplementedMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_REQUEST_SUCCESS",                        Number = 81,                        Type = typeof(RequestSuccessMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_SUCCESS",                        Number = 99,                        Type = typeof(ChannelSuccessMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_USERAUTH_PASSWD_CHANGEREQ",                        Number = 60,                        Type = typeof(PasswordChangeRequiredMessage)                    },                    new MessageMetadata {Name = "SSH_MSG_DISCONNECT", Number = 1, Type = typeof(DisconnectMessage)},                    new MessageMetadata                    {                        Name = "SSH_MSG_SERVICE_REQUEST",                        Number = 5,                        Type = typeof(ServiceRequestMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_KEX_DH_GEX_REQUEST",                        Number = 34,                        Type = typeof(KeyExchangeDhGroupExchangeRequest)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_KEX_DH_GEX_GROUP",                        Number = 31,                        Type = typeof(KeyExchangeDhGroupExchangeGroup)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_USERAUTH_SUCCESS",                        Number = 52,                        Type = typeof(SuccessMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_USERAUTH_PK_OK",                        Number = 60,                        Type = typeof(PublicKeyMessage)                    },                    new MessageMetadata {Name = "SSH_MSG_IGNORE", Number = 2, Type = typeof(IgnoreMessage)},                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_WINDOW_ADJUST",                        Number = 93,                        Type = typeof(ChannelWindowAdjustMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_EOF",                        Number = 96,                        Type = typeof(ChannelEofMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_CHANNEL_CLOSE",                        Number = 97,                        Type = typeof(ChannelCloseMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_SERVICE_ACCEPT",                        Number = 6,                        Type = typeof(ServiceAcceptMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_KEXDH_REPLY",                        Number = 31,                        Type = typeof(KeyExchangeDhReplyMessage)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_KEX_DH_GEX_INIT",                        Number = 32,                        Type = typeof(KeyExchangeDhGroupExchangeInit)                    },                    new MessageMetadata                    {                        Name = "SSH_MSG_KEX_DH_GEX_REPLY",                        Number = 33,                        Type = typeof(KeyExchangeDhGroupExchangeReply)                    }                };            }            /// <summary>            /// Disables and deactivate all messages.            /// </summary>            public void Reset()            {                foreach (var messageMetadata in _messagesMetadata)                {                    messageMetadata.Activated = messageMetadata.Enabled = false;                }            }            public void EnableActivatedMessages()            {                foreach (var messageMetadata in _messagesMetadata)                {                    if (messageMetadata.Activated)                        messageMetadata.Enabled = true;                }            }            public Message Create(byte messageNumber)            {                var messageMetadata =                    (from m in _messagesMetadata where m.Number == messageNumber && m.Enabled && m.Activated select m)                        .FirstOrDefault();                if (messageMetadata == null)                    throw new SshException(string.Format(CultureInfo.CurrentCulture, "Message type {0} is not valid.",                        messageNumber));                return messageMetadata.Type.CreateInstance<Message>();            }            public void DisableNonKeyExchangeMessages()            {                foreach (var messageMetadata in _messagesMetadata)                {                    if (messageMetadata.Activated && messageMetadata.Number > 2 &&                        (messageMetadata.Number < 20 || messageMetadata.Number > 30))                    {                        //Console.WriteLine("Disabling " + messageMetadata.Name + "...");                        messageMetadata.Enabled = false;                    }                }            }            public void EnableAndActivateMessage(string messageName)            {                lock (_messagesMetadata)                {                    var messagesMetadata = _messagesMetadata.Where(m => m.Name == messageName);                    foreach (var messageMetadata in messagesMetadata)                        messageMetadata.Enabled = messageMetadata.Activated = true;                }            }            public void DisableAndDeactivateMessage(string messageName)            {                lock (_messagesMetadata)                {                    var messagesMetadata = _messagesMetadata.Where(m => m.Name == messageName);                    foreach (var messageMetadata in messagesMetadata)                        messageMetadata.Enabled = messageMetadata.Activated = false;                }            }            private class MessageMetadata            {                public string Name { get; set; }                public byte Number { get; set; }                public bool Enabled { get; set; }                public bool Activated { get; set; }                public Type Type { get; set; }            }        }    }}
 |