public static bool Test(MailBox account)
        {
            BaseProtocolClient ingoing_client = (account.Imap) ? (BaseProtocolClient)MailClientBuilder.Imap() : MailClientBuilder.Pop();

            MailServerHelper.Test(ingoing_client, new MailServerSettings
            {
                Url                = account.Server,
                Port               = account.Port,
                AccountName        = account.Account,
                AccountPass        = account.Password,
                AuthenticationType = account.AuthenticationTypeIn,
                EncryptionType     = account.IncomingEncryptionType
            });

            MailServerHelper.TestSmtp(new MailServerSettings
            {
                Url                = account.SmtpServer,
                Port               = account.SmtpPort,
                AccountName        = account.SmtpAccount,
                AccountPass        = account.SmtpPassword,
                AuthenticationType = account.AuthenticationTypeSmtp,
                EncryptionType     = account.OutcomingEncryptionType
            });

            return(true);
        }
Example #2
0
        public static string Authorize(this BaseProtocolClient ingoingMailClient, MailServerSettings settings, int waitTimeout = 5000, ILogger log = null)
        {
            if (log == null)
            {
                log = new NullLogger();
            }

            string lastResponse;

            switch (settings.EncryptionType)
            {
            case EncryptionType.SSL:
                //var timeout = TimeSpan.FromMinutes(3); // 3 minutes
                log.Debug("SSL connecting to {0} ", settings.Url);                        // (timeout = {1} minutes)", settings.Url, timeout.TotalMinutes);
                lastResponse = ingoingMailClient.ConnectSsl(settings.Url, settings.Port); //, (int)timeout.TotalMilliseconds);

                break;

            default:
                log.Debug("PLAIN connecting to {0}", settings.Url);
                lastResponse = ingoingMailClient.ConnectPlain(settings.Url, settings.Port);

                if (ingoingMailClient is SmtpClient &&
                    (settings.AuthenticationType != SaslMechanism.None ||
                     settings.EncryptionType == EncryptionType.StartTLS))
                {
                    lastResponse = ingoingMailClient.SendEhloHelo();
                }

                if (settings.EncryptionType == EncryptionType.StartTLS)
                {
                    log.Debug("StartTLS {0}", settings.Url);
                    lastResponse = ingoingMailClient.StartTLS(settings.Url);
                }

                break;
            }

            if (settings.AuthenticationType == SaslMechanism.Login)
            {
                log.Debug("Login as {0} with secret password", settings.AccountName);
                lastResponse = ingoingMailClient.Login(settings.AccountName, settings.AccountPass);
            }
            else
            {
                if (ingoingMailClient is SmtpClient && settings.AuthenticationType == SaslMechanism.None)
                {
                    log.Debug("Authentication not required");
                    return(lastResponse);
                }

                log.Debug("Authenticate as {0} with secret password", settings.AccountName);
                lastResponse = ingoingMailClient.Authenticate(settings.AccountName, settings.AccountPass, settings.AuthenticationType);
            }

            return(lastResponse);
        }
Example #3
0
        public static bool Test(BaseProtocolClient ingoingMailClient, MailServerSettings settings)
        {
            try
            {
                var sResult = ingoingMailClient.Authorize(settings, settings.MailServerOperationTimeoutInMilliseconds);
                if (sResult.ToLower().IndexOf("success", StringComparison.Ordinal) == -1 &&
                    sResult.ToLower().IndexOf("+", StringComparison.Ordinal) == -1 &&
                    sResult.ToLower().IndexOf("ok", StringComparison.Ordinal) == -1)
                {
                    if (ingoingMailClient is Imap4Client)
                        throw new ImapConnectionException(sResult);
                    if(ingoingMailClient is Pop3Client)
                        throw new Pop3ConnectionException(sResult);
                    else
                        throw new SmtpConnectionException(sResult);
                }

                return true;
            }
            catch (TargetInvocationException exTarget)
            {
                if (ingoingMailClient is Imap4Client)
                        throw new ImapConnectionException(exTarget.InnerException.Message);
                    if(ingoingMailClient is Pop3Client)
                        throw new Pop3ConnectionException(exTarget.InnerException.Message);
                    else
                        throw new SmtpConnectionException(exTarget.InnerException.Message);
            }
            catch (TimeoutException)
            {
                if (ingoingMailClient is Imap4Client)
                    throw new ImapConnectionTimeoutException();
                if (ingoingMailClient is Pop3Client)
                    throw new Pop3ConnectionTimeoutException();
                else
                    throw new SmtpConnectionTimeoutException();
            }
            finally
            {
                if (ingoingMailClient.IsConnected)
                {
                    try
                    {
                        ingoingMailClient.Disconnect();
                    }
                    catch {}
                    
                }
            }
        }
