private DnsMessage ProcessQuery(DnsMessageBase queryBase, IPAddress clientAddress, ProtocolType protocol) { DnsMessage query = queryBase as DnsMessage; foreach (DnsQuestion q in query.Questions) { if (q.RecordType == RecordType.A) { if (!q.Name.EndsWith(".p2p")) { query.ReturnCode = ReturnCode.Refused; return query; } Console.WriteLine("DNS LOOKUP: " + q.Name); DomainMapping mapping; if (!mappingLookup.TryGetValue(q.Name, out mapping)) { query.ReturnCode = ReturnCode.ServerFailure; return query; } query.AnswerRecords.Add(new ARecord(mapping.Name, mapping.TimeToLive.Seconds, mapping.Address)); return query; } else query.ReturnCode = ReturnCode.NotImplemented; } return query; }
protected override void When() { this.response = this.dnsLookup.ProcessQuery( new DnsMessage { Questions = new System.Collections.Generic.List<DnsQuestion> { new DnsQuestion("test.dev", RecordType.A, RecordClass.Any) } }, IPAddress.Parse("192.168.0.1"), ProtocolType.IPv4); }
public DnsMessageBase HandleQuery(DnsMessageBase message, IPAddress clientAddress, ProtocolType protocol) { var query = message as DnsMessage; if (query == null) message.ReturnCode = ReturnCode.ServerFailure; else ProcessQuery(query); return message; }
static DnsMessageBase ProcessQuery(DnsMessageBase message, IPAddress clientAddress, ProtocolType protocol) { message.IsQuery = false; DnsMessage query = message as DnsMessage; if ((query != null) && (query.Questions.Count == 1)) { // send query to upstream server DnsQuestion question = query.Questions[0]; Random rnd = new Random(); Console.WriteLine(question.Name); System.Threading.Tasks.Parallel.ForEach(dnslist, (site, state) => { Console.WriteLine("Get Info from: " +site); DnsClient cd = new DnsClient(IPAddress.Parse(dnslist[rnd.Next(0, dnslist.Length - 1)]), 500); DnsMessage answer = cd.Resolve(question.Name, question.RecordType, question.RecordClass); if (answer != null) { foreach (DnsRecordBase record in (answer.AnswerRecords)) { lock (query) { query.AnswerRecords.Add(record); } Console.WriteLine(record.Name); } foreach (DnsRecordBase record in (answer.AdditionalRecords)) { lock (query) { query.AnswerRecords.Add(record); } Console.WriteLine(record.Name); } lock (query) { query.ReturnCode = ReturnCode.NoError; state.Break(); } } }); // if got an answer, copy it to the message sent to the client } if (query.ReturnCode == ReturnCode.NoError) { return query; } // Not a valid query or upstream server did not answer correct message.ReturnCode = ReturnCode.ServerFailure; return message; }
static DnsMessageBase ProcessQuery(DnsMessageBase message, IPAddress clientAddress, ProtocolType protocol) { Ok = true; message.IsQuery = false; DnsMessage query = message as DnsMessage; if (query != null) { if (query.Questions.Count == 1) { DnsQuestion question = query.Questions[0]; Console.WriteLine("Query: {0} {1} {2}", question.Name, question.RecordType, question.RecordClass); DnsMessage answer; answer = ResolverInstance.GetAnswer(question); // if got an answer, copy it to the message sent to the client if (answer != null) { foreach (DnsRecordBase record in (answer.AnswerRecords)) { Console.WriteLine("Answer: {0}", record); query.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (answer.AdditionalRecords)) { Console.WriteLine("Additional Answer: {0}", record); query.AnswerRecords.Add(record); } query.ReturnCode = ReturnCode.NoError; return query; } } else Debug.WriteLine("Too many questions ({0})", query.Questions.Count); } // Not a valid query or upstream server did not answer correct message.ReturnCode = ReturnCode.ServerFailure; return message; }
public DnsMessageBase ProcessQuery(DnsMessageBase message, IPAddress clientAddress, ProtocolType protocol) { message.IsQuery = false; var query = message as DnsMessage; if ((query != null) && (query.Questions.Count == 1)) { var question = query.Questions[0]; var answers = this.mappings.Select(m => m.Answer(question)).Where(a => a != null); if (answers.Any()) { query.ReturnCode = ReturnCode.NoError; foreach (var answer in answers) query.AnswerRecords.Add(answer); return query; } } message.ReturnCode = ReturnCode.ServerFailure; return message; }
private DnsMessageBase OnQuery(DnsMessageBase message, IPAddress clientaddress, ProtocolType protocoltype) { message.IsQuery = false; if (!Configuration.ServerEnabled) { Logger.Log(LogSeverity.Warning, "Received a DNS request while the server is not enabled."); message.ReturnCode = ReturnCode.ServerFailure; return message; } var query = message as DnsMessage; if (query != null && query.Questions.Count == 1) { // Get the question DnsQuestion question = query.Questions[0]; // Apply all filters on the question FilterAction filterResult = ApplyFilters(question); // Only check the cache when we do not need to auto-reject if (filterResult != FilterAction.Reject) { DnsRecordBase[] remappedRecords = ApplyRemaps(question); if (remappedRecords.Length > 0) { query.AnswerRecords.AddRange(remappedRecords); query.ReturnCode = ReturnCode.NoError; return query; } if (Configuration.DnsCacheEnabled) { lock (_dnsCache) { // Check the cache CacheEntry cachedEntry = _dnsCache.FirstOrDefault(c => c.Question.IsEqualTo(question)); if (cachedEntry != null) { // Cache hit! if (Configuration.DnsCacheTtl > 0 && DateTime.UtcNow - cachedEntry.LastHit > new TimeSpan(0, 0, 0, Configuration.DnsCacheTtl)) { // Hit expired _dnsCache.Remove(cachedEntry); } else { // Hit did not expire, use it. cachedEntry.Hit(); query.AnswerRecords.AddRange(cachedEntry.Records); query.ReturnCode = ReturnCode.NoError; return query; } } } } } Logger.Log(LogSeverity.Debug, "QUERY: {0} CLASS: {1} TYPE: {2} FILTER: {3}", question.Name, question.RecordClass.ToString(), question.RecordType.ToString(), filterResult.ToString()); DnsMessage answer = null; switch (filterResult) { case FilterAction.Proxy: if (_dnsSocksClient == null) { // Socks not enabled message.ReturnCode = ReturnCode.ServerFailure; return message; } answer = _dnsSocksClient.Resolve(question.Name, question.RecordType, question.RecordClass); break; case FilterAction.SkipProxy: if (_dnsClient == null) { // Socks not enabled message.ReturnCode = ReturnCode.ServerFailure; return message; } answer = _dnsClient.Resolve(question.Name, question.RecordType, question.RecordClass); break; case FilterAction.Reject: message.ReturnCode = ReturnCode.ServerFailure; return message; } // if got an answer, copy it to the message sent to the client if (answer != null) { foreach (DnsRecordBase record in (answer.AnswerRecords)) { query.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (answer.AdditionalRecords)) { query.AnswerRecords.Add(record); } query.ReturnCode = ReturnCode.NoError; if (Configuration.DnsCacheEnabled) { lock (_dnsCache) { if (!_dnsCache.Any(c => c.Question.IsEqualTo(question))) { var cacheEntry = new CacheEntry(question, query.AnswerRecords.ToArray(), Configuration.DnsCacheTtl); cacheEntry.Hit(); _dnsCache.Add(cacheEntry); // Check if the cache is full if (Configuration.DnsCacheSize > 0 && _dnsCache.Count > Configuration.DnsCacheSize) { // Remove the oldest entry _dnsCache.Remove(_dnsCache.OrderBy(c => c.LastHit).First()); } Logger.Log(LogSeverity.Debug, "DNS reply cached."); } } } return query; } } // Not a valid query or upstream server did not answer correct message.ReturnCode = ReturnCode.ServerFailure; return message; }
internal override void ParseRecordData(byte[] resultData, int currentPosition, int length) { Longitude = Double.Parse(DnsMessageBase.ParseText(resultData, ref currentPosition), CultureInfo.InvariantCulture); Latitude = Double.Parse(DnsMessageBase.ParseText(resultData, ref currentPosition), CultureInfo.InvariantCulture); Altitude = Double.Parse(DnsMessageBase.ParseText(resultData, ref currentPosition), CultureInfo.InvariantCulture); }
internal override void ParseRecordData(byte[] resultData, int startPosition, int length) { Priority = DnsMessageBase.ParseUShort(resultData, ref startPosition); Weight = DnsMessageBase.ParseUShort(resultData, ref startPosition); Target = DnsMessageBase.ParseText(resultData, ref startPosition, length - 4); }
private async void HandleTcpListenerAsync() { TcpClient client = null; try { try { client = await _tcpListener.AcceptTcpClientAsync(); ClientConnectedEventArgs clientConnectedEventArgs = new ClientConnectedEventArgs(ProtocolType.Udp, (IPEndPoint)client.Client.RemoteEndPoint); await ClientConnected.RaiseAsync(this, clientConnectedEventArgs); if (clientConnectedEventArgs.RefuseConnect) { return; } } finally { lock (_listenerLock) { _hasActiveTcpListener = false; } } StartTcpListenerTask(); using (NetworkStream stream = client.GetStream()) { while (true) { byte[] buffer = await ReadIntoBufferAsync(client, stream, 2); if (buffer == null) // client disconneted while reading or timeout { break; } int offset = 0; int length = DnsMessageBase.ParseUShort(buffer, ref offset); buffer = await ReadIntoBufferAsync(client, stream, length); if (buffer == null) // client disconneted while reading or timeout { throw new Exception("Client disconnted or timed out while sending data"); } DnsMessageBase query; byte[] tsigMac; try { query = DnsMessageBase.CreateByFlag(buffer, TsigKeySelector, null); tsigMac = query.TSigOptions?.Mac; } catch (Exception e) { throw new Exception("Error parsing dns query", e); } DnsMessageBase response; try { response = await ProcessMessageAsync(query, ProtocolType.Tcp, (IPEndPoint)client.Client.RemoteEndPoint); } catch (Exception ex) { OnExceptionThrownAsync(ex); response = DnsMessageBase.CreateByFlag(buffer, TsigKeySelector, null); response.IsQuery = false; response.AdditionalRecords.Clear(); response.AuthorityRecords.Clear(); response.ReturnCode = ReturnCode.ServerFailure; } byte[] newTsigMac; length = response.Encode(true, tsigMac, false, out buffer, out newTsigMac); if (length <= 65535) { await stream.WriteAsync(buffer, 0, length); } else { if ((response.Questions.Count == 0) || (response.Questions[0].RecordType != RecordType.Axfr)) { OnExceptionThrownAsync(new ArgumentException("The length of the serialized response is greater than 65,535 bytes")); response = DnsMessageBase.CreateByFlag(buffer, TsigKeySelector, null); response.IsQuery = false; response.AdditionalRecords.Clear(); response.AuthorityRecords.Clear(); response.ReturnCode = ReturnCode.ServerFailure; length = response.Encode(true, tsigMac, false, out buffer, out newTsigMac); await stream.WriteAsync(buffer, 0, length); } else { bool isSubSequentResponse = false; while (true) { List <DnsRecordBase> nextPacketRecords = new List <DnsRecordBase>(); while (length > 65535) { int lastIndex = Math.Min(500, response.AnswerRecords.Count / 2); int removeCount = response.AnswerRecords.Count - lastIndex; nextPacketRecords.InsertRange(0, response.AnswerRecords.GetRange(lastIndex, removeCount)); response.AnswerRecords.RemoveRange(lastIndex, removeCount); length = response.Encode(true, tsigMac, isSubSequentResponse, out buffer, out newTsigMac); } await stream.WriteAsync(buffer, 0, length); if (nextPacketRecords.Count == 0) { break; } isSubSequentResponse = true; tsigMac = newTsigMac; response.AnswerRecords = nextPacketRecords; length = response.Encode(true, tsigMac, true, out buffer, out newTsigMac); } } } // Since support for multiple tsig signed messages is not finished, just close connection after response to first signed query if (newTsigMac != null) { break; } } } } catch (Exception ex) { OnExceptionThrownAsync(ex); } finally { try { // ReSharper disable once ConstantConditionalAccessQualifier client?.Close(); } catch { // ignored } lock (_listenerLock) { _availableTcpListener++; } StartTcpListenerTask(); } }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <DomainName, ushort> domainNames, bool useCanonical) { DnsMessageBase.EncodeUInt(messageData, ref currentPosition, SerialNumber); DnsMessageBase.EncodeUShort(messageData, ref currentPosition, (ushort)Flags); EncodeTypeBitmap(messageData, ref currentPosition, Types); }
internal override void ParseRecordData(byte[] resultData, int startPosition, int length) { Preference = DnsMessageBase.ParseUShort(resultData, ref startPosition); ExchangeDomainName = DnsMessageBase.ParseDomainName(resultData, ref startPosition); }
internal override void ParseRecordData(byte[] resultData, int startPosition, int length) { Preference = DnsMessageBase.ParseUShort(resultData, ref startPosition); NodeID = DnsMessageBase.ParseULong(resultData, ref startPosition); }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <DomainName, ushort> domainNames, bool useCanonical) { DnsMessageBase.EncodeByteArray(messageData, ref currentPosition, PublicKey); }
private static DateTime ParseDateTime(byte[] buffer, ref int currentPosition) { int timeStamp = DnsMessageBase.ParseInt(buffer, ref currentPosition); return(new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(timeStamp).ToLocalTime()); }
internal static void EncodeDateTime(byte[] buffer, ref int currentPosition, DateTime value) { int timeStamp = (int)(value.ToUniversalTime() - new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc)).TotalSeconds; DnsMessageBase.EncodeInt(buffer, ref currentPosition, timeStamp); }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <string, ushort> domainNames) { DnsMessageBase.EncodeByteArray(messageData, ref currentPosition, Address.GetAddressBytes()); }
internal override void ParseRecordData(byte[] resultData, int startPosition, int length) { Address = new IPAddress(DnsMessageBase.ParseByteData(resultData, ref startPosition, 16)); }
internal override void EncodeData(byte[] messageData, ref int currentPosition) { DnsMessageBase.EncodeByteArray(messageData, ref currentPosition, Data); }
internal InvalidSignedMessageEventArgs(DnsMessageBase query, ProtocolType protocolType, IPEndPoint remoteEndpoint) { Query = query; ProtocolType = protocolType; RemoteEndpoint = remoteEndpoint; }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <string, ushort> domainNames) { DnsMessageBase.EncodeDomainName(messageData, offset, ref currentPosition, MailBox, false, domainNames); DnsMessageBase.EncodeDomainName(messageData, offset, ref currentPosition, TxtDomainName, false, domainNames); }
private async Task<DnsMessageBase> ProcessMessageAsync(DnsMessageBase query, ProtocolType protocolType, IPEndPoint remoteEndpoint) { if (query.TSigOptions != null) { switch (query.TSigOptions.ValidationResult) { case ReturnCode.BadKey: case ReturnCode.BadSig: query.IsQuery = false; query.ReturnCode = ReturnCode.NotAuthoritive; query.TSigOptions.Error = query.TSigOptions.ValidationResult; query.TSigOptions.KeyData = null; #pragma warning disable 4014 InvalidSignedMessageReceived.RaiseAsync(this, new InvalidSignedMessageEventArgs(query, protocolType, remoteEndpoint)); #pragma warning restore 4014 return query; case ReturnCode.BadTime: query.IsQuery = false; query.ReturnCode = ReturnCode.NotAuthoritive; query.TSigOptions.Error = query.TSigOptions.ValidationResult; query.TSigOptions.OtherData = new byte[6]; int tmp = 0; TSigRecord.EncodeDateTime(query.TSigOptions.OtherData, ref tmp, DateTime.Now); #pragma warning disable 4014 InvalidSignedMessageReceived.RaiseAsync(this, new InvalidSignedMessageEventArgs(query, protocolType, remoteEndpoint)); #pragma warning restore 4014 return query; } } QueryReceivedEventArgs eventArgs = new QueryReceivedEventArgs(query, protocolType, remoteEndpoint); await QueryReceived.RaiseAsync(this, eventArgs); return eventArgs.Response; }
internal override void ParseData(byte[] resultData, int startPosition, int length) { LeaseTime = TimeSpan.FromSeconds(DnsMessageBase.ParseInt(resultData, ref startPosition)); }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <string, ushort> domainNames) { DnsMessageBase.EncodeUShort(messageData, ref currentPosition, Preference); DnsMessageBase.EncodeULong(messageData, ref currentPosition, NodeID); }
internal override void EncodeData(byte[] messageData, ref int currentPosition) { DnsMessageBase.EncodeInt(messageData, ref currentPosition, (int)LeaseTime.TotalSeconds); }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <DomainName, ushort> domainNames, bool useCanonical) { DnsMessageBase.EncodeUShort(messageData, ref currentPosition, Preference); DnsMessageBase.EncodeDomainName(messageData, offset, ref currentPosition, ExchangeDomainName, domainNames, useCanonical); }
internal override void ParseRecordData(byte[] resultData, int startPosition, int length) { RecordData = DnsMessageBase.ParseByteData(resultData, ref startPosition, length); }
private async void HandleUdpListenerAsync() { try { UdpReceiveResult receiveResult; try { receiveResult = await _udpListener.ReceiveAsync(); } catch (ObjectDisposedException) { return; } finally { lock (_listenerLock) { _hasActiveUdpListener = false; } } ClientConnectedEventArgs clientConnectedEventArgs = new ClientConnectedEventArgs(ProtocolType.Udp, receiveResult.RemoteEndPoint); await ClientConnected.RaiseAsync(this, clientConnectedEventArgs); if (clientConnectedEventArgs.RefuseConnect) { return; } StartUdpListenerTask(); byte[] buffer = receiveResult.Buffer; DnsMessageBase query; byte[] originalMac; try { query = DnsMessageBase.CreateByFlag(buffer, TsigKeySelector, null); originalMac = query.TSigOptions?.Mac; } catch (Exception e) { throw new Exception("Error parsing dns query", e); } DnsMessageBase response; try { response = await ProcessMessageAsync(query, ProtocolType.Udp, receiveResult.RemoteEndPoint); } catch (Exception ex) { OnExceptionThrownAsync(ex); response = null; } if (response == null) { response = query; query.IsQuery = false; query.ReturnCode = ReturnCode.ServerFailure; } int length = response.Encode(false, originalMac, out buffer); #region Truncating DnsMessage message = response as DnsMessage; if (message != null) { int maxLength = 512; if (query.IsEDnsEnabled && message.IsEDnsEnabled) { maxLength = Math.Max(512, (int)message.EDnsOptions.UdpPayloadSize); } while (length > maxLength) { // First step: remove data from additional records except the opt record if ((message.IsEDnsEnabled && (message.AdditionalRecords.Count > 1)) || (!message.IsEDnsEnabled && (message.AdditionalRecords.Count > 0))) { for (int i = message.AdditionalRecords.Count - 1; i >= 0; i--) { if (message.AdditionalRecords[i].RecordType != RecordType.Opt) { message.AdditionalRecords.RemoveAt(i); } } length = message.Encode(false, originalMac, out buffer); continue; } int savedLength = 0; if (message.AuthorityRecords.Count > 0) { for (int i = message.AuthorityRecords.Count - 1; i >= 0; i--) { savedLength += message.AuthorityRecords[i].MaximumLength; message.AuthorityRecords.RemoveAt(i); if ((length - savedLength) < maxLength) { break; } } message.IsTruncated = true; length = message.Encode(false, originalMac, out buffer); continue; } if (message.AnswerRecords.Count > 0) { for (int i = message.AnswerRecords.Count - 1; i >= 0; i--) { savedLength += message.AnswerRecords[i].MaximumLength; message.AnswerRecords.RemoveAt(i); if ((length - savedLength) < maxLength) { break; } } message.IsTruncated = true; length = message.Encode(false, originalMac, out buffer); continue; } if (message.Questions.Count > 0) { for (int i = message.Questions.Count - 1; i >= 0; i--) { savedLength += message.Questions[i].MaximumLength; message.Questions.RemoveAt(i); if ((length - savedLength) < maxLength) { break; } } message.IsTruncated = true; length = message.Encode(false, originalMac, out buffer); } } } #endregion await _udpListener.SendAsync(buffer, length, receiveResult.RemoteEndPoint); } catch (Exception ex) { OnExceptionThrownAsync(ex); } finally { lock (_listenerLock) { _availableUdpListener++; } StartUdpListenerTask(); } }
internal override void ParseRecordData(byte[] resultData, int startPosition, int length) { X25Address += DnsMessageBase.ParseText(resultData, ref startPosition); }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <DomainName, ushort> domainNames, bool useCanonical) { DnsMessageBase.EncodeUShort(messageData, ref currentPosition, Priority); DnsMessageBase.EncodeUShort(messageData, ref currentPosition, Weight); DnsMessageBase.EncodeTextWithoutLength(messageData, ref currentPosition, Target); }
internal void Encode(byte[] messageData, int offset, ref int currentPosition, Dictionary <DomainName, ushort> domainNames) { DnsMessageBase.EncodeDomainName(messageData, offset, ref currentPosition, Name, domainNames, false); DnsMessageBase.EncodeUShort(messageData, ref currentPosition, (ushort)RecordType); DnsMessageBase.EncodeUShort(messageData, ref currentPosition, (ushort)RecordClass); }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <DomainName, ushort> domainNames, bool useCanonical) { DnsMessageBase.EncodeTextBlock(messageData, ref currentPosition, Longitude.ToString(CultureInfo.InvariantCulture)); DnsMessageBase.EncodeTextBlock(messageData, ref currentPosition, Latitude.ToString(CultureInfo.InvariantCulture)); DnsMessageBase.EncodeTextBlock(messageData, ref currentPosition, Altitude.ToString(CultureInfo.InvariantCulture)); }
private DnsMessageBase ProcessDnsQuery(DnsMessageBase message, IPAddress clientAddress, ProtocolType protocol) { state_.Logger.Debug("DNS query received"); message.IsQuery = false; DnsMessage query = message as DnsMessage; if(query == null) { message.ReturnCode = ReturnCode.ServerFailure; return message; } foreach(DnsQuestion question in query.Questions) { state_.Logger.Debug("DNS question of type {0} received", question.RecordType); List<DnsRecordBase> records = ProcessQuestion(question); if(records == null) records = ForwardQuery(question); if(records == null) { message.ReturnCode = ReturnCode.ServerFailure; return message; } else query.AnswerRecords.AddRange(records); } return message; }
public InvalidSignedMessageEventArgs(DnsMessageBase message) { Message = message; }
internal QueryReceivedEventArgs(DnsMessageBase query, ProtocolType protocolType, IPEndPoint remoteEndpoint) { Query = query; ProtocolType = protocolType; RemoteEndpoint = remoteEndpoint; }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <DomainName, ushort> domainNames, bool useCanonical) { DnsMessageBase.EncodeTextBlock(messageData, ref currentPosition, X25Address); }
/// <summary> /// Creates a new signing key pair /// </summary> /// <param name="name">The name of the key or zone</param> /// <param name="recordClass">The record class of the DnsKeyRecord</param> /// <param name="timeToLive">The TTL in seconds to the DnsKeyRecord</param> /// <param name="flags">The Flags of the DnsKeyRecord</param> /// <param name="protocol">The protocol version</param> /// <param name="algorithm">The key algorithm</param> /// <param name="keyStrength">The key strength or 0 for default strength</param> /// <returns></returns> public static DnsKeyRecord CreateSigningKey(DomainName name, RecordClass recordClass, int timeToLive, DnsKeyFlags flags, byte protocol, DnsSecAlgorithm algorithm, int keyStrength = 0) { byte[] privateKey; byte[] publicKey; switch (algorithm) { case DnsSecAlgorithm.RsaSha1: case DnsSecAlgorithm.RsaSha1Nsec3Sha1: case DnsSecAlgorithm.RsaSha256: case DnsSecAlgorithm.RsaSha512: if (keyStrength == 0) { keyStrength = (flags == (DnsKeyFlags.Zone | DnsKeyFlags.SecureEntryPoint)) ? 2048 : 1024; } RsaKeyPairGenerator rsaKeyGen = new RsaKeyPairGenerator(); rsaKeyGen.Init(new KeyGenerationParameters(_secureRandom, keyStrength)); var rsaKey = rsaKeyGen.GenerateKeyPair(); privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(rsaKey.Private).GetDerEncoded(); var rsaPublicKey = (RsaKeyParameters)rsaKey.Public; var rsaExponent = rsaPublicKey.Exponent.ToByteArrayUnsigned(); var rsaModulus = rsaPublicKey.Modulus.ToByteArrayUnsigned(); int offset = 1; if (rsaExponent.Length > 255) { publicKey = new byte[3 + rsaExponent.Length + rsaModulus.Length]; DnsMessageBase.EncodeUShort(publicKey, ref offset, (ushort)publicKey.Length); } else { publicKey = new byte[1 + rsaExponent.Length + rsaModulus.Length]; publicKey[0] = (byte)rsaExponent.Length; } DnsMessageBase.EncodeByteArray(publicKey, ref offset, rsaExponent); DnsMessageBase.EncodeByteArray(publicKey, ref offset, rsaModulus); break; case DnsSecAlgorithm.Dsa: case DnsSecAlgorithm.DsaNsec3Sha1: if (keyStrength == 0) { keyStrength = 1024; } DsaParametersGenerator dsaParamsGen = new DsaParametersGenerator(); dsaParamsGen.Init(keyStrength, 12, _secureRandom); DsaKeyPairGenerator dsaKeyGen = new DsaKeyPairGenerator(); dsaKeyGen.Init(new DsaKeyGenerationParameters(_secureRandom, dsaParamsGen.GenerateParameters())); var dsaKey = dsaKeyGen.GenerateKeyPair(); privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(dsaKey.Private).GetDerEncoded(); var dsaPublicKey = (DsaPublicKeyParameters)dsaKey.Public; var dsaY = dsaPublicKey.Y.ToByteArrayUnsigned(); var dsaP = dsaPublicKey.Parameters.P.ToByteArrayUnsigned(); var dsaQ = dsaPublicKey.Parameters.Q.ToByteArrayUnsigned(); var dsaG = dsaPublicKey.Parameters.G.ToByteArrayUnsigned(); var dsaT = (byte)((dsaY.Length - 64) / 8); publicKey = new byte[21 + 3 * dsaY.Length]; publicKey[0] = dsaT; dsaQ.CopyTo(publicKey, 1); dsaP.CopyTo(publicKey, 21); dsaG.CopyTo(publicKey, 21 + dsaY.Length); dsaY.CopyTo(publicKey, 21 + 2 * dsaY.Length); break; case DnsSecAlgorithm.EccGost: ECDomainParameters gostEcDomainParameters = ECGost3410NamedCurves.GetByOid(CryptoProObjectIdentifiers.GostR3410x2001CryptoProA); var gostKeyGen = new ECKeyPairGenerator(); gostKeyGen.Init(new ECKeyGenerationParameters(gostEcDomainParameters, _secureRandom)); var gostKey = gostKeyGen.GenerateKeyPair(); privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(gostKey.Private).GetDerEncoded(); var gostPublicKey = (ECPublicKeyParameters)gostKey.Public; publicKey = new byte[64]; gostPublicKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 32); gostPublicKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 0); publicKey = publicKey.Reverse().ToArray(); break; case DnsSecAlgorithm.EcDsaP256Sha256: case DnsSecAlgorithm.EcDsaP384Sha384: int ecDsaDigestSize; X9ECParameters ecDsaCurveParameter; if (algorithm == DnsSecAlgorithm.EcDsaP256Sha256) { ecDsaDigestSize = new Sha256Digest().GetDigestSize(); ecDsaCurveParameter = NistNamedCurves.GetByOid(SecObjectIdentifiers.SecP256r1); } else { ecDsaDigestSize = new Sha384Digest().GetDigestSize(); ecDsaCurveParameter = NistNamedCurves.GetByOid(SecObjectIdentifiers.SecP384r1); } ECDomainParameters ecDsaP384EcDomainParameters = new ECDomainParameters( ecDsaCurveParameter.Curve, ecDsaCurveParameter.G, ecDsaCurveParameter.N, ecDsaCurveParameter.H, ecDsaCurveParameter.GetSeed()); var ecDsaKeyGen = new ECKeyPairGenerator(); ecDsaKeyGen.Init(new ECKeyGenerationParameters(ecDsaP384EcDomainParameters, _secureRandom)); var ecDsaKey = ecDsaKeyGen.GenerateKeyPair(); privateKey = PrivateKeyInfoFactory.CreatePrivateKeyInfo(ecDsaKey.Private).GetDerEncoded(); var ecDsaPublicKey = (ECPublicKeyParameters)ecDsaKey.Public; publicKey = new byte[ecDsaDigestSize * 2]; ecDsaPublicKey.Q.AffineXCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, 0); ecDsaPublicKey.Q.AffineYCoord.ToBigInteger().ToByteArrayUnsigned().CopyTo(publicKey, ecDsaDigestSize); break; default: throw new NotSupportedException(); } return(new DnsKeyRecord(name, recordClass, timeToLive, flags, protocol, algorithm, publicKey, privateKey)); }
internal override void ParseRecordData(byte[] resultData, int startPosition, int length) { MailBox = DnsMessageBase.ParseDomainName(resultData, ref startPosition); TxtDomainName = DnsMessageBase.ParseDomainName(resultData, ref startPosition); }
static DnsMessageBase OnDnsQuery(DnsMessageBase message, System.Net.IPAddress clientAddress, ProtocolType protocol) { message.IsQuery = false; DnsMessage query = message as DnsMessage; DnsMessage answer = null; if ((query != null) && (query.Questions.Count == 1)) { //log File.AppendAllLines("VenomDNS.log", new String[] { String.Format("DNS QUERY FROM {0} FOR {1}", clientAddress.ToString(), query.Questions[0].Name) }); //HOOK: //resolve whatsapp.net subdomains if (query.Questions[0].RecordType == RecordType.A && ( (query.Questions[0].Name == WA_CERT_HOST) || (query.Questions[0].Name == WA_REG_HOST && frmMain.enableReg) || (query.Questions[0].Name == WA_SYNC_HOST && frmMain.enableSync) || ( //media files query.Questions[0].Name.StartsWith("mms") && query.Questions[0].Name.EndsWith("whatsapp.net") && frmMain.enableMedia ) || ( ( query.Questions[0].Name == WA_CHAT_HOST1 || query.Questions[0].Name == WA_CHAT_HOST2 || query.Questions[0].Name == WA_CHAT_HOST3 ) && frmMain.enableTCP ) ) ) { query.ReturnCode = ReturnCode.NoError; System.Net.IPAddress localIP = GetIP(); if (localIP != null) { query.AnswerRecords.Add(new ARecord(query.Questions[0].Name, 30, localIP)); return query; } } // send query to upstream server try { DnsQuestion question = query.Questions[0]; answer = DnsClient.Default.Resolve(question.Name, question.RecordType, question.RecordClass); // if got an answer, copy it to the message sent to the client if (answer != null) { foreach (DnsRecordBase record in (answer.AnswerRecords)) { query.AnswerRecords.Add(record); } foreach (DnsRecordBase record in (answer.AdditionalRecords)) { query.AnswerRecords.Add(record); } query.ReturnCode = ReturnCode.NoError; return query; } } catch (Exception e) { } } // Not a valid query or upstream server did not answer correct message.ReturnCode = ReturnCode.ServerFailure; return message; }
protected internal override void EncodeRecordData(byte[] messageData, int offset, ref int currentPosition, Dictionary <DomainName, ushort> domainNames, bool useCanonical) { DnsMessageBase.EncodeDomainName(messageData, offset, ref currentPosition, MailBox, null, useCanonical); DnsMessageBase.EncodeDomainName(messageData, offset, ref currentPosition, TxtDomainName, null, useCanonical); }
private DnsMessageBase ProcessMessage(DnsMessageBase query, IPAddress ipAddress, ProtocolType protocolType) { if (query.TSigOptions != null) { switch (query.TSigOptions.ValidationResult) { case ReturnCode.BadKey: case ReturnCode.BadSig: query.IsQuery = false; query.ReturnCode = ReturnCode.NotAuthoritive; query.TSigOptions.Error = query.TSigOptions.ValidationResult; query.TSigOptions.KeyData = null; if (InvalidSignedMessageReceived != null) InvalidSignedMessageReceived(this, new InvalidSignedMessageEventArgs(query)); return query; case ReturnCode.BadTime: query.IsQuery = false; query.ReturnCode = ReturnCode.NotAuthoritive; query.TSigOptions.Error = query.TSigOptions.ValidationResult; query.TSigOptions.OtherData = new byte[6]; int tmp = 0; TSigRecord.EncodeDateTime(query.TSigOptions.OtherData, ref tmp, DateTime.Now); if (InvalidSignedMessageReceived != null) InvalidSignedMessageReceived(this, new InvalidSignedMessageEventArgs(query)); return query; } } return _processQueryDelegate(query, ipAddress, protocolType); }
protected async Task <TMessage> SendMessageAsync <TMessage>(TMessage message, CancellationToken token) where TMessage : DnsMessageBase, new() { int messageLength; byte[] messageData; DnsServer.SelectTsigKey tsigKeySelector; byte[] tsigOriginalMac; PrepareMessage(message, out messageLength, out messageData, out tsigKeySelector, out tsigOriginalMac); bool sendByTcp = ((messageLength > MaximumQueryMessageSize) || message.IsTcpUsingRequested || !IsUdpEnabled); var endpointInfos = GetEndpointInfos(); for (int i = 0; i < endpointInfos.Count; i++) { token.ThrowIfCancellationRequested(); var endpointInfo = endpointInfos[i]; QueryResponse resultData = null; try { resultData = await(sendByTcp ? QueryByTcpAsync(endpointInfo.ServerAddress, messageData, messageLength, null, null, token) : QuerySingleResponseByUdpAsync(endpointInfo, messageData, messageLength, token)); if (resultData == null) { return(null); } TMessage result; try { result = DnsMessageBase.Parse <TMessage>(resultData.Buffer, tsigKeySelector, tsigOriginalMac); } catch (Exception e) { Trace.TraceError("Error on dns query: " + e); continue; } if (!ValidateResponse(message, result)) { continue; } if ((result.ReturnCode != ReturnCode.NoError) && (result.ReturnCode != ReturnCode.NxDomain) && (i != endpointInfos.Count - 1)) { continue; } if (result.IsTcpResendingRequested) { resultData = await QueryByTcpAsync(resultData.ResponderAddress, messageData, messageLength, resultData.TcpClient, resultData.TcpStream, token); if (resultData != null) { TMessage tcpResult; try { tcpResult = DnsMessageBase.Parse <TMessage>(resultData.Buffer, tsigKeySelector, tsigOriginalMac); } catch (Exception e) { Trace.TraceError("Error on dns query: " + e); return(null); } if (tcpResult.ReturnCode == ReturnCode.ServerFailure) { return(result); } else { result = tcpResult; } } } bool isTcpNextMessageWaiting = result.IsTcpNextMessageWaiting(false); bool isSucessfullFinished = true; while (isTcpNextMessageWaiting) { // ReSharper disable once PossibleNullReferenceException resultData = await QueryByTcpAsync(resultData.ResponderAddress, null, 0, resultData.TcpClient, resultData.TcpStream, token); if (resultData != null) { TMessage tcpResult; try { tcpResult = DnsMessageBase.Parse <TMessage>(resultData.Buffer, tsigKeySelector, tsigOriginalMac); } catch (Exception e) { Trace.TraceError("Error on dns query: " + e); isSucessfullFinished = false; break; } if (tcpResult.ReturnCode == ReturnCode.ServerFailure) { isSucessfullFinished = false; break; } else { result.AnswerRecords.AddRange(tcpResult.AnswerRecords); isTcpNextMessageWaiting = tcpResult.IsTcpNextMessageWaiting(true); } } else { isSucessfullFinished = false; break; } } if (isSucessfullFinished) { return(result); } } finally { if (resultData != null) { try { resultData.TcpStream?.Dispose(); resultData.TcpClient?.Close(); } catch { // ignored } } } } return(null); }
internal InvalidSignedMessageEventArgs(DnsMessageBase message) { Message = message; }
protected TMessage SendMessage <TMessage>(TMessage message) where TMessage : DnsMessageBase, new() { int messageLength; byte[] messageData; DnsServer.SelectTsigKey tsigKeySelector; byte[] tsigOriginalMac; PrepareMessage(message, out messageLength, out messageData, out tsigKeySelector, out tsigOriginalMac); bool sendByTcp = ((messageLength > MaximumQueryMessageSize) || message.IsTcpUsingRequested || !IsUdpEnabled); var endpointInfos = GetEndpointInfos(); for (int i = 0; i < endpointInfos.Count; i++) { TcpClient tcpClient = null; NetworkStream tcpStream = null; try { var endpointInfo = endpointInfos[i]; IPAddress responderAddress; byte[] resultData = sendByTcp ? QueryByTcp(endpointInfo.ServerAddress, messageData, messageLength, ref tcpClient, ref tcpStream, out responderAddress) : QueryByUdp(endpointInfo, messageData, messageLength, out responderAddress); if (resultData != null) { TMessage result; try { result = DnsMessageBase.Parse <TMessage>(resultData, tsigKeySelector, tsigOriginalMac); } catch (Exception e) { Trace.TraceError("Error on dns query: " + e); continue; } if (!ValidateResponse(message, result)) { continue; } if ((result.ReturnCode == ReturnCode.ServerFailure) && (i != endpointInfos.Count - 1)) { continue; } if (result.IsTcpResendingRequested) { resultData = QueryByTcp(responderAddress, messageData, messageLength, ref tcpClient, ref tcpStream, out responderAddress); if (resultData != null) { TMessage tcpResult; try { tcpResult = DnsMessageBase.Parse <TMessage>(resultData, tsigKeySelector, tsigOriginalMac); } catch (Exception e) { Trace.TraceError("Error on dns query: " + e); continue; } if (tcpResult.ReturnCode == ReturnCode.ServerFailure) { if (i != endpointInfos.Count - 1) { continue; } } else { result = tcpResult; } } } bool isTcpNextMessageWaiting = result.IsTcpNextMessageWaiting(false); bool isSucessfullFinished = true; while (isTcpNextMessageWaiting) { resultData = QueryByTcp(responderAddress, null, 0, ref tcpClient, ref tcpStream, out responderAddress); if (resultData != null) { TMessage tcpResult; try { tcpResult = DnsMessageBase.Parse <TMessage>(resultData, tsigKeySelector, tsigOriginalMac); } catch (Exception e) { Trace.TraceError("Error on dns query: " + e); isSucessfullFinished = false; break; } if (tcpResult.ReturnCode == ReturnCode.ServerFailure) { isSucessfullFinished = false; break; } else { result.AnswerRecords.AddRange(tcpResult.AnswerRecords); isTcpNextMessageWaiting = tcpResult.IsTcpNextMessageWaiting(true); } } else { isSucessfullFinished = false; break; } } if (isSucessfullFinished) { return(result); } } } finally { try { tcpStream?.Dispose(); tcpClient?.Close(); } catch { // ignored } } } return(null); }