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;
        }
        /// <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;
        }
Exemple #3
0
 private void RcptCommandHandler(ReceiveCommandEventSource source, RcptCommandEventArgs args)
 {
     DeliveryThrottlingAgent.Diag.TraceDebug(0, (long)this.GetHashCode(), "RcptCommandHandler started");
     if (!DeliveryThrottling.Instance.CheckAndTrackThrottleRecipient(args.RecipientAddress, args.SmtpSession.SessionId, this.destinationMdbGuid.ToString(), args.MailItem.TenantId))
     {
         MSExchangeStoreDriver.DeliveryRetry.Increment();
         source.RejectCommand(AckReason.RecipientThreadLimitExceeded);
     }
     if (this.connectionManager != null)
     {
         this.connectionManager.UpdateLastActivityTime(args.SmtpSession.SessionId);
     }
 }
        /// <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);
        }
 private void OnRcptCommandHandler(ReceiveCommandEventSource source, RcptCommandEventArgs e)
 {
     Logger.Debug("[GenericTransportAgent] SmtpReceiveAgent - OnRcptCommand fired...");
     foreach (var x in Configuration.Config.SmtpReceiveAgentConfig.OnRcptCommand)
     {
         try
         {
             x.Execute(new EmailItem(e.MailItem));
         }
         catch (Exception ex)
         {
             Logger.Error(ex, @"Error executing ""OnRcptCommand""");
         }
     }
 }
Exemple #6
0
        /// <summary>
        /// Handles the "RCPT TO:" SMTP command
        /// </summary>
        /// <param name="source">The event source.</param>
        /// <param name="rcptArgs"></param>
        public void RcptToHandler(ReceiveCommandEventSource source, RcptCommandEventArgs rcptArgs)
        {
            // Get the recipient address as a lowercase string.
            string strRecipientAddress = rcptArgs.RecipientAddress.ToString().ToLower();

            // Search the banned email List for the recipient.
            bool exists = _catchAllConfig.Banned.Exists(element => element == strRecipientAddress);

            if (exists)
            {
                // If found respond to the sending MTA with the reject response.
                source.RejectCommand(RejectResponse);

                // No further processing.
                return;
            }

            // For each pair of regexps to email addresses
            foreach (var pair in _catchAllConfig.AddressMap)
            {
                // Create the regular expression and the routing address from the dictionary.
                var            emailPattern = new Regex(pair.Key);
                RoutingAddress emailAddress = pair.Value;

                // If the recipient address matches the regular expression.
                if (emailPattern.IsMatch(strRecipientAddress))
                {
                    // And if the recipient is NOT in the address book.
                    if ((_addressBook != null) && (_addressBook.Find(rcptArgs.RecipientAddress) == null))
                    {
                        // Redirect the recipient to the other address.
                        rcptArgs.RecipientAddress = emailAddress;

                        // No further processing.
                        return;
                    }
                }
            }

            // No further processing.
            return;
        }
        /// <summary>
        /// Handles the "RCPT TO:" SMTP command
        /// </summary>
        /// <param name="source">The event source.</param>
        /// <param name="rcptArgs"></param>
        public void RcptToHandler(ReceiveCommandEventSource source, RcptCommandEventArgs rcptArgs)
        {
            // Get the recipient address as a lowercase string.
            string strRecipientAddress = rcptArgs.RecipientAddress.ToString().ToLower();

            // Search the banned email List for the recipient.
            bool exists = _catchAllConfig.Banned.Exists(element => element == strRecipientAddress);
            if (exists)
            {
                // If found respond to the sending MTA with the reject response.
                source.RejectCommand(RejectResponse);

                // No further processing.
                return;
            }

            // For each pair of regexps to email addresses
            foreach (var pair in _catchAllConfig.AddressMap)
            {
                // Create the regular expression and the routing address from the dictionary.
                var emailPattern = new Regex(pair.Key);
                RoutingAddress emailAddress = pair.Value;

                // If the recipient address matches the regular expression.
                if (emailPattern.IsMatch(strRecipientAddress))
                {
                    // And if the recipient is NOT in the address book.
                    if ((_addressBook != null) && (_addressBook.Find(rcptArgs.RecipientAddress) == null))
                    {
                        // Redirect the recipient to the other address.
                        rcptArgs.RecipientAddress = emailAddress;

                        // No further processing.
                        return;
                    }
                }
            }

            // No further processing.
            return;
        }