Example #4
0
        private static BaseProtocolClient BuildMailClient(MailClientType type)
        {
            BaseProtocolClient client = null;

            switch (type)
            {
            case MailClientType.Imap:
                client = new Imap4Client();
                break;

            case MailClientType.Pop3:
                client = new Pop3Client();
                break;

            case MailClientType.Smtp:
                client = new SmtpClient();
                break;

            default:
                throw new ArgumentException(String.Format("Unknown client type: {0}", type));
            }

            try
            {
                client.SendTimeout    = Convert.ToInt32(WebConfigurationManager.AppSettings["mail.SendTcpTimeout"]);
                client.ReceiveTimeout = Convert.ToInt32(WebConfigurationManager.AppSettings["mail.RecieveTcpTimeout"]);
            }
            catch (Exception e)
            {
                client.ReceiveTimeout = 30000;
                client.SendTimeout    = 30000;

                var logger  = LogManager.GetLogger("MailBoxManager");
                var message = String.Format("Problems with config parsing for SendTimeout: {0} or RecieveTimeout: {1}. Values was reseted to default - 30000.\n",
                                            WebConfigurationManager.AppSettings["mail.SendTcpTimeout"],
                                            WebConfigurationManager.AppSettings["mail.RecieveTcpTimeout"]);
                logger.DebugException(message, e);
            }

            return(client);
        }
        public static bool TestOAuth(BaseProtocolClient client, MailBox account)
        {
            if (string.IsNullOrEmpty(account.RefreshToken))
            {
                return(false);
            }

            try
            {
                var imap4Client = client as Imap4Client;
                if (imap4Client != null)
                {
                    imap4Client.AuthenticateImapGoogleOAuth2(account);

                    return(true);
                }

                var smtpClient = client as SmtpClient;
                if (smtpClient != null)
                {
                    smtpClient.AuthenticateSmtpGoogleOAuth2(account);

                    return(true);
                }
            }
            finally
            {
                if (client.IsConnected)
                {
                    try
                    {
                        client.Disconnect();
                    }
                    catch { }
                }
            }

            return(false);
        }
