OpenSim.Modules.EMail/src/MailKitMailModule.cs

401 lines
15 KiB
C#
Raw Normal View History

2020-06-30 15:11:03 +00:00
using log4net;
using MailKit;
2020-06-30 14:20:45 +00:00
using MailKit.Net.Imap;
using MailKit.Net.Smtp;
2020-06-30 09:50:25 +00:00
using MailKit.Security;
2020-06-30 07:54:27 +00:00
using MimeKit;
2020-06-30 06:46:07 +00:00
using Mono.Addins;
using Nini.Config;
using OpenMetaverse;
using OpenSim.Region.Framework.Interfaces;
using OpenSim.Region.Framework.Scenes;
2020-06-30 06:21:49 +00:00
using System;
using System.Collections.Generic;
using System.Linq;
2020-07-01 15:47:33 +00:00
using System.Net.Security;
2020-06-30 15:11:03 +00:00
using System.Reflection;
2020-07-01 15:47:33 +00:00
using System.Security.Cryptography.X509Certificates;
2020-06-30 06:21:49 +00:00
using System.Text;
using System.Threading.Tasks;
2020-06-30 14:20:45 +00:00
using System.Timers;
2020-06-30 06:21:49 +00:00
2020-06-30 06:46:07 +00:00
[assembly: Addin("MailKitMailModule", "0.1")]
[assembly: AddinDependency("OpenSim.Region.Framework", OpenSim.VersionInfo.VersionNumber)]
2020-06-30 06:21:49 +00:00
namespace OpenSim.Modules.EMail
{
2020-06-30 06:46:07 +00:00
[Extension(Path = "/OpenSim/RegionModules", NodeName = "RegionModule", Id = "MailKitMailModule")]
class MailKitMailModule : INonSharedRegionModule, IEmailModule
2020-06-30 06:21:49 +00:00
{
2020-06-30 15:11:03 +00:00
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
2020-06-30 06:46:07 +00:00
private IConfigSource m_config = null;
private bool m_enabled = false;
2020-06-30 06:21:49 +00:00
2020-06-30 06:46:07 +00:00
private Scene m_scene = null;
2020-07-01 19:43:42 +00:00
private Timer m_timer_recive = null;
private Timer m_timer_send = null;
2020-06-30 14:20:45 +00:00
2020-07-01 16:21:50 +00:00
private List<InternalMail> m_messages = new List<InternalMail>();
2020-07-01 19:43:42 +00:00
private List<MimeMessage> m_sendMessages = new List<MimeMessage>();
2020-06-30 14:20:45 +00:00
2020-07-01 16:45:41 +00:00
private bool m_debug = false;
2020-07-01 20:06:52 +00:00
private int m_sending = 0;
2020-07-01 16:45:41 +00:00
2020-06-30 06:46:07 +00:00
private String SMTP_SERVER_HOSTNAME = null;
private String SMTP_SERVER_LOGIN = null;
private String SMTP_SERVER_PASSWORD = null;
private String SMTP_SERVER_SENDER = null;
private int SMTP_SERVER_PORT = 25;
2020-06-30 09:50:25 +00:00
private bool SMTP_SERVER_SSL = false;
private bool SMTP_SERVER_TLS = false;
2020-06-30 06:46:07 +00:00
private String IMAP_SERVER_HOSTNAME = null;
private String IMAP_SERVER_LOGIN = null;
private String IMAP_SERVER_PASSWORD = null;
private int IMAP_SERVER_PORT = 25;
2020-06-30 09:50:25 +00:00
private bool IMAP_SERVER_SSL = false;
private bool IMAP_SERVER_TLS = false;
2020-06-30 06:46:07 +00:00
private bool m_requester = false;
2020-06-30 14:20:45 +00:00
2020-06-30 06:46:07 +00:00
#region ISharedRegionModule
public string Name
{
get { return "MailKitMailModule"; }
}
public Type ReplaceableInterface
{
get { return null; }
}
public void AddRegion(Scene scene)
{
if (!m_enabled)
return;
scene.RegisterModuleInterface<IEmailModule>(this);
m_scene = scene;
2020-06-30 14:20:45 +00:00
2020-07-01 19:43:42 +00:00
m_timer_send = new Timer();
2020-07-01 20:22:06 +00:00
m_timer_send.Interval = 1000 * 2;
2020-07-01 19:43:42 +00:00
m_timer_send.Elapsed += sendAllMails;
m_timer_send.Enabled = true;
m_timer_send.Start();
if (IMAP_SERVER_HOSTNAME != String.Empty)
2020-06-30 15:37:12 +00:00
{
2020-07-01 19:43:42 +00:00
m_timer_recive = new Timer();
m_timer_recive.Interval = 1000 * 15;
m_timer_recive.Elapsed += checkForMails;
m_timer_recive.Enabled = true;
m_timer_recive.Start();
2020-06-30 15:37:12 +00:00
}
2020-06-30 06:46:07 +00:00
}
2020-07-01 19:43:42 +00:00
2020-06-30 06:46:07 +00:00
public void Close()
{
2020-07-01 19:43:42 +00:00
2020-06-30 06:46:07 +00:00
}
public void Initialise(IConfigSource source)
{
m_config = source;
if(source.Configs["Startup"] != null)
{
m_enabled = (m_config.Configs["Startup"].GetString("emailmodule", "DefaultEmailModule") == "MailKitMailModule");
if (!m_enabled)
return;
}
if (source.Configs["Mail"] == null)
return;
2020-07-01 16:45:41 +00:00
m_debug = m_config.Configs["Mail"].GetBoolean("DEBUG", m_debug);
2020-06-30 10:15:20 +00:00
SMTP_SERVER_HOSTNAME = m_config.Configs["Mail"].GetString("SMTP_SERVER_HOSTNAME", String.Empty);
2020-06-30 06:46:07 +00:00
SMTP_SERVER_PORT = m_config.Configs["Mail"].GetInt("SMTP_SERVER_PORT", 25);
2020-06-30 09:50:25 +00:00
SMTP_SERVER_SSL = m_config.Configs["Mail"].GetBoolean("SMTP_SERVER_SSL", false);
SMTP_SERVER_TLS = m_config.Configs["Mail"].GetBoolean("SMTP_SERVER_TLS", false);
2020-06-30 10:15:20 +00:00
SMTP_SERVER_LOGIN = m_config.Configs["Mail"].GetString("SMTP_SERVER_LOGIN", String.Empty);
SMTP_SERVER_PASSWORD = m_config.Configs["Mail"].GetString("SMTP_SERVER_PASSWORD", String.Empty);
2020-06-30 06:46:07 +00:00
SMTP_SERVER_SENDER = m_config.Configs["Mail"].GetString("SMTP_SERVER_SENDER", "");
2020-06-30 10:15:20 +00:00
IMAP_SERVER_HOSTNAME = m_config.Configs["Mail"].GetString("IMAP_SERVER_HOSTNAME", String.Empty);
2020-07-01 15:47:33 +00:00
IMAP_SERVER_PORT = m_config.Configs["Mail"].GetInt("IMAP_SERVER_PORT", 143);
2020-06-30 10:15:20 +00:00
IMAP_SERVER_SSL = m_config.Configs["Mail"].GetBoolean("IMAP_SERVER_SSL", false);
IMAP_SERVER_TLS = m_config.Configs["Mail"].GetBoolean("IMAP_SERVER_TLS", false);
IMAP_SERVER_LOGIN = m_config.Configs["Mail"].GetString("IMAP_SERVER_LOGIN", String.Empty);
IMAP_SERVER_PASSWORD = m_config.Configs["Mail"].GetString("IMAP_SERVER_PASSWORD", String.Empty);
2020-06-30 06:46:07 +00:00
}
public void PostInitialise()
{
}
public void RegionLoaded(Scene scene)
{
}
public void RemoveRegion(Scene scene)
{
}
#endregion
2020-07-01 15:47:33 +00:00
private void checkForMails(object sender, ElapsedEventArgs f)
2020-06-30 14:20:45 +00:00
{
if (!m_requester)
return;
2020-06-30 15:37:12 +00:00
try
2020-06-30 14:20:45 +00:00
{
2020-07-01 16:45:41 +00:00
if(m_debug)
m_log.Info("[" + Name + "] checkForMails");
2020-06-30 14:20:45 +00:00
2020-06-30 15:37:12 +00:00
using (var client = new ImapClient())
2020-06-30 14:20:45 +00:00
{
2020-06-30 15:37:12 +00:00
client.CheckCertificateRevocation = false;
2020-07-01 19:26:14 +00:00
client.Timeout = 10000;
2020-07-01 15:47:33 +00:00
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
2020-06-30 14:20:45 +00:00
2020-06-30 15:37:12 +00:00
if (IMAP_SERVER_SSL == true)
{
2020-07-01 16:56:15 +00:00
if (m_debug)
m_log.Info("[" + Name + "] Connect SSL");
2020-06-30 15:37:12 +00:00
client.Connect(IMAP_SERVER_HOSTNAME, IMAP_SERVER_PORT, SecureSocketOptions.Auto);
}
else if (IMAP_SERVER_TLS == true)
{
2020-07-01 16:56:15 +00:00
if (m_debug)
m_log.Info("[" + Name + "] Connect TLS");
2020-06-30 15:37:12 +00:00
client.Connect(IMAP_SERVER_HOSTNAME, IMAP_SERVER_PORT, SecureSocketOptions.StartTlsWhenAvailable);
}
else
{
2020-07-01 16:56:15 +00:00
if (m_debug)
m_log.Info("[" + Name + "] Connect None");
2020-06-30 15:37:12 +00:00
client.Connect(IMAP_SERVER_HOSTNAME, IMAP_SERVER_PORT, SecureSocketOptions.None);
}
2020-06-30 14:20:45 +00:00
2020-06-30 15:37:12 +00:00
if (IMAP_SERVER_LOGIN != String.Empty && IMAP_SERVER_PASSWORD != String.Empty)
{
2020-07-01 16:56:15 +00:00
if (m_debug)
m_log.Info("[" + Name + "] Login with " + IMAP_SERVER_LOGIN + ";" + IMAP_SERVER_PASSWORD);
2020-06-30 15:37:12 +00:00
client.Authenticate(IMAP_SERVER_LOGIN, IMAP_SERVER_PASSWORD);
2020-07-01 15:47:33 +00:00
2020-06-30 15:37:12 +00:00
}
2020-06-30 14:20:45 +00:00
2020-06-30 15:37:12 +00:00
IMailFolder IMAPInbox = client.Inbox;
IMAPInbox.Open(FolderAccess.ReadWrite);
2020-07-01 16:56:15 +00:00
if (m_debug)
m_log.Info("[" + Name + "] Found " + IMAPInbox.Count + " messages.");
2020-06-30 15:37:12 +00:00
for (int i = 0; i < IMAPInbox.Count; i++)
2020-06-30 14:20:45 +00:00
{
2020-06-30 15:37:12 +00:00
MimeMessage message = IMAPInbox.GetMessage(i);
foreach (MailboxAddress adress in message.To.Mailboxes)
2020-06-30 14:20:45 +00:00
{
2020-07-01 16:07:20 +00:00
try
{
2020-07-01 16:45:41 +00:00
if (m_debug)
{
m_log.Info("[" + Name + "] Message To: " + adress.Address);
m_log.Info("[" + Name + "] Objekt ID: " + adress.Address.Split('@')[0]);
}
2020-07-01 16:07:20 +00:00
String UUIDString = adress.Address.Split('@')[0].Trim();
if(isUUID(UUIDString))
{
UUID objID = UUID.Parse(UUIDString);
SceneObjectPart sceneObject = m_scene.GetSceneObjectPart(objID);
if (sceneObject != null)
{
2020-07-01 16:27:40 +00:00
m_messages.Add(new InternalMail(message, objID));
2020-07-01 16:07:20 +00:00
IMAPInbox.SetFlags(i, MessageFlags.Deleted, true);
2020-07-01 16:45:41 +00:00
if (m_debug)
m_log.Info("[" + Name + "] Get Message for objekt " + sceneObject.Name + " (" + sceneObject.UUID + ")");
2020-07-01 16:07:20 +00:00
}
}
2020-07-01 16:09:05 +00:00
else
{
IMAPInbox.SetFlags(i, MessageFlags.Deleted, true);
}
2020-07-01 16:07:20 +00:00
}catch(Exception _innerEroor)
2020-06-30 15:37:12 +00:00
{
2020-07-01 16:07:20 +00:00
m_log.Error("[" + Name + "] " + _innerEroor.Message);
2020-06-30 15:37:12 +00:00
IMAPInbox.SetFlags(i, MessageFlags.Deleted, true);
}
2020-06-30 14:20:45 +00:00
}
}
2020-06-30 15:37:12 +00:00
IMAPInbox.Expunge();
client.Disconnect(true);
}
}catch(Exception _error)
{
m_log.Error("[" + Name + "] " + _error.Message);
2020-06-30 14:20:45 +00:00
}
}
2020-06-30 06:46:07 +00:00
2020-07-01 19:43:42 +00:00
private void sendAllMails(object sender, ElapsedEventArgs e)
2020-06-30 06:46:07 +00:00
{
2020-07-01 20:06:52 +00:00
int _currentUnixTime = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
2020-07-01 19:43:42 +00:00
if (m_sendMessages.Count == 0)
return;
2020-07-01 20:22:06 +00:00
if ((m_sending + 2) > _currentUnixTime)
2020-07-01 20:06:52 +00:00
return;
2020-07-01 20:14:54 +00:00
List<MimeMessage> _messageToSend = new List<MimeMessage>();
2020-07-01 20:06:52 +00:00
2020-07-01 20:14:54 +00:00
lock (m_sendMessages)
{
_messageToSend.AddRange(m_sendMessages);
m_sendMessages = new List<MimeMessage>();
}
m_log.Info("[" + Name + "] Sending " + _messageToSend.Count + " Mails.");
2020-07-01 19:51:45 +00:00
2020-07-01 19:36:10 +00:00
try
{
using (var client = new SmtpClient())
2020-06-30 09:50:25 +00:00
{
2020-07-01 19:36:10 +00:00
client.CheckCertificateRevocation = false;
client.Timeout = 10000;
if (SMTP_SERVER_SSL == true)
{
client.Connect(SMTP_SERVER_HOSTNAME, SMTP_SERVER_PORT, SecureSocketOptions.Auto);
}
else if (SMTP_SERVER_TLS == true)
{
client.Connect(SMTP_SERVER_HOSTNAME, SMTP_SERVER_PORT, SecureSocketOptions.StartTlsWhenAvailable);
}
else
{
client.Connect(SMTP_SERVER_HOSTNAME, SMTP_SERVER_PORT, SecureSocketOptions.None);
}
2020-06-30 07:54:27 +00:00
2020-07-01 19:36:10 +00:00
if (SMTP_SERVER_LOGIN != String.Empty && SMTP_SERVER_PASSWORD != String.Empty)
client.Authenticate(SMTP_SERVER_LOGIN, SMTP_SERVER_PASSWORD);
2020-06-30 07:54:27 +00:00
2020-07-01 20:14:54 +00:00
foreach (MimeMessage message in _messageToSend)
2020-07-01 19:43:42 +00:00
{
2020-07-01 20:14:54 +00:00
try
2020-07-01 19:43:42 +00:00
{
2020-07-01 20:14:54 +00:00
client.Send(message);
}
catch (Exception _innerError)
{
m_log.Error("[" + Name + "] " + _innerError.Message);
2020-07-01 19:43:42 +00:00
}
}
2020-07-01 19:36:10 +00:00
client.Disconnect(true);
}
2020-07-01 19:43:42 +00:00
}
catch(Exception _error)
{
m_log.Error("[" + Name + "] " + _error.Message);
}
}
public void SendEmail(UUID objectID, string address, string subject, string body)
{
2020-07-01 19:49:54 +00:00
SceneObjectPart sceneObject = m_scene.GetSceneObjectPart(objectID);
2020-07-01 20:06:52 +00:00
m_sending = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
2020-07-01 19:49:54 +00:00
2020-07-01 19:43:42 +00:00
try
{
2020-07-01 19:49:54 +00:00
lock(m_sendMessages)
{
MimeMessage message = new MimeMessage();
message.From.Add(new MailboxAddress(sceneObject.Name, sceneObject.UUID + "@" + SMTP_SERVER_SENDER));
message.To.Add(new MailboxAddress("", address));
message.Subject = subject;
message.Body = new TextPart("plain") { Text = body };
2020-07-01 19:43:42 +00:00
2020-07-01 19:49:54 +00:00
message.Headers.Add(new Header(Encoding.UTF8, "ObjectID", sceneObject.UUID.ToString()));
message.Headers.Add(new Header(Encoding.UTF8, "AvatarID", sceneObject.OwnerID.ToString()));
message.Headers.Add(new Header(Encoding.UTF8, "Location", m_scene.Name + "@" + sceneObject.GetWorldPosition().ToString()));
2020-07-01 19:43:42 +00:00
2020-07-01 19:49:54 +00:00
m_sendMessages.Add(message);
}
2020-07-01 19:43:42 +00:00
2020-07-01 19:36:10 +00:00
}catch(Exception _error)
{
m_log.Error("[" + Name + "] " + _error.Message);
2020-06-30 07:54:27 +00:00
}
2020-06-30 06:46:07 +00:00
}
public Email GetNextEmail(UUID objectID, string sender, string subject)
{
m_requester = true;
2020-06-30 14:20:45 +00:00
SceneObjectPart sceneObject = m_scene.GetSceneObjectPart(objectID);
2020-07-01 16:21:50 +00:00
2020-07-01 16:38:05 +00:00
if(sceneObject != null)
{
List<InternalMail> messages = m_messages.FindAll(X => X.ID == objectID);
if (messages.Count == 0)
return null;
2020-07-01 16:21:50 +00:00
2020-07-01 19:19:08 +00:00
foreach (InternalMail mail in messages)
2020-07-01 16:38:05 +00:00
{
2020-07-01 19:19:08 +00:00
if (mail.Mail != null)
2020-07-01 16:45:41 +00:00
{
Email lslMessage = new Email();
lslMessage.time = DateTime.Now.ToShortTimeString();
2020-07-01 16:48:25 +00:00
2020-07-01 19:19:08 +00:00
if (mail.Mail.TextBody != null)
lslMessage.message = mail.Mail.TextBody.ToString();
2020-07-01 16:48:25 +00:00
2020-07-01 19:19:08 +00:00
if (mail.Mail.From[0] != null)
2020-07-01 19:30:21 +00:00
lslMessage.sender = mail.Mail.From[0].ToString().Split(' ').Last().Replace("<", "").Replace(">", "");
2020-07-01 16:48:25 +00:00
2020-07-01 19:19:08 +00:00
if (mail.Mail.Subject != null)
lslMessage.subject = mail.Mail.Subject;
2020-07-01 16:48:25 +00:00
2020-07-01 16:45:41 +00:00
lslMessage.numLeft = messages.Count - 1;
2020-07-01 19:19:08 +00:00
if ((lslMessage.sender == sender || sender == "") && (lslMessage.subject == subject || subject == ""))
2020-07-01 19:15:44 +00:00
{
2020-07-01 19:19:08 +00:00
m_messages.Remove(mail);
2020-07-01 19:15:44 +00:00
return lslMessage;
}
2020-07-01 16:45:41 +00:00
}
2020-07-01 16:38:05 +00:00
}
2020-07-01 16:45:41 +00:00
2020-07-01 19:19:08 +00:00
return null;
2020-07-01 16:38:05 +00:00
}
else
{
2020-07-01 16:45:41 +00:00
if (m_debug)
m_log.Error("[" + Name + "] Cant find caller objekt!");
2020-07-01 16:38:05 +00:00
return null;
}
2020-06-30 06:46:07 +00:00
}
2020-07-01 16:07:20 +00:00
public bool isUUID(string thing)
{
UUID test;
2020-07-01 16:11:39 +00:00
return UUID.TryParse(thing, out test) ? true : false;
2020-07-01 16:07:20 +00:00
}
2020-06-30 06:21:49 +00:00
}
}