コード例 #1
0
        private EmailMessage CreateFblRequestMessage(FblRequestParameters requestParameters)
        {
            if (requestParameters == null)
            {
                throw new ArgumentNullException("requestParameters", "Cannot create FBL Request Message from null request parameters.");
            }
            EmailMessage emailMessage = EmailMessage.Create();

            this.AddHeader(emailMessage, "X-Version", "1");
            this.AddHeader(emailMessage, "X-GuidCustomer", requestParameters.CustomerGuid.ToString());
            if (requestParameters.IsClassifyRequest())
            {
                this.AddHeader(emailMessage, "X-GuidMail", requestParameters.MailGuid.ToString());
                this.AddHeader(emailMessage, "X-Class", requestParameters.MessageClass);
            }
            else
            {
                RoutingAddress routingAddress = new RoutingAddress(requestParameters.PrimaryEmail);
                this.AddHeader(emailMessage, "X-UserName", routingAddress.LocalPart);
                this.AddHeader(emailMessage, "X-Domain", routingAddress.DomainPart);
                this.AddHeader(emailMessage, "X-OptIn", requestParameters.OptIn ? "1" : "0");
            }
            this.AddEncryptedMessageRoutingHeaderToMessage(emailMessage);
            return(emailMessage);
        }
コード例 #2
0
 public static bool TryGetDecisionMakers(string decisionMakers, out RoutingAddress[] addresses)
 {
     addresses = null;
     if (string.IsNullOrEmpty(decisionMakers))
     {
         ApprovalUtils.diag.TraceDebug(0L, "null or empty decisionMakers string");
         return(false);
     }
     if (decisionMakers.Length > 4096)
     {
         ApprovalUtils.diag.TraceDebug <string>(0L, "decision makers too long {0}", decisionMakers);
         return(false);
     }
     string[] array = decisionMakers.Split(ApprovalUtils.decisionMakerSeparator, 26, StringSplitOptions.RemoveEmptyEntries);
     addresses = new RoutingAddress[array.Length];
     for (int i = 0; i < array.Length; i++)
     {
         addresses[i] = (RoutingAddress)array[i].Trim();
         if (!addresses[i].IsValid || addresses[i] == RoutingAddress.NullReversePath)
         {
             addresses = null;
             return(false);
         }
     }
     return(true);
 }
コード例 #3
0
ファイル: Utils.cs プロジェクト: YHZX2013/exchange_diff
 internal static Utils.EntryType ValidateAddressEntrySyntax(string address)
 {
     try
     {
         RoutingAddress.Parse(address);
         return(Utils.EntryType.SmtpAddress);
     }
     catch (FormatException)
     {
     }
     try
     {
         SmtpDomain.Parse(address);
         return(Utils.EntryType.Domain);
     }
     catch (FormatException)
     {
     }
     if (address == "*")
     {
         return(Utils.EntryType.WildCardedDomain);
     }
     if (address.StartsWith("*.") && address.Length > 2)
     {
         SmtpDomain.Parse(address.Substring(2, address.Length - 2));
         return(Utils.EntryType.WildCardedDomain);
     }
     throw new FormatException(Strings.AddressRewriteUnrecognizedAddress);
 }
コード例 #4
0
        public void AddRecipient(RoutingAddress address, bool sendToThisRecipient)
        {
            Participant participant = new Participant(string.Empty, (string)address, "smtp");
            Recipient   recipient   = this.messageItem.Recipients.Add(participant, RecipientItemType.To);

            recipient[ItemSchema.Responsibility] = sendToThisRecipient;
        }