Example #6
0
        protected override bool ProcessMessages(BaseProtocolClient baseProtocolClient)
        {
            var client = (Pop3Client)baseProtocolClient;

            UpdateTimeCheckedIfNeeded();

            var badMessagesExist = false;

            if (!_isUidlSupported)
            {
                log.Info("UIDL is not supported! Account '{0}' has been skiped.", Account.EMail);
                return(true);
            }

            var newMessages = GetPop3NewMessagesIDs(client);

            var quotaErrorFlag = false;

            if (client.IsConnected)
            {
                if (newMessages.Count == 0)
                {
                    log.Debug("New messages not found.\r\n");
                }
                else
                {
                    log.Debug("Found {0} new messages.\r\n", newMessages.Count);

                    if (newMessages.Count > 1)
                    {
                        log.Debug("Calculating order");

                        try
                        {
                            var firstHeader = client.RetrieveHeaderObject(newMessages.First().Key);
                            var lastHeader  = client.RetrieveHeaderObject(newMessages.Last().Key);

                            if (firstHeader.Date < lastHeader.Date)
                            {
                                log.Debug("Account '{0}' order is DESC", Account.EMail.Address);
                                newMessages = newMessages
                                              .OrderByDescending(item => item.Key) // This is to ensure that the newest message would be handled primarily.
                                              .ToDictionary(id => id.Key, id => id.Value);
                            }
                            else
                            {
                                log.Debug("Account '{0}' order is ASC", Account.EMail.Address);
                            }
                        }
                        catch (Exception)
                        {
                            log.Warn("Calculating order skipped! Account '{0}' order is ASC", Account.EMail.Address);
                        }
                    }

                    var skipOnDate = Account.BeginDate != MailBoxManager.MinBeginDate;

                    var skipBreakOnDate = MailQueueItemSettings.PopUnorderedDomains.Contains(Account.Server.ToLowerInvariant());

                    foreach (var newMessage in newMessages)
                    {
                        var hasParseError = false;

                        cancelToken.ThrowIfCancellationRequested();

                        try
                        {
                            if (_maxMessagesPerSession == 0)
                            {
                                log.Debug("Limit of max messages per session is exceeded!");
                                break;
                            }

                            if (!client.IsConnected)
                            {
                                log.Warn("POP3-server is disconnected. Skip another messages.");
                                badMessagesExist = true;
                                break;
                            }

                            log.Debug("Processing new message\tUID: {0}\tUIDL: {1}\t",
                                      newMessage.Key,
                                      newMessage.Value);

                            var message = client.RetrieveMessageObject(newMessage.Key);

                            if (message.ParseException != null)
                            {
                                log.Error(
                                    "ActiveUp: message parsed with some errors. MailboxId = {0} Message UID = \"{1}\" Error: {2}",
                                    Account.MailBoxId, newMessage.Value, message.ParseException.ToString());

                                hasParseError = true;
                            }

                            UpdateTimeCheckedIfNeeded();

                            if (message.Date < Account.BeginDate && skipOnDate)
                            {
                                if (!skipBreakOnDate)
                                {
                                    log.Info("Skip other messages older then {0}.", Account.BeginDate);
                                    break;
                                }
                                log.Debug("Skip message (Date = {0}) on BeginDate = {1}", message.Date,
                                          Account.BeginDate);
                                continue;
                            }

                            var uniqueIdentifier = string.Format("{0}|{1}|{2}|{3}",
                                                                 message.From.Email,
                                                                 message.Subject,
                                                                 message.DateString,
                                                                 message.MessageId);

                            var headerMd5 = uniqueIdentifier.GetMd5();

                            RetrieveMessage(message,
                                            MailFolder.Ids.inbox, newMessage.Value, headerMd5, hasParseError);
                        }
                        catch (Exception e)
                        {
                            var commonError =
                                string.Format(
                                    "ProcessMessages() Tenant={0} User='******' Account='{2}', MailboxId={3}, MessageIndex={4}, UIDL='{5}' Exception:\r\n{6}\r\n",
                                    Account.TenantId, Account.UserId, Account.EMail.Address, Account.MailBoxId,
                                    newMessage.Key, newMessage.Value, e);


                            if (e is IOException || e is MailBoxOutException)
                            {
                                _maxMessagesPerSession = 0; //It needed for stop messsages proccessing.
                                badMessagesExist       = true;
                                if (e is IOException)
                                {
                                    log.Error(commonError);
                                }
                                else
                                {
                                    log.Info(commonError);
                                }
                                break;
                            }

                            if (e is TenantQuotaException)
                            {
                                log.Info("Tenant {0} quota exception: {1}", Account.TenantId, e.Message);
                                quotaErrorFlag = true;
                            }
                            else
                            {
                                badMessagesExist = true;
                                log.Error(commonError);
                            }
                        }

                        UpdateTimeCheckedIfNeeded();
                        _maxMessagesPerSession--;
                    }
                }
            }
            else
            {
                log.Debug("POP3 server is disconnected.");
                badMessagesExist = true;
            }

            if (Account.QuotaError != quotaErrorFlag && !Account.QuotaErrorChanged)
            {
                Account.QuotaError        = quotaErrorFlag;
                Account.QuotaErrorChanged = true;
            }

            return(!badMessagesExist && _maxMessagesPerSession > 0);
        }
