예제 #1
0
        /// <summary>
        ///   Returns the textual representation of the SenderID record
        /// </summary>
        /// <returns> Textual representation </returns>
        public override string ToString()
        {
            StringBuilder res = new StringBuilder();

            if (Version == 1)
            {
                res.Append("v=spf1");
            }
            else
            {
                res.Append("v=spf");
                res.Append(Version);
                res.Append(".");
                res.Append(MinorVersion);
                res.Append("/");
                res.Append(String.Join(",", Scopes.Where(s => s != SenderIDScope.Unknown).Select(s => EnumHelper <SenderIDScope> .ToString(s).ToLower()).ToArray()));
            }

            if ((Terms != null) && (Terms.Count > 0))
            {
                foreach (SpfTerm term in Terms)
                {
                    SpfModifier modifier = term as SpfModifier;
                    if ((modifier == null) || (modifier.Type != SpfModifierType.Unknown))
                    {
                        res.Append(" ");
                        res.Append(term.ToString());
                    }
                }
            }

            return(res.ToString());
        }
예제 #2
0
        /// <summary>
        ///   Returns the textual representation of a SPF record
        /// </summary>
        /// <returns> Textual representation </returns>
        public override string ToString()
        {
            StringBuilder res = new StringBuilder();

            res.Append("v=spf1");

            if ((Terms != null) && (Terms.Count > 0))
            {
                foreach (SpfTerm term in Terms)
                {
                    SpfModifier modifier = term as SpfModifier;
                    if ((modifier == null) || (modifier.Type != SpfModifierType.Unknown))
                    {
                        res.Append(" ");
                        res.Append(term.ToString());
                    }
                }
            }

            return(res.ToString());
        }
