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; }
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"""); } } }
/// <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; }
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); }
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"""); } }); }