コード例 #5
0
        /// <summary>
        /// Determines whether there are any recipient-specific settings that
        /// mean the message should not go through mail filtering.
        /// </summary>
        /// <param name="sender">The address of the sender.</param>
        /// <param name="recipient">The address of the recipient.</param>
        /// <param name="server">The server instance.</param>
        /// <returns>Whether the sender is a safe sender.</returns>
        private bool ShouldBypassFilter(RoutingAddress sender, RoutingAddress recipient, SmtpServer server)
        {
            if (server == null || sender == null || recipient == null)
            {
                return(false);
            }

            AddressBook addressBook = server.AddressBook;

            if (addressBook != null)
            {
                AddressBookEntry addressBookEntry = addressBook.Find(recipient);
                if (addressBookEntry != null)
                {
                    if (addressBookEntry.AntispamBypass ||
                        addressBookEntry.IsSafeSender(sender) ||
                        addressBookEntry.IsSafeRecipient(recipient))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
コード例 #6
0
        internal static bool TryGetRoutingAddressFromAD(IADRecipientCache recipientCache, string address, string type, out RoutingAddress result)
        {
            ProxyAddress proxyAddress = ProxyAddress.Parse(type, address);

            if (proxyAddress is InvalidProxyAddress)
            {
                TraceHelper.StoreDriverTracer.TracePass(TraceHelper.MessageProbeActivityId, 0L, "Proxy address is invalid");
                return(false);
            }
            Result <ADRawEntry> result2 = recipientCache.FindAndCacheRecipient(proxyAddress);

            if (result2.Data != null)
            {
                string primarySmtpAddress = SubmissionItemUtils.GetPrimarySmtpAddress(result2.Data);
                if (string.IsNullOrEmpty(primarySmtpAddress))
                {
                    TraceHelper.StoreDriverTracer.TracePass <string, string>(TraceHelper.MessageProbeActivityId, 0L, "Primary SMTP address for \"{0}:{1}\" is invalid or missing", address, type);
                    return(false);
                }
                TraceHelper.StoreDriverTracer.TracePass <string>(TraceHelper.MessageProbeActivityId, 0L, "Use primary smtp address {0}", primarySmtpAddress);
                result = new RoutingAddress(primarySmtpAddress);
                return(true);
            }
            else
            {
                if (result2.Error != null && result2.Error != ProviderError.NotFound)
                {
                    TraceHelper.StoreDriverTracer.TracePass <ProviderError>(TraceHelper.MessageProbeActivityId, 0L, "Failed to look up due to error :{0}", result2.Error);
                    return(false);
                }
                TraceHelper.StoreDriverTracer.TracePass(TraceHelper.MessageProbeActivityId, 0L, "The address doesn't exist in AD");
                return(false);
            }
        }
        public void RcptToHandler(ReceiveCommandEventSource source, RcptCommandEventArgs rcptArgs)
        {
            // Check to see if this is an internal message
            if (!rcptArgs.SmtpSession.IsExternalConnection)
            {
                return;
            }

            string[] parts = rcptArgs.RecipientAddress.LocalPart.Split('+');

            if (parts.Length < 1 || (_addressBook == null) || (_addressBook.Find(rcptArgs.RecipientAddress) != null))
            {
                return;
            }

            RoutingAddress emailAddress = new RoutingAddress(String.Join("+", parts, 0, (parts.Length - 1)) + "@" + rcptArgs.RecipientAddress.DomainPart);

            if (!emailAddress.IsValid)
            {
                return;
            }

            rcptArgs.RecipientAddress = emailAddress;

            return;
        }
コード例 #8
0
        internal static EmailMessage GenerateDecisionNotTakenNotification(RoutingAddress from, RoutingAddress recipient, string subject, string threadIndex, string threadTopic, string decisionMaker, bool?decision, ExDateTime?decisionTime, Header acceptLanguageHeader, Header contentLanguageHeader, CultureInfo fallbackCulture)
        {
            if (from.Equals(RoutingAddress.NullReversePath) || recipient.Equals(RoutingAddress.NullReversePath) || !from.IsValid || !recipient.IsValid)
            {
                return(null);
            }
            DsnHumanReadableWriter dsnHumanReadableWriter      = Components.DsnGenerator.DsnHumanReadableWriter;
            ApprovalInformation    decisionConflictInformation = dsnHumanReadableWriter.GetDecisionConflictInformation(subject, decisionMaker, decision, decisionTime, acceptLanguageHeader, contentLanguageHeader, fallbackCulture);
            EmailMessage           emailMessage = EmailMessage.Create(BodyFormat.Html, false, decisionConflictInformation.MessageCharset.Name);

            emailMessage.From = new EmailRecipient(string.Empty, from.ToString());
            emailMessage.To.Add(new EmailRecipient(string.Empty, recipient.ToString()));
            emailMessage.Subject = decisionConflictInformation.Subject;
            using (Stream contentWriteStream = emailMessage.Body.GetContentWriteStream())
            {
                dsnHumanReadableWriter.WriteHtmlModerationBody(contentWriteStream, decisionConflictInformation);
                contentWriteStream.Flush();
            }
            Header header = Header.Create("X-MS-Exchange-Organization-SCL");

            header.Value = "-1";
            emailMessage.RootPart.Headers.AppendChild(header);
            Header header2 = (TextHeader)Header.Create("Thread-Index");

            header2.Value = threadIndex;
            emailMessage.RootPart.Headers.AppendChild(header2);
            Header header3 = (TextHeader)Header.Create("Thread-Topic");

            header3.Value = threadTopic;
            emailMessage.RootPart.Headers.AppendChild(header3);
            return(emailMessage);
        }
コード例 #9
0
        /// <summary>
        /// Handles the "RCPT TO:" SMTP command
        /// </summary>
        /// <param name="source">The event source.</param>
        /// <param name="eodArgs">The event arguments.</param>
        public void RcptToHandler(ReceiveCommandEventSource source, RcptCommandEventArgs rcptArgs)
        {
            //check if recipient exists in exchange address book
            if (this.addressBook != null && this.addressBook.Find(rcptArgs.RecipientAddress) != null)
            {
                //recipient is an existing user
                return;
            }

            string replaceWith = null;

            foreach (DomainElement d in domainList)
            {
                if (!d.Regex && d.Name.ToLower().Equals(rcptArgs.RecipientAddress.DomainPart.ToLower()))
                {
                    replaceWith = d.Address;
                    break;
                }
                else if (d.Regex)
                {
                    if (d.RegexCompiled.Match(rcptArgs.RecipientAddress.ToString().ToLower()).Success)
                    {
                        replaceWith = d.RegexCompiled.Replace(rcptArgs.RecipientAddress.ToString().ToLower(), d.Address.ToLower());

                        break;
                    }
                }
            }

            if (replaceWith != null)
            {
                RoutingAddress catchAllAddress = new RoutingAddress(replaceWith);

                if (this.databaseConnector == null || !this.databaseConnector.isBlocked(rcptArgs.RecipientAddress.ToString().ToLower()))
                {
                    Logger.LogInformation("Caught: " + rcptArgs.RecipientAddress.ToString().ToLower() + " -> " + catchAllAddress.ToString(), 100);
                    // on Exchange 2013 SP1 it seems the RcptToHandler is called multiple times for the same MailItem
                    // hash code is not guaranteed to be unique. Add time to fix uniqueness
                    string itemId = rcptArgs.MailItem.GetHashCode().ToString() + rcptArgs.MailItem.FromAddress.ToString();
                    if (!origToMapping.ContainsKey(itemId))
                    {
                        string[] addrs = new string[] { rcptArgs.RecipientAddress.ToString().ToLower(), catchAllAddress.ToString().ToLower() };
                        origToMapping.Add(itemId, addrs);
                    }
                    rcptArgs.RecipientAddress = catchAllAddress;
                }
                else
                {
                    // reject email, because address is blocked
                    Logger.LogInformation("Recipient blocked: " + rcptArgs.RecipientAddress.ToString().ToLower(), 200);

                    if (CatchAllFactory.AppSettings.RejectIfBlocked)
                    {
                        source.RejectCommand(CatchAllAgent.rejectResponse);
                    }
                }
            }

            return;
        }
コード例 #10
0
        public void Add(string addressOrDomain)
        {
            if (string.IsNullOrEmpty(addressOrDomain))
            {
                return;
            }
            if (addressOrDomain[0] == '@')
            {
                addressOrDomain = addressOrDomain.Substring(1);
                if (!SmtpAddress.IsValidDomain(addressOrDomain))
                {
                    return;
                }
            }
            else if (!RoutingAddress.IsValidAddress(addressOrDomain))
            {
                return;
            }
            uint key = (uint)this.hasher.GetHash(addressOrDomain);

            if (this.List.ContainsKey(key))
            {
                return;
            }
            this.List.Add(key, 0);
        }
コード例 #11
0
 internal void RemoveRecipient(long sessionId, RoutingAddress address)
 {
     this.RwLock.EnterUpgradeableReadLock();
     try
     {
         if (this.session.Count != 0)
         {
             if (!this.session.ContainsKey(sessionId))
             {
                 throw new ArgumentException(string.Format("Failed to remove recipient. Session Id={0} not found.", sessionId));
             }
             this.RwLock.EnterWriteLock();
             try
             {
                 int num = this.session[sessionId].Recipients[address];
                 if (num == 1)
                 {
                     this.session[sessionId].Recipients.Remove(address);
                 }
                 else
                 {
                     this.session[sessionId].Recipients[address] = num - 1;
                 }
             }
             finally
             {
                 this.RwLock.ExitWriteLock();
             }
         }
     }
     finally
     {
         this.RwLock.ExitUpgradeableReadLock();
     }
 }
コード例 #12
0
 private EmailItem(Object underlyingObject, EmailMessage message, RoutingAddress fromAddress,
                   Stream mimeReadStream)
 {
     _underlyingObject = underlyingObject;
     Message = message;
     FromAddress = fromAddress;
     MimeReadStream = mimeReadStream;
 }
コード例 #13
0
 private EmailItem(Object underlyingObject, EmailMessage message, RoutingAddress fromAddress,
                   Stream mimeReadStream)
 {
     _underlyingObject = underlyingObject;
     Message           = message;
     FromAddress       = fromAddress;
     MimeReadStream    = mimeReadStream;
 }
コード例 #14
0
 private ApprovalEngine(EmailMessage incomingMessage, RoutingAddress sender, RoutingAddress recipient, MessageItem messageItem, MbxTransportMailItem mbxTransportMailItem, ApprovalEngine.ApprovalRequestCreateDelegate requestCreate)
 {
     this.message              = incomingMessage;
     this.sender               = sender;
     this.recipient            = recipient;
     this.requestCreate        = requestCreate;
     this.messageItem          = messageItem;
     this.mbxTransportMailItem = mbxTransportMailItem;
 }
コード例 #15
0
 public static string RedactRoutingAddressIfNecessary(RoutingAddress address, bool isNecessary)
 {
     ArgumentValidator.ThrowIfNullOrEmpty("address.ToString()", address.ToString());
     if (isNecessary)
     {
         return(SuppressingPiiData.Redact(address).ToString());
     }
     return(address.ToString());
 }
コード例 #16
0
        // Get the usage record, creating it if necessary.
        /// This method assumes that the caller has locked the dictionary.
        private BandwidthUsageRecord GetUsageRecord(RoutingAddress primaryAddress)
        {
            if (!BandwidthLogger.records.ContainsKey(primaryAddress))
            {
                BandwidthLogger.records.Add(primaryAddress, new BandwidthUsageRecord());
            }

            return(BandwidthLogger.records[primaryAddress]);
        }
コード例 #17
0
        public static SmtpDomain GetDomainPart(RoutingAddress address)
        {
            string domainPart = address.DomainPart;

            if (domainPart != null)
            {
                return(new SmtpDomain(domainPart, false));
            }
            return(null);
        }
コード例 #18
0
        protected override void InternalProcessRecord()
        {
            RoutingAddress purportedResponsibleAddress = new RoutingAddress("postmaster", this.purportedResponsibleDomain.Domain);

            this.validator  = new SenderIdValidator(new TestSenderId.TestServer());
            this.resetEvent = new AutoResetEvent(false);
            this.validator.BeginCheckHost(this.ipAddress, purportedResponsibleAddress, (this.helloDomain != null) ? this.helloDomain : string.Empty, true, new AsyncCallback(this.CheckHostCallback), null);
            this.resetEvent.WaitOne();
            base.WriteObject(this.result);
        }
コード例 #19
0
        public new static AutoDiscoverSmtpDomain GetDomainPart(RoutingAddress address)
        {
            string domainPart = address.DomainPart;

            if (domainPart != null)
            {
                return(new AutoDiscoverSmtpDomain(domainPart, false));
            }
            return(null);
        }
コード例 #20
0
        public static RoutingAddress Redact(RoutingAddress address)
        {
            if (string.IsNullOrWhiteSpace(address.LocalPart) || string.IsNullOrWhiteSpace(address.DomainPart))
            {
                return(address);
            }
            string text;
            string text2;

            return(new RoutingAddress(SuppressingPiiData.Redact(address.LocalPart.ToUpperInvariant(), out text, out text2), address.DomainPart));
        }
コード例 #21
0
        // Token: 0x0600003B RID: 59 RVA: 0x000041DC File Offset: 0x000023DC
        private bool TryGetOriginalSender(MessageItem messageItem, out RoutingAddress originalSender)
        {
            RoutingAddress routingAddress = (RoutingAddress)messageItem.GetValueOrDefault <string>(MessageItemSchema.ApprovalRequestor);

            if (!routingAddress.IsValid || routingAddress == RoutingAddress.NullReversePath)
            {
                ModeratedDLApplication.diag.TraceDebug((long)this.GetHashCode(), "Approval requestor not present or it is invalid");
                return(false);
            }
            originalSender = routingAddress;
            return(true);
        }
コード例 #22
0
        /// <summary>
        /// The core of the MailFilter algorithm. Determines whether
        /// a triplet matches a known sender/recipient relationship and should
        /// be accepted.
        /// </summary>
        /// <param name="remoteIP">The remote host's IP address.</param>
        /// <param name="sender">The sender's address.</param>
        /// <param name="recipient">The recipient's address.</param>
        /// <returns>Whether the triplet is verified by the MailFilter.</returns>
        private bool VerifyTriplet(IPAddress remoteIP, RoutingAddress sender, RoutingAddress recipient)
        {
            // Create a MailFilterEntry object for the current session.
            // This code uses senderAddress.DomainPart to truncate
            // the sender's address to use only the domain. To use the full
            // address, use ToString() as with recipient.
            UInt64 tripletHash = this.HashTriplet(
                remoteIP,
                sender.DomainPart,
                recipient.ToString());

            MailFilterEntry currentEntry = new MailFilterEntry(tripletHash);

            // Determine whether a matching entry is in the verified database.
            // If it is, save with an updated time stamp.
            // This ensures that the most recent entries are
            // at the start of the bucket lists in the array tables.
            if (this.verifiedDatabase.GetEntry(currentEntry.TripletHash) != null)
            {
                currentEntry.TimeStamp = DateTime.UtcNow;
                this.verifiedDatabase.SaveEntry(currentEntry);
                return(true);
            }

            // If the entry is in the unverified table passed in
            // the initial blocking period, remove it.
            MailFilterEntry entry = this.unverifiedDatabase.GetEntry(currentEntry.TripletHash);

            if (entry != null)
            {
                if (entry.IsPastPeriod(this.settings.InitialBlockingPeriod))
                {
                    this.verifiedDatabase.SaveEntry(currentEntry);
                    this.unverifiedDatabase.DeleteEntry(currentEntry);
                    return(true);
                }
                else
                {
                    // The entry was in the table of unverified entries,
                    // but the blocking period has not passed yet.
                    return(false);
                }
            }
            else
            {
                // The triplet is not in either database. Send a rejection and
                // put it in the unverified database.
                this.unverifiedDatabase.SaveEntry(currentEntry);
                return(false);
            }
        }
コード例 #23
0
        /// <summary>
        /// Invoked by Exchange when an SMTP RCPT command is sent.
        /// This is the command that gives you the recipient
        /// address in the SMTP envelope.
        /// </summary>
        /// <param name="source">The source of this event.</param>
        /// <param name="rcptArgs">Arguments for this event.</param>
        public void OnRcptCommandHandler(ReceiveCommandEventSource source, RcptCommandEventArgs rcptArgs)
        {
            // Check the parameter values.
            if (source == null || rcptArgs == null)
            {
                return;
            }

            // Skip filtering for internal mail.
            if (!rcptArgs.SmtpSession.IsExternalConnection)
            {
                return;
            }

            // Retrieve data used to identify this message.
            this.senderAddress    = rcptArgs.MailItem.FromAddress;
            this.senderIP         = rcptArgs.SmtpSession.RemoteEndPoint.Address;
            this.recipientAddress = rcptArgs.RecipientAddress;

            // If the sender domain is null, you will have to wait until
            // after the EndOfData event to check the message.
            if (RoutingAddress.NullReversePath.Equals(this.senderAddress))
            {
                this.testOnEndOfHeaders = true;
                return;
            }

            // Skip temporary blocking for safe senders.
            if (this.ShouldBypassFilter(this.senderAddress, this.recipientAddress, this.server))
            {
                return;
            }

            // Check the database to determine whether the message should be rejected
            // or let through.
            if (!this.VerifyTriplet(this.senderIP, this.senderAddress, this.recipientAddress))
            {
                source.RejectCommand(DelayResponseMessage);
            }

            // Finally, check a few rows
            // for expired entries that need to be cleaned up.
            this.verifiedDatabase.RetireOldEntries(
                this.settings.CleanRowCount,
                this.settings.VerifiedExpirationTime);

            this.unverifiedDatabase.RetireOldEntries(
                this.settings.CleanRowCount,
                this.settings.UnverifiedExpirationTime);
        }
コード例 #24
0
ファイル: ADUtils.cs プロジェクト: YHZX2013/exchange_diff
        public static bool IsExternalPartner(RoutingAddress routingAddress, OrganizationId organizationId)
        {
            if (organizationId == null)
            {
                throw new ArgumentNullException("emailAddress");
            }
            if (string.IsNullOrEmpty(routingAddress.DomainPart))
            {
                throw new ArgumentException(string.Format("routingAddress.DomainPart is null or empty for the routingaddress:{0}.", routingAddress));
            }
            OwaPerTenantTransportSettings owaPerTenantTransportSettings = ADCacheUtils.GetOwaPerTenantTransportSettings(organizationId);

            return(owaPerTenantTransportSettings.IsTLSSendSecureDomain(routingAddress.DomainPart));
        }
コード例 #25
0
        public static bool IsMemberOf(RmsClientManagerContext clientContext, string recipientAddress, string groupAddress)
        {
            ArgumentValidator.ThrowIfNull("recipientAddress", recipientAddress);
            ArgumentValidator.ThrowIfNullOrEmpty("groupAddress", groupAddress);
            if (!ServerManager.instance.isHostingInstance)
            {
                throw new InvalidOperationException("Can't call IsMemberOf directly as ServerManager is NOT allowed to host in current calling process");
            }
            if (!SmtpAddress.IsValidSmtpAddress(recipientAddress))
            {
                ServerManagerLog.LogEvent(ServerManagerLog.Subcomponent.DirectoryServiceProvider, ServerManagerLog.EventType.Error, clientContext, string.Format("recipientAddress {0} is invalid SMTP Address", recipientAddress));
                return(false);
            }
            if (!RoutingAddress.IsValidAddress(groupAddress))
            {
                ServerManagerLog.LogEvent(ServerManagerLog.Subcomponent.DirectoryServiceProvider, ServerManagerLog.EventType.Error, clientContext, string.Format("groupAddress {0} is invalid SMTP Address", groupAddress));
                return(false);
            }
            ServerManager.InitializeIfNeeded();
            bool result;

            if (ServerManager.CheckForSpecialRmsOnlineTenantMembershipQuery(recipientAddress, groupAddress, out result))
            {
                return(result);
            }
            ADRawEntry adrawEntry = clientContext.ResolveRecipient(recipientAddress);

            if (adrawEntry == null)
            {
                ServerManagerLog.LogEvent(ServerManagerLog.Subcomponent.DirectoryServiceProvider, ServerManagerLog.EventType.Verbose, clientContext, string.Format("Failed to resolve recipientAddress {0} in Active Directory. Treat IsMemberOf for {1} against {2} as false", recipientAddress, recipientAddress, groupAddress));
                return(false);
            }
            ProxyAddressCollection proxyAddressCollection = (ProxyAddressCollection)adrawEntry[ADRecipientSchema.EmailAddresses];
            SmtpProxyAddress       other = new SmtpProxyAddress(groupAddress, true);

            foreach (ProxyAddress proxyAddress in proxyAddressCollection)
            {
                if (proxyAddress.Equals(other))
                {
                    ServerManagerLog.LogEvent(ServerManagerLog.Subcomponent.DirectoryServiceProvider, ServerManagerLog.EventType.Success, clientContext, string.Format("IsMemberOf return true as proxyAddress {0} is the same is groupAddress {1}", recipientAddress, groupAddress));
                    return(true);
                }
            }
            RoutingAddress groupKey = new RoutingAddress(groupAddress);
            bool           result2  = ServerManager.instance.isMemberOfResolver.IsMemberOf(clientContext.RecipientSession, adrawEntry.Id, groupKey);

            ServerManagerLog.LogEvent(ServerManagerLog.Subcomponent.DirectoryServiceProvider, ServerManagerLog.EventType.Success, clientContext, string.Format("IsMemberOf return {0} for proxyAddress {1} against groupAddress {2}", result2.ToString(CultureInfo.InvariantCulture), recipientAddress, groupAddress));
            return(result2);
        }
コード例 #26
0
 private bool TryParseEmail(string address, out string result)
 {
     if (string.IsNullOrEmpty(address))
     {
         result = null;
         return(false);
     }
     if (!RoutingAddress.IsValidAddress(address))
     {
         result = null;
         return(false);
     }
     result = RoutingAddress.Parse(address).ToString();
     return(true);
 }
コード例 #27
0
 public bool CheckAndTrackThrottleRecipient(RoutingAddress recipient, long smtpSessionId, string mdbName, Guid tenantId)
 {
     ArgumentValidator.ThrowIfNullOrEmpty("recipient.ToString()", recipient.ToString());
     ArgumentValidator.ThrowIfNullOrEmpty("mdbName", mdbName);
     ArgumentValidator.ThrowIfNull("tenantId", tenantId);
     if (!DeliveryThrottling.deliveryRecipientThreadMap.TryCheckAndIncrement(recipient, (ulong)smtpSessionId, string.Empty))
     {
         DeliveryThrottling.Diag.TraceDebug <string, int>(0L, "Delivery for recipient \"{0}\" is skipped as it exceeds delivery recipient thread limit of {1}", recipient.ToString(), DeliveryConfiguration.Instance.Throttling.RecipientThreadLimit);
         this.DeliveryThrottlingLogWorker.TrackRecipientThrottle(true, Utils.RedactRoutingAddressIfNecessary(recipient, Utils.IsRedactionNecessary()), tenantId, mdbName, (double)DeliveryConfiguration.Instance.Throttling.RecipientThreadLimit);
         return(false);
     }
     this.DeliveryThrottlingLogWorker.TrackRecipientThrottle(false, Utils.RedactRoutingAddressIfNecessary(recipient, Utils.IsRedactionNecessary()), tenantId, mdbName, (double)DeliveryConfiguration.Instance.Throttling.RecipientThreadLimit);
     DeliveryThrottling.sessionMap.AddRecipient(smtpSessionId, recipient);
     return(true);
 }
コード例 #28
0
        // Token: 0x060014CD RID: 5325 RVA: 0x00049D1C File Offset: 0x00047F1C
        public override bool Evaluate(RulesEvaluationContext baseContext)
        {
            BaseTransportRulesEvaluationContext baseTransportRulesEvaluationContext = (BaseTransportRulesEvaluationContext)baseContext;

            if (baseTransportRulesEvaluationContext == null)
            {
                throw new ArgumentException("context is either null or not of type: BaseTransportRulesEvaluationContext");
            }
            baseTransportRulesEvaluationContext.PredicateName = this.Name;
            ShortList <string> shortList = (ShortList <string>)base.Property.GetValue(baseTransportRulesEvaluationContext);
            List <string>      matches   = new List <string>();
            bool flag = false;

            if (shortList != null && shortList.Count > 0)
            {
                List <RoutingAddress> list = new List <RoutingAddress>(shortList.Count);
                foreach (string address in shortList)
                {
                    if (RoutingAddress.IsValidAddress(address))
                    {
                        list.Add((RoutingAddress)address);
                    }
                }
                switch (this.Type)
                {
                case ScopeType.Internal:
                    flag = ADUtils.IsAnyInternal(list, ((OwaRulesEvaluationContext)baseTransportRulesEvaluationContext).OrganizationId, base.EvaluationMode, ref matches);
                    break;

                case ScopeType.External:
                    flag = ADUtils.IsAnyExternal(list, ((OwaRulesEvaluationContext)baseTransportRulesEvaluationContext).OrganizationId, base.EvaluationMode, ref matches);
                    break;

                case ScopeType.ExternalPartner:
                    flag = ADUtils.IsAnyExternalPartner(list, ((OwaRulesEvaluationContext)baseTransportRulesEvaluationContext).OrganizationId, base.EvaluationMode, ref matches);
                    break;

                case ScopeType.ExternalNonPartner:
                    flag = ADUtils.IsAnyExternalNonPartner(list, ((OwaRulesEvaluationContext)baseTransportRulesEvaluationContext).OrganizationId, base.EvaluationMode, ref matches);
                    break;

                default:
                    throw new ArgumentException(string.Format("this.Type:{0} is not a valid ScopeType.", this.Type));
                }
            }
            base.UpdateEvaluationHistory(baseContext, flag, matches, 0);
            return(flag);
        }
コード例 #29
0
ファイル: ADUtils.cs プロジェクト: YHZX2013/exchange_diff
        public static bool IsInternal(RoutingAddress routingAddress, OrganizationId organizationId)
        {
            if (organizationId == null)
            {
                throw new ArgumentNullException("organizationId");
            }
            if (string.IsNullOrEmpty(routingAddress.DomainPart))
            {
                throw new ArgumentException(string.Format("routingAddress.DomainPart is null or empty for the routingaddress:{0}.", routingAddress));
            }
            OwaPerTenantAcceptedDomains owaPerTenantAcceptedDomains = ADCacheUtils.GetOwaPerTenantAcceptedDomains(organizationId);
            OwaPerTenantRemoteDomains   owaPerTenantRemoteDomains   = ADCacheUtils.GetOwaPerTenantRemoteDomains(organizationId);
            IsInternalResolver          isInternalResolver          = new IsInternalResolver(organizationId, new IsInternalResolver.GetAcceptedDomainCollectionDelegate(owaPerTenantAcceptedDomains.GetAcceptedDomainMap), new IsInternalResolver.GetRemoteDomainCollectionDelegate(owaPerTenantRemoteDomains.GetRemoteDomainMap));

            return(isInternalResolver.IsInternal(new RoutingDomain(routingAddress.DomainPart)));
        }
コード例 #30
0
        internal static JournalNdrValidationCheckResult ValidateJournalNdrMailboxSetting(IConfigDataProvider dataProvider, SmtpAddress journalNdrToAddress)
        {
            ADJournalRuleStorageManager adjournalRuleStorageManager = null;
            bool flag = false;

            try
            {
                adjournalRuleStorageManager = new ADJournalRuleStorageManager("JournalingVersioned", dataProvider);
            }
            catch (RuleCollectionNotInAdException)
            {
            }
            if (adjournalRuleStorageManager != null)
            {
                adjournalRuleStorageManager.LoadRuleCollection();
                RoutingAddress value = new RoutingAddress(journalNdrToAddress.ToString());
                if (value == RoutingAddress.NullReversePath)
                {
                    if (adjournalRuleStorageManager.Count > 0)
                    {
                        return(JournalNdrValidationCheckResult.JournalNdrCannotBeNullReversePath);
                    }
                }
                else
                {
                    foreach (Microsoft.Exchange.MessagingPolicies.Rules.Rule rule in adjournalRuleStorageManager.GetRuleCollection())
                    {
                        TransportRule     transportRule     = (TransportRule)rule;
                        JournalRuleObject journalRuleObject = new JournalRuleObject();
                        journalRuleObject.Deserialize(transportRule as JournalingRule);
                        if (journalRuleObject.Recipient != null && journalRuleObject.Recipient != null && journalNdrToAddress == journalRuleObject.Recipient.Value)
                        {
                            return(JournalNdrValidationCheckResult.JournalNdrExistInJournalRuleRecipient);
                        }
                        if (journalNdrToAddress == journalRuleObject.JournalEmailAddress)
                        {
                            flag = true;
                        }
                    }
                }
            }
            if (!flag)
            {
                return(JournalNdrValidationCheckResult.JournalNdrValidationPassed);
            }
            return(JournalNdrValidationCheckResult.JournalNdrExistInJournalRuleJournalEmailAddress);
        }
コード例 #31
0
        public bool Contains(RoutingAddress address)
        {
            if (!AddressHashes.IsValidAddress(address))
            {
                return(false);
            }
            uint key = (uint)this.hasher.GetHash((string)address);

            if (this.List.ContainsKey(key))
            {
                return(true);
            }
            string domainPart = address.DomainPart;

            key = (uint)this.hasher.GetHash(domainPart);
            return(this.List.ContainsKey(key));
        }
コード例 #32
0
ファイル: PlusAgent.cs プロジェクト: jmdevince/PlusAgent
        public void RcptToHandler(ReceiveCommandEventSource source, RcptCommandEventArgs rcptArgs)
        {
            // Check to see if this is an internal message
            if (!rcptArgs.SmtpSession.IsExternalConnection)
            {
                return;
            }

            string[] parts = rcptArgs.RecipientAddress.LocalPart.Split('+');

            if (parts.Length < 1 || (_addressBook == null) || (_addressBook.Find(rcptArgs.RecipientAddress) != null))
            {
                return;
            }

            RoutingAddress emailAddress = new RoutingAddress(String.Join("+", parts, 0, (parts.Length - 1)) + "@" + rcptArgs.RecipientAddress.DomainPart);
            if(!emailAddress.IsValid) {
                return;
            }

            rcptArgs.RecipientAddress = emailAddress;

            return;
        }
コード例 #33
0
 public bool TestVerify(IPAddress senderIP, RoutingAddress sender, RoutingAddress recipient)
 {
     return this.VerifyTriplet(senderIP, sender, recipient);
 }
コード例 #34
0
        private bool ShouldBypassFilter(RoutingAddress sender, RoutingAddress recipient, IPAddress senderIP)
        {
            if (this.server == null || sender == null || recipient == null)
            {
                return false;
            }
            
            
            // Check Exchange bypasses
            AddressBook addressBook = this.server.AddressBook;
            if (addressBook != null)
            {
                AddressBookEntry addressBookEntry = addressBook.Find(recipient);
                if (addressBookEntry != null)
                {
                    if (addressBookEntry.AntispamBypass || addressBookEntry.IsSafeSender(sender) || addressBookEntry.IsSafeRecipient(recipient))
                    {
                        return true;
                    }
                }
            }

            // IPs (Can have netmask)
            foreach (String ip in this.settings.WhitelistIPs)
            {
                try
                {
                    IPAddressRange range = IPAddressRange.Parse(ip);
                    if (range.Contains(senderIP))
                    {
                        return true;
                    }
                }
                catch
                {
                    // Do Nothing
                }
            }

            // Do a reverse DNS lookup on the IP
            try
            {
                IPHostEntry hostInfo = Dns.GetHostEntry(senderIP);
                string reversedHostname = Reverse(hostInfo.HostName);
                foreach (String domain in this.settings.WhitelistClients)
                {
                    // Test for regex
                    if (domain.IndexOf('/') == 0)
                    {
                        try
                        {
                            Regex domaintest = new Regex(domain);
                            if (domaintest.IsMatch(hostInfo.HostName)) {
                                return true;
                            }
                        }
                        catch
                        {
                            continue;
                        }
                        continue;
                    }

                    // Test for a literal match
                    if (hostInfo.HostName == domain)
                    {
                        return true;
                    }

                    // Test for any subdomain match
                    string reversed = Reverse("."+domain);
                    if (reversedHostname.IndexOf(reversed) == 0) {
                        return true;
                    }
                }
            }
            catch
            {
                // Do nothing
            }

            return false;
        }
コード例 #35
0
        private bool VerifyTriplet(IPAddress remoteIP, RoutingAddress sender, RoutingAddress recipient)
        {

            String tripletHash = this.HashTriplet(remoteIP, sender.DomainPart, recipient.ToString());

            // Check to see if we are already aware of this hash
            if (this.greylistDatabase.Contains(tripletHash))
            {
                // We are aware of it. Check to see if it's already been confirmed
                if (((GreyListEntry)this.greylistDatabase[tripletHash]).Confirmed)
                {
                    // Update the last seen
                    ((GreyListEntry)this.greylistDatabase[tripletHash]).Count += 1;
                    ((GreyListEntry)this.greylistDatabase[tripletHash]).LastSeen = DateTime.UtcNow;
                    
                    // Go ahead and return true
                    return true;
                }

                // We are aware of it but it's not confirmed, Check to see if the blocking period has passed
                if (DateTime.UtcNow.Subtract(this.settings.GreylistingPeriod) > ((GreyListEntry)this.greylistDatabase[tripletHash]).LastSeen)
                {
                    ((GreyListEntry)this.greylistDatabase[tripletHash]).Confirmed = true;
                    ((GreyListEntry)this.greylistDatabase[tripletHash]).LastSeen = DateTime.UtcNow;
                    return true;
                }

                // We are aware and the blocking period has NOT passed.
                return false;
            }
            // We aren't aware of it, create an entry
            greylistDatabase.Add(tripletHash, new GreyListEntry(remoteIP, sender.DomainPart, recipient.ToString()));

            return false;

        }
コード例 #36
0
        public void OnEndOfHeaderHandler(ReceiveMessageEventSource source, EndOfHeadersEventArgs eodArgs)
        {
            if (this.testOnEndOfHeaders)
            {
                RoutingAddress senderAddress;
                // Reset the flag.
                this.testOnEndOfHeaders = false;

                // Get the sender address from the message header.
                Header fromAddress = eodArgs.Headers.FindFirst(HeaderId.From);
                if (fromAddress != null)
                {
                    senderAddress = new RoutingAddress(fromAddress.Value);
                }
                else
                {
                    this.logLine("FROM=, TO=Multiple, REMOTE=" + eodArgs.SmtpSession.RemoteEndPoint.Address.ToString() + ", STATE=Greylist, REASON=No from address.", 2);                
                    // No sender address, reject the message.
                    source.RejectMessage(DelayResponseMessage);
                    return;
                }

                // Determine whether any of the recipients should be rejected, and if so, reject them all.
                bool rejectAll = false;
                foreach (EnvelopeRecipient currentRecipient in eodArgs.MailItem.Recipients)
                {
                    if (this.ShouldBypassFilter(senderAddress, currentRecipient.Address, eodArgs.SmtpSession.RemoteEndPoint.Address))
                    {
                        continue;
                    }
                    if (!this.VerifyTriplet(eodArgs.SmtpSession.RemoteEndPoint.Address, senderAddress, currentRecipient.Address))
                    {
                        this.logLine("FROM="+senderAddress.ToString()+", TO="+currentRecipient.Address.ToString()+", REMOTE=" + eodArgs.SmtpSession.RemoteEndPoint.Address.ToString() + ", STATE=Greylist, REASON=Triplet verify failed.", 2);  
                        rejectAll = true;
                    }
                }

                if (rejectAll)
                {
                    this.logLine("FROM=" + senderAddress.ToString() + ", TO=MANY, REMOTE=" + eodArgs.SmtpSession.RemoteEndPoint.Address.ToString() + ", STATE=Greylist, REASON=One or more recipients failed Triplet verification.", 2);                
                    source.RejectMessage(DelayResponseMessage);
                    return;
                }
                this.logLine("FROM=" + senderAddress.ToString() + ", TO=MANY, REMOTE=" + eodArgs.SmtpSession.RemoteEndPoint.Address.ToString() + ", STATE=Accept, REASON=Triplets Match.", 2);                
                    
            }
        }
コード例 #37
0
        /// <summary>
        /// Load the configuration file. If any errors occur, does nothing.
        /// </summary>
        private void Load()
        {
            Trace.WriteLine("");
            Trace.WriteLine(String.Format("{0:s} Configuration Change. Reloading.", DateTime.Now));

            // Load the configuration
            var doc = new XmlDocument();
            bool docLoaded = false;
            string fileName = Path.Combine(
                _configDirectory,
                ConfigFileName);

            try
            {
                doc.Load(fileName);
                docLoaded = true;
            }
            catch (FileNotFoundException)
            {
                Trace.WriteLine("Configuration file not found: {0}", fileName);
            }
            catch (XmlException e)
            {
                Trace.WriteLine("XML error: {0}", e.Message);
            }
            catch (IOException e)
            {
                Trace.WriteLine("IO error: {0}", e.Message);
            }

            // If a failure occured, ignore and simply return
            if (!docLoaded || doc.FirstChild == null)
            {
                Trace.WriteLine("Configuration error: either no file or XML error.");
                return;
            }

            // Create a dictionary to hold the mappings
            var map = new Dictionary<string, RoutingAddress>(100);

            // List to hold banned emails
            var banned = new List<string>();

            // Track whether there are invalid entries
            bool invalidEntries = false;

            // get all the <banned ... /> elements
            foreach (XmlNode node in doc.GetElementsByTagName("banned"))
            {
                // Get the banned email address
                XmlAttribute address = node.Attributes["address"];

                // Is the address valid as an SMTP address?
                if (!RoutingAddress.IsValidAddress(address.Value))
                {
                    invalidEntries = true;
                    Trace.WriteLine(String.Format("Reject configuration due to invalid ban address: {0}", address));
                    break;
                }

                // Add the string to the List
                banned.Add(address.Value);
                Trace.WriteLine(String.Format(" Banning: {0}", address.Value));
            }

            // get all the <redirect ... /> elements
            foreach (XmlNode node in doc.GetElementsByTagName("redirect"))
            {
                // Get the regex pattern and the redirect email address
                XmlAttribute pattern = node.Attributes["pattern"];
                XmlAttribute address = node.Attributes["address"];

                // Validate the data
                if (pattern == null || address == null)
                {
                    invalidEntries = true;
                    Trace.WriteLine("Reject configuration due to incomplete entry. (Either or both pattern and address missing.)");
                    break;
                }

                // Is the redirect address valid as an SMTP address?
                if (!RoutingAddress.IsValidAddress(address.Value))
                {
                    invalidEntries = true;
                    Trace.WriteLine(String.Format("Reject configuration due to invalid redirect address: {0}", address));
                    break;
                }

                // Add the new entry
                string strPattern = pattern.Value;
                map[strPattern] = new RoutingAddress(address.Value);

                Trace.WriteLine(String.Format("Redirect: {0} -> {1}", strPattern, address.Value));
            }

            // If there are no invalid entries, swap in the map
            if (!invalidEntries)
            {
                Interlocked.Exchange(ref _addressMap, map);
                Interlocked.Exchange(ref _banned, banned);
                Trace.WriteLine("Configuration Accepted.");
            }
        }
コード例 #38
0
        /// <summary>
        /// Load the configuration file. If any errors occur, does nothing.
        /// </summary>
        private void Load()
        {
            // Load the configuration
            XmlDocument doc = new XmlDocument();
            bool docLoaded = false;
            string fileName = Path.Combine(
                this.configDirectory,
                CatchAllConfig.configFileName);

            try
            {
                doc.Load(fileName);
                docLoaded = true;
            }
            catch (FileNotFoundException)
            {
                Trace.WriteLine("configuration file not found: {0}", fileName);
            }
            catch (XmlException e)
            {
                Trace.WriteLine("XML error: {0}", e.Message);
            }
            catch (IOException e)
            {
                Trace.WriteLine("IO error: {0}", e.Message);
            }

            // If a failure occured, ignore and simply return
            if (!docLoaded || doc.FirstChild == null)
            {
                Trace.WriteLine("configuration error: either no file or an XML error");
                return;
            }

            // Create a dictionary to hold the mappings
            Dictionary<Regex, RoutingAddress> map = new Dictionary<Regex, RoutingAddress>(100);

            // Track whether there are invalid entries
            bool invalidEntries = false;

            // Validate all entries and load into a dictionary
            foreach (XmlNode node in doc.FirstChild.ChildNodes)
            {
                if (string.Compare(node.Name, "rewriteAddress", true, CultureInfo.InvariantCulture) != 0)
                {
                    continue;
                }

                // address is the address to which the address of the incoming mail is matched.
                XmlAttribute address = node.Attributes["address"];
                // recipient is the address whereto the mail is forwarded if the match succeeds.
                XmlAttribute recipient = node.Attributes["recipient"];

                // Validate the data
                if (address == null || recipient == null)
                {
                    invalidEntries = true;
                    Trace.WriteLine("reject configuration due to an incomplete entry. (Either or both match address and recipient address missing.)");
                    break;
                }

                if (!RoutingAddress.IsValidAddress(recipient.Value))
                {
                    invalidEntries = true;
                    Trace.WriteLine(String.Format("reject configuration due to an invalid address ({0}).", address));
                    break;
                }

                // Add the new entry
                Regex lowerAddress = new Regex(address.Value.Replace("*", "(.*)+"), RegexOptions.IgnoreCase);
                map[lowerAddress] = new RoutingAddress(recipient.Value);

                Trace.WriteLine(String.Format("added entry ({0} -> {1})", lowerAddress, recipient.Value));
            }

            // If there are no invalid entries, swap in the map
            if (!invalidEntries)
            {
                Interlocked.Exchange<Dictionary<Regex, RoutingAddress>>(ref this.addressMap, map);
                Trace.WriteLine("accepted configuration");
            }
        }