Exemple #8
0
        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;
        }
 void OnRcptCommandHandler(ReceiveCommandEventSource source, RcptCommandEventArgs e)
 {
     Logger.Debug("[GenericTransportAgent] SmtpReceiveAgent - OnRcptCommand fired...");
     _config.SmtpReceiveAgentConfig.OnRcptCommand.ToList().ForEach(x => { try { x.Execute(new EmailItem(e.MailItem)); } catch (Exception ex) { Logger.Error(ex, @"Error executing ""OnRcptCommand"""); } });
 }
        /// <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(ReceiveEventSource source, RcptCommandEventArgs rcptArgs)
        {
            RoutingAddress catchAllAddress;

            // Check whether to handle the recipient's domain
            //if (this.catchAllConfig.AddressMap.TryGetValue(
            //    rcptArgs.RecipientAddress.DomainPart.ToLower(),
            //    out catchAllAddress))
            foreach (Regex r in this.catchAllConfig.AddressMap.Keys)
            {
                if(r.IsMatch(rcptArgs.RecipientAddress.ToString()))
                {
                    // DO THE DIRTY WORK HERE
                }
            }
            if (false)
            {
                // Rewrite the (envelope) recipient address if 'not found'
                if ((this.addressBook != null) &&
                    (this.addressBook.Find(rcptArgs.RecipientAddress) == null))
                {
                    rcptArgs.RecipientAddress = catchAllAddress;
                }
            }

            return;
        }
        public void OnRcptCommandHandler(ReceiveCommandEventSource source, RcptCommandEventArgs rcptArgs)
        {
            // Check the parameter values.
            if (source == null || rcptArgs == null)
            {
                this.logLine("ERROR: Source or Recipient Argements was null", 1);
                return;
            }

            // Skip filtering for internal mail.
            if (!rcptArgs.SmtpSession.IsExternalConnection)
            {
                
                if (rcptArgs.RecipientAddress.ToString().IndexOf("HealthMailbox") == 0)
                {
                    return;
                }
                this.logLine("FROM=, TO=" + rcptArgs.RecipientAddress.ToString() + ", REMOTE=" + rcptArgs.SmtpSession.RemoteEndPoint.Address.ToString() + ", STATE=Bypassed, REASON=Internal Connection", 2);
                return;
            }

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

            // Check to see if whitelisted or in safe senders list
            if (this.ShouldBypassFilter(rcptArgs.MailItem.FromAddress, rcptArgs.RecipientAddress, rcptArgs.SmtpSession.RemoteEndPoint.Address))
            {
                this.logLine("FROM=" + rcptArgs.MailItem.FromAddress.ToString() + ", TO=" + rcptArgs.RecipientAddress.ToString() + ", REMOTE=" + rcptArgs.SmtpSession.RemoteEndPoint.Address.ToString() + ", STATE=Bypassed, REASON=Filter Bypass Match", 2);
                return;
            }

            // Check the database to determine whether the message should be rejected 
            // or let through.
            if (!this.VerifyTriplet(rcptArgs.SmtpSession.RemoteEndPoint.Address, rcptArgs.MailItem.FromAddress, rcptArgs.RecipientAddress))
            {
                this.logLine("FROM=" + rcptArgs.MailItem.FromAddress.ToString() + ", TO=" + rcptArgs.RecipientAddress.ToString() + ", REMOTE=" + rcptArgs.SmtpSession.RemoteEndPoint.Address.ToString() + ", STATE=Greylist, REASON=Triplet verification Fail", 2);
                source.RejectCommand(DelayResponseMessage);
                return;
            }
            this.logLine("FROM=" + rcptArgs.MailItem.FromAddress.ToString() + ", TO=" + rcptArgs.RecipientAddress.ToString() + ", REMOTE=" + rcptArgs.SmtpSession.RemoteEndPoint.Address.ToString() + ", STATE=Accept, REASON=Triplet Match.", 2);
                
            // Finally, check a few rows
            // for expired entries that need to be cleaned up.
            this.greylistDatabase.Clean(this.settings.CleanRowCount, this.settings.ConfirmedMaxAge, this.settings.UnconfirmedMaxAge);
        }
Exemple #12
0
 void OnRcptCommandHandler(ReceiveCommandEventSource source, RcptCommandEventArgs e)
 {
     Logger.Debug("[GenericExchangeTransportagent] [SmtpReceiveAgent] OnRcptCommand fired...");
     _config.SmtpReceiveAgentConfig.OnRcptCommand.ToList().ForEach(x => { try { x.Execute(new EmailItem(e.MailItem)); } catch (Exception ex) { Logger.Error(ex, @"Error executing ""OnRcptCommand"""); } });
 }