diff --git a/WebsitePanel/Lib/References/Microsoft/Microsoft.Exchange.Data.Common.dll b/WebsitePanel/Lib/References/Microsoft/Microsoft.Exchange.Data.Common.dll new file mode 100644 index 00000000..6357f145 Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Microsoft.Exchange.Data.Common.dll differ diff --git a/WebsitePanel/Lib/References/Microsoft/Microsoft.Exchange.Data.Transport.dll b/WebsitePanel/Lib/References/Microsoft/Microsoft.Exchange.Data.Transport.dll new file mode 100644 index 00000000..971c863e Binary files /dev/null and b/WebsitePanel/Lib/References/Microsoft/Microsoft.Exchange.Data.Transport.dll differ diff --git a/WebsitePanel/Sources/WSPTransportAgent/App.config b/WebsitePanel/Sources/WSPTransportAgent/App.config new file mode 100644 index 00000000..f3d7ccd1 --- /dev/null +++ b/WebsitePanel/Sources/WSPTransportAgent/App.config @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/WebsitePanel/Sources/WSPTransportAgent/Properties/AssemblyInfo.cs b/WebsitePanel/Sources/WSPTransportAgent/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..2235d8fb --- /dev/null +++ b/WebsitePanel/Sources/WSPTransportAgent/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("WSPTransportAgent")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WSPTransportAgent")] +[assembly: AssemblyCopyright("Copyright © 2012")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("e28cac4e-9660-4174-8010-c6a00c81bf57")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/WebsitePanel/Sources/WSPTransportAgent/WSPRoutingAgent.cs b/WebsitePanel/Sources/WSPTransportAgent/WSPRoutingAgent.cs new file mode 100644 index 00000000..84fe075b --- /dev/null +++ b/WebsitePanel/Sources/WSPTransportAgent/WSPRoutingAgent.cs @@ -0,0 +1,260 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Diagnostics; +using System.IO; +using System.Configuration; +using System.Collections.ObjectModel; +using System.Collections; +using System.Collections.Specialized; +using System.Xml; +using Microsoft.Exchange.Data.Transport; +using Microsoft.Exchange.Data.Transport.Routing; +using Microsoft.Exchange.Data.Mime; +using System.DirectoryServices; + + +namespace WSPTransportAgent +{ + public class WSPRoutingAgentFactory : RoutingAgentFactory + { + public override RoutingAgent CreateAgent(SmtpServer server) + { + return new WSPRoutingAgent(server); + } + } + + public class WSPRoutingAgent : RoutingAgent + { + private string routingDomain; + private bool enableVerboseLogging; + private string logFile; + private Hashtable htAcceptedDomains; + private bool blockInternalInterTenantOOF; + + public WSPRoutingAgent(SmtpServer server) + { + //subscribe to different events + loadConfiguration(); + + WriteLine("WSPRoutingAgent Registration started"); + loadAcceptedDomains(server); + //GetAcceptedDomains(); + WriteLine("\trouting Domain: " + routingDomain); + + base.OnResolvedMessage += new ResolvedMessageEventHandler(WSPRoutingAgent_OnResolvedMessage); + + WriteLine("WSPRoutingAgent Registration completed"); + } + + private void loadConfiguration() + { + this.routingDomain = ".tmpdefault"; + this.enableVerboseLogging = true; + this.logFile = "C:\\WSP.LOG"; + + try + { + ExeConfigurationFileMap map = new ExeConfigurationFileMap(); + map.ExeConfigFilename = System.Reflection.Assembly.GetExecutingAssembly().Location + ".config"; + Configuration libConfig = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None); + AppSettingsSection section = (libConfig.GetSection("appSettings") as AppSettingsSection); + + this.routingDomain = section.Settings["routingDomain"].Value; + this.enableVerboseLogging = (section.Settings["enableVerboseLogging"].Value == "true"); + this.blockInternalInterTenantOOF = (section.Settings["blockInternalInterTenantOOF"].Value == "true"); + this.logFile = section.Settings["logFile"].Value; + } + catch (Exception ex) + { + WriteLine("\t[Error] " + ex.Message); + LogErrorToEventLog("[Error] [loadConfiguration] Error :" + ex.Message); + } + + + } + + + private void loadAcceptedDomains(SmtpServer server) + { + try + { + if (htAcceptedDomains == null) + this.htAcceptedDomains = new Hashtable(); + else + this.htAcceptedDomains.Clear(); + + foreach (AcceptedDomain domain in server.AcceptedDomains) + { + htAcceptedDomains.Add(domain.ToString(), "1"); + WriteLine("\tAccepted Domain: " + domain.ToString()); + } + } + catch (Exception ex) + { + WriteLine("\t[Error] " + ex.Message); + LogErrorToEventLog("[Error] [loadAcceptedDomains] Error :" + ex.Message); + } + } + + + void WSPRoutingAgent_OnResolvedMessage(ResolvedMessageEventSource source, QueuedMessageEventArgs e) + { + try + { + + WriteLine("Start WSPRoutingAgent_OnResolvedMessage"); + + WriteLine("\tFromAddress: " + e.MailItem.FromAddress.ToString()); + WriteLine("\tSubject: " + e.MailItem.Message.Subject.ToString()); + WriteLine("\tMapiMessageClass: " + e.MailItem.Message.MapiMessageClass.ToString()); + + MimeDocument mdMimeDoc = e.MailItem.Message.MimeDocument; + HeaderList hlHeaderlist = mdMimeDoc.RootPart.Headers; + Header mhProcHeader = hlHeaderlist.FindFirst("X-WSP"); + + if (mhProcHeader == null) + { + WriteLine("\tTouched: " + "No"); + + if (!e.MailItem.Message.IsSystemMessage) + { + bool touched = false; + + if (e.MailItem.FromAddress.DomainPart != null) + { + foreach (EnvelopeRecipient recp in e.MailItem.Recipients) + { + WriteLine("\t\tTo: " + recp.Address.ToString().ToLower()); + if (IsMessageBetweenTenants(e.MailItem.FromAddress.DomainPart.ToLower(), recp.Address.DomainPart.ToLower())) + { + WriteLine("\t\tMessage routed to domain: " + recp.Address.DomainPart.ToLower() + routingDomain); + RoutingDomain myRoutingDomain = new RoutingDomain(recp.Address.DomainPart.ToLower() + routingDomain); + RoutingOverride myRoutingOverride = new RoutingOverride(myRoutingDomain, DeliveryQueueDomain.UseOverrideDomain); + source.SetRoutingOverride(recp, myRoutingOverride); + touched = true; + } + } + } + else + { + if ((e.MailItem.Message.MapiMessageClass.ToString() == "IPM.Note.Rules.OofTemplate.Microsoft") & + blockInternalInterTenantOOF) + { + WriteLine("\t\tOOF From: " + e.MailItem.Message.From.SmtpAddress); + if (e.MailItem.Message.From.SmtpAddress.Contains("@")) + { + string[] tmp = e.MailItem.Message.From.SmtpAddress.Split('@'); + foreach (EnvelopeRecipient recp in e.MailItem.Recipients) + { + WriteLine("\t\tTo: " + recp.Address.ToString().ToLower()); + if (IsMessageBetweenTenants(tmp[1].ToLower(), recp.Address.DomainPart.ToLower())) + { + WriteLine("\t\tRemove: " + recp.Address.DomainPart.ToLower()); + e.MailItem.Recipients.Remove(recp); + } + } + } + } + } + + if (touched) + { + MimeNode lhLasterHeader = hlHeaderlist.LastChild; + TextHeader nhNewHeader = new TextHeader("X-WSP", "Logged00"); + hlHeaderlist.InsertBefore(nhNewHeader, lhLasterHeader); + } + } + else + WriteLine("\tSystem Message"); + } + else + WriteLine("\tTouched: " + "Yes"); + + } + + catch (Exception ex) + { + WriteLine("\t[Error] Error :" + ex.Message); + LogErrorToEventLog("[Error] [OnResolvedMessage] Error :" + ex.Message); + } + + WriteLine("End WSPRoutingAgent_OnResolvedMessage"); + } + + private bool IsMessageBetweenTenants(string senderDomain, string recipientDomain) + { + if (senderDomain == recipientDomain) return false; + + if ((htAcceptedDomains[senderDomain] != null) && + (htAcceptedDomains[recipientDomain] != null)) + return true; + + return false; + } + + /* + private void GetAcceptedDomains() + { + try + { + htAcceptedDomains.Clear(); + DirectoryEntry rdRootDSE = new DirectoryEntry("LDAP://RootDSE"); + DirectoryEntry cfConfigPartition = new DirectoryEntry("LDAP://" + rdRootDSE.Properties["configurationnamingcontext"].Value); + DirectorySearcher cfConfigPartitionSearch = new DirectorySearcher(cfConfigPartition); + cfConfigPartitionSearch.Filter = "(objectClass=msExchAcceptedDomain)"; + cfConfigPartitionSearch.SearchScope = SearchScope.Subtree; + SearchResultCollection srSearchResults = cfConfigPartitionSearch.FindAll(); + + foreach (SearchResult srSearchResult in srSearchResults) + { + DirectoryEntry acDomain = srSearchResult.GetDirectoryEntry(); + htAcceptedDomains.Add(acDomain.Properties["msexchaccepteddomainname"].Value.ToString().ToLower(), "1"); + WriteLine("\tAccepted Domain :" + acDomain.Properties["msexchaccepteddomainname"].Value.ToString().ToLower()); + } + } + catch (Exception ex) + { + WriteLine("\tError :" + ex.Message); + EventLog.WriteEntry("WSP Transport Agent", ex.Message, EventLogEntryType.Error); + } + } + */ + + + private void WriteLine(string Line) + { + if (!enableVerboseLogging) return; + + try + { + StreamWriter writer = new StreamWriter(logFile, true, System.Text.Encoding.ASCII); + writer.WriteLine("[" + DateTime.Now.ToString() + "]" + Line); + writer.Close(); + } + catch (Exception e) + { + + } + } + + + private void LogErrorToEventLog(string Line) + { + try + { + if (EventLog.SourceExists("WSPTransportAgent")) + { + EventLog.WriteEntry("WSPTransportAgent", Line, EventLogEntryType.Error); + } + } + catch (Exception ex) + { + WriteLine("[Error] WritingEventLog :" + ex.Message); + } + } + + + } + +} diff --git a/WebsitePanel/Sources/WSPTransportAgent/WSPTransportAgent.csproj b/WebsitePanel/Sources/WSPTransportAgent/WSPTransportAgent.csproj new file mode 100644 index 00000000..47bfc898 --- /dev/null +++ b/WebsitePanel/Sources/WSPTransportAgent/WSPTransportAgent.csproj @@ -0,0 +1,62 @@ + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {D959F137-A56F-4F4E-BA80-599FBE3700E3} + Library + Properties + WSPTransportAgent + WSPTransportAgent + v4.0 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\Lib\References\Microsoft\Microsoft.Exchange.Data.Common.dll + + + ..\..\Lib\References\Microsoft\Microsoft.Exchange.Data.Transport.dll + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WebsitePanel/Sources/WSPTransportAgent/WSPTransportAgent.reg b/WebsitePanel/Sources/WSPTransportAgent/WSPTransportAgent.reg new file mode 100644 index 00000000..755c888a --- /dev/null +++ b/WebsitePanel/Sources/WSPTransportAgent/WSPTransportAgent.reg @@ -0,0 +1,15 @@ +Windows Registry Editor Version 5.00 + +[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\MEACPTransportAgent] +"MaxSize"=dword:00080000 +"AutoBackupLogFiles"=dword:00000000 +"Retention"=dword:00000000 + +[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\eventlog\MEACPTransportAgent\MEACPTransportAgent] +"EventMessageFile"=hex(2):43,00,3a,00,5c,00,57,00,69,00,6e,00,64,00,6f,00,77,\ + 00,73,00,5c,00,4d,00,69,00,63,00,72,00,6f,00,73,00,6f,00,66,00,74,00,2e,00,\ + 4e,00,45,00,54,00,5c,00,46,00,72,00,61,00,6d,00,65,00,77,00,6f,00,72,00,6b,\ + 00,36,00,34,00,5c,00,76,00,34,00,2e,00,30,00,2e,00,33,00,30,00,33,00,31,00,\ + 39,00,5c,00,45,00,76,00,65,00,6e,00,74,00,4c,00,6f,00,67,00,4d,00,65,00,73,\ + 00,73,00,61,00,67,00,65,00,73,00,2e,00,64,00,6c,00,6c,00,00,00 + diff --git a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.sln b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.sln index fb708ef8..a88f65b6 100644 --- a/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.sln +++ b/WebsitePanel/Sources/WebsitePanel.EnterpriseServer.sln @@ -43,6 +43,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebsitePanel.Plugins.PayPal EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebsitePanel.Templates", "WebsitePanel.Templates\WebsitePanel.Templates.csproj", "{387FA0EF-3927-45FF-8F8F-BCCD735540C6}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WSPTransportAgent", "WSPTransportAgent\WSPTransportAgent.csproj", "{D959F137-A56F-4F4E-BA80-599FBE3700E3}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -107,6 +109,10 @@ Global {387FA0EF-3927-45FF-8F8F-BCCD735540C6}.Debug|Any CPU.Build.0 = Debug|Any CPU {387FA0EF-3927-45FF-8F8F-BCCD735540C6}.Release|Any CPU.ActiveCfg = Release|Any CPU {387FA0EF-3927-45FF-8F8F-BCCD735540C6}.Release|Any CPU.Build.0 = Release|Any CPU + {D959F137-A56F-4F4E-BA80-599FBE3700E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D959F137-A56F-4F4E-BA80-599FBE3700E3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D959F137-A56F-4F4E-BA80-599FBE3700E3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D959F137-A56F-4F4E-BA80-599FBE3700E3}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/WebsitePanel/Sources/WebsitePanel.WebPortal/WebsitePanel.WebPortal.csproj b/WebsitePanel/Sources/WebsitePanel.WebPortal/WebsitePanel.WebPortal.csproj index 30bb5548..2f0e726b 100644 --- a/WebsitePanel/Sources/WebsitePanel.WebPortal/WebsitePanel.WebPortal.csproj +++ b/WebsitePanel/Sources/WebsitePanel.WebPortal/WebsitePanel.WebPortal.csproj @@ -106,6 +106,7 @@ +