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); }
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); }
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); }
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; }
/// <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); }
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; }
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); }
/// <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; }
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); }
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(); } }
private EmailItem(Object underlyingObject, EmailMessage message, RoutingAddress fromAddress, Stream mimeReadStream) { _underlyingObject = underlyingObject; Message = message; FromAddress = fromAddress; MimeReadStream = mimeReadStream; }
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; }
public static string RedactRoutingAddressIfNecessary(RoutingAddress address, bool isNecessary) { ArgumentValidator.ThrowIfNullOrEmpty("address.ToString()", address.ToString()); if (isNecessary) { return(SuppressingPiiData.Redact(address).ToString()); } return(address.ToString()); }
// 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]); }
public static SmtpDomain GetDomainPart(RoutingAddress address) { string domainPart = address.DomainPart; if (domainPart != null) { return(new SmtpDomain(domainPart, false)); } return(null); }
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); }
public new static AutoDiscoverSmtpDomain GetDomainPart(RoutingAddress address) { string domainPart = address.DomainPart; if (domainPart != null) { return(new AutoDiscoverSmtpDomain(domainPart, false)); } return(null); }
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)); }
// 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); }
/// <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); } }
/// <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); }
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)); }
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); }
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); }
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); }
// 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); }
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))); }
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); }
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)); }
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; }
public bool TestVerify(IPAddress senderIP, RoutingAddress sender, RoutingAddress recipient) { return this.VerifyTriplet(senderIP, sender, recipient); }
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; }
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; }
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); } }
/// <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."); } }
/// <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"); } }