IDns ResolverQuery Txt Method
Definition
Assembly: MimeKit.Cryptography (in MimeKit.Cryptography.dll) Version: 5.0.0
DnsTxtResponse QueryTxt(
string domain,
CancellationToken cancellationToken = default
)Parameters
- domain String
- The fully-qualified domain name to query, in ASCII (A-label) form.
- cancellationToken CancellationToken (Optional)
- The cancellation token.
Return Value
DnsTxtResponseThe DNS response.
Remarks
Queries the DNS TXT records for the specified domain name.
Each TXT record in the response is made up of one or more character-strings which MUST be concatenated, without any separator, into a single string before being returned in Records.
Implementations should return a DnsTxtResponse with a Status that reflects the outcome of the query rather than throw an exception. In particular, it is important to distinguish a domain name that does not exist (NonExistentDomain) from a domain name that exists but has no TXT records (Success with an empty list of records) and from a query that could not be completed (TemporaryFailure). Any exception other than an OperationCanceledException is treated as a TemporaryFailure.
Example
using System;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using Heijden.DNS;
using Org.BouncyCastle.Crypto;
using MimeKit;
using MimeKit.Cryptography;
namespace DkimVerifierExample
{
// Note: By using the DkimPublicKeyLocatorBase, we avoid having to parse the DNS TXT records
// in order to get the public key ourselves.
class ExamplePublicKeyLocator : DkimPublicKeyLocatorBase
{
readonly Dictionary<string, AsymmetricKeyParameter> cache;
readonly Resolver resolver;
public ExamplePublicKeyLocator ()
{
cache = new Dictionary<string, AsymmetricKeyParameter> ();
resolver = new Resolver ("8.8.8.8") {
TransportType = TransportType.Udp,
UseCache = true,
Retries = 3
};
}
AsymmetricKeyParameter DnsLookup (string domain, string selector, CancellationToken cancellationToken)
{
var query = selector + "._domainkey." + domain;
AsymmetricKeyParameter pubkey;
// checked if we've already fetched this key
if (cache.TryGetValue (query, out pubkey))
return pubkey;
// make a DNS query
var response = resolver.Query (query, QType.TXT);
var builder = new StringBuilder ();
// combine the TXT records into 1 string buffer
foreach (var record in response.RecordsTXT) {
foreach (var text in record.TXT)
builder.Append (text);
}
var txt = builder.ToString ();
// DkimPublicKeyLocatorBase provides us with this helpful method.
pubkey = GetPublicKey (txt);
cache.Add (query, pubkey);
return pubkey;
}
public AsymmetricKeyParameter LocatePublicKey (string methods, string domain, string selector, CancellationToken cancellationToken = default (CancellationToken))
{
var methodList = methods.Split (new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < methodList.Length; i++) {
if (methodList[i] == "dns/txt")
return DnsLookup (domain, selector, cancellationToken);
}
throw new NotSupportedException (string.Format ("{0} does not include any supported lookup methods.", methods));
}
public Task<AsymmetricKeyParameter> LocatePublicKeyAsync (string methods, string domain, string selector, CancellationToken cancellationToken = default (CancellationToken))
{
return Task.Run (() => {
return LocatePublicKey (methods, domain, selector, cancellationToken);
}, cancellationToken);
}
}
class Program
{
public static void Main (string[] args)
{
if (args.Length == 0) {
Help ();
return;
}
for (int i = 0; i < args.Length; i++) {
if (args[i] == "--help") {
Help ();
return;
}
}
var locator = new ExamplePublicKeyLocator ();
var verifier = new DkimVerifier (locator);
for (int i = 0; i < args.Length; i++) {
if (!File.Exists (args[i])) {
Console.Error.WriteLine ("{0}: No such file.", args[i]);
continue;
}
Console.Write ("{0} -> ", args[i]);
var message = MimeMessage.Load (args[i]);
var index = message.Headers.IndexOf (HeaderId.DkimSignature);
if (index == -1) {
Console.WriteLine ("NO SIGNATURE");
continue;
}
var dkim = message.Headers[index];
if (verifier.Verify (message, dkim)) {
// the DKIM-Signature header is valid!
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine ("VALID");
Console.ResetColor ();
} else {
// the DKIM-Signature is invalid!
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine ("INVALID");
Console.ResetColor ();
}
}
}
static void Help ()
{
Console.WriteLine ("Usage is: DkimVerifier [options] [messages]");
Console.WriteLine ();
Console.WriteLine ("Options:");
Console.WriteLine (" --help This help menu.");
}
}
}
Exceptions
| OperationCanceledException | The operation was canceled via the cancellation token. |