예제 #3
0
        internal static bool TryParse(string s, out SpfTerm value)
        {
            if (String.IsNullOrEmpty(s))
            {
                value = null;
                return(false);
            }

            #region Parse Mechanism
            Regex regex = new Regex(@"^(\s)*(?<qualifier>[~+?-]?)(?<type>[a-z0-9]+)(:(?<domain>[^/]+))?(/(?<prefix>[0-9]+)(/(?<prefix6>[0-9]+))?)?(\s)*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            Match match = regex.Match(s);
            if (match.Success)
            {
                SpfMechanism mechanism = new SpfMechanism();

                switch (match.Groups["qualifier"].Value)
                {
                case "+":
                    mechanism.Qualifier = SpfQualifier.Pass;
                    break;

                case "-":
                    mechanism.Qualifier = SpfQualifier.Fail;
                    break;

                case "~":
                    mechanism.Qualifier = SpfQualifier.SoftFail;
                    break;

                case "?":
                    mechanism.Qualifier = SpfQualifier.Neutral;
                    break;

                default:
                    mechanism.Qualifier = SpfQualifier.Pass;
                    break;
                }

                SpfMechanismType type;
                mechanism.Type = EnumHelper <SpfMechanismType> .TryParse(match.Groups["type"].Value, true, out type) ? type : SpfMechanismType.Unknown;

                mechanism.Domain = match.Groups["domain"].Value;

                string tmpPrefix = match.Groups["prefix"].Value;
                int    prefix;
                if (!String.IsNullOrEmpty(tmpPrefix) && Int32.TryParse(tmpPrefix, out prefix))
                {
                    mechanism.Prefix = prefix;
                }

                tmpPrefix = match.Groups["prefix6"].Value;
                if (!String.IsNullOrEmpty(tmpPrefix) && Int32.TryParse(tmpPrefix, out prefix))
                {
                    mechanism.Prefix6 = prefix;
                }

                value = mechanism;
                return(true);
            }
            #endregion

            #region Parse Modifier
            regex = new Regex(@"^(\s)*(?<type>[a-z]+)=(?<domain>[^\s]+)(\s)*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
            match = regex.Match(s);
            if (match.Success)
            {
                SpfModifier modifier = new SpfModifier();

                SpfModifierType type;
                modifier.Type = EnumHelper <SpfModifierType> .TryParse(match.Groups["type"].Value, true, out type) ? type : SpfModifierType.Unknown;

                modifier.Domain = match.Groups["domain"].Value;

                value = modifier;
                return(true);
            }
            #endregion

            value = null;
            return(false);
        }
예제 #4
0
        private SpfQualifier CheckHostInternal(IPAddress ip, string sender, string domain, bool expandExplanation, out string explanation)
        {
            explanation = String.Empty;

            if (String.IsNullOrEmpty(domain))
            {
                return(SpfQualifier.None);
            }

            if (String.IsNullOrEmpty(sender))
            {
                sender = "postmaster@unknown";
            }
            else if (!sender.Contains('@'))
            {
                sender = "postmaster@" + sender;
            }

            SpfQualifier result;
            T            record;

            if (!TryLoadRecords(domain, out record, out result))
            {
                return(result);
            }

            if ((record.Terms == null) || (record.Terms.Count == 0))
            {
                return(SpfQualifier.Neutral);
            }

            if (record.Terms.OfType <SpfModifier>().GroupBy(m => m.Type).Where(g => (g.Key == SpfModifierType.Exp) || (g.Key == SpfModifierType.Redirect)).Any(g => g.Count() > 1))
            {
                return(SpfQualifier.PermError);
            }

            #region Evaluate mechanism
            foreach (SpfMechanism mechanism in record.Terms.OfType <SpfMechanism>())
            {
                if (LookupCount > DnsLookupLimit)
                {
                    return(SpfQualifier.PermError);
                }

                SpfQualifier qualifier = CheckMechanism(mechanism, ip, sender, domain);

                if (qualifier != SpfQualifier.None)
                {
                    result = qualifier;
                    break;
                }
            }
            #endregion

            #region Evaluate modifiers
            if (result == SpfQualifier.None)
            {
                SpfModifier redirectModifier = record.Terms.OfType <SpfModifier>().FirstOrDefault(m => m.Type == SpfModifierType.Redirect);
                if (redirectModifier != null)
                {
                    string redirectDomain = ExpandDomain(redirectModifier.Domain ?? String.Empty, ip, sender, domain);

                    if (String.IsNullOrEmpty(redirectDomain) || (redirectDomain.Equals(domain, StringComparison.InvariantCultureIgnoreCase)))
                    {
                        result = SpfQualifier.PermError;
                    }
                    else
                    {
                        result = CheckHostInternal(ip, sender, redirectDomain, expandExplanation, out explanation);

                        if (result == SpfQualifier.None)
                        {
                            result = SpfQualifier.PermError;
                        }
                    }
                }
            }
            else if ((result == SpfQualifier.Fail) && expandExplanation)
            {
                SpfModifier expModifier = record.Terms.OfType <SpfModifier>().Where(m => m.Type == SpfModifierType.Exp).FirstOrDefault();
                if (expModifier != null)
                {
                    string target = ExpandDomain(expModifier.Domain, ip, sender, domain);

                    if (String.IsNullOrEmpty(target))
                    {
                        explanation = String.Empty;
                    }
                    else
                    {
                        DnsMessage dnsMessage = ResolveDns(target, RecordType.Txt);
                        if ((dnsMessage != null) && (dnsMessage.ReturnCode == ReturnCode.NoError))
                        {
                            TxtRecord txtRecord = dnsMessage.AnswerRecords.OfType <TxtRecord>().FirstOrDefault();
                            if (txtRecord != null)
                            {
                                explanation = ExpandDomain(txtRecord.TextData, ip, sender, domain);
                            }
                        }
                    }
                }
            }
            #endregion

            return((result != SpfQualifier.None) ? result : SpfQualifier.Neutral);
        }
예제 #5
0
파일: SpfTerm.cs 프로젝트: 0x0mar/Xploit
		internal static bool TryParse(string s, out SpfTerm value)
		{
			if (String.IsNullOrEmpty(s))
			{
				value = null;
				return false;
			}

			#region Parse Mechanism
			Regex regex = new Regex(@"^(\s)*(?<qualifier>[~+?-]?)(?<type>[a-z0-9]+)(:(?<domain>[^/]+))?(/(?<prefix>[0-9]+)(/(?<prefix6>[0-9]+))?)?(\s)*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
			Match match = regex.Match(s);
			if (match.Success)
			{
				SpfMechanism mechanism = new SpfMechanism();

				switch (match.Groups["qualifier"].Value)
				{
					case "+":
						mechanism.Qualifier = SpfQualifier.Pass;
						break;
					case "-":
						mechanism.Qualifier = SpfQualifier.Fail;
						break;
					case "~":
						mechanism.Qualifier = SpfQualifier.SoftFail;
						break;
					case "?":
						mechanism.Qualifier = SpfQualifier.Neutral;
						break;

					default:
						mechanism.Qualifier = SpfQualifier.Pass;
						break;
				}

				SpfMechanismType type;
				mechanism.Type = EnumHelper<SpfMechanismType>.TryParse(match.Groups["type"].Value, true, out type) ? type : SpfMechanismType.Unknown;

				mechanism.Domain = match.Groups["domain"].Value;

				string tmpPrefix = match.Groups["prefix"].Value;
				int prefix;
				if (!String.IsNullOrEmpty(tmpPrefix) && Int32.TryParse(tmpPrefix, out prefix))
				{
					mechanism.Prefix = prefix;
				}

				tmpPrefix = match.Groups["prefix6"].Value;
				if (!String.IsNullOrEmpty(tmpPrefix) && Int32.TryParse(tmpPrefix, out prefix))
				{
					mechanism.Prefix6 = prefix;
				}

				value = mechanism;
				return true;
			}
			#endregion

			#region Parse Modifier
			regex = new Regex(@"^(\s)*(?<type>[a-z]+)=(?<domain>[^\s]+)(\s)*$", RegexOptions.Compiled | RegexOptions.IgnoreCase);
			match = regex.Match(s);
			if (match.Success)
			{
				SpfModifier modifier = new SpfModifier();

				SpfModifierType type;
				modifier.Type = EnumHelper<SpfModifierType>.TryParse(match.Groups["type"].Value, true, out type) ? type : SpfModifierType.Unknown;
				modifier.Domain = match.Groups["domain"].Value;

				value = modifier;
				return true;
			}
			#endregion

			value = null;
			return false;
		}