Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
* 'dev' of https://github.com/MichaCo/DnsClient.NET:
  More DNSSEC resource records (MichaCo#87)
  Some changes and cleanup to the TLSA and RRSig records (MichaCo#86)
  Add TLSA and RRSIG support (MichaCo#71)

# Conflicts:
#	src/DnsClient/DnsRecordFactory.cs
#	src/DnsClient/QueryType.cs
  • Loading branch information
Ralf Jänike committed Sep 15, 2020
2 parents 6822e4e + 2d8527b commit df24800
Show file tree
Hide file tree
Showing 18 changed files with 1,080 additions and 65 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ var ip = record?.Address;

### Supported resource records

* A, AAAA, NS, CNAME, SOA, MB, MG, MR, WKS, HINFO, MINFO, MX, RP, TXT, AFSDB, URI, CAA, NULL, SSHFP
* A, AAAA, NS, CNAME, SOA, MB, MG, MR, WKS, HINFO, MINFO, MX, RP, TXT, AFSDB, URI, CAA, NULL, SSHFP, TLSA, RRSIG, NSEC, DNSKEY, DS
* PTR for reverse lookups
* SRV for service discovery. `LookupClient` has some extensions to help with that.
* AXFR zone transfer (as per spec, LookupClient has to be set to TCP mode only for this type. Also, the result depends on if the DNS server trusts your current connection)
Expand Down
2 changes: 1 addition & 1 deletion samples/MiniDig/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"profiles": {
"MiniDig": {
"commandName": "Project",
"commandLineArgs": "-s localhost mcnet.com any --time -1"
"commandLineArgs": "mx3.mailbox.org spf --time -1"
}
}
}
8 changes: 8 additions & 0 deletions src/DnsClient/DnsDatagramReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ public ArraySegment<byte> ReadBytes(int length)
return result;
}

public ArraySegment<byte> ReadBytesToEnd(int startIndex, int lengthOfRawData)
{
var bytesRead = _index - startIndex;
var length = lengthOfRawData - bytesRead;

return ReadBytes(length);
}

public IPAddress ReadIPAddress()
{
if (_count < _index + IPv4Length)
Expand Down
171 changes: 124 additions & 47 deletions src/DnsClient/DnsRecordFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -112,43 +112,67 @@ public DnsResourceRecord GetRecord(ResourceRecordInfo info)
break;

case ResourceRecordType.TXT:
result = ResolveTXTRecord(info);
result = ResolveTxtRecord(info);
break;

case ResourceRecordType.RP:
result = new RpRecord(info, _reader.ReadDnsName(), _reader.ReadDnsName());
break;

case ResourceRecordType.AFSDB:
case ResourceRecordType.AFSDB: // 18
result = new AfsDbRecord(info, (AfsType)_reader.ReadUInt16NetworkOrder(), _reader.ReadDnsName());
break;

case ResourceRecordType.AAAA:
case ResourceRecordType.AAAA: // 28
result = new AaaaRecord(info, _reader.ReadIPv6Address());
break;

case ResourceRecordType.SRV:
case ResourceRecordType.SRV: // 33
result = ResolveSrvRecord(info);
break;

case ResourceRecordType.NAPTR:
result = ResolveNaptrRecord(info);
break;

case ResourceRecordType.OPT:
case ResourceRecordType.OPT: // 41
result = ResolveOptRecord(info);
break;

case ResourceRecordType.URI:
result = ResolveUriRecord(info);
case ResourceRecordType.DS: // 43
result = ResolveDsRecord(info);
break;

case ResourceRecordType.CAA:
result = ResolveCaaRecord(info);
case ResourceRecordType.SSHFP: // 44
result = ResolveSshfpRecord(info);
break;

case ResourceRecordType.SSHFP:
result = ResolveSshfpRecord(info);
case ResourceRecordType.RRSIG: // 46
result = ResolveRRSigRecord(info);
break;

case ResourceRecordType.NSEC: // 47
result = ResolveNSecRecord(info);
break;

case ResourceRecordType.DNSKEY: // 48
result = ResolveDnsKeyRecord(info);
break;

case ResourceRecordType.TLSA: // 52
result = ResolveTlsaRecord(info);
break;

case ResourceRecordType.SPF: // 99
result = ResolveTxtRecord(info);
break;

case ResourceRecordType.URI: // 256
result = ResolveUriRecord(info);
break;

case ResourceRecordType.CAA: // 257
result = ResolveCaaRecord(info);
break;

default:
Expand All @@ -162,19 +186,17 @@ public DnsResourceRecord GetRecord(ResourceRecordInfo info)
return result;
}

private DnsResourceRecord ResolveUriRecord(ResourceRecordInfo info)
private DnsResourceRecord ResolveSoaRecord(ResourceRecordInfo info)
{
var prio = _reader.ReadUInt16NetworkOrder();
var weight = _reader.ReadUInt16NetworkOrder();
var target = _reader.ReadString(info.RawDataLength - 4);
return new UriRecord(info, prio, weight, target);
}
var mName = _reader.ReadDnsName();
var rName = _reader.ReadDnsName();
var serial = _reader.ReadUInt32NetworkOrder();
var refresh = _reader.ReadUInt32NetworkOrder();
var retry = _reader.ReadUInt32NetworkOrder();
var expire = _reader.ReadUInt32NetworkOrder();
var minimum = _reader.ReadUInt32NetworkOrder();

private DnsResourceRecord ResolveOptRecord(ResourceRecordInfo info)
{
// Consume bytes in case the OPT record has any.
var bytes = _reader.ReadBytes(info.RawDataLength).ToArray();
return new OptRecord((int)info.RecordClass, ttlFlag: info.InitialTimeToLive, length: info.RawDataLength, data: bytes);
return new SoaRecord(info, mName, rName, serial, refresh, retry, expire, minimum);
}

private DnsResourceRecord ResolveWksRecord(ResourceRecordInfo info)
Expand All @@ -194,17 +216,23 @@ private DnsResourceRecord ResolveMXRecord(ResourceRecordInfo info)
return new MxRecord(info, preference, domain);
}

