diff --git a/SMTPServer/DNSResolver/DNSResolver.csproj b/SMTPServer/DNSResolver/DNSResolver.csproj index 35c4d2b..13c8161 100644 --- a/SMTPServer/DNSResolver/DNSResolver.csproj +++ b/SMTPServer/DNSResolver/DNSResolver.csproj @@ -1,16 +1,16 @@ - + - + + 1701;1702;1705;1006 + Exe netcoreapp1.0 - - 1.0.1 @@ -20,6 +20,5 @@ All - \ No newline at end of file diff --git a/SMTPServer/DNSResolver/DnsHelper.cs b/SMTPServer/DNSResolver/DnsHelper.cs new file mode 100644 index 0000000..24614ab --- /dev/null +++ b/SMTPServer/DNSResolver/DnsHelper.cs @@ -0,0 +1,115 @@ +using System; +using System.Text; + +namespace DNSResolver +{ + internal static class DnsHelpers + { + private const long Epoch = 621355968000000000; + + internal static byte[] CanonicaliseDnsName(string name, bool lowerCase) + { + if (!name.EndsWith(".")) + { + name += "."; + } + + if (name == ".") + { + return new byte[1]; + } + + StringBuilder sb = new StringBuilder(); + + sb.Append('\0'); + + for (int i = 0, j = 0; i < name.Length; i++, j++) + { + if (lowerCase) + { + sb.Append(char.ToLower(name[i])); + } + else + { + sb.Append(name[i]); + } + + if (name[i] == '.') + { + sb[i - j] = (char)(j & 0xff); + j = -1; + } + } + + sb[sb.Length - 1] = '\0'; + + return Encoding.ASCII.GetBytes(sb.ToString()); + } + + internal static String DumpArrayToString(byte[] bytes) + { + StringBuilder builder = new StringBuilder(); + + builder.Append("["); + + foreach (byte b in bytes) + { + builder.Append(" "); + builder.Append((sbyte)b); + builder.Append(" "); + } + + builder.Append("]"); + + return builder.ToString(); + } + + /// + /// Converts a instance of a class to a 48 bit format time since epoch. + /// Epoch is defined as 1-Jan-70 UTC. + /// + /// The instance to convert to DNS format. + /// The upper 16 bits of time. + /// The lower 32 bits of the time object. + internal static void ConvertToDnsTime(DateTime dateTimeToConvert, out int timeHigh, out long timeLow) + { + long secondsFromEpoch = (dateTimeToConvert.ToUniversalTime().Ticks - Epoch) / 10000000; + timeHigh = (int)(secondsFromEpoch >> 32); + timeLow = (secondsFromEpoch & 0xFFFFFFFFL); + + Logging.AddLogMessage(LoggingType.TRACE, "test"); + Trace.WriteLine(String.Format("Date: {0}", dateTimeToConvert)); + Trace.WriteLine(String.Format("secondsFromEpoch: {0}", secondsFromEpoch)); + Trace.WriteLine(String.Format("timeHigh: {0}", timeHigh)); + Trace.WriteLine(String.Format("timeLow: {0}", timeLow)); + } + + /// + /// Convert from DNS 48 but time format to a instance. + /// + /// The upper 16 bits of time. + /// The lower 32 bits of the time object. + /// The converted date time + internal static DateTime ConvertFromDnsTime(long timeLow, long timeHigh) + { + long time = (timeHigh << 32) + timeLow; + time = time * 10000000; + time += Epoch; + + return new DateTime(time); + } + + /// + /// Convert from DNS 48 but time format to a instance. + /// + /// The upper 48 bits of time. + /// The converted date time + internal static DateTime ConvertFromDnsTime(long dnsTime) + { + dnsTime = dnsTime * 10000000; + dnsTime += Epoch; + + return new DateTime(dnsTime); + } + } +} diff --git a/SMTPServer/DNSResolver/Program.cs b/SMTPServer/DNSResolver/Program.cs deleted file mode 100644 index 104ecf0..0000000 --- a/SMTPServer/DNSResolver/Program.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; - -class Program -{ - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } -} \ No newline at end of file diff --git a/SMTPServer/Logging/Logging.cs b/SMTPServer/Logging/Logging.cs new file mode 100644 index 0000000..afdd261 --- /dev/null +++ b/SMTPServer/Logging/Logging.cs @@ -0,0 +1,50 @@ +using System; + +namespace Logging +{ + public class Logging + { + private static LoggingType[] _ActiveLoggingTypes { get; set; } + + public enum LoggingType + { + TRACE, + ERROR, + DEBUG, + WARNING, + INFO, + ALL + } + + + + private static void AddLogMessage(LoggingType messagetype, string message) + { + if(CheckLoggingType(messagetype)) PrintToConsole(messagetype, message); + } + + private static bool CheckLoggingType(LoggingType lt){ + if (_ActiveLoggingTypes.Length < 1) { + _ActiveLoggingTypes = new LoggingType[1]; + _ActiveLoggingTypes[0] = LoggingType.ALL; + } + bool found = false; + foreach(LoggingType l in _ActiveLoggingTypes) + { + if (l == lt || l == LoggingType.ALL) + { + found = true; + break; + } + } + + + return found; + } + + private static void PrintToConsole(LoggingType lt, string message) + { + Console.WriteLine("[" + lt.ToString() + "]" + message); + } + } +} diff --git a/SMTPServer/Logging/Logging.csproj b/SMTPServer/Logging/Logging.csproj new file mode 100644 index 0000000..550eaa7 --- /dev/null +++ b/SMTPServer/Logging/Logging.csproj @@ -0,0 +1,23 @@ + + + + 1701;1702;1705;1006 + + + netstandard1.4 + + + + + + + + 1.6 + + + 1.0.0-alpha-20161104-2 + All + + + + \ No newline at end of file diff --git a/SMTPServer/SMTPServer.sln b/SMTPServer/SMTPServer.sln index 8362e85..0591f69 100644 --- a/SMTPServer/SMTPServer.sln +++ b/SMTPServer/SMTPServer.sln @@ -4,14 +4,9 @@ Microsoft Visual Studio Solution File, Format Version 12.00 VisualStudioVersion = 15.0.25914.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SMTPServer", "SMTPServer\SMTPServer.csproj", "{ABB6A3E6-38B6-4D02-AC9C-91FA69CF03BE}" - ProjectSection(ProjectDependencies) = postProject - {55342A63-351F-4908-B708-DC4111FF34E7} = {55342A63-351F-4908-B708-DC4111FF34E7} - EndProjectSection EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{D43013F8-933F-4ADC-8943-08E91662A070}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DNSResolver", "DNSResolver\DNSResolver.csproj", "{55342A63-351F-4908-B708-DC4111FF34E7}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -22,10 +17,6 @@ Global {ABB6A3E6-38B6-4D02-AC9C-91FA69CF03BE}.Debug|Any CPU.Build.0 = Debug|Any CPU {ABB6A3E6-38B6-4D02-AC9C-91FA69CF03BE}.Release|Any CPU.ActiveCfg = Release|Any CPU {ABB6A3E6-38B6-4D02-AC9C-91FA69CF03BE}.Release|Any CPU.Build.0 = Release|Any CPU - {55342A63-351F-4908-B708-DC4111FF34E7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {55342A63-351F-4908-B708-DC4111FF34E7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {55342A63-351F-4908-B708-DC4111FF34E7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {55342A63-351F-4908-B708-DC4111FF34E7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/SMTPServer/SMTPServer/DNSClient/DnsHelpers.cs b/SMTPServer/SMTPServer/DNSClient/DnsHelpers.cs new file mode 100644 index 0000000..608138a --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/DnsHelpers.cs @@ -0,0 +1,115 @@ +using System; +using System.Diagnostics; +using System.Text; + +namespace DnDns +{ + internal static class DnsHelpers + { + private const long Epoch = 621355968000000000; + + internal static byte[] CanonicaliseDnsName(string name, bool lowerCase) + { + if (!name.EndsWith(".")) + { + name += "."; + } + + if (name == ".") + { + return new byte[1]; + } + + StringBuilder sb = new StringBuilder(); + + sb.Append('\0'); + + for (int i = 0, j = 0; i < name.Length; i++, j++) + { + if (lowerCase) + { + sb.Append(char.ToLower(name[i])); + } + else + { + sb.Append(name[i]); + } + + if (name[i] == '.') + { + sb[i - j] = (char) (j & 0xff); + j = -1; + } + } + + sb[sb.Length - 1] = '\0'; + + return Encoding.ASCII.GetBytes(sb.ToString()); + } + + internal static String DumpArrayToString(byte[] bytes) + { + StringBuilder builder = new StringBuilder(); + + builder.Append("["); + + foreach (byte b in bytes) + { + builder.Append(" "); + builder.Append((sbyte)b); + builder.Append(" "); + } + + builder.Append("]"); + + return builder.ToString(); + } + + /// + /// Converts a instance of a class to a 48 bit format time since epoch. + /// Epoch is defined as 1-Jan-70 UTC. + /// + /// The instance to convert to DNS format. + /// The upper 16 bits of time. + /// The lower 32 bits of the time object. + internal static void ConvertToDnsTime(DateTime dateTimeToConvert, out int timeHigh, out long timeLow) + { + long secondsFromEpoch = (dateTimeToConvert.ToUniversalTime().Ticks - Epoch) / 10000000; + timeHigh = (int)(secondsFromEpoch >> 32); + timeLow = (secondsFromEpoch & 0xFFFFFFFFL); + + Console.WriteLine(String.Format("Date: {0}", dateTimeToConvert)); + Console.WriteLine(String.Format("secondsFromEpoch: {0}", secondsFromEpoch)); + Console.WriteLine(String.Format("timeHigh: {0}", timeHigh)); + Console.WriteLine(String.Format("timeLow: {0}", timeLow)); + } + + /// + /// Convert from DNS 48 but time format to a instance. + /// + /// The upper 16 bits of time. + /// The lower 32 bits of the time object. + /// The converted date time + internal static DateTime ConvertFromDnsTime(long timeLow, long timeHigh) + { + long time = (timeHigh << 32) + timeLow; + time = time*10000000; + time += Epoch; + + return new DateTime(time); + } + + /// + /// Convert from DNS 48 but time format to a instance. + /// + /// The upper 48 bits of time. + /// The converted date time + internal static DateTime ConvertFromDnsTime(long dnsTime) + { + dnsTime = dnsTime * 10000000; + dnsTime += Epoch; + + return new DateTime(dnsTime); + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Enums/NsClass.cs b/SMTPServer/SMTPServer/DNSClient/Enums/NsClass.cs new file mode 100644 index 0000000..ed1e2c4 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Enums/NsClass.cs @@ -0,0 +1,94 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DnDns.Enums +{ + /// + /// RFC 1035: + /// + /// 3.2.4. CLASS values + /// + /// CLASS fields appear in resource records. The following CLASS mnemonics + /// and values are defined: + /// + /// IN 1 the Internet + /// + /// CS 2 the CSNET class (Obsolete - used only for examples in + /// some obsolete RFCs) + /// + /// CH 3 the CHAOS class + /// + /// HS 4 Hesiod [Dyer 87] + /// + /// 3.2.5. QCLASS values + /// + /// QCLASS fields appear in the question section of a query. QCLASS values + /// are a superset of CLASS values; every CLASS is a valid QCLASS. In + /// addition to CLASS values, the following QCLASSes are defined: + /// + /// * 255 any class + /// + public enum NsClass : byte + { + /// + /// Cookie?? - NOT IMPLEMENTED + /// + INVALID = 0, + /// + /// // Internet (inet), RFC 1035 + /// + INET = 1, + /// + /// MIT Chaos-net, RFC 1035 - NOT IMPLEMENTED + /// + CHAOS = 3, + /// + /// MIT Hesiod, RFC 1035 - NOT IMPLEMENTED + /// + HS = 4, + /// + /// RFC 2136 - None + /// prereq sections in update requests -- NOT IMPLEMENTED + /// + NONE = 254, + /// + /// Any QCLASS only, Wildcard match, RFC 1035 - IMPLEMENTED for INET only + /// + ANY = 255 + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Enums/NsFlags.cs b/SMTPServer/SMTPServer/DNSClient/Enums/NsFlags.cs new file mode 100644 index 0000000..f66553f --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Enums/NsFlags.cs @@ -0,0 +1,298 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DnDns.Enums +{ + // DNS HEADER: http://www.faqs.org/rfcs/rfc1035.html + // 1 1 1 1 1 1 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | Query Identifier | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // |QR| Opcode |AA|TC|RD|RA| Z|AD|CD| RCODE | <-- The Enums below are combined to create this 16 bit (2 byte) field + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | QDCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | ANCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | NSCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | ARCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + + /// + /// FlagMasks are used as a bitmask to isolate bits 16 through 31 of the DNS header to convert + /// them to their appropriate Enum types + /// + internal enum FlagMasks : ushort + { + QueryResponseMask = 0x8000, + OpCodeMask = 0x7800, + NsFlagMask = 0x07F0, + RCodeMask = 0x000F + } + + /// + /// |QR| - Starts at bit 16 of DNS Header, size: 1 bit + /// + /// RFC 1035: + /// A one bit field that specifies whether this message is a + /// query (0), or a response (1). + /// + /// + [Flags()] + public enum QueryResponse : ushort + { + /// + /// // QR Query or Response [RFC1035] ( 0 = Query ) + /// + Query = 0x0, + /// + /// // QR Query or Response [RFC1035] ( 1 = Response ) + /// + Response = 0x8000 + } + + /// + /// | OpCode | - 4 bits of Dns header, Bit 17 - 20, see RFC 1035 + /// + /// RFC 1035: + /// + /// A four bit field that specifies kind of query in this + /// message. This value is set by the originator of a query + /// and copied into the response. + /// + /// The values are: + /// + /// 0 a standard query (QUERY) + /// + /// 1 an inverse query (IQUERY) + /// + /// 2 a server status request (STATUS) + /// + /// 3-15 reserved for future + /// + [Flags()] + public enum OpCode : ushort + { + /// + /// Standard query + /// [RFC1035] (QUERY) + /// + QUERY = 0x0000, + /// + /// Inverse query + /// [RFC1035] (IQUERY) + /// + IQUERY = 0x0800, + /// + /// Server status request + /// [RFC1035] (STATUS) + /// + STATUS = 0x1000, + } + + /// + /// |AA|TC|RD|RA| Z|AD|CD| - 8 bits (1 byte) flag fields + /// + /// reference: http://www.networksorcery.com/enp/protocol/dns.htm + /// + [Flags()] + public enum NsFlags : ushort + { + /// + /// AA - Authorative Answer [RFC1035] ( 0 = Not authoritative, 1 = Is authoritative ) + /// Authoritative Answer - this bit is valid in responses, + /// and specifies that the responding name server is an + /// authority for the domain name in question section. + /// + /// Note that the contents of the answer section may have + /// multiple owner names because of aliases. The AA bit + /// corresponds to the name which matches the query name, or + /// the first owner name in the answer section. + /// + AA = 0x0400, + /// + /// TC - Truncated Response [RFC1035] ( 0 = Not truncated, 1 = Message truncated ) + /// + /// TrunCation - specifies that this message was truncated + /// due to length greater than that permitted on the + /// transmission channel. + /// + TC = 0x0200, + /// + /// RD - Recursion Desired [RFC1035] ( 0 = Recursion not desired, 1 = Recursion desired ) + /// + /// Recursion Desired - this bit may be set in a query and + /// is copied into the response. If RD is set, it directs + /// the name server to pursue the query recursively. + /// Recursive query support is optional. + /// + RD = 0x0100, + /// + /// RA - Recursion Allowed [RFC1035] ( 0 = Recursive query support not available, 1 = Recursive query support available ) + /// + /// Recursion Available - this be is set or cleared in a + /// response, and denotes whether recursive query support is + /// available in the name server. + /// + RA = 0x0080, + /// + /// AD - Authentic Data [RFC4035] ( Authenticated data. 1 bit ) [NOT IMPLEMENTED] + /// + /// Indicates in a response that all data included in the answer and authority + /// sections of the response have been authenticated by the server according to + /// the policies of that server. It should be set only if all data in the response + /// has been cryptographically verified or otherwise meets the server's local security + /// policy. + /// + AD = 0x0020, + /// + /// CD - Checking Disabled [RFC4035] ( Checking Disabled. 1 bit ) [NOT IMPLEMENTED] + /// + CD = 0x0010 + } + + /// + /// | RCODE | - 4 bits error codes + /// + /// Response code - this 4 bit field is set as part of + /// responses. The values have the following interpretation: + /// + /// Fields 6-15 Reserved for future use. + /// + /// reference: http://www.networksorcery.com/enp/protocol/dns.htm + /// + [Flags()] + public enum RCode : ushort + { + /// + /// No error condition + /// + NoError = 0, + /// + /// Format error - The name server was unable to + /// interpret the query. + /// + FormatError = 1, + /// + /// Server failure - The name server was unable to process + /// this query due to a problem with the name server. + /// + ServerFailure = 2, + /// + /// Name Error - Meaningful only for responses from an + /// authoritative name server, this code signifies that + /// the domain name referenced in the query does not + /// exist. + /// + NameError = 3, + /// + /// Not Implemented - The name server does not support + /// the requested kind of query. + /// + NotImplemented = 4, + /// + /// Refused - The name server refuses to perform the + /// specified operation for policy reasons. For example, + /// a name server may not wish to provide the information + /// to the particular requester, or a name server may not + /// wish to perform a particular operation (e.g., zone + /// transfer) for particular data. + /// + Refused = 5, + /// + /// RFC 2136 + /// Name Exists when it should not. + /// + YXDomain = 6, + /// + /// RFC 2136 + /// RR Set Exists when it should not. + /// + YXRRSet = 7, + /// + /// RFC 2136 + /// RR Set that should exist does not. + /// + NXRRSet = 8, + /// + /// RFC 2136 + /// Server Not Authoritative for zone. + /// + NotAuth = 9, + /// + /// RFC 2136 + /// Name not contained in zone. + /// + NotZone = 10, + /// + /// RFC 2671 + /// RFC 2845 + /// + /// BADVERS Bad OPT Version. + /// BADSIG TSIG Signature Failure. + /// + BADVERS_BADSIG = 16, + /// + /// RFC 2845 + /// Key not recognized. + /// + BADKEY = 17, + /// + /// RFC 2845 + /// Signature out of time window. + /// + BADTIME = 18, + /// + /// RFC 2930 + /// Bad TKEY Mode. + /// + BADMODE = 19, + /// + /// RFC 2930 + /// Duplicate key name. + /// + BADNAME = 20, + /// + /// RFC 2930 + /// Algorithm not supported. + /// + BADALG = 21 + } +} \ No newline at end of file diff --git a/SMTPServer/SMTPServer/DNSClient/Enums/NsType.cs b/SMTPServer/SMTPServer/DNSClient/Enums/NsType.cs new file mode 100644 index 0000000..b97e990 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Enums/NsType.cs @@ -0,0 +1,305 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DnDns.Enums +{ + /// + /// Currently defined type values for resources and queries. + /// + /// RFC 1034 + /// + /// 3.2.2. TYPE values + /// + /// TYPE fields are used in resource records. Note that these types are a + /// subset of QTYPEs. + /// + /// TYPE value and meaning + /// + /// A 1 a host address, Implemented + /// + /// NS 2 an authoritative name server, Implemented + /// + /// MD 3 a mail destination (Obsolete - use MX), NOT Implemented + /// + /// MF 4 a mail forwarder (Obsolete - use MX), NOT Implemented + /// + /// CNAME 5 the canonical name for an alias, Implemented + /// + /// SOA 6 marks the start of a zone of authority, Implemented + /// + /// MB 7 a mailbox domain name (EXPERIMENTAL), Implemented + /// + /// MG 8 a mail group member (EXPERIMENTAL), Implemented + /// + /// MR 9 a mail rename domain name (EXPERIMENTAL), Implemented + /// + /// NULL 10 a null RR (EXPERIMENTAL), NOT IMPLEMENTED + /// + /// WKS 11 a well known service description + /// + /// PTR 12 a domain name pointer + /// + /// HINFO 13 host information + /// + /// MINFO 14 mailbox or mail list information + /// + /// MX 15 mail exchange + /// + /// TXT 16 text strings + /// + /// 3.2.3. QTYPE values + /// + /// QTYPE fields appear in the question part of a query. QTYPES are a + /// superset of TYPEs, hence all TYPEs are valid QTYPEs. In addition, the + /// following QTYPEs are defined: + /// + /// AXFR 252 A request for a transfer of an entire zone + /// + /// MAILB 253 A request for mailbox-related records (MB, MG or MR) + /// + /// MAILA 254 A request for mail agent RRs (Obsolete - see MX) + /// + /// * 255 A request for all records + /// + /// + public enum NsType : uint + { + /// + /// Invalid + /// + INVALID = 0, + /// + /// Host address + /// + A = 1, + /// + /// Authoritative server + /// + NS = 2, + /// + /// Mail destination - NOT IMPLEMENTED + /// + MD = 3, + /// + /// Mail forwarder, NOT IMPLEMENTED + /// + MF = 4, + /// + /// Canonical name + /// + CNAME = 5, + /// + /// Start of authority zone + /// + SOA = 6, + // Mailbox domain name + MB = 7, + /// + /// Mail group member + /// + MG = 8, + /// + /// Mail rename name + /// + MR = 9, + /// + /// Null resource record + /// + NULL = 10, + /// + /// Well known service + /// + WKS = 11, + /// + /// Domain name pointer + /// + PTR = 12, + /// + /// Host information + /// + HINFO = 13, + /// + /// Mailbox information + /// + MINFO = 14, + /// + /// Mail routing information + /// + MX = 15, + /// + /// Text strings, RFC 1464 + /// + TXT = 16, + /// + /// Responsible person, RFC 1183, Implemented + /// + RP = 17, + /// + /// AFS cell database, RFC 1183, Implemented + /// + AFSDB = 18, + /// + /// X_25 calling address, RFC 1183, Implemented + /// + X25 = 19, + /// + /// ISDN calling address, RFC 1183, Implemented + /// + ISDN = 20, + /// + /// Router, RFC 1183, Implemented + /// + RT = 21, + /// + /// NSAP address, RFC 1706 + /// + NSAP = 22, + /// + /// Reverse NSAP lookup - deprecated by PTR ? + /// + NSAP_PTR = 23, + /// + /// Security signature, RFC 2535 + /// + SIG = 24, + /// + /// Security key, RFC 2535 + /// + KEY = 25, + /// + /// X.400 mail mapping, RFC ? + /// + PX = 26, + /// + /// Geographical position - withdrawn, RFC 1712 + /// + GPOS = 27, + /// + /// Ip6 Address, RFC 1886 -- Implemented + /// + AAAA = 28, + /// + /// Location Information, RFC 1876, Implemented + /// + LOC = 29, + /// + /// Next domain (security), RFC 2065 + /// + NXT = 30, + /// + /// Endpoint identifier,RFC ? + /// + EID = 31, + /// + /// Nimrod Locator, RFC ? + /// + NIMLOC = 32, + /// + /// Server Record, RFC 2052, Implemented + /// + SRV = 33, + /// + /// ATM Address, RFC ?, Implemented + /// + ATMA = 34, + /// + /// Naming Authority PoinTeR, RFC 2915 + /// + MAPTR = 35, + /// + /// Key Exchange, RFC 2230 + /// + KX = 36, + /// + /// Certification record, RFC 2538 + /// + CERT = 37, + /// + /// IPv6 address (deprecates AAAA), RFC 3226 + /// + A6 = 38, + /// + /// Non-terminal DNAME (for IPv6), RFC 2874 + /// + DNAME = 39, + /// + /// Kitchen sink (experimentatl), RFC ? + /// + SINK = 40, + /// + /// EDNS0 option (meta-RR), RFC 2671 + /// + OPT = 41, + /// + /// Transaction key, RFC 2930 + /// + TKEY = 249, + /// + /// Transaction signature, RFC 2845 + /// + TSIG = 250, + /// + /// Incremental zone transfer, RFC 1995 + /// + IXFR = 251, + /// + /// Transfer zone of authority, RFC 1035 + /// + AXFR = 252, + /// + /// Transfer mailbox records, RFC 1035 + /// + MAILB = 253, + /// + /// Transfer mail agent records, RFC 1035 + /// + MAILA = 254, + /// + /// All of the above, RFC 1035 + /// + ANY = 255, + /// + /// DNSSEC Trust Authorities + /// + DNSSECTrustAuthorities = 32768, + /// + /// DNSSEC Lookaside Validation, RFC4431 + /// + DNSSECLookasideValidation = 32769 + } +} \ No newline at end of file diff --git a/SMTPServer/SMTPServer/DNSClient/Enums/TcpServices.cs b/SMTPServer/SMTPServer/DNSClient/Enums/TcpServices.cs new file mode 100644 index 0000000..c646f00 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Enums/TcpServices.cs @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DnDns.Enums +{ + /// + /// Defines Well Known TCP Ports for Services + /// + public enum TcpServices : short + { + /// + /// Domain Name Server Port + /// + Domain = 53 + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Enums/UdpServices.cs b/SMTPServer/SMTPServer/DNSClient/Enums/UdpServices.cs new file mode 100644 index 0000000..0e57058 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Enums/UdpServices.cs @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; + +namespace DnDns.Enums +{ + /// + /// Defines Well Known UDP Ports for Services + /// + public enum UdpServices : short + { + /// + /// Domain Name Server Protocol Port + /// + Domain = 53 + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryBase.cs b/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryBase.cs new file mode 100644 index 0000000..a70ebde --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryBase.cs @@ -0,0 +1,287 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; + +using DnDns.Enums; +using DnDns.Records; + +namespace DnDns.Query +{ + /// + /// DnsQueryBase maintains the common state of DNS Queries (both responses and requests) + /// + public abstract class DnsQueryBase + { + #region Fields + // RFC 1034 + // + // 4.1.1. Header section format + // + // 1 1 1 1 1 1 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | ID | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // |QR| Opcode |AA|TC|RD|RA| Z | RCODE | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | QDCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | ANCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | NSCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | ARCOUNT | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + + /// + /// ID - A 16 bit identifier. This identifier is copied + /// the corresponding reply and can be used by the requester + /// to match up replies to outstanding queries. + /// + protected ushort _transactionId; + /// + /// _flags will store a combination of the enums that make up the 16 bits after the + /// TransactionID in the DNS protocol header + /// + protected ushort _flags; + /// + /// A one bit field that specifies whether this message is a + /// query (0), or a response (1). + /// + protected QueryResponse _queryResponse; + /// + /// OPCODE - A four bit field that specifies kind of query in this + /// message. This value is set by the originator of a query + /// and copied into the response. + /// + protected OpCode _opCode; + /// + /// - A combination of flag fields in the DNS header (|AA|TC|RD|RA|) + /// + protected NsFlags _nsFlags; + /// + /// Response code - this 4 bit field is set as part of + /// responses only. + /// + protected RCode _rCode; + /// + /// QDCOUNT - an unsigned 16 bit integer specifying the number of + /// entries in the question section. + /// + protected ushort _questions; + /// + /// ANCOUNT - an unsigned 16 bit integer specifying the number of + /// resource records in the answer section. + /// + protected ushort _answerRRs; + /// + /// NSCOUNT - an unsigned 16 bit integer specifying the number of name + /// server resource records in the authority records + /// section. + /// + protected ushort _authorityRRs; + + // RFC 1034 + // 4.1.2. Question section format + // 1 1 1 1 1 1 + // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | | + // / QNAME / + // / / + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | QTYPE | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | QCLASS | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + + /// + /// QNAME - a domain name represented as a sequence of labels, where + /// each label consists of a length octet followed by that + /// number of octets. The domain name terminates with the + /// zero length octet for the null label of the root. Note + /// that this field may be an odd number of octets; no + /// padding is used + /// + protected string _name; + /// + /// QTYPE - a two octet code which specifies the type of the query. + /// The values for this field include all codes valid for a + /// TYPE field, together with some more general codes which + /// can match more than one type of RR. + /// + protected NsType _nsType; + /// + /// QCLASS - a two octet code that specifies the class of the query. + /// For example, the QCLASS field is IN for the Internet. + /// + protected NsClass _nsClass; + + /// + /// The additional records for the DNS Query + /// + protected List _additionalRecords = new List(); + + #endregion Fields + + #region Properties + + /// ID - A 16 bit identifier. This identifier is copied + /// the corresponding reply and can be used by the requester + /// to match up replies to outstanding queries. + /// + public ushort TransactionID + { + get { return _transactionId; } + } + + /// + /// A one bit field that specifies whether this message is a + /// query (0), or a response (1). + /// + public QueryResponse QueryResponse + { + get { return _queryResponse; } + } + + /// + /// OPCODE - A four bit field that specifies kind of query in this + /// message. This value is set by the originator of a query + /// and copied into the response. + /// + public OpCode OpCode + { + get { return _opCode; } + } + + /// + /// NsFlags - A combination of flag fields in the DNS header (|AA|TC|RD|RA|) + /// + public NsFlags NsFlags + { + get { return _nsFlags; } + } + + /// + /// Response code - this 4 bit field is set as part of + /// responses only. + /// + public RCode RCode + { + get { return _rCode; } + } + + /// + /// QDCOUNT - an unsigned 16 bit integer specifying the number of + /// entries in the question section. + /// + public ushort Questions + { + get { return _questions; } + } + + /// + /// ANCOUNT - an unsigned 16 bit integer specifying the number of + /// resource records in the answer section. + /// + public ushort AnswerRRs + { + get { return _answerRRs; } + } + + /// + /// NSCOUNT - an unsigned 16 bit integer specifying the number of name + /// server resource records in the authority records + /// section. + /// + public ushort AuthorityRRs + { + get { return _authorityRRs; } + } + + /// + /// ARCOUNT - an unsigned 16 bit integer specifying the number of + /// resource records in the additional records section. + /// + public ushort AdditionalRRs + { + get { return (ushort) _additionalRecords.Count; } + } + + /// + /// QNAME - a domain name represented as a sequence of labels, where + /// each label consists of a length octet followed by that + /// number of octets. The domain name terminates with the + /// zero length octet for the null label of the root. Note + /// that this field may be an odd number of octets; no + /// padding is used + /// + public string Name + { + get { return _name; } + set { _name = value; } + } + + /// + /// QTYPE - a two octet code which specifies the type of the query. + /// The values for this field include all codes valid for a + /// TYPE field, together with some more general codes which + /// can match more than one type of RR. + /// + public NsType NsType + { + get { return _nsType; } + set { _nsType = value; } + } + + /// + /// QCLASS - a two octet code that specifies the class of the query. + /// For example, the QCLASS field is IN for the Internet. + /// + public NsClass NsClass + { + get { return _nsClass; } + set { _nsClass = value; } + } + + public List AdditionalRRecords + { + get { return _additionalRecords; } + } + #endregion + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryRequest.cs b/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryRequest.cs new file mode 100644 index 0000000..f781111 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryRequest.cs @@ -0,0 +1,377 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Net.NetworkInformation; +using System.Security.Permissions; +using System.Text; + +using DnDns.Enums; +using DnDns.Records; +using DnDns.Security; + +namespace DnDns.Query +{ + /// + /// Summary description for DnsQueryRequest. + /// + public class DnsQueryRequest : DnsQueryBase + { + private static Random r = new Random(); + + private DnsPermission _dnsPermissions; + + private int _bytesSent = 0; + private int _socketTimeout = 5000; + + /// + /// The number of bytes sent to query the DNS Server. + /// + public int BytesSent + { + get { return _bytesSent; } + } + + /// + /// Gets or sets the amount of time in milliseconds that a DnsQueryRequest will wait to receive data once a read operation is initiated. + /// Defauts to 5 seconds (5000 ms) + /// + public int Timeout + { + get { return _socketTimeout; } + set { _socketTimeout = value; } + } + + #region Constructors + public DnsQueryRequest() + { + _dnsPermissions = new DnsPermission(PermissionState.Unrestricted); + + // Construct the class with some defaults + _transactionId = (ushort) r.Next(); + _flags = 0; + _queryResponse = QueryResponse.Query; + this._opCode = OpCode.QUERY; + // Recursion Desired + this._nsFlags = NsFlags.RD; + this._questions = 1; + } + + #endregion Constructors + + private byte[] BuildQuery(string host) + { + string newHost; + int newLocation = 0; + int oldLocation = 0; + + MemoryStream ms = new MemoryStream(); + + host = host.Trim(); + // decide how to build this query based on type + switch (_nsType) + { + case NsType.PTR: + IPAddress queryIP = IPAddress.Parse(host); + + // pointer should be translated as follows + // 209.115.22.3 -> 3.22.115.209.in-addr.arpa + char[] ipDelim = new char[] {'.'}; + + string[] s = host.Split(ipDelim,4); + newHost = String.Format("{0}.{1}.{2}.{3}.in-addr.arpa", s[3], s[2], s[1], s[0]); + break; + default: + newHost = host; + break; + } + + // Package up the host + while(oldLocation < newHost.Length) + { + newLocation = newHost.IndexOf(".", oldLocation); + + if (newLocation == -1) newLocation = newHost.Length; + + byte subDomainLength = (byte)(newLocation - oldLocation); + char[] sub = newHost.Substring(oldLocation, subDomainLength).ToCharArray(); + + ms.WriteByte(subDomainLength); + ms.Write(Encoding.ASCII.GetBytes(sub, 0, sub.Length), 0, sub.Length); + + oldLocation = newLocation + 1; + } + + // Terminate the domain name w/ a 0x00. + ms.WriteByte(0x00); + + return ms.ToArray(); + } + + /// + /// + /// + /// + /// + /// + /// + /// + public DnsQueryResponse Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol) + { + return Resolve(host, queryType, queryClass, protocol, null); + } + + public DnsQueryResponse Resolve(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, TsigMessageSecurityProvider provider) + { + string dnsServer = string.Empty; + + // Test for Unix/Linux OS + if (Tools.IsPlatformLinuxUnix()) + { + dnsServer = Tools.DiscoverUnixDnsServerAddress(); + } + else + { + IPAddressCollection dnsServerCollection = Tools.DiscoverDnsServerAddresses(); + if (dnsServerCollection.Count == 0) + throw new Exception("Couldn't detect local DNS Server."); + + dnsServer = dnsServerCollection[0].ToString(); + } + + if (String.IsNullOrEmpty(dnsServer)) + throw new Exception("Couldn't detect local DNS Server."); + + return Resolve(dnsServer, host, queryType, queryClass, protocol, provider); + + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// The instance of the message security provider to use to secure the DNS request. + /// A instance that contains the Dns Answer for the request query. + /// + /// + /// + public DnsQueryResponse Resolve(string dnsServer, string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider) + { + // Do stack walk and Demand all callers have DnsPermission. + _dnsPermissions.Demand(); + + byte[] bDnsQuery = this.BuildDnsRequest(host, queryType, queryClass, protocol, messageSecurityProvider); + + // Connect to DNS server and get the record for the current server. + IPHostEntry ipe = System.Net.Dns.GetHostEntry(dnsServer); + IPAddress ipa = ipe.AddressList[0]; + IPEndPoint ipep = new IPEndPoint(ipa, (int)UdpServices.Domain); + + byte[] recvBytes = null; + + switch (protocol) + { + case ProtocolType.Tcp: + { + recvBytes = ResolveTcp(bDnsQuery, ipep); + break; + } + case ProtocolType.Udp: + { + recvBytes = ResolveUdp(bDnsQuery, ipep); + break; + } + default: + { + throw new InvalidOperationException("Invalid Protocol: " + protocol); + } + } + + Trace.Assert(recvBytes != null, "Failed to retrieve data from the remote DNS server."); + + DnsQueryResponse dnsQR = new DnsQueryResponse(); + + dnsQR.ParseResponse(recvBytes, protocol); + + return dnsQR; + } + + private byte[] ResolveUdp(byte[] bDnsQuery, IPEndPoint ipep) + { + // UDP messages, data size = 512 octets or less + UdpClient udpClient = new UdpClient(); + byte[] recvBytes = null; + + try + { + udpClient.Client.ReceiveTimeout = _socketTimeout; + udpClient.Connect(ipep); + udpClient.Send(bDnsQuery, bDnsQuery.Length); + recvBytes = udpClient.Receive(ref ipep); + } + finally + { + udpClient.Close(); + } + return recvBytes; + } + + private static byte[] ResolveTcp(byte[] bDnsQuery, IPEndPoint ipep) + { + TcpClient tcpClient = new TcpClient(); + byte[] recvBytes = null; + + try + { + tcpClient.Connect(ipep); + + NetworkStream netStream = tcpClient.GetStream(); + BinaryReader netReader = new System.IO.BinaryReader(netStream); + + netStream.Write(bDnsQuery, 0, bDnsQuery.Length); + + // wait until data is avail + while (!netStream.DataAvailable) ; + + if (tcpClient.Connected && netStream.DataAvailable) + { + // Read first two bytes to find out the length of the response + byte[] bLen = new byte[2]; + + // NOTE: The order of the next two lines matter. Do not reorder + // Array indexes are also intentionally reversed + bLen[1] = (byte)netStream.ReadByte(); + bLen[0] = (byte)netStream.ReadByte(); + + UInt16 length = BitConverter.ToUInt16(bLen, 0); + + recvBytes = new byte[length]; + netStream.Read(recvBytes, 0, length); + } + } + finally + { + tcpClient.Close(); + } + return recvBytes; + } + + private byte[] BuildDnsRequest(string host, NsType queryType, NsClass queryClass, ProtocolType protocol, IMessageSecurityProvider messageSecurityProvider) + { + // Combind the NsFlags with our constant flags + ushort flags = (ushort)((ushort)_queryResponse | (ushort)_opCode | (ushort)_nsFlags); + this._flags = flags; + + //NOTE: This limits the librarys ablity to issue multiple queries per request. + this._nsType = queryType; + this._nsClass = queryClass; + this._name = host; + + if(messageSecurityProvider != null) + { + messageSecurityProvider.SecureMessage(this); + } + + byte[] bDnsQuery = GetMessageBytes(); + + // Add two byte prefix that contains the packet length per RFC 1035 section 4.2.2 + if (protocol == ProtocolType.Tcp) + { + // 4.2.2. TCP usageMessages sent over TCP connections use server port 53 (decimal). + // The message is prefixed with a two byte length field which gives the message + // length, excluding the two byte length field. This length field allows the + // low-level processing to assemble a complete message before beginning to parse + // it. + int len = bDnsQuery.Length; + Array.Resize(ref bDnsQuery, len + 2); + Array.Copy(bDnsQuery, 0, bDnsQuery, 2, len); + bDnsQuery[0] = (byte)((len >> 8) & 0xFF); + bDnsQuery[1] = (byte)((len & 0xFF)); + } + + return bDnsQuery; + } + + internal byte[] GetMessageBytes() + { + MemoryStream memoryStream = new MemoryStream(); + byte[] data = new byte[2]; + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_transactionId) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_flags) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_questions) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_answerRRs) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_authorityRRs) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_additionalRecords.Count) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = DnsHelpers.CanonicaliseDnsName(_name, false); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsType) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsClass) >> 16)); + memoryStream.Write(data, 0, data.Length); + + foreach (IDnsRecord dnsRecord in AdditionalRRecords) + { + data = dnsRecord.GetMessageBytes(); + memoryStream.Write(data, 0, data.Length); + } + + Trace.WriteLine(String.Format("The message bytes: {0}", DnsHelpers.DumpArrayToString(memoryStream.ToArray()))); + + return memoryStream.ToArray(); + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryResponse.cs b/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryResponse.cs new file mode 100644 index 0000000..7332e84 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Query/DnsQueryResponse.cs @@ -0,0 +1,168 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.IO; +using System.Net; +using System.Net.Sockets; +using DnDns.Records; + +using DnDns.Enums; + +namespace DnDns.Query +{ + /// + /// Summary description for DnsQueryResponse. + /// + public class DnsQueryResponse : DnsQueryBase + { + #region Fields + private DnsQueryRequest _queryRequest = new DnsQueryRequest(); + + private IDnsRecord[] _answers; + private IDnsRecord[] _authoritiveNameServers; + private int _bytesReceived = 0; + #endregion Fields + + #region properties + public DnsQueryRequest QueryRequest + { + get { return _queryRequest; } + } + + public IDnsRecord[] Answers + { + get { return _answers; } + } + + public IDnsRecord[] AuthoritiveNameServers + { + get { return _authoritiveNameServers; } + } + + public int BytesReceived + { + get { return _bytesReceived; } + } + #endregion + + /// + /// + /// + public DnsQueryResponse() + { + } + + private DnsQueryRequest ParseQuery(ref MemoryStream ms) + { + DnsQueryRequest queryRequest = new DnsQueryRequest(); + + // Read name + queryRequest.Name = DnsRecordBase.ParseName(ref ms); + + return queryRequest; + } + + internal void ParseResponse(byte[] recvBytes, ProtocolType protocol) + { + MemoryStream memoryStream = new MemoryStream(recvBytes); + byte[] flagBytes = new byte[2]; + byte[] transactionId = new byte[2]; + byte[] questions = new byte[2]; + byte[] answerRRs = new byte[2]; + byte[] authorityRRs = new byte[2]; + byte[] additionalRRCountBytes = new byte[2]; + byte[] nsType = new byte[2]; + byte[] nsClass = new byte[2]; + + this._bytesReceived = recvBytes.Length; + + // Parse DNS Response + memoryStream.Read(transactionId, 0, 2); + memoryStream.Read(flagBytes, 0, 2); + memoryStream.Read(questions, 0, 2); + memoryStream.Read(answerRRs, 0, 2); + memoryStream.Read(authorityRRs, 0, 2); + memoryStream.Read(additionalRRCountBytes, 0, 2); + + // Parse Header + _transactionId = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(transactionId, 0)); + _flags = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(flagBytes, 0)); + _queryResponse = (QueryResponse)(_flags & (ushort)FlagMasks.QueryResponseMask); + _opCode = (OpCode)(_flags & (ushort)FlagMasks.OpCodeMask); + _nsFlags = (NsFlags)(_flags & (ushort)FlagMasks.NsFlagMask); + _rCode = (RCode)(_flags & (ushort)FlagMasks.RCodeMask); + + // Parse Questions Section + _questions = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(questions, 0)); + _answerRRs = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(answerRRs, 0)); + _authorityRRs = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(authorityRRs, 0)); + ushort additionalRRCount = (ushort)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(additionalRRCountBytes, 0)); + _additionalRecords = new List(); + _answers = new DnsRecordBase[_answerRRs]; + _authoritiveNameServers = new DnsRecordBase[_authorityRRs]; + + // Parse Queries + _queryRequest = this.ParseQuery(ref memoryStream); + + // Read dnsType + memoryStream.Read(nsType, 0, 2); + + // Read dnsClass + memoryStream.Read(nsClass, 0, 2); + + _nsType = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsType, 0)); + _nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClass, 0)); + + // Read in Answer Blocks + for (int i=0; i < _answerRRs; i++) + { + _answers[i] = RecordFactory.Create(ref memoryStream); + } + + // Parse Authority Records + for (int i=0; i < _authorityRRs; i++) + { + _authoritiveNameServers[i] = RecordFactory.Create(ref memoryStream); + } + + // Parse Additional Records + for (int i=0; i < additionalRRCount; i++) + { + _additionalRecords.Add(RecordFactory.Create(ref memoryStream)); + } + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/ARecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/ARecord.cs new file mode 100644 index 0000000..419d23f --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/ARecord.cs @@ -0,0 +1,83 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + /// + /// RFC 1035: + /// + /// 3.4.1. A RDATA format + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | ADDRESS | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// + /// where: + /// + /// ADDRESS A 32 bit Internet address. + /// + /// Hosts that have multiple Internet addresses will have multiple A + /// records. + /// + /// A records cause no additional section processing. The RDATA section of + /// an A line in a master file is an Internet address expressed as four + /// decimal numbers separated by dots without any imbedded spaces (e.g., + /// "10.2.0.52" or "192.0.5.6"). + /// + /// + public sealed class ARecord : DnsRecordBase, IDnsRecord + { + private string _hostAddress; + + /// + /// The answer host address for the DNS A Record. + /// + public string HostAddress + { + get { return _hostAddress; } + } + + internal ARecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + _hostAddress = ms.ReadByte() + "." + ms.ReadByte() + "." + ms.ReadByte() + "." + ms.ReadByte(); + _answer = "Address: " + _hostAddress; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/AaaaRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/AaaaRecord.cs new file mode 100644 index 0000000..dc592f3 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/AaaaRecord.cs @@ -0,0 +1,97 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class AaaaRecord : DnsRecordBase + { + private string m_ipAddress; + + internal AaaaRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + // TODO: Test and incorporate BinToHex function below + m_ipAddress = + ms.ReadByte().ToString("x2") + ms.ReadByte().ToString("x2") + ":" + ms.ReadByte().ToString("x2") + ms.ReadByte().ToString("x2") + ":" + + ms.ReadByte().ToString("x2") + ms.ReadByte().ToString("x2") + ":" + ms.ReadByte().ToString("x2") + ms.ReadByte().ToString("x2") + ":" + + ms.ReadByte().ToString("x2") + ms.ReadByte().ToString("x2") + ":" + ms.ReadByte().ToString("x2") + ms.ReadByte().ToString("x2") + ":" + + ms.ReadByte().ToString("x2") + ms.ReadByte().ToString("x2") + ":" + ms.ReadByte().ToString("x2") + ms.ReadByte().ToString("x2"); + _answer = "IPv6 Address: " + m_ipAddress; + } + + // TODO: converted from VB.NET, test to make sure it works properly + private static string BinToHex(byte[] data) + { + if (data != null) + { + StringBuilder sb = new System.Text.StringBuilder(1024); + for (int i = 0; i < data.Length; i++) + { + sb.Append(data[i].ToString("X2")); + } + return sb.ToString(); + } + else + { + return null; + } + } + + // TODO: converted from VB.NET, test to make sure it works properly + private static byte[] HexToBin(string s) + { + int arraySize = s.Length / 2; + byte[] bytes = new byte[arraySize - 1]; + int counter = 0; + + for (int i = 0; i < s.Length - 1; i = 2) + { + string hexValue = s.Substring(i, 2); + + // Tell convert to interpret the string as a 16 bit hex value + int intValue = Convert.ToInt32(hexValue, 16); + // Convert the integer to a byte and store it in the array + bytes[counter] = Convert.ToByte(intValue); + counter += 1; + } + return bytes; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/AfsdbRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/AfsdbRecord.cs new file mode 100644 index 0000000..d92a520 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/AfsdbRecord.cs @@ -0,0 +1,78 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; + +namespace DnDns.Records +{ + public sealed class AfsdbRecord : DnsRecordBase + { + private ushort _port; + private string _name; + private short _type; + + public ushort Port + { + get { return _port; } + } + + public string AfsdbName + { + get { return _name; } + } + + public short Type + { + get { return _type; } + } + + internal AfsdbRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + byte[] type = new byte[2]; + ms.Read(type, 0, 2); + // _port = (ushort)Tools.ByteToUInt(type); + _port = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(type, 0)); + _name = DnsRecordBase.ParseName(ref ms); + //_type = (short)Tools.ByteToUInt(type); + _type = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(type, 0)); + _answer = "Name: " + _name + ", Port: " + _port + ", Type: " + _type; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/AtmaRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/AtmaRecord.cs new file mode 100644 index 0000000..58f5103 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/AtmaRecord.cs @@ -0,0 +1,74 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class AtmaRecord : DnsRecordBase + { + private string _address; + private ATMFormat _format; + + public string Address + { + get { return _address; } + } + + public ATMFormat Format + { + get { return _format; } + } + + internal AtmaRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + byte[] address = new byte[this.DnsHeader.DataLength - 1]; + _format = (ATMFormat)ms.ReadByte(); + ms.Read(address, 0, this.DnsHeader.DataLength - 1); + _address = Encoding.ASCII.GetString(address); + _answer = "Address: " + _address + ", Format: " + _format; + } + + public enum ATMFormat : byte + { + E164 = 0x01, + NSAP = 0x02 + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/BaseDnsRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/BaseDnsRecord.cs new file mode 100644 index 0000000..b0aec06 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/BaseDnsRecord.cs @@ -0,0 +1,338 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; +using System.Diagnostics; + +namespace DnDns.Records +{ + /// + /// Handles a basic Dns record + /// + /// From RFC 1035: + /// + /// 3.2.1. Format + /// + /// All RRs have the same top level format shown below: + /// + /// 1 1 1 1 1 1 + /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | | + /// / / + /// / NAME / + /// | | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | TYPE | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | CLASS | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | TTL | + /// | | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | RDLENGTH | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| + /// / RDATA / + /// / / + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// + /// where: + /// + /// NAME an owner name, i.e., the name of the node to which this + /// resource record pertains. + /// + /// TYPE two octets containing one of the RR TYPE codes. + /// + /// CLASS two octets containing one of the RR CLASS codes. + /// + /// TTL a 32 bit signed integer that specifies the time interval + /// that the resource record may be cached before the source + /// of the information should again be consulted. Zero + /// values are interpreted to mean that the RR can only be + /// used for the transaction in progress, and should not be + /// cached. For example, SOA records are always distributed + /// with a zero TTL to prohibit caching. Zero values can + /// also be used for extremely volatile data. + /// + /// RDLENGTH an unsigned 16 bit integer that specifies the length in + /// octets of the RDATA field. + /// + /// RDATA a variable length string of octets that describes the + /// resource. The format of this information varies + /// according to the TYPE and CLASS of the resource record. + /// + public abstract class DnsRecordBase : IDnsRecord + { + #region Fields + // NAME an owner name, i.e., the name of the node to which this + // resource record pertains. + //private string _name; + // TYPE two octets containing one of the RR TYPE codes. + //protected NsType _nsType; + // CLASS - two octets containing one of the RR CLASS codes. + //private NsClass _nsClass; + // TTL - a 32 bit signed integer that specifies the time interval + // that the resource record may be cached before the source + // of the information should again be consulted. Zero + // values are interpreted to mean that the RR can only be + // used for the transaction in progress, and should not be + // cached. For example, SOA records are always distributed + // with a zero TTL to prohibit caching. Zero values can + /// also be used for extremely volatile data. + //private int _timeToLive; + // RDLENGTH - an unsigned 16 bit integer that specifies the length in + // octets of the RDATA field. + //protected short _dataLength; + protected RecordHeader _dnsHeader; + protected string _answer; + protected string _errorMsg; + #endregion + + #region Properties + /// + /// NAME - an owner name, i.e., the name of the node to which this + /// resource record pertains. + /// + //public string Name + //{ + // get { return _name; } + //} + + public RecordHeader DnsHeader + { + get { return _dnsHeader; } + protected set { _dnsHeader = value; } + } + + public string Answer + { + get { return _answer; } + } + + + /// + /// TYPE two octets containing one of the RR TYPE codes. + /// + //public NsType NsType + //{ + // get { return _nsType; } + //} + + /// + /// CLASS - two octets containing one of the RR CLASS codes. + /// + //public NsClass NsClass + //{ + // get { return _nsClass; } + //} + + /// + /// TTL - a 32 bit signed integer that specifies the time interval + /// that the resource record may be cached before the source + /// of the information should again be consulted. Zero + /// values are interpreted to mean that the RR can only be + /// used for the transaction in progress, and should not be + /// cached. For example, SOA records are always distributed + /// with a zero TTL to prohibit caching. Zero values can + /// also be used for extremely volatile data. + /// + //public int TimeToLive + //{ + // get { return _timeToLive; } + //} + + /// + /// RDLENGTH - an unsigned 16 bit integer that specifies the length in + /// octets of the RDATA field. + /// + //public short DataLength + //{ + // get { return _dataLength; } + //} + + public string ErrorMsg + { + get { return _errorMsg; } + } + #endregion + + internal DnsRecordBase() + { + } + + public virtual void ParseRecord(ref MemoryStream ms) + { + // Default implementation - the most common. + _answer = DnsRecordBase.ParseName(ref ms); + } + + internal DnsRecordBase(RecordHeader dnsHeader) + { + _dnsHeader = dnsHeader; + } + + // RFC + // 4.1.4. Message compression + // + // In order to reduce the size of messages, the domain system utilizes a + // compression scheme which eliminates the repetition of domain names in a + // message. In this scheme, an entire domain name or a list of labels at + // the end of a domain name is replaced with a pointer to a prior occurance + // of the same name. + // + // The pointer takes the form of a two octet sequence: + // + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | 1 1| OFFSET | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // + // The first two bits are ones. This allows a pointer to be distinguished + // from a label, since the label must begin with two zero bits because + // labels are restricted to 63 octets or less. (The 10 and 01 combinations + // are reserved for future use.) The OFFSET field specifies an offset from + // the start of the message (i.e., the first octet of the ID field in the + // domain header). A zero offset specifies the first byte of the ID field, + // etc. + // + // The compression scheme allows a domain name in a message to be + // represented as either: + // + // - a sequence of labels ending in a zero octet + // - a pointer + // - a sequence of labels ending with a pointer + // + + internal static string ParseName(ref MemoryStream ms) + { + Trace.WriteLine("Reading Name..."); + StringBuilder sb = new StringBuilder(); + + uint next = (uint)ms.ReadByte(); + Trace.WriteLine("Next is 0x" + next.ToString("x2")); + int bPointer; + + while ((next != 0x00)) + { + // Isolate 2 most significat bits -> e.g. 11xx xxxx + // if it's 0xc0 (11000000b} then pointer + switch (0xc0 & next) + { + // 0xc0 -> Name is a pointer. + case 0xc0: + { + // Isolate Offset + int offsetMASK = ~0xc0; + + // Example on how to calculate the offset + // e.g. + // + // So if given the following 2 bytes - 0xc1 0x1c (11000001 00011100) + // + // The pointer takes the form of a two octet sequence: + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | 1 1| OFFSET | + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // | 1 1| 0 0 0 0 0 1 0 0 0 1 1 1 0 0| + // +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + // + // A pointer is indicated by the a 1 in the two most significant bits + // The Offset is the remaining bits. + // + // The Pointer = 0xc0 (11000000 00000000) + // The offset = 0x11c (00000001 00011100) + + // Move offset into the proper position + int offset = (int)(offsetMASK & next) << 8; + + // extract the pointer to the data in the stream + bPointer = ms.ReadByte() + offset; + // store the position so we can resume later + long oldPtr = ms.Position; + // Move to the specified position in the stream and + // parse the name (recursive call) + ms.Position = bPointer; + sb.Append(DnsRecordBase.ParseName(ref ms)); + Trace.WriteLine(sb.ToString()); + // Move back to original position, and continue + ms.Position = oldPtr; + next = 0x00; + break; + } + case 0x00: + { + Debug.Assert(next < 0xc0, "Offset cannot be greater then 0xc0."); + byte[] buffer = new byte[next]; + ms.Read(buffer, 0, (int)next); + sb.Append(Encoding.ASCII.GetString(buffer) + "."); + next = (uint)ms.ReadByte(); + Trace.WriteLine("0x" + next.ToString("x2")); + break; + } + default: + throw new InvalidOperationException("There was a problem decompressing the DNS Message."); + } + } + return sb.ToString(); + } + + internal string ParseText(ref MemoryStream ms) + { + StringBuilder sb = new StringBuilder(); + + int len = ms.ReadByte(); + byte[] buffer = new byte[len]; + ms.Read(buffer, 0, len); + sb.Append(Encoding.ASCII.GetString(buffer)); + return sb.ToString(); + } + + public override string ToString() + { + return _answer; + } + + #region IDnsRecord Members + + public virtual byte[] GetMessageBytes() + { + return new byte[]{}; + } + + #endregion + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/CNameRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/CNameRecord.cs new file mode 100644 index 0000000..c734237 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/CNameRecord.cs @@ -0,0 +1,52 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class CNameRecord : DnsRecordBase + { + internal CNameRecord(RecordHeader dnsHeader) : base(dnsHeader) {} + + public override void ParseRecord(ref MemoryStream ms) + { + base.ParseRecord(ref ms); + _answer = "Host: " + _answer; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/HInfoRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/HInfoRecord.cs new file mode 100644 index 0000000..24a1853 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/HInfoRecord.cs @@ -0,0 +1,67 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class HInfoRecord : DnsRecordBase + { + private string _cpuType; + private string _operatingSys; + + public string CpuType + { + get { return _cpuType; } + } + + public string OperatingSys + { + get { return _operatingSys; } + } + + internal HInfoRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + _cpuType = base.ParseText(ref ms); + _operatingSys = base.ParseText(ref ms); + _answer = "CPU: " + _cpuType + ", OS: " + _operatingSys; + } + } + +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/IDnsRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/IDnsRecord.cs new file mode 100644 index 0000000..7b97905 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/IDnsRecord.cs @@ -0,0 +1,58 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public interface IDnsRecord + { + RecordHeader DnsHeader { get; } + string Answer { get; } + //short DataLength { get; } + string ErrorMsg { get; } + //string Name { get; } + //NsClass NsClass { get; } + //NsType NsType { get; } + //int TimeToLive { get; } + //void ParseRecordHeader(ref MemoryStream ms); + void ParseRecord(ref MemoryStream ms); + string ToString(); + + byte[] GetMessageBytes(); + } +} \ No newline at end of file diff --git a/SMTPServer/SMTPServer/DNSClient/Records/IsdnRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/IsdnRecord.cs new file mode 100644 index 0000000..e5c46a9 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/IsdnRecord.cs @@ -0,0 +1,66 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class IsdnRecord : DnsRecordBase + { + private string _address; + private string _subAddress; + + public string Address + { + get { return _address; } + } + + public string SubAddress + { + get { return _subAddress; } + } + + internal IsdnRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + _address = base.ParseText(ref ms); + _subAddress = base.ParseText(ref ms); + _answer = "ISDN Address: " + _address + ", SubAddress: " + _subAddress; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/LocRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/LocRecord.cs new file mode 100644 index 0000000..a8a0c2b --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/LocRecord.cs @@ -0,0 +1,194 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; + +namespace DnDns.Records +{ + public sealed class LocRecord : DnsRecordBase + { + // For LOC + #region Fields + private byte _version; + private byte _size; + private byte _horPrecision; + private byte _vertPrecision; + private uint _latitude; + private uint _longitude; + private uint _altitude; + #endregion + + #region Properties + public byte Version + { + get { return _version; } + } + + public byte Size + { + get { return _size; } + } + + public byte HorPrecision + { + get { return _horPrecision; } + } + + public byte VertPrecision + { + get { return _vertPrecision; } + } + + public uint Latitude + { + get { return _latitude; } + } + + public uint Longitude + { + get { return _longitude; } + } + + public uint Altitude + { + get { return _altitude; } + } + #endregion + + private char[] _latDirection = new char[2] {'N', 'S'}; + private char[] _longDirection = new char[2] {'E', 'W'}; + + internal LocRecord(RecordHeader dnsHeader) : base(dnsHeader) {} + + public override void ParseRecord(ref MemoryStream ms) + { + byte[] latitude = new Byte[4]; + byte[] longitude = new Byte[4]; + byte[] altitude = new Byte[4]; + + _version = (byte)ms.ReadByte(); + _size = (byte)ms.ReadByte(); + _horPrecision = (byte)ms.ReadByte(); + _vertPrecision = (byte)ms.ReadByte(); + + ms.Read(latitude,0,latitude.Length); + // _latitude = Tools.ByteToUInt(latitude); + _latitude = (uint)IPAddress.NetworkToHostOrder((int)BitConverter.ToUInt32(latitude, 0)); + + ms.Read(longitude,0,longitude.Length); + // _longitude = Tools.ByteToUInt(longitude); + _longitude = (uint)IPAddress.NetworkToHostOrder((int)BitConverter.ToUInt32(longitude, 0)); + + + ms.Read(altitude,0,altitude.Length); + // _altitude = Tools.ByteToUInt(altitude); + _altitude = (uint)IPAddress.NetworkToHostOrder((int)BitConverter.ToUInt32(altitude, 0)); + + StringBuilder sb = new StringBuilder(); + sb.Append("Version: "); + sb.Append(_version); + sb.Append("\r\n"); + + sb.Append("Size: "); + sb.Append(CalcSize(_size)); + sb.Append(" m\r\n"); + + sb.Append("Horizontal Precision: "); + sb.Append(CalcSize(_horPrecision)); + sb.Append(" m\r\n"); + + sb.Append("Vertical Precision: "); + sb.Append(CalcSize(_vertPrecision)); + sb.Append(" m\r\n"); + + sb.Append("Latitude: "); + sb.Append(CalcLoc(_latitude, _latDirection)); + sb.Append("\r\n"); + + sb.Append("Longitude: "); + sb.Append(CalcLoc(_longitude, _longDirection)); + sb.Append("\r\n"); + + sb.Append("Altitude: "); + sb.Append((_altitude - 10000000) / 100.0); + sb.Append(" m\r\n"); + + _answer = sb.ToString(); + } + + private string CalcLoc(uint angle, char[] nsew) + { + char direction; + if (angle < 0x80000000) + { + angle = 0x80000000 - angle; + direction = nsew[1]; + } + else + { + angle = angle - 0x80000000; + direction = nsew[0]; + } + + uint tsecs = angle % 1000; + angle = angle / 1000; + uint secs = angle % 60; + angle = angle / 60; + uint minutes = angle % 60; + uint degrees = angle / 60; + + return degrees + " deg, " + minutes + " min " + secs+ "." + tsecs + " sec " + direction; + } + + // return size in meters + private double CalcSize(byte val) + { + double size; + int exponent; + + size = (val & 0xF0) >> 4; + exponent = (val & 0x0F); + while (exponent != 0) + { + size *= 10; + exponent--; + } + return size / 100; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/MInfoRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/MInfoRecord.cs new file mode 100644 index 0000000..7ad5cab --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/MInfoRecord.cs @@ -0,0 +1,66 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class MInfoRecord : DnsRecordBase + { + private string _responsibleMb; + private string _errorMb; + + public string ResponsibleMb + { + get { return _responsibleMb; } + } + + public string ErrorMb + { + get { return _errorMb; } + } + + internal MInfoRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + _responsibleMb = DnsRecordBase.ParseName(ref ms); + _errorMb = DnsRecordBase.ParseName(ref ms); + _answer = "Responsible MailBox: " + _responsibleMb + ", Error MailBox: " + _errorMb; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/MbRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/MbRecord.cs new file mode 100644 index 0000000..80c0aba --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/MbRecord.cs @@ -0,0 +1,52 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class MbRecord : DnsRecordBase + { + internal MbRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + //public override void ParseRecord(ref MemoryStream ms) + //{ + // _answer = BaseDnsRecord.ParseName(ref ms); + //} + } + +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/MgRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/MgRecord.cs new file mode 100644 index 0000000..9b1b78a --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/MgRecord.cs @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class MgRecord : DnsRecordBase + { + internal MgRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + //public override void ParseRecord(ref MemoryStream ms) + //{ + // _answer = BaseDnsRecord.ParseName(ref ms); + //} + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/MrRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/MrRecord.cs new file mode 100644 index 0000000..38ad481 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/MrRecord.cs @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class MrRecord : DnsRecordBase + { + internal MrRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + //public override void ParseRecord(ref MemoryStream ms) + //{ + // _answer = BaseDnsRecord.ParseName(ref ms); + //} + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/MxRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/MxRecord.cs new file mode 100644 index 0000000..8eaae83 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/MxRecord.cs @@ -0,0 +1,75 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; + +namespace DnDns.Records +{ + public sealed class MxRecord : DnsRecordBase + { + // For MX + private short _preference; + private string _mailExchange; + + public short Preference + { + get { return _preference; } + } + + public string MailExchange + { + get { return _mailExchange; } + } + + internal MxRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + // Preference is a function of MX records + byte[] nsPreference = new byte[2]; + ms.Read(nsPreference, 0, 2); + //_preference = (short)Tools.ByteToUInt(nsPreference); + // TODO: Should this be a UShort instead of a short? + _preference = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsPreference, 0)); + + // Parse Name + _mailExchange = DnsRecordBase.ParseName(ref ms); + _answer = "MX Preference: " + _preference + ", Mail Exchanger: " + _mailExchange; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/NsRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/NsRecord.cs new file mode 100644 index 0000000..801d882 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/NsRecord.cs @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class NsRecord : DnsRecordBase + { + internal NsRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + //public override void ParseRecord(ref MemoryStream ms) + //{ + // _answer = BaseDnsRecord.ParseName(ref ms); + //} + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/PtrRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/PtrRecord.cs new file mode 100644 index 0000000..0cacbc4 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/PtrRecord.cs @@ -0,0 +1,51 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class PtrRecord : DnsRecordBase + { + internal PtrRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + //public override void ParseRecord(ref MemoryStream ms) + //{ + // _answer = BaseDnsRecord.ParseName(ref ms); + //} + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/RecordFactory.cs b/SMTPServer/SMTPServer/DNSClient/Records/RecordFactory.cs new file mode 100644 index 0000000..75a9f26 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/RecordFactory.cs @@ -0,0 +1,191 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +using DnDns.Enums; + +namespace DnDns.Records +{ + class RecordFactory + { + public static IDnsRecord Create(ref MemoryStream ms) + { + IDnsRecord dnsRecord; + // Have to start out with an unknown record, since we have to parse the entire + // header before we can determine the type of DNS record it is. + // TODO: Consider other options. + + // start as an unknown type, then create a known type, parse the response + // and return the object. + //DnsRecordBase dr = new DnsUnknownRecord(); + //dr.ParseRecordHeader(ref ms); + + RecordHeader dnsHeader = new RecordHeader(); + dnsHeader.ParseRecordHeader(ref ms); + + switch (dnsHeader.NsType) + { + case NsType.A: + { + dnsRecord = new ARecord(dnsHeader); + break; + } + case NsType.AAAA: + { + dnsRecord = new AaaaRecord(dnsHeader); + break; + } + case NsType.MX: + { + dnsRecord = new MxRecord(dnsHeader); + break; + } + case NsType.RP: + { + dnsRecord = new RpRecord(dnsHeader); + break; + } + case NsType.MR: + { + dnsRecord = new MrRecord(dnsHeader); + break; + } + case NsType.MB: + { + dnsRecord = new MbRecord(dnsHeader); + break; + } + case NsType.MG: + { + dnsRecord = new MgRecord(dnsHeader); + break; + } + case NsType.NS: + { + dnsRecord = new NsRecord(dnsHeader); + break; + } + case NsType.CNAME: + { + dnsRecord = new CNameRecord(dnsHeader); + break; + } + case NsType.PTR: + { + dnsRecord = new PtrRecord(dnsHeader); + break; + } + case NsType.HINFO: + { + dnsRecord = new HInfoRecord(dnsHeader); + break; + } + case NsType.MINFO: + { + dnsRecord = new MInfoRecord(dnsHeader); + break; + } + case NsType.X25: + { + dnsRecord = new X25Record(dnsHeader); + break; + } + case NsType.TXT: + { + dnsRecord = new TxtRecord(dnsHeader); + break; + } + case NsType.LOC: + { + dnsRecord = new LocRecord(dnsHeader); + break; + } + case NsType.SOA: + { + dnsRecord = new SoaRecord(dnsHeader); + break; + } + case NsType.SRV: + { + dnsRecord = new SrvRecord(dnsHeader); + break; + } + case NsType.AFSDB: + { + dnsRecord = new AfsdbRecord(dnsHeader); + break; + } + case NsType.ATMA: + { + dnsRecord = new AtmaRecord(dnsHeader); + break; + } + case NsType.ISDN: + { + dnsRecord = new IsdnRecord(dnsHeader); + break; + } + case NsType.RT: + { + dnsRecord = new RtRecord(dnsHeader); + break; + } + case NsType.WKS: + { + dnsRecord = new WksRecord(dnsHeader); + break; + } + case NsType.TSIG: + { + dnsRecord = new TSigRecord(dnsHeader); + break; + } + default: + { + // Unknown type. parse and return the DnsUnknownRecord + dnsRecord = new UnknownRecord(dnsHeader); + break; + } + } + + //dnsRecord.ParseRecordHeader(ref ms); + dnsRecord.ParseRecord(ref ms); + return dnsRecord; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/RecordHeader.cs b/SMTPServer/SMTPServer/DNSClient/Records/RecordHeader.cs new file mode 100644 index 0000000..7c5c2c6 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/RecordHeader.cs @@ -0,0 +1,242 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; + +using DnDns.Enums; + +namespace DnDns.Records +{ + /// + /// The DnsRecordHeader class contains fields, properties and + /// parsing cababilities within the DNS Record except the the + /// RDATA. The Name, Type, Class, TTL, and RDLength. + /// + /// This class is used in the DnsRecordFactory to instantiate + /// concrete DnsRecord Classes. + /// + /// RFC 1035 + /// + /// 3.2.1. Format + /// + /// All RRs have the same top level format shown below: + /// + /// 1 1 1 1 1 1 + /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | | + /// / / + /// / NAME / + /// | | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | TYPE | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | CLASS | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | TTL | + /// | | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ + /// | RDLENGTH | + /// +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| + /// + /// where: + /// + /// NAME an owner name, i.e., the name of the node to which this + /// resource record pertains. + /// + /// TYPE two octets containing one of the RR TYPE codes. + /// + /// CLASS two octets containing one of the RR CLASS codes. + /// + /// TTL a 32 bit signed integer that specifies the time interval + /// that the resource record may be cached before the source + /// of the information should again be consulted. Zero + /// values are interpreted to mean that the RR can only be + /// used for the transaction in progress, and should not be + /// cached. For example, SOA records are always distributed + /// with a zero TTL to prohibit caching. Zero values can + /// also be used for extremely volatile data. + /// + /// RDLENGTH an unsigned 16 bit integer that specifies the length in + /// octets of the RDATA field. + /// + /// + public class RecordHeader + { + #region Fields + // NAME an owner name, i.e., the name of the node to which this + // resource record pertains. + private string _name; + // TYPE two octets containing one of the RR TYPE codes. + private NsType _nsType; + // CLASS - two octets containing one of the RR CLASS codes. + private NsClass _nsClass; + // TTL - a 32 bit signed integer that specifies the time interval + // that the resource record may be cached before the source + // of the information should again be consulted. Zero + // values are interpreted to mean that the RR can only be + // used for the transaction in progress, and should not be + // cached. For example, SOA records are always distributed + // with a zero TTL to prohibit caching. Zero values can + /// also be used for extremely volatile data. + private int _timeToLive; + // RDLENGTH - an unsigned 16 bit integer that specifies the length in + // octets of the RDATA field. + private short _dataLength; + + /// + /// Initalise the + /// + /// The header name + /// The resource type + /// The class type + /// The time to live + public RecordHeader(string name, NsType nsType, NsClass nsClass, int timeToLive) + { + _name = name; + _nsType = nsType; + _nsClass = nsClass; + _timeToLive = timeToLive; + } + + public RecordHeader() + { + } + + #endregion + + #region Properties + /// + /// NAME - an owner name, i.e., the name of the node to which this + /// resource record pertains. + /// + public string Name + { + get { return _name; } + } + + /// + /// TYPE two octets containing one of the RR TYPE codes. + /// + public NsType NsType + { + get { return _nsType; } + } + + /// + /// CLASS - two octets containing one of the RR CLASS codes. + /// + public NsClass NsClass + { + get { return _nsClass; } + } + + /// + /// TTL - a 32 bit signed integer that specifies the time interval + /// that the resource record may be cached before the source + /// of the information should again be consulted. Zero + /// values are interpreted to mean that the RR can only be + /// used for the transaction in progress, and should not be + /// cached. For example, SOA records are always distributed + /// with a zero TTL to prohibit caching. Zero values can + /// also be used for extremely volatile data. + /// + public int TimeToLive + { + get { return _timeToLive; } + } + + /// + /// RDLENGTH - an unsigned 16 bit integer that specifies the length in + /// octets of the RDATA field. + /// + public short DataLength + { + get { return _dataLength; } + } + #endregion + + /// + /// + /// + /// + public void ParseRecordHeader(ref MemoryStream ms) + { + byte[] nsType = new byte[2]; + byte[] nsClass = new byte[2]; + byte[] nsTTL = new byte[4]; + byte[] nsDataLength = new byte[2]; + + // Read the name + _name = DnsRecordBase.ParseName(ref ms); + + // Read the data header + ms.Read(nsType, 0, 2); + ms.Read(nsClass, 0, 2); + ms.Read(nsTTL, 0, 4); + ms.Read(nsDataLength, 0, 2); + _nsType = (NsType)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsType, 0)); + _nsClass = (NsClass)IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsClass, 0)); + + _timeToLive = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(nsTTL, 0)); + _dataLength = IPAddress.NetworkToHostOrder(BitConverter.ToInt16(nsDataLength, 0)); + } + + internal byte[] GetMessageBytes() + { + MemoryStream memoryStream = new MemoryStream(); + + byte[] data = DnsHelpers.CanonicaliseDnsName(_name, false); + memoryStream.Write(data,0,data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsType) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_nsClass) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((uint)(IPAddress.HostToNetworkOrder((ushort)_timeToLive) >> 32)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_dataLength) >> 16)); + memoryStream.Write(data, 0, data.Length); + + return memoryStream.ToArray(); + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/RpRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/RpRecord.cs new file mode 100644 index 0000000..bd47d41 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/RpRecord.cs @@ -0,0 +1,68 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class RpRecord : DnsRecordBase + { + // For RP + private string _name; + private string _textLocation; + + public string RpName + { + get { return _name; } + } + + public string TextLocation + { + get { return _textLocation; } + } + + internal RpRecord(RecordHeader dnsHeader) : base(dnsHeader) {} + + public override void ParseRecord(ref MemoryStream ms) + { + _name = DnsRecordBase.ParseName(ref ms); + _textLocation = DnsRecordBase.ParseName(ref ms); + _answer = _name + ", " + _textLocation; + } + } + +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/RtRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/RtRecord.cs new file mode 100644 index 0000000..627aafd --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/RtRecord.cs @@ -0,0 +1,71 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; + +namespace DnDns.Records +{ + public sealed class RtRecord : DnsRecordBase + { + private ushort _preference; + private string _intermediateHost; + + public ushort Preference + { + get { return _preference; } + } + + public string IntermediateHost + { + get { return _intermediateHost; } + } + + internal RtRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + byte[] preference = new byte[2]; + ms.Read(preference, 0, 2); + //_preference = (ushort)Tools.ByteToUInt(preference); + _preference = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(preference, 0)); + _intermediateHost = DnsRecordBase.ParseName(ref ms); + _answer = "Preference: " + _preference + ", Intermediate Host: " + _intermediateHost; + } + } + +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/SoaRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/SoaRecord.cs new file mode 100644 index 0000000..1a671bb --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/SoaRecord.cs @@ -0,0 +1,160 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; + +namespace DnDns.Records +{ + public sealed class SoaRecord : DnsRecordBase + { + // For SOA + #region fields + private string _primaryNameServer; + private string _responsiblePerson; + private uint _serial; + private uint _refreshInterval; + private uint _retryInterval; + private uint _expirationLimit; + // RFC 1034: TTL - only positive values of a signed 32 bit number. + private int _minimumTimeToLive; + #endregion + + #region properties + public string PrimaryNameServer + { + get { return _primaryNameServer; } + } + + public string ResponsiblePerson + { + get { return _responsiblePerson; } + } + + public uint Serial + { + get { return _serial; } + } + + public uint RefreshInterval + { + get { return _refreshInterval; } + } + + public uint RetryInterval + { + get { return _retryInterval; } + } + + public uint ExpirationLimit + { + get { return _expirationLimit; } + } + + public int MinimumTimeToLive + { + get { return _minimumTimeToLive; } + } + #endregion + + internal SoaRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + StringBuilder sb = new StringBuilder(); + // Parse Name + _primaryNameServer = DnsRecordBase.ParseName(ref ms); + sb.Append("Primary NameServer: "); + sb.Append(_primaryNameServer); + sb.Append("\r\n"); + + // Parse Responsible Persons Mailbox (Parse Name) + _responsiblePerson = DnsRecordBase.ParseName(ref ms); + sb.Append("Responsible Person: "); + sb.Append(_responsiblePerson); + sb.Append("\r\n"); + + byte[] serial = new Byte[4]; + byte[] refreshInterval = new Byte[4]; + byte[] retryInterval = new Byte[4]; + byte[] expirationLimit = new Byte[4]; + byte[] minTTL = new Byte[4]; + + // Parse Serial (4 bytes) + ms.Read(serial, 0, 4); + //_serial = Tools.ByteToUInt(serial); + _serial = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(serial, 0)); + sb.Append("Serial: "); + sb.Append(_serial); + sb.Append("\r\n"); + + // Parse Refresh Interval (4 bytes) + ms.Read(refreshInterval, 0, 4); + // _refreshInterval = Tools.ByteToUInt(refreshInterval); + _refreshInterval = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(refreshInterval, 0)); + sb.Append("Refresh Interval: "); + sb.Append(_refreshInterval); + sb.Append("\r\n"); + + // Parse Retry Interval (4 bytes) + ms.Read(retryInterval, 0, 4); + //_retryInterval = Tools.ByteToUInt(retryInterval); + _retryInterval = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(retryInterval, 0)); + sb.Append("Retry Interval: "); + sb.Append(_retryInterval); + sb.Append("\r\n"); + + // Parse Expiration limit (4 bytes) + ms.Read(expirationLimit, 0, 4); + // _expirationLimit = Tools.ByteToUInt(expirationLimit); + _expirationLimit = (uint)IPAddress.NetworkToHostOrder(BitConverter.ToInt32(expirationLimit, 0)); + sb.Append("Expire: "); + sb.Append(_expirationLimit); + sb.Append("\r\n"); + + // Parse Min TTL (4 bytes) + ms.Read(minTTL, 0, 4); + // _minTTL = Tools.ByteToUInt(minTTL); + _minimumTimeToLive = IPAddress.NetworkToHostOrder(BitConverter.ToInt32(minTTL, 0)); + sb.Append("TTL: "); + sb.Append(_minimumTimeToLive); + sb.Append("\r\n"); + + _answer = sb.ToString(); + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/SrvRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/SrvRecord.cs new file mode 100644 index 0000000..f306a0e --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/SrvRecord.cs @@ -0,0 +1,95 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; + +namespace DnDns.Records +{ + public sealed class SrvRecord : DnsRecordBase + { + // For SRV + private ushort _priority; + private ushort _weight; + private ushort _port; + private string _hostName; + + public ushort Priority + { + get { return _priority; } + } + public ushort Weight + { + get { return _weight; } + } + + public ushort Port + { + get { return _port; } + } + + public string HostName + { + get { return _hostName; } + } + + internal SrvRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + byte[] priority = new byte[2]; + ms.Read(priority, 0, 2); + //_priority = (ushort)Tools.ByteToUInt(Priority); + _priority = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(priority, 0)); + + byte[] weight = new byte[2]; + ms.Read(weight, 0, 2); + // _weight = (ushort)Tools.ByteToUInt(Weight); + _weight = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(weight, 0)); + + byte[] port = new byte[2]; + ms.Read(port, 0, 2); + //_port = (ushort)Tools.ByteToUInt(port); + _port = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(port, 0)); + + _hostName = DnsRecordBase.ParseName(ref ms); + + _answer = "Service Location: \r\nPriority: " + _priority + "\r\nWeight: " + + _weight + "\r\nPort: " + _port + "\r\nHostName: " + _hostName + "\r\n"; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/TSigRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/TSigRecord.cs new file mode 100644 index 0000000..f7f2638 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/TSigRecord.cs @@ -0,0 +1,235 @@ +using System; +using System.IO; +using System.Net; +using System.Text; +using DnDns.Enums; + +namespace DnDns.Records +{ + /// + /// Implementation of a TSIG record structure as per RFC 2845 + /// + public sealed class TSigRecord : DnsRecordBase + { + private string _algorithmName; + private RCode _error; + private ushort _fudge; + private ushort _originalId; + private byte[] _otherData; + private byte[] _mac; + private DateTime _timeSigned; + + public string AlgorithmName + { + get { return _algorithmName; } + } + + public RCode Error + { + get { return _error; } + } + + public ushort Fudge + { + get { return _fudge; } + } + + public ushort OriginalID + { + get { return _originalId; } + } + + public byte[] OtherData + { + get { return _otherData; } + } + + public byte[] Mac + { + get { return _mac; } + } + + public DateTime TimeSigned + { + get { return _timeSigned; } + } + + public TSigRecord(RecordHeader dnsHeader) : base(dnsHeader) + { + } + + public TSigRecord(string name, string algorithmName, RCode error, ushort fudge, ushort originalId, byte[] otherData, byte[] mac, DateTime timeSigned) + { + DnsHeader = new RecordHeader(name, NsType.TSIG, NsClass.ANY, 0); + + _algorithmName = algorithmName; + _error = error; + _fudge = fudge; + _originalId = originalId; + _otherData = otherData; + _mac = mac; + _timeSigned = timeSigned; + + if(otherData == null) + { + _otherData = new byte[]{}; + } + } + + public override void ParseRecord(ref MemoryStream memoryStream) + { + Byte[] dataUInt16 = new byte[2]; + Byte[] dataUInt32 = new byte[4]; + + _algorithmName = ParseName(ref memoryStream); + + memoryStream.Read(dataUInt16, 0, dataUInt16.Length); + long timeHigh = (ushort) IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(dataUInt16, 0)); + memoryStream.Read(dataUInt32, 0, dataUInt32.Length); + long timeLow = (uint) IPAddress.NetworkToHostOrder((int)BitConverter.ToUInt32(dataUInt32, 0)); + _timeSigned = DnsHelpers.ConvertFromDnsTime(timeLow, timeHigh); + + memoryStream.Read(dataUInt16, 0, dataUInt16.Length); + _fudge = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(dataUInt16, 0)); + + memoryStream.Read(dataUInt16, 0, dataUInt16.Length); + Int32 macLen = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(dataUInt16, 0)); + _mac = new byte[macLen]; + memoryStream.Read(_mac, 0, macLen); + + memoryStream.Read(dataUInt16, 0, dataUInt16.Length); + _originalId = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(dataUInt16, 0)); + + memoryStream.Read(dataUInt16, 0, dataUInt16.Length); + _error = (RCode)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(dataUInt16, 0)); + + memoryStream.Read(dataUInt16, 0, dataUInt16.Length); + Int32 otherLen = (ushort)IPAddress.NetworkToHostOrder((short)BitConverter.ToUInt16(dataUInt16, 0)); + + if(otherLen > 0) + { + _otherData = new byte[otherLen]; + memoryStream.Read(_otherData, 0, otherLen); + } + else + { + _otherData = null; + } + + _answer = ToString(); + + } + + public override byte[] GetMessageBytes() + { + MemoryStream memoryStream = new MemoryStream(); + + byte[] data = DnsHeader.GetMessageBytes(); + memoryStream.Write(data,0,data.Length); + + long rLengthPosition = memoryStream.Position; + + data = DnsHelpers.CanonicaliseDnsName(_algorithmName, false); + memoryStream.Write(data, 0, data.Length); + + int timeHigh; + long timeLow; + DnsHelpers.ConvertToDnsTime(_timeSigned.ToUniversalTime(), out timeHigh, out timeLow); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)timeHigh) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((uint)(IPAddress.HostToNetworkOrder((uint)timeLow) >> 32)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_fudge) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_mac.Length) >> 16)); + memoryStream.Write(data, 0, data.Length); + + memoryStream.Write(_mac, 0, _mac.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder(_originalId) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_error) >> 16)); + memoryStream.Write(data, 0, data.Length); + + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)_otherData.Length) >> 16)); + memoryStream.Write(data, 0, data.Length); + + if(_otherData.Length != 0) + { + memoryStream.Write(_otherData, 0, _otherData.Length); + } + + // Add the rdata lenght + long rlength = memoryStream.Position - rLengthPosition; + + memoryStream.Seek(rLengthPosition - 2, SeekOrigin.Begin); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)rlength) >> 16)); + memoryStream.Write(data, 0, data.Length); + + return memoryStream.ToArray(); + } + + public override string ToString() + { + StringBuilder sb = new StringBuilder(); + sb.Append(_algorithmName); + sb.Append(" "); + sb.Append(_timeSigned); + sb.Append(" "); + sb.Append(_fudge); + sb.Append(" "); + sb.Append(_mac.Length); + sb.Append(" "); + sb.Append(Convert.ToBase64String(Mac)); + sb.Append(" "); + sb.Append(_error); + sb.Append(" "); + + if (_otherData == null) + { + sb.Append(0); + } + else + { + sb.Append(_otherData.Length); + sb.Append(" "); + + if (_error == RCode.BADTIME) + { + if (_otherData.Length != 6) + { + sb.Append(""); + } + else + { + long time = ((long)(_otherData[0] & 0xFF) << 40) + + ((long)(_otherData[1] & 0xFF) << 32) + + ((_otherData[2] & 0xFF) << 24) + + ((_otherData[3] & 0xFF) << 16) + + ((_otherData[4] & 0xFF) << 8) + + ((_otherData[5] & 0xFF)); + + sb.Append(""); + } + } + else + { + sb.Append("<"); + sb.Append(Convert.ToBase64String(_otherData)); + sb.Append(">"); + } + } + + return sb.ToString(); + } + } +} \ No newline at end of file diff --git a/SMTPServer/SMTPServer/DNSClient/Records/TxtRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/TxtRecord.cs new file mode 100644 index 0000000..13393e9 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/TxtRecord.cs @@ -0,0 +1,63 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + /// + /// + /// + public sealed class TxtRecord : DnsRecordBase + { + private string _text; + + public string Text + { + get { return _text; } + } + + internal TxtRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + _text = base.ParseText(ref ms); + _answer = "text: " + _text; + } + } + +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/UnknownRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/UnknownRecord.cs new file mode 100644 index 0000000..b48431d --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/UnknownRecord.cs @@ -0,0 +1,69 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + class UnknownRecord : DnsRecordBase + { + public UnknownRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + // Type not implemented so we read it into a buffer and print out the data. + StringBuilder sb = new StringBuilder(this.DnsHeader.DataLength); + byte[] b = new byte[1]; + // Loop over data, if char is easily converted to ASCII, convert it. + // Otherwise print a '.' + for (int i = 0; i < this.DnsHeader.DataLength; i++) + { + ms.Read(b, 0, 1); + if ((b[0] > 0x20) && (b[0] < 0x7e)) + { + sb.Append(Encoding.ASCII.GetString(b)); + } + else + { + sb.Append('.'); + } + } + _answer = sb.ToString(); + _errorMsg = "Type " + this.DnsHeader.NsType + " not implemented."; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/WksRecord.cs b/SMTPServer/SMTPServer/DNSClient/Records/WksRecord.cs new file mode 100644 index 0000000..9039c13 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/WksRecord.cs @@ -0,0 +1,115 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; +using System.Net; +using System.Net.Sockets; + +namespace DnDns.Records +{ + public sealed class WksRecord : DnsRecordBase + { + private ProtocolType _protocolType; + private IPAddress _ipAddress; + private short[] _ports; + + public ProtocolType ProtocolType + { + get { return _protocolType; } + set { _protocolType = value; } + } + + public IPAddress IpAddress + { + get { return _ipAddress; } + set { _ipAddress = value; } + } + + public short[] Ports + { + get { return _ports; } + set { _ports = value; } + } + + internal WksRecord(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + // Bit map is the data length minus the IpAddress (4 bytes) and the Protocol (1 byte), 5 bytes total. + int bitMapLen = this.DnsHeader.DataLength - 4 - 1; + byte[] ipAddr = new byte[4]; + byte[] BitMap = new byte[bitMapLen]; + + ms.Read(ipAddr, 0, 4); + // _ipAddress = new IPAddress(Tools.ToUInt32(ipAddr, 0)); + _ipAddress = new IPAddress((uint)IPAddress.NetworkToHostOrder(BitConverter.ToUInt32(ipAddr, 0))); + _protocolType = (ProtocolType)ms.ReadByte(); + ms.Read(BitMap, 0, BitMap.Length); + _ports = GetKnownServices(BitMap); + _answer = _protocolType + ": " + Tools.GetServByPort(_ports, _protocolType); + } + + private short[] GetKnownServices(byte[] BitMap) + { + short[] tempPortArr = new short[1024]; + int portCount = 0; + // mask to isolate left most bit + const byte mask = 0x80; + // Iterate through each byte + for (int i = 0; i < BitMap.Length; i++) + { + byte currentByte = BitMap[i]; + int count = 0; + // iterate through each bit + for (byte j = 0x07; j != 0xFF; j--) + { + int port = (((i * 8) + count++) + 1); + currentByte = (byte)(currentByte << 1); + // is the flag set? + if ((mask & currentByte) == 0x80) + { + tempPortArr[portCount] = (short)port; + portCount++; + } + } + } + short[] portArr = new short[portCount]; + Array.Copy(tempPortArr, 0, portArr, 0, portCount); + return portArr; + } + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Records/X25Record.cs b/SMTPServer/SMTPServer/DNSClient/Records/X25Record.cs new file mode 100644 index 0000000..886efcc --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Records/X25Record.cs @@ -0,0 +1,60 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace DnDns.Records +{ + public sealed class X25Record : DnsRecordBase + { + private string _x25Address; + + public string X25Address + { + get { return _x25Address; } + } + + internal X25Record(RecordHeader dnsHeader) : base(dnsHeader) { } + + public override void ParseRecord(ref MemoryStream ms) + { + _x25Address = base.ParseText(ref ms); + _answer = "X.25 X.121 Address: " + _x25Address; + } + } + +} diff --git a/SMTPServer/SMTPServer/DNSClient/Security/IMessageSecurityProvider.cs b/SMTPServer/SMTPServer/DNSClient/Security/IMessageSecurityProvider.cs new file mode 100644 index 0000000..0332000 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Security/IMessageSecurityProvider.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Text; +using DnDns.Query; + +namespace DnDns.Security +{ + public interface IMessageSecurityProvider + { + DnsQueryRequest SecureMessage(DnsQueryRequest dnsQueryRequest); + } +} diff --git a/SMTPServer/SMTPServer/DNSClient/Security/TsigMessageSecurityProvider.cs b/SMTPServer/SMTPServer/DNSClient/Security/TsigMessageSecurityProvider.cs new file mode 100644 index 0000000..bbd9471 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Security/TsigMessageSecurityProvider.cs @@ -0,0 +1,109 @@ +using System; +using System.Diagnostics; +using System.IO; +using System.Net; +using System.Security.Cryptography; +using DnDns.Enums; +using DnDns.Query; +using DnDns.Records; + +namespace DnDns.Security +{ + /// + /// Implements TSIG signing of DNS messages as per RFC2845 + /// + /// This class only supports the one hashing algorithim, hmac-sha256. + /// It would be trivial to add more. + public class TsigMessageSecurityProvider : IMessageSecurityProvider + { + private const string Hmacsha1String = "hmac-sha256."; + + private readonly string _name; + private readonly string _algorithimName; + private readonly ushort _fudge; + private readonly byte[] _sharedKey; + private readonly HMACSHA256 _hmac; + + /// + /// Initalise the + /// + /// The name of the shared key + /// The shared key in base64 string format + /// The signing time fudge value + public TsigMessageSecurityProvider(string name, string sharedKey, ushort fudge) + { + _name = name; + _fudge = fudge; + _sharedKey = Convert.FromBase64String(sharedKey); + + if (_sharedKey == null) + { + throw new ArgumentException("Argument is not a valid base64 string", "sharedKey"); + } + + _hmac = new HMACSHA256(_sharedKey); + + _algorithimName = Hmacsha1String; + } + + #region IMessageSecurityProvider Members + /// + /// Apply a TSIG record to the request message. + /// + /// The to add the security headers too. + /// A instance with additional security attributes assigned. + public DnsQueryRequest SecureMessage(DnsQueryRequest dnsQueryRequest) + { + DateTime signDateTime = DateTime.Now; + int timeHigh; + long timeLow; + + byte[] messageBytes = dnsQueryRequest.GetMessageBytes(); + Trace.WriteLine(String.Format("Message Header Bytes: {0}", DnsHelpers.DumpArrayToString(messageBytes))); + + MemoryStream memoryStream = new MemoryStream(); + memoryStream.Write(messageBytes, 0, messageBytes.Length); + + // the shared key name + byte[] data = DnsHelpers.CanonicaliseDnsName(_name, false); + memoryStream.Write(data, 0, data.Length); + data = BitConverter.GetBytes((ushort) (IPAddress.HostToNetworkOrder((ushort) NsClass.ANY) >> 16)); + memoryStream.Write(data, 0, data.Length); + // the TTL value + data = BitConverter.GetBytes((uint) (IPAddress.HostToNetworkOrder((uint) 0) >> 32)); + memoryStream.Write(data, 0, data.Length); + // the algorithim name + data = DnsHelpers.CanonicaliseDnsName(_algorithimName, true); + memoryStream.Write(data, 0, data.Length); + + DnsHelpers.ConvertToDnsTime(signDateTime.ToUniversalTime(), out timeHigh, out timeLow); + + data = BitConverter.GetBytes((ushort)(IPAddress.HostToNetworkOrder((ushort)timeHigh) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((uint) (IPAddress.HostToNetworkOrder((uint)timeLow) >> 32)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort) (IPAddress.HostToNetworkOrder(_fudge) >> 16)); + memoryStream.Write(data, 0, data.Length); + + data = BitConverter.GetBytes((ushort) (IPAddress.HostToNetworkOrder((ushort) RCode.NoError) >> 16)); + memoryStream.Write(data, 0, data.Length); + + // no other data + data = BitConverter.GetBytes((ushort) (IPAddress.HostToNetworkOrder((ushort) 0) >> 16)); + memoryStream.Write(data, 0, data.Length); + + byte[] dataToHash = memoryStream.ToArray(); + Trace.WriteLine(String.Format("Data to hash: {0}", DnsHelpers.DumpArrayToString(dataToHash))); + byte[] mac = _hmac.ComputeHash(dataToHash); + Trace.WriteLine(String.Format("hash: {0}", DnsHelpers.DumpArrayToString(mac))); + + dnsQueryRequest.AdditionalRRecords.Add(new TSigRecord(_name, _algorithimName, RCode.NoError, _fudge, dnsQueryRequest.TransactionID, new byte[] { }, mac, signDateTime)); + + return dnsQueryRequest; + } + + #endregion + } +} \ No newline at end of file diff --git a/SMTPServer/SMTPServer/DNSClient/Tools.cs b/SMTPServer/SMTPServer/DNSClient/Tools.cs new file mode 100644 index 0000000..6fb99b1 --- /dev/null +++ b/SMTPServer/SMTPServer/DNSClient/Tools.cs @@ -0,0 +1,221 @@ +/********************************************************************** + * Copyright (c) 2010, j. montgomery * + * All rights reserved. * + * * + * Redistribution and use in source and binary forms, with or without * + * modification, are permitted provided that the following conditions * + * are met: * + * * + * + Redistributions of source code must retain the above copyright * + * notice, this list of conditions and the following disclaimer. * + * * + * + Redistributions in binary form must reproduce the above copyright* + * notice, this list of conditions and the following disclaimer * + * in the documentation and/or other materials provided with the * + * distribution. * + * * + * + Neither the name of j. montgomery's employer nor the names of * + * its contributors may be used to endorse or promote products * + * derived from this software without specific prior written * + * permission. * + * * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS* + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,* + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,* + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED* + * OF THE POSSIBILITY OF SUCH DAMAGE. * + **********************************************************************/ +using System; +using System.Text; +using System.Net; +using System.Net.NetworkInformation; +using System.Net.Sockets; + +using DnDns.Enums; + +namespace DnDns +{ + public class Tools + { + /// + /// Look up the port names for the given array of port numbers. + /// + /// An array of port numbers. + /// The protocol type. (TCP or UPD) + /// The name of the port. + public static string GetServByPort(short[] port, ProtocolType proto) + { + StringBuilder sb = new StringBuilder(); + for (int i=0; i < port.Length; i++) + { + sb.Append(GetServByPort(port[i], proto)); + sb.Append(", "); + } + sb.Remove(sb.Length-2,2); + return sb.ToString(); + } + + /// + /// Tests to see if this is running on a Linux or Unix Platform + /// + /// true if unix or linux is detected + //public static bool IsPlatformLinuxUnix() + //{ + // int p = (int)Environment.OSVersion.Platform; + + // Test for Unix / Linux OS + // if (p == 4 || p == 128) + // { + // return true; + // } + // else + // { + // return false; + // } + //} + + /// + /// Look up the port name for any given port number. + /// + /// The port number. + /// The protocol type. (TCP or UPD) + /// The name of the port. + public static string GetServByPort(short port, ProtocolType proto) + { + StringBuilder ans = new StringBuilder(); + + switch (proto) + { + case ProtocolType.Tcp: + { + TcpServices tcps; + tcps = (TcpServices)port; + ans.Append(tcps); + ans.Append("("); + ans.Append(port); + ans.Append(")"); + break; + } + case ProtocolType.Udp: + { + UdpServices udps; + udps = (UdpServices)port; + ans.Append(udps); + ans.Append("("); + ans.Append(port); + ans.Append(")"); + break; + } + default: + { + ans.Append("("); + ans.Append(port); + ans.Append(")"); + break; + } + } + return ans.ToString(); + } + + public static string DiscoverUnixDnsServerAddress() + { + if (System.IO.File.Exists("/etc/resolv.conf")) + { + using (System.IO.StreamReader sr = new System.IO.StreamReader(new System.IO.FileStream("/etc/resolv.conf", System.IO.FileMode.Open))) + { + while (!sr.EndOfStream) + { + string line = sr.ReadLine().TrimStart(); + + if (line.StartsWith("nameserver") && line.Length > 11) + { + line = line.Substring(10).Trim(); + if (!string.IsNullOrEmpty(line)) + { + sr.Dispose(); + return line; + } + } + } + sr.Dispose(); + } + } + return string.Empty; + } + + public static IPAddressCollection DiscoverDnsServerAddresses() + { + NetworkInterface[] arrNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); + + foreach (NetworkInterface objNetworkInterface in arrNetworkInterfaces) + { + if ( + (objNetworkInterface.OperationalStatus == OperationalStatus.Up) && + (objNetworkInterface.Speed > 0) && + (objNetworkInterface.NetworkInterfaceType != NetworkInterfaceType.Loopback) && + (objNetworkInterface.NetworkInterfaceType != NetworkInterfaceType.Tunnel) + ) + { + IPAddressCollection candidate = objNetworkInterface.GetIPProperties().DnsAddresses; + bool found = false; + foreach (IPAddress addr in candidate) + { + // Make this collection contains IPv4 addresses only + if (addr.AddressFamily == AddressFamily.InterNetwork) + found = true; + } + + if (found) + return candidate; + } + } + + return null; + } + + //public static uint ByteToUInt(byte[] theByte) + //{ + // uint l = 0; + + // for (int i = 0; i < theByte.Length; i++) + // { + // l += (uint)theByte[(theByte.Length - i) - 1] << i * 8; + // } + + // return l; + //} + + // Use BitConverter.GetBytes() + //public static byte[] IntToByteArray(uint theInt) + //{ + // byte[] byteArray = new byte[4]; + // int i; + // int shift; + + // for (i = 0, shift = 24; i < 4; i++, shift -= 8) + // byteArray[i] = (byte)(0xFF & (theInt >> shift)); + + // return byteArray; + //} + + // use BitConverter.GetBytes() + //public static byte[] UshortToByteArray(ushort theShort) + //{ + // byte[] byteArray = new byte[2]; + // int i; + // int shift; + + // for (i = 0, shift = 16; i < 2; i++, shift -= 8) + // byteArray[i] = (byte)(0xFF & (theShort >> shift)); + + // return byteArray; + //} + } +} \ No newline at end of file diff --git a/SMTPServer/SMTPServer/Logging/Logging.cs b/SMTPServer/SMTPServer/Logging/Logging.cs new file mode 100644 index 0000000..afdd261 --- /dev/null +++ b/SMTPServer/SMTPServer/Logging/Logging.cs @@ -0,0 +1,50 @@ +using System; + +namespace Logging +{ + public class Logging + { + private static LoggingType[] _ActiveLoggingTypes { get; set; } + + public enum LoggingType + { + TRACE, + ERROR, + DEBUG, + WARNING, + INFO, + ALL + } + + + + private static void AddLogMessage(LoggingType messagetype, string message) + { + if(CheckLoggingType(messagetype)) PrintToConsole(messagetype, message); + } + + private static bool CheckLoggingType(LoggingType lt){ + if (_ActiveLoggingTypes.Length < 1) { + _ActiveLoggingTypes = new LoggingType[1]; + _ActiveLoggingTypes[0] = LoggingType.ALL; + } + bool found = false; + foreach(LoggingType l in _ActiveLoggingTypes) + { + if (l == lt || l == LoggingType.ALL) + { + found = true; + break; + } + } + + + return found; + } + + private static void PrintToConsole(LoggingType lt, string message) + { + Console.WriteLine("[" + lt.ToString() + "]" + message); + } + } +} diff --git a/SMTPServer/SMTPServer/MailTransferAgent.cs b/SMTPServer/SMTPServer/MailTransferAgent.cs index af8850a..cdf38f4 100644 --- a/SMTPServer/SMTPServer/MailTransferAgent.cs +++ b/SMTPServer/SMTPServer/MailTransferAgent.cs @@ -14,36 +14,41 @@ namespace SMTPServer public static void StartMailTransferAgent() { - _Thread = new Thread(new ThreadStart(MTA)); + _Thread = new Thread(new ThreadStart(MTAAsync)); _Thread.Start(); } - public static void MTA() + public static async void MTAAsync() { while (true) { try { var mail = MailQueue.GetNextMail(); - } catch (NoMailsInQueueException) { + } + catch (NoMailsInQueueException) + { Thread.Sleep(100); continue; } var charset = Encoding.UTF8; - var dnsname = GetDNSName(""); + var dnsname = await GetDNSNameAsync(""); var client = new StartTcpConnection(25, new IPAddress(GetIpFromDNS(dnsname)), charset); if (!client.Connected) ; //ToDo Errorfall } } - public static string GetDNSName(string mailTo) + public static async System.Threading.Tasks.Task GetDNSNameAsync(string mailTo) { var parts = mailTo.Split('@'); var domain = parts[1]; + var dns = await System.Net.Dns.GetHostEntryAsync(domain); + //dns. + return null; } diff --git a/SMTPServer/SMTPServer/SMTPServer.csproj b/SMTPServer/SMTPServer/SMTPServer.csproj index fbb51e6..576f706 100644 --- a/SMTPServer/SMTPServer/SMTPServer.csproj +++ b/SMTPServer/SMTPServer/SMTPServer.csproj @@ -1,5 +1,8 @@  + + 1701;1702;1705;1006 + Exe netcoreapp1.0 @@ -9,9 +12,9 @@ - - - + + 5.0.2 + 1.1.0 @@ -19,6 +22,21 @@ 1.0.0-alpha-20161104-2 All + + 1.1.0 + + + 1.0.2-rc2-24027 + + + 1.1.0 + + + 4.0.1 + + + 4.3.0 + \ No newline at end of file diff --git a/SMTPServer/TCPListener.cs b/SMTPServer/TCPListener.cs deleted file mode 100644 index d555ecb..0000000 --- a/SMTPServer/TCPListener.cs +++ /dev/null @@ -1,8 +0,0 @@ -using System; - -public class Class1 -{ - public Class1() - { - } -}