Example #7
0
        static public bool Test(BaseProtocolClient ingoing_mail_client, MailServerSettings settings)
        {
            try
            {
                IAsyncResult async_res;
                switch (settings.EncryptionType)
                {
                case EncryptionType.StartTLS:
                    async_res = ingoing_mail_client.BeginConnect(settings.Url, settings.Port, null);
                    break;

                case EncryptionType.SSL:
                    async_res = ingoing_mail_client.BeginConnectSsl(settings.Url, settings.Port, null);
                    break;

                default:
                    async_res = ingoing_mail_client.BeginConnect(settings.Url, settings.Port, null);
                    break;
                }

                if (!async_res.AsyncWaitHandle.WaitOne(WAIT_TIMEOUT))
                {
                    throw new ImapConnectionException(MailQueueItem.CONNECTION_TIMEOUT_ERROR);
                }

                if (settings.EncryptionType == EncryptionType.StartTLS)
                {
                    ingoing_mail_client.StartTLS(settings.Url);
                }

                if (settings.AuthenticationType == SaslMechanism.Login)
                {
                    ingoing_mail_client.Login(settings.AccountName, settings.AccountPass, "");
                }
                else
                {
                    async_res = ingoing_mail_client.BeginAuthenticate(settings.AccountName, settings.AccountPass, settings.AuthenticationType, null);
                }

                if (!async_res.AsyncWaitHandle.WaitOne(WAIT_TIMEOUT))
                {
                    throw new ImapConnectionException(MailQueueItem.CONNECTION_TIMEOUT_ERROR);
                }

                if (async_res.AsyncState == null)
                {
                    throw new AuthenticationException("Auth failed. Check your settings.");
                }

                string s_result = ingoing_mail_client.EndConnectSsl(async_res).ToLowerInvariant();

                if (s_result.IndexOf("success", StringComparison.Ordinal) == -1 &&
                    s_result.IndexOf("+", StringComparison.Ordinal) == -1 &&
                    s_result.IndexOf("ok", StringComparison.Ordinal) == -1)
                {
                    throw new ImapConnectionException(s_result);
                }

                return(true);
            }
            finally
            {
                if (ingoing_mail_client.IsConnected)
                {
                    ingoing_mail_client.Disconnect();
                }
            }
        }
Example #8
0
 protected abstract bool ProcessMessages(BaseProtocolClient baseProtocolClient);