private DnsResourceRecord ResolveSoaRecord(ResourceRecordInfo info)
private DnsResourceRecord ResolveTxtRecord(ResourceRecordInfo info)
{
var mName = _reader.ReadDnsName();
var rName = _reader.ReadDnsName();
var serial = _reader.ReadUInt32NetworkOrder();
var refresh = _reader.ReadUInt32NetworkOrder();
var retry = _reader.ReadUInt32NetworkOrder();
var expire = _reader.ReadUInt32NetworkOrder();
var minimum = _reader.ReadUInt32NetworkOrder();
int pos = _reader.Index;

return new SoaRecord(info, mName, rName, serial, refresh, retry, expire, minimum);
var values = new List<string>();
var utf8Values = new List<string>();
while ((_reader.Index - pos) < info.RawDataLength)
{
var length = _reader.ReadByte();
var bytes = _reader.ReadBytes(length);
var escaped = DnsDatagramReader.ParseString(bytes);
var utf = DnsDatagramReader.ReadUTF8String(bytes);
values.Add(escaped);
utf8Values.Add(utf);
}

return new TxtRecord(info, values.ToArray(), utf8Values.ToArray());
}

private DnsResourceRecord ResolveSrvRecord(ResourceRecordInfo info)
Expand All @@ -229,23 +257,21 @@ private DnsResourceRecord ResolveNaptrRecord(ResourceRecordInfo info)
return new NaptrRecord(info, order, preference, flags, services, regexp, replacement);
}

private DnsResourceRecord ResolveTXTRecord(ResourceRecordInfo info)
private DnsResourceRecord ResolveOptRecord(ResourceRecordInfo info)
{
int pos = _reader.Index;

var values = new List<string>();
var utf8Values = new List<string>();
while ((_reader.Index - pos) < info.RawDataLength)
{
var length = _reader.ReadByte();
var bytes = _reader.ReadBytes(length);
var escaped = DnsDatagramReader.ParseString(bytes);
var utf = DnsDatagramReader.ReadUTF8String(bytes);
values.Add(escaped);
utf8Values.Add(utf);
}
// Consume bytes in case the OPT record has any.
var bytes = _reader.ReadBytes(info.RawDataLength).ToArray();
return new OptRecord((int)info.RecordClass, ttlFlag: info.InitialTimeToLive, length: info.RawDataLength, data: bytes);
}

