}//end sslCheck public static string spfCheck(string fqdn) { var spfValidator = new ARSoft.Tools.Net.Spf.SpfValidator(); var ip = IPAddress.Parse("8.8.8.8"); spfValidator.CheckHost(ip, fqdn, "*****@*****.**"); return(spfValidator.ToString()); } //end spfCheck
//private static readonly Regex ipRegex = new Regex(@"ip[46]\:(?<ip>[^ ]+) ?", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant); //private static readonly Regex domainRegex = new Regex(@"include\:(?<domain>[^ ]+) ?", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant); /// <summary> /// Walk SPF records until a valid value is found. Two levels deep walk. /// </summary> /// <param name="writer">Stream writer</param> /// <param name="connectionEndPoint">Connected end point</param> /// <param name="fromAddress">Mail address from</param> /// <param name="fromAddressDomain">Mail address from domain</param> /// <returns>Task</returns> /// <exception cref="InvalidOperationException">SPF fails to validate</exception> public async Task ValidateSPF(StreamWriter writer, IPEndPoint connectionEndPoint, string fromAddress, string fromAddressDomain) { if (!requireSpfMatch) { return; } MailDemonLog.Info("Validating spf for end point {0}, from address: {1}, from domain: {2}", connectionEndPoint.Address, fromAddress, fromAddressDomain); // example smtp host: mail-it1-f173.google.com IPHostEntry entry = await Dns.GetHostEntryAsync(connectionEndPoint.Address); var spfValidator = new ARSoft.Tools.Net.Spf.SpfValidator(); ARSoft.Tools.Net.Spf.ValidationResult result = await spfValidator.CheckHostAsync(connectionEndPoint.Address, fromAddressDomain, fromAddress); if (result.Result == ARSoft.Tools.Net.Spf.SpfQualifier.Pass) { return; } else if (result.Result == ARSoft.Tools.Net.Spf.SpfQualifier.None) { // no spf record... what to do? // TODO: Maybe email back to the address and tell them to setup SPF records...? } /* * LookupClient lookup = new LookupClient(); * IDnsQueryResponse dnsQueryRoot = await lookup.QueryAsync(fromAddressDomain, QueryType.TXT); * foreach (var record in dnsQueryRoot.AllRecords) * { * MatchCollection ipMatches = ipRegex.Matches(record.ToString()); * foreach (Match ipMatch in ipMatches) * { * if (IPAddressRange.TryParse(ipMatch.Groups["ip"].Value, out IPAddressRange testIp)) * { * foreach (IPAddress ip in entry.AddressList) * { * if (testIp.Contains(ip)) * { * // good * return; * } * } * } * } * * MatchCollection matches = domainRegex.Matches(record.ToString()); * foreach (Match match in matches) * { * string domainHost = match.Groups["domain"].Value; * IDnsQueryResponse dnsQuery = await lookup.QueryAsync(domainHost, QueryType.TXT); * foreach (var record2 in dnsQuery.AllRecords) * { * MatchCollection ipMatches2 = ipRegex.Matches(record2.ToString()); * foreach (Match ipMatch in ipMatches2) * { * if (IPAddressRange.TryParse(ipMatch.Groups["ip"].Value, out IPAddressRange testIp)) * { * foreach (IPAddress ip in entry.AddressList) * { * if (testIp.Contains(ip)) * { * // good * return; * } * } * } * } * * MatchCollection matches2 = domainRegex.Matches(record2.ToString()); * foreach (Match match2 in matches2) * { * string domainHost2 = match2.Groups["domain"].Value; * IDnsQueryResponse dnsQuery3 = await lookup.QueryAsync(domainHost2, QueryType.TXT); * foreach (var record3 in dnsQuery3.AllRecords) * { * MatchCollection ipMatches3 = ipRegex.Matches(record3.ToString()); * foreach (Match ipMatch in ipMatches3) * { * if (IPAddressRange.TryParse(ipMatch.Groups["ip"].Value, out IPAddressRange testIp)) * { * foreach (IPAddress ip in entry.AddressList) * { * if (testIp.Contains(ip)) * { * // good * return; * } * } * } * } * } * } * } * } * } */ if (writer != null) { await writer.WriteLineAsync($"500 invalid command - SPF records from mail domain '{fromAddressDomain}' do not match connection host '{entry.HostName}'"); await writer.FlushAsync(); } throw new InvalidOperationException($"SPF validation failed for host '{entry.HostName}', address domain '{fromAddressDomain}'"); }