Example #9
0
        protected override bool ProcessMessages(BaseProtocolClient baseProtocolClient)
        {
            var client = (Imap4Client)baseProtocolClient;

            var mailboxes =
                client.GetImapMailboxes(Account.Server, MailQueueItemSettings.DefaultFolders, MailQueueItemSettings.SpecialDomainFolders,
                                        MailQueueItemSettings.SkipImapFlags, MailQueueItemSettings.ImapFlags)
                .Reverse()
                .OrderBy(m => m.folder_id)
                .ToList();

            if (!mailboxes.Any())
            {
                log.Error("There was no folder parsed! MailboxId={0}", Account.MailBoxId);
            }

            var index = mailboxes.FindIndex(x => x.name.ToUpperInvariant() == "INBOX");

            if (index > 0)
            {
                //Move folder INBOX to top of list in order to quickly receive new messages
                var item = mailboxes[index];
                mailboxes[index] = mailboxes[0];
                mailboxes[0]     = item;
            }

            var quotaErrorByTotalFolders = false;

            foreach (var mailbox in mailboxes)
            {
                log.Info("Select imap folder: {0}", mailbox.name);

                Mailbox mbObj;

                cancelToken.ThrowIfCancellationRequested();

                if (!client.IsConnected)
                {
                    break;
                }

                try
                {
                    mbObj = client.SelectMailbox(mailbox.name);
                }
                catch (Exception ex)
                {
                    log.Error("imap.SelectMailbox(\"{0}\") in MailboxId={1} failed with exception:\r\n{2}",
                              mailbox.name, Account.MailBoxId, ex.ToString());
                    continue;
                }

                bool quotaErrorFlag;

                _maxMessagesPerSession = LoadMailboxMessage(mbObj,
                                                            mailbox.folder_id,
                                                            _maxMessagesPerSession,
                                                            mailbox.tags, out quotaErrorFlag);

                if (quotaErrorFlag)
                {
                    quotaErrorByTotalFolders = true;
                }

                if (0 == _maxMessagesPerSession)
                {
                    break;
                }

                UpdateTimeCheckedIfNeeded();
            }

            if (Account.QuotaError != quotaErrorByTotalFolders && !Account.QuotaErrorChanged)
            {
                Account.QuotaError        = quotaErrorByTotalFolders;
                Account.QuotaErrorChanged = true;
            }

            return(true);
        }
        public static string Authorize(this BaseProtocolClient ingoing_mail_client, MailServerSettings settings, int wait_timeout = 5000, ILogger log = null)
        {
            if (log == null)
            {
                log = new NullLogger();
            }

            string last_response;

            IAsyncResult async_res;

            switch (settings.EncryptionType)
            {
            case EncryptionType.SSL:
                log.Debug("SSL connecting to {0}", settings.Url);
                async_res = ingoing_mail_client.BeginConnectSsl(settings.Url, settings.Port,
                                                                result =>
                                                                log.Debug("OnConnectSSL: completed {0}",
                                                                          result.IsCompleted ? "SUCCESS" : "FAIL"));
                if (!async_res.AsyncWaitHandle.WaitOne(wait_timeout))
                {
                    log.Warn("BeginConnectSsl: operation timeout = {0} seconds",
                             TimeSpan.FromMilliseconds(wait_timeout).Seconds);
                    ingoing_mail_client.EndAsyncOperation(async_res);
                    async_res.AsyncWaitHandle.Close();
                    throw new TimeoutException();
                }
                last_response = ingoing_mail_client.EndAsyncOperation(async_res);

                break;

            default:
                log.Debug("PLAIN connecting to {0}", settings.Url);
                async_res = ingoing_mail_client.BeginConnectPlain(settings.Url, settings.Port, result =>
                                                                  log.Debug(
                                                                      "OnConnect: completed {0}",
                                                                      result
                                                                      .IsCompleted
                                                                                                           ? "SUCCESS"
                                                                                                           : "FAIL"));

                if (!async_res.AsyncWaitHandle.WaitOne(wait_timeout))
                {
                    log.Warn("BeginConnect: operation timeout = {0} seconds",
                             TimeSpan.FromMilliseconds(wait_timeout).Seconds);
                    ingoing_mail_client.EndAsyncOperation(async_res);
                    async_res.AsyncWaitHandle.Close();
                    throw new TimeoutException();
                }
                last_response = ingoing_mail_client.EndAsyncOperation(async_res);

                if (ingoing_mail_client is SmtpClient &&
                    (settings.AuthenticationType != SaslMechanism.None ||
                     settings.EncryptionType == EncryptionType.StartTLS))
                {
                    last_response = ingoing_mail_client.SendEhloHelo();
                }

                if (settings.EncryptionType == EncryptionType.StartTLS)
                {
                    log.Debug("StartTLS {0}", settings.Url);
                    last_response = ingoing_mail_client.StartTLS(settings.Url);
                }

                break;
            }

            if (settings.AuthenticationType == SaslMechanism.Login)
            {
                log.Debug("Login as {0} with secret password", settings.AccountName);
                async_res = ingoing_mail_client.BeginLogin(settings.AccountName, settings.AccountPass, result =>
                                                           log.Debug("OnLogin: completed {0}",
                                                                     result.IsCompleted ? "SUCCESS" : "FAIL"));

                if (!async_res.AsyncWaitHandle.WaitOne(wait_timeout))
                {
                    log.Warn("BeginLogin: operation timeout = {0} seconds", TimeSpan.FromMilliseconds(wait_timeout).Seconds);
                    ingoing_mail_client.EndAsyncOperation(async_res);
                    async_res.AsyncWaitHandle.Close();
                    throw new TimeoutException();
                }

                last_response = ingoing_mail_client.EndAsyncOperation(async_res);
            }
            else
            {
                if (ingoing_mail_client is SmtpClient && settings.AuthenticationType == SaslMechanism.None)
                {
                    log.Debug("Authentication not required");
                    return(last_response);
                }

                log.Debug("Authenticate as {0} with secret password", settings.AccountName);
                async_res = ingoing_mail_client.BeginAuthenticate(settings.AccountName, settings.AccountPass, settings.AuthenticationType, result =>
                                                                  log.Debug("OnAuthenticate: completed {0}",
                                                                            result.IsCompleted ? "SUCCESS" : "FAIL"));

                if (!async_res.AsyncWaitHandle.WaitOne(wait_timeout))
                {
                    log.Warn("BeginAuthenticate: operation timeout = {0} seconds", TimeSpan.FromMilliseconds(wait_timeout).Seconds);
                    ingoing_mail_client.EndAsyncOperation(async_res);
                    async_res.AsyncWaitHandle.Close();
                    throw new TimeoutException();
                }

                last_response = ingoing_mail_client.EndAsyncOperation(async_res);
            }

            return(last_response);
        }