/// <summary> /// Starts messages fetching. /// </summary> public void StartFetching() { if (m_Fetching) { return; } m_Fetching = true; try { DataView dvUsers = m_pApi.GetUsers("ALL"); using (DataView dvServers = m_pApi.GetUserRemoteServers("")) { foreach (DataRowView drV in dvServers) { try { if (!ConvertEx.ToBoolean(drV["Enabled"])) { continue; } // Find user name from user ID string userName = ""; dvUsers.RowFilter = "UserID='" + drV["UserID"] + "'"; if (dvUsers.Count > 0) { userName = dvUsers[0]["UserName"].ToString(); } else { continue; } string server = drV.Row["RemoteServer"].ToString(); int port = Convert.ToInt32(drV.Row["RemotePort"]); string user = drV.Row["RemoteUserName"].ToString(); string passw = drV.Row["RemotePassword"].ToString(); bool useSSL = ConvertEx.ToBoolean(drV["UseSSL"]); // Connect and login to pop3 server using (POP3_Client clnt = new POP3_Client()) { clnt.Logger = new LumiSoft.Net.Log.Logger(); clnt.Logger.WriteLog += new EventHandler <WriteLogEventArgs>(Pop3_WriteLog); clnt.Connect(server, port, useSSL); clnt.Login(user, passw); foreach (POP3_ClientMessage message in clnt.Messages) { // Store message m_pServer.ProcessUserMsg("", "", userName, "Inbox", new MemoryStream(message.MessageToByte()), null); message.MarkForDeletion(); } } } catch { } } } m_LastFetch = DateTime.Now; } catch (Exception x) { Error.DumpError(m_pServer.Name, x); } m_Fetching = false; }
/// <summary> /// Loads virtual server from xml file. /// </summary> internal void LoadVirtualServers() { try{ if (!File.Exists(SCore.PathFix(m_StartupPath + "Settings\\localServers.xml"))) { return; } DateTime dateServers = File.GetLastWriteTime(SCore.PathFix(m_StartupPath + "Settings\\localServers.xml")); if (DateTime.Compare(dateServers, m_ServersFileDate) != 0) { m_ServersFileDate = dateServers; DataSet ds = new DataSet(); ds.Tables.Add("Servers"); ds.Tables["Servers"].Columns.Add("ID"); ds.Tables["Servers"].Columns.Add("Enabled"); ds.Tables["Servers"].Columns.Add("Name"); ds.Tables["Servers"].Columns.Add("API_assembly"); ds.Tables["Servers"].Columns.Add("API_class"); ds.Tables["Servers"].Columns.Add("API_initstring"); ds.ReadXml(SCore.PathFix(m_StartupPath + "Settings\\localServers.xml")); if (ds.Tables.Contains("Servers")) { // Delete running virtual servers what has deleted. for (int i = 0; i < m_pVirtualServers.Count; i++) { VirtualServer server = m_pVirtualServers[i]; bool exists = false; foreach (DataRow dr in ds.Tables["Servers"].Rows) { if (server.ID == dr["ID"].ToString()) { exists = true; break; } } if (!exists) { server.Stop(); m_pVirtualServers.Remove(server); i--; } } // Add new added virtual servers what aren't running already. foreach (DataRow dr in ds.Tables["Servers"].Rows) { //--- See if specified server already running, if so, skip it. --// bool exists = false; foreach (VirtualServer server in m_pVirtualServers) { if (server.ID == dr["ID"].ToString()) { exists = true; server.Enabled = ConvertEx.ToBoolean(dr["Enabled"], true); break; } } if (exists) { continue; } //--------------------------------------------------------------// string id = dr["ID"].ToString(); string name = dr["Name"].ToString(); string assembly = dr["API_assembly"].ToString(); string apiClass = dr["API_class"].ToString(); string intiStr = dr["API_initstring"].ToString(); IMailServerApi api = LoadApi(assembly, apiClass, intiStr); VirtualServer virtualServer = new VirtualServer(this, id, name, intiStr, api); m_pVirtualServers.Add(virtualServer); virtualServer.Enabled = ConvertEx.ToBoolean(dr["Enabled"], true); } } } } catch (Exception x) { Error.DumpError(x, new System.Diagnostics.StackTrace()); } }
/// <summary> /// Filters message. /// </summary> /// <param name="messageStream">Message stream which to filter.</param> /// <param name="filteredStream">Filtered stream.</param> /// <param name="sender">Senders email address.</param> /// <param name="recipients">Recipients email addresses.</param> /// <param name="api">Access to server API.</param> /// <param name="session">Reference to SMTP session.</param> /// <param name="errorText">Filtering error text what is returned to client. ASCII text, 500 chars maximum.</param> public FilterResult Filter(Stream messageStream, out Stream filteredStream, string sender, string[] recipients, IMailServerApi api, SMTP_Session session, out string errorText) { errorText = null; filteredStream = null; try{ // Store message to tmp file string file = API_Utlis.PathFix(Path.GetTempPath() + "\\" + Guid.NewGuid().ToString() + ".eml"); using (FileStream fs = File.Create(file)){ byte[] data = new byte[messageStream.Length]; messageStream.Read(data, 0, data.Length); fs.Write(data, 0, data.Length); } // Execute virus program to scan tmp message // #FileName - place holder is replaced with file DataSet ds = new DataSet(); ds.Tables.Add("Settings"); ds.Tables["Settings"].Columns.Add("Program"); ds.Tables["Settings"].Columns.Add("Arguments"); ds.Tables["Settings"].Columns.Add("VirusExitCode"); ds.ReadXml(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\lsVirusFilter_db.xml"); string virusSoft = ds.Tables["Settings"].Rows[0]["Program"].ToString(); string virusSoftArgs = ds.Tables["Settings"].Rows[0]["Arguments"].ToString().Replace("#FileName", file); int virusExitCode = ConvertEx.ToInt32(ds.Tables["Settings"].Rows[0]["Program"], 1); int exitCode = 0; System.Diagnostics.ProcessStartInfo sInf = new System.Diagnostics.ProcessStartInfo(virusSoft, virusSoftArgs); sInf.CreateNoWindow = true; sInf.UseShellExecute = false; System.Diagnostics.Process p = System.Diagnostics.Process.Start(sInf); if (p != null) { p.WaitForExit(60000); exitCode = p.ExitCode; } if (File.Exists(file)) { // Return scanned message and delete tmp file using (FileStream fs = File.OpenRead(file)){ byte[] data = new byte[fs.Length]; fs.Read(data, 0, data.Length); filteredStream = new MemoryStream(data); } File.Delete(file); } // Virus scanner deleted messaeg, probably contains virus else { virusExitCode = exitCode; } // Do exit code mapping if (virusExitCode == exitCode) { errorText = "Message is blocked, contains virus !"; return(FilterResult.Error); } } catch (Exception x) { string dummy = x.Message; // Virus scanning failed, allow message through filteredStream = messageStream; } return(FilterResult.Store); }
/// <summary> /// Filters sender. /// </summary> /// <param name="from">Sender.</param> /// <param name="api">Reference to server API.</param> /// <param name="session">Reference to SMTP session.</param> /// <param name="errorText">Filtering error text what is returned to client. ASCII text, 100 chars maximum.</param> /// <returns>Returns true if sender is ok or false if rejected.</returns> public bool Filter(string from, IMailServerApi api, SMTP_Session session, out string errorText) { errorText = null; bool ok = true; // Don't check authenticated users or LAN IP if (session.IsAuthenticated || IsPrivateIP(session.RemoteEndPoint.Address)) { return(true); } try{ //--- Load data ----------------------- DataSet ds = new DataSet(); ds.Tables.Add("General"); ds.Tables["General"].Columns.Add("CheckHelo"); ds.Tables["General"].Columns.Add("LogRejections"); ds.Tables.Add("BlackListSettings"); ds.Tables["BlackListSettings"].Columns.Add("ErrorText"); ds.Tables.Add("BlackList"); ds.Tables["BlackList"].Columns.Add("IP"); ds.Tables.Add("Servers"); ds.Tables["Servers"].Columns.Add("Cost"); ds.Tables["Servers"].Columns.Add("Server"); ds.Tables["Servers"].Columns.Add("DefaultRejectionText"); ds.ReadXml(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\lsDNSBL_Filter_db.xml"); bool logRejections = false; #region General if (ds.Tables["General"].Rows.Count == 1) { if (Convert.ToBoolean(ds.Tables["General"].Rows[0]["CheckHelo"])) { DnsServerResponse response = Dns_Client.Static.Query(session.EhloHost, DNS_QType.A); // If dns server connection errors, don't block. if (response.ConnectionOk && response.ResponseCode != DNS_RCode.SERVER_FAILURE) { bool found = false; foreach (DNS_rr_A a in response.GetARecords()) { if (session.RemoteEndPoint.Address.Equals(a.IP)) { found = true; break; } } if (!found) { errorText = "Not valid DNS EHLO/HELO name for your IP '" + session.EhloHost + "' !"; return(false); } } } logRejections = ConvertEx.ToBoolean(ds.Tables["General"].Rows[0]["LogRejections"]); } #endregion #region Balck List foreach (DataRow dr in ds.Tables["BlackList"].Rows) { if (IsAstericMatch(dr["IP"].ToString(), session.RemoteEndPoint.Address.ToString())) { errorText = ds.Tables["BlackListSettings"].Rows[0]["ErrorText"].ToString(); return(false); } } #endregion #region DNSBL foreach (DataRow dr in ds.Tables["Servers"].Rows) { DnsServerResponse dnsResponse = Dns_Client.Static.Query(ReverseIP(session.RemoteEndPoint.Address) + "." + dr["Server"].ToString(), DNS_QType.ANY); DNS_rr_A[] recs = dnsResponse.GetARecords(); if (recs.Length > 0) { if (logRejections) { WriteFilterLog("Sender:" + from + " IP:" + session.RemoteEndPoint.Address.ToString() + " blocked\r\n"); } errorText = dr["DefaultRejectionText"].ToString(); // Server provided return text, use it if (dnsResponse.GetTXTRecords().Length > 0) { errorText = dnsResponse.GetTXTRecords()[0].Text; } if (errorText == "") { errorText = "You are in '" + dr["Server"].ToString() + "' rejection list !"; } return(false); } } #endregion } catch { } return(ok); }