return new TxtRecord(info, values.ToArray(), utf8Values.ToArray());
private DnsResourceRecord ResolveDsRecord(ResourceRecordInfo info)
{
var startIndex = _reader.Index;
var keyTag = _reader.ReadUInt16NetworkOrder();
var algorithm = _reader.ReadByte();
var digestType = _reader.ReadByte();
var digest = _reader.ReadBytesToEnd(startIndex, info.RawDataLength).ToArray();
return new DsRecord(info, keyTag, algorithm, digestType, digest);
}

private DnsResourceRecord ResolveSshfpRecord(ResourceRecordInfo info)
Expand All @@ -257,6 +283,57 @@ private DnsResourceRecord ResolveSshfpRecord(ResourceRecordInfo info)
return new SshfpRecord(info, algorithm, fingerprintType, fingerprintHexString);
}

private DnsResourceRecord ResolveRRSigRecord(ResourceRecordInfo info)
{
var startIndex = _reader.Index;
var type = _reader.ReadUInt16NetworkOrder();
var algorithmNumber = _reader.ReadByte();
var labels = _reader.ReadByte();
var originalTtl = _reader.ReadUInt32NetworkOrder();
var signatureExpiration = _reader.ReadUInt32NetworkOrder();
var signatureInception = _reader.ReadUInt32NetworkOrder();
var keyTag = _reader.ReadUInt16NetworkOrder();
var signersName = _reader.ReadDnsName();
var signature = _reader.ReadBytesToEnd(startIndex, info.RawDataLength).ToArray();
return new RRSigRecord(info, type, algorithmNumber, labels, originalTtl, signatureExpiration, signatureInception, keyTag, signersName, signature);
}

private DnsResourceRecord ResolveNSecRecord(ResourceRecordInfo info)
{
var startIndex = _reader.Index;
var nextName = _reader.ReadDnsName();
var bitMaps = _reader.ReadBytesToEnd(startIndex, info.RawDataLength).ToArray();
return new NSecRecord(info, nextName, bitMaps);
}

private DnsResourceRecord ResolveDnsKeyRecord(ResourceRecordInfo info)
{
var startIndex = _reader.Index;
int flags = _reader.ReadUInt16NetworkOrder();
var protocol = _reader.ReadByte();
var algorithm = _reader.ReadByte();
var publicKey = _reader.ReadBytesToEnd(startIndex, info.RawDataLength).ToArray();
return new DnsKeyRecord(info, flags, protocol, algorithm, publicKey);
}

private DnsResourceRecord ResolveTlsaRecord(ResourceRecordInfo info)
{
var startIndex = _reader.Index;
var certificateUsage = _reader.ReadByte();
var selector = _reader.ReadByte();
var matchingType = _reader.ReadByte();
var certificateAssociationData = _reader.ReadBytesToEnd(startIndex, info.RawDataLength).ToArray();
return new TlsaRecord(info, certificateUsage, selector, matchingType, certificateAssociationData);
}

private DnsResourceRecord ResolveUriRecord(ResourceRecordInfo info)
{
var prio = _reader.ReadUInt16NetworkOrder();
var weight = _reader.ReadUInt16NetworkOrder();
var target = _reader.ReadString(info.RawDataLength - 4);
return new UriRecord(info, prio, weight, target);
}

private DnsResourceRecord ResolveCaaRecord(ResourceRecordInfo info)
{
var flag = _reader.ReadByte();
Expand All @@ -265,4 +342,4 @@ private DnsResourceRecord ResolveCaaRecord(ResourceRecordInfo info)
return new CaaRecord(info, flag, tag, stringValue);
}
}
}
}
11 changes: 6 additions & 5 deletions src/DnsClient/DnsString.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,18 +202,19 @@ public static DnsString Parse(string query)
/// <returns>The <see cref="DnsString"/> representation.</returns>
public static DnsString FromResponseQueryString(string query)
{
var data = query;
if (query.Length == 0 || query[query.Length - 1] != Dot)
{
query += DotStr;
data += DotStr;
}

if (query.Contains(ACEPrefix))
if (data.Contains(ACEPrefix))
{
var unicode = IDN.GetUnicode(query);
return new DnsString(unicode, query);
var unicode = IDN.GetUnicode(data);
return new DnsString(query, unicode);
}

return new DnsString(query, query);
return new DnsString(query, data);
}
}
}
Loading

0 comments on commit df24800

Please sign in to comment.