Exemplo n.º 1
0
        /// <summary>
        /// Moves messages from the trash mailbox back to the inbox.
        /// </summary>
        /// <param name="messages">The messages to move.</param>
        internal async Task RestoreMessagesAsync(MailMessageContext[] messages)
        {
            try {
                if (messages.Length < 1)
                {
                    return;
                }

                var inbox = messages.First().Mailbox.Account.GetInbox();
                using (var connection = new ImapConnection {
                    Security = _account.ImapSecurity
                }) {
                    using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                        using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                            var mailbox = await session.SelectAsync(Name);

                            if (IsTrash)
                            {
                                await mailbox.MoveMailsAsync(messages.Select(x => x.Uid).ToArray(), inbox.Name);
                            }
                        }
                    }
                }

                await DeleteMessagesAsync(messages, _account.GetTrashMailbox().Name);

                App.Context.NotifyMessagesRemoved(messages);
            } catch (Exception ex) {
                Logger.Error(ex);
            }
        }
Exemplo n.º 2
0
        internal async Task MarkAsSeenAsync(MailMessageContext[] messages)
        {
            Application.Current.AssertBackgroundThread();

            try {
                messages.ForEach(x => x.IsSeen = true);
                var uids = messages.Select(x => x.Uid).ToArray();

                using (var connection = new ImapConnection {
                    Security = _account.ImapSecurity
                }) {
                    connection.RemoteCertificateValidationFailed += (sender, e) => e.IsCanceled = false;
                    using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                        using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                            var folder = await session.SelectAsync(Name);

                            await folder.MarkAsSeenAsync(uids);
                        }
                    }
                }

                await CountNotSeenAsync();
            } catch (Exception ex) {
                messages.ForEach(x => x.IsSeen = false);
                Logger.Error(ex);
            }
        }
        public async Task <HealthCheckResult> CheckHealthAsync(HealthCheckContext context, CancellationToken cancellationToken = default)
        {
            try
            {
                _imapConnection = new ImapConnection(_options);

                if (await _imapConnection.ConnectAsync())
                {
                    if (_options.AccountOptions.Login)
                    {
                        return(await ExecuteAuthenticatedUserActions(context));
                    }
                }
                else
                {
                    return(new HealthCheckResult(context.Registration.FailureStatus, description: $"Connection to server {_options.Host} has failed - SSL Enabled : {_options.ConnectionType}"));
                }

                return(HealthCheckResult.Healthy());
            }
            catch (Exception ex)
            {
                return(new HealthCheckResult(context.Registration.FailureStatus, exception: ex));
            }
            finally
            {
                _imapConnection.Dispose();
            }
        }
Exemplo n.º 4
0
        public async Task <(string, bool)> IsHealthy(HttpContext context, LivenessExecutionContext livenessContext, CancellationToken cancellationToken = default)
        {
            try
            {
                _imapConnection = new ImapConnection(_options);

                if (await _imapConnection.ConnectAsync())
                {
                    if (_options.AccountOptions.login)
                    {
                        return(await ExecuteAuthenticatedUserActions());
                    }
                }
                else
                {
                    return($"Connection to server {_options.Host} has failed - SSL Enabled : {_options.ConnectionType}", false);
                }

                return(BeatPulseKeys.BEATPULSE_HEALTHCHECK_DEFAULT_OK_MESSAGE, true);
            }
            catch (Exception ex)
            {
                var message = !livenessContext.IsDevelopment ? string.Format(BeatPulseKeys.BEATPULSE_HEALTHCHECK_DEFAULT_ERROR_MESSAGE, livenessContext.Name)
                   : $"Exception {ex.GetType().Name} with message ('{ex.Message}')";

                return(message, false);
            }
            finally
            {
                _imapConnection.Dispose();
            }
        }
Exemplo n.º 5
0
        internal async Task IdleAsync()
        {
            try {
                using (var connection = new ImapConnection {
                    Security = _account.ImapSecurity
                }) {
                    connection.RemoteCertificateValidationFailed += (sender, e) => e.IsCanceled = false;
                    using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                        using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                            if (!connection.CanIdle)
                            {
                                return;
                            }
                            var mailbox = await session.SelectAsync(Name);

                            try {
                                IsIdling = true;
                                mailbox.ChangeNotificationReceived += OnChangeNotificationReceived;
                                await mailbox.IdleAsync();
                            } finally {
                                mailbox.ChangeNotificationReceived -= OnChangeNotificationReceived;
                                IsIdling = false;
                            }
                        }
                    }
                }
            } catch (Exception ex) {
                Logger.Error(ex);
            }
        }
Exemplo n.º 6
0
 public ImapMailbox(ConnectionParameters connectionParameters, ImapAuthenticationParameters authenticationParameters, ImapServerParameters serverParameters, SmtpServerParameters smtpParameters) : base(LocalMailboxFlags.None)
 {
     this.ConnectionParameters     = connectionParameters;
     this.AuthenticationParameters = authenticationParameters;
     this.ServerParameters         = serverParameters;
     this.SmtpParameters           = smtpParameters;
     this.ImapConnection           = ImapConnection.CreateInstance(connectionParameters);
 }
Exemplo n.º 7
0
        internal async Task DeleteMessagesAsync(MailMessageContext[] messages, string trashFolder)
        {
            var uids = messages.Select(x => x.Uid).ToArray();

            using (var connection = new ImapConnection {
                Security = _account.ImapSecurity
            }) {
                using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                    using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                        var mailbox = await session.SelectAsync(Name);

                        if (IsTrash)
                        {
                            await mailbox.DeleteMailsAsync(uids);
                        }
                        else
                        {
                            await mailbox.MoveMailsAsync(uids, trashFolder);
                        }
                    }
                }
            }

            using (var context = new DatabaseContext()) {
                await context.Database.Connection.OpenAsync();

                foreach (var message in messages)
                {
                    var id = message.Id;
                    using (var transaction = context.Database.BeginTransaction()) {
                        try {
                            var mime = await context.MimeMessages
                                       .FirstOrDefaultAsync(x => x.MessageId == id);

                            context.MimeMessages.Remove(mime);
                            await context.SaveChangesAsync();

                            var model = new MailMessageModel {
                                Id        = message.Id,
                                MailboxId = Id
                            };

                            context.MailMessages.Attach(model);
                            context.MailMessages.Remove(model);

                            await context.SaveChangesAsync();

                            transaction.Commit();

                            App.Context.NotifyMessageRemoved(message);
                        } catch (Exception) {
                            transaction.Rollback();
                        }
                    }
                }
            }
        }
Exemplo n.º 8
0
        private IEnumerable <ImapMessageRec> EnumerateMessagesInfoFromImapServer(ImapConnection imapConnection, EnumerateMessagesParams enumerateParams)
        {
            if (enumerateParams.LowFetchValue > enumerateParams.HighFetchValue)
            {
                return(new List <ImapMessageRec>(0));
            }
            ImapResultData messageInfoByRange = imapConnection.GetMessageInfoByRange(enumerateParams.LowFetchValue.ToString(CultureInfo.InvariantCulture), enumerateParams.HighFetchValue.ToString(CultureInfo.InvariantCulture), enumerateParams.FetchMessagesFlags.HasFlag(FetchMessagesFlags.FetchByUid), enumerateParams.FetchMessagesFlags.HasFlag(FetchMessagesFlags.IncludeExtendedData) ? ImapConnection.MessageInfoDataItemsForNewMessages : ImapConnection.MessageInfoDataItemsForChangesOnly);

            return(this.GetImapMessageRecsFromResultData(messageInfoByRange, enumerateParams.FetchMessagesFlags));
        }
Exemplo n.º 9
0
        public List <ImapMessageRec> LookupMessages(ImapConnection imapConnection, List <uint> uidList)
        {
            this.SelectImapFolder(imapConnection);
            LookupMessagesParams         lookupParams = new LookupMessagesParams(uidList);
            IEnumerable <ImapMessageRec> collection   = this.LookupMessagesInfoFromImapServer(imapConnection, lookupParams);
            List <ImapMessageRec>        list         = new List <ImapMessageRec>(collection);

            list.Sort();
            return(list);
        }
Exemplo n.º 10
0
        public async void StartAccepting()
        {
            // Establish the local endpoint for the socket.
            var localEndPoint = new IPEndPoint(IPAddress.Any, ((IPEndPoint)this.LocalEndpoint).Port);

            // Create a TCP/IP socket.
            var listener = new ImapListener(this.server, localEndPoint);

            // Bind the socket to the local endpoint and listen for incoming connections.
            try
            {
                listener.Start(100);

                while (true)
                {
                    // Start an asynchronous socket to listen for connections.
                    var handler = await listener.AcceptTcpClientAsync();

                    // Create the state object.
                    ImapConnection imapConnection;

                    if (this.PortType == PortClass.ClearText || this.PortType == PortClass.ExplicitTLS)
                    {
                        var stream = handler.GetStream();

                        imapConnection = new ImapConnection(_Store, this.server, handler, stream);
                    }
                    else
                    {
                        var stream    = handler.GetStream();
                        var sslStream = new SslStream(stream);

                        try
                        {
                            await sslStream.AuthenticateAsServerAsync(this.server.ServerAuthenticationCertificate);
                        }
                        catch (IOException ioe)
                        {
                            _Logger.Error("I/O Exception attempting to perform TLS handshake", ioe);
                            return;
                        }

                        imapConnection = new ImapConnection(_Store, this.server, handler, sslStream, true);
                    }

                    this.server.AddConnection(imapConnection);

                    imapConnection.Process();
                }
            }
            catch (Exception ex)
            {
                _Logger.Error("Exception when trying to accept connection from listener", ex);
            }
        }
        // Token: 0x06000F80 RID: 3968 RVA: 0x0003F3BC File Offset: 0x0003D5BC
        protected override OperationStatusCode TestUserCanLogonWithCurrentSettings(SmtpAddress email, string userName, SecureString password)
        {
            OperationStatusCode result;

            using (ImapConnection imapConnection = ImapConnection.CreateInstance(this.connectionParameters))
            {
                ImapServerParameters serverParameters = new ImapServerParameters(this.ServerName, this.Port);
                result = imapConnection.TestLogon(serverParameters, new ImapAuthenticationParameters(userName, password, this.Authentication, this.Security), ImapConnectionSettings.requiredCapabilities);
            }
            return(result);
        }
Exemplo n.º 12
0
 internal void RemoveConnection([NotNull] ImapConnection ImapConnection)
 {
     this.connections.Remove(ImapConnection);
     if (ImapConnection.Identity == null)
     {
         Logger.VerboseFormat("Disconnection from {0}:{1}", ImapConnection.RemoteAddress, ImapConnection.RemotePort, ImapConnection.LocalAddress, ImapConnection.LocalPort);
     }
     else
     {
         Logger.VerboseFormat("Disconnection from {0}:{1} ({2})", ImapConnection.RemoteAddress, ImapConnection.RemotePort, ImapConnection.LocalAddress, ImapConnection.LocalPort, ImapConnection.Identity.Username);
     }
 }
Exemplo n.º 13
0
 internal async Task <List <ImapMailboxInfo> > ListSubscribedMailboxesAsync(string pattern = "")
 {
     using (var connection = new ImapConnection {
         Security = ImapSecurity
     }) {
         connection.RemoteCertificateValidationFailed += (sender, e) => e.IsCanceled = false;
         using (var auth = await connection.ConnectAsync(ImapHost, ImapPort)) {
             using (var session = await auth.LoginAsync(ImapUsername, ImapPassword)) {
                 var wildcard = string.IsNullOrEmpty(pattern) ? "%" : pattern;
                 return(await session.LSubAsync("", ImapMailbox.EncodeName(wildcard)));
             }
         }
     }
 }
Exemplo n.º 14
0
        private async Task DeleteAsync()
        {
            using (var connection = new ImapConnection {
                Security = _account.ImapSecurity
            }) {
                using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                    using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                        await session.DeleteMailboxAsync(Name);
                    }
                }
            }

            await DeleteLocalAsync();

            _account.NotifyMailboxRemoved(this);
        }
Exemplo n.º 15
0
        private async Task UnsubscribeAsync()
        {
            using (var connection = new ImapConnection {
                Security = _account.ImapSecurity
            }) {
                using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                    using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                        await session.UnsubscribeAsync(Name);
                    }
                }
            }

            using (var database = new DatabaseContext()) {
                var mailbox = await database.Mailboxes.FindAsync(_mailbox.Id);

                mailbox.IsSubscribed = false;
                await database.SaveChangesAsync();
            }
        }
Exemplo n.º 16
0
        public async Task CreateMailboxAsync(string mailbox)
        {
            using (var connection = new ImapConnection {
                Security = _account.ImapSecurity
            }) {
                using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                    using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                        var name = string.Format("{0}{1}{2}", Name, Delimiter, mailbox);
                        await session.CreateMailboxAsync(name);
                    }
                }
            }

            // Reset to allow new mailboxes to be discovered.
            _isSyncedInitially = false;
            await Task.Run(() => SyncMailboxesAsync());

            IsExpanded = true;
        }
Exemplo n.º 17
0
        internal async Task RestoreMessagesAsync(ICollection <MailMessageContext> messages)
        {
            try {
                var inbox = GetInbox();
                var trash = GetTrashMailbox();
                using (var connection = new ImapConnection {
                    Security = _account.ImapSecurity
                }) {
                    using (var auth = await connection.ConnectAsync(_account.ImapHost, _account.ImapPort)) {
                        using (var session = await auth.LoginAsync(_account.ImapUsername, _account.ImapPassword)) {
                            var mailbox = await session.SelectAsync(trash.Name);

                            await mailbox.MoveMailsAsync(messages.Select(x => x.Uid).ToArray(), inbox.Name);
                        }
                    }
                }

                using (var database = new DatabaseContext()) {
                    foreach (var message in messages)
                    {
                        try {
                            var model = new MailMessageModel {
                                Id        = message.Id,
                                MailboxId = Id
                            };

                            database.MailMessages.Attach(model);
                            database.MailMessages.Remove(model);
                        } catch (Exception ex) {
                            Logger.Error(ex);
                            throw;
                        }
                    }
                    await database.SaveChangesAsync();
                }

                App.Context.NotifyMessagesRemoved(messages);
            } catch (Exception ex) {
                Logger.Error(ex);
            }
        }
Exemplo n.º 18
0
        private async Task TestImapSettingsAsync()
        {
            Testing = new TestingContext {
                Message = Resources.TestingImapStatus
            };

            try {
                using (var connection = new ImapConnection {
                    Security = ImapSecurity
                }) {
                    using (var auth = await connection.ConnectAsync(ImapHost, ImapPort)) {
                        await auth.LoginAsync(ImapUsername, ImapPassword);
                    }
                }
            } catch (Exception ex) {
                Testing = new TestingContext {
                    IsFaulted = true,
                    Message   = ex.Message
                };
                Logger.Error(ex);
            }
        }
Exemplo n.º 19
0
        public List <ImapMessageRec> EnumerateMessages(ImapConnection imapConnection, FetchMessagesFlags flags, int?highFetchValue = null, int?lowFetchValue = null)
        {
            ImapMailbox imapMailbox      = imapConnection.SelectImapMailbox(this.folder);
            int?        numberOfMessages = imapMailbox.NumberOfMessages;

            if (numberOfMessages == null || numberOfMessages.Value == 0)
            {
                MrsTracer.Provider.Debug("Imap folder {0} does not have any messages to be enumerated", new object[]
                {
                    this.Name
                });
                return(new List <ImapMessageRec>(0));
            }
            int highFetchValue2 = highFetchValue ?? numberOfMessages.Value;
            int lowFetchValue2  = lowFetchValue ?? 1;
            EnumerateMessagesParams      enumerateParams = new EnumerateMessagesParams(highFetchValue2, lowFetchValue2, flags);
            IEnumerable <ImapMessageRec> collection      = this.EnumerateMessagesInfoFromImapServer(imapConnection, enumerateParams);
            List <ImapMessageRec>        list            = new List <ImapMessageRec>(collection);

            list.Sort();
            return(list);
        }
Exemplo n.º 20
0
        public async Task <LivenessResult> IsHealthy(LivenessExecutionContext context, CancellationToken cancellationToken = default)
        {
            try
            {
                _logger?.LogInformation($"{nameof(ImapLiveness)} is checking IMAP entries.");

                _imapConnection = new ImapConnection(_options);

                if (await _imapConnection.ConnectAsync())
                {
                    if (_options.AccountOptions.Login)
                    {
                        return(await ExecuteAuthenticatedUserActions());
                    }
                }
                else
                {
                    _logger?.LogWarning($"{nameof(ImapLiveness)} fail connect to server {_options.Host}- SSL Enabled : {_options.ConnectionType}.");

                    return(LivenessResult.UnHealthy($"Connection to server {_options.Host} has failed - SSL Enabled : {_options.ConnectionType}"));
                }

                _logger?.LogInformation($"The {nameof(ImapLiveness)} check success.");

                return(LivenessResult.Healthy());
            }
            catch (Exception ex)
            {
                _logger?.LogWarning($"The {nameof(ImapLiveness)} check fail with the exception {ex.ToString()}.");

                return(LivenessResult.UnHealthy(ex));
            }
            finally
            {
                _imapConnection.Dispose();
            }
        }
Exemplo n.º 21
0
        static void Main(string[] args)
        {
            var devEnvironmentVariable = Environment.GetEnvironmentVariable("NETCORE_ENVIRONMENT");

            var isDevelopment = string.IsNullOrEmpty(devEnvironmentVariable) ||
                                devEnvironmentVariable.ToLower() == "development";
            //Determines the working environment as IHostingEnvironment is unavailable in a console app

            var builder = new ConfigurationBuilder();

            // tell the builder to look for the appsettings.json file
            builder
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true);

            //only add secrets in development
            if (isDevelopment)
            {
                builder.AddUserSecrets <Program>();
            }

            using (
                var connection = new ImapConnection(
                    builder.Build().Get <ImapConfiguration>()
                    )
                )
            {
                connection.Connect();

                foreach (var email in new LatestEmails(connection, 10))
                {
                    Console.WriteLine($"Email from: {email.From}");
                    Console.WriteLine($"Subject: {email.Subject}");
                }
                Console.WriteLine("Press any key");
                Console.ReadKey();
            }
        }
Exemplo n.º 22
0
        private async Task <byte[]> FetchMimeAsync()
        {
            var mailbox = await GetMailboxAsync();

            var account = await GetAccountAsync(mailbox);

            using (var connection = new ImapConnection {
                Security = account.ImapSecurity
            }) {
                connection.RemoteCertificateValidationFailed += (sender, e) => e.IsCanceled = false;
                using (var auth = await connection.ConnectAsync(account.ImapHost, account.ImapPort)) {
                    using (var session = await auth.LoginAsync(account.ImapUsername, account.ImapPassword)) {
                        var folder = await session.SelectAsync(mailbox.Name);

                        folder.ByteCountChanged += OnByteCountChanged;
                        var mime = await folder.FetchMessageBodyAsync(Uid);

                        folder.ByteCountChanged -= OnByteCountChanged;

                        return(mime);
                    }
                }
            }
        }
Exemplo n.º 23
0
 public void SelectImapFolder(ImapConnection imapConnection)
 {
     imapConnection.SelectImapMailbox(this.folder);
 }
Exemplo n.º 24
0
 internal void AddConnection([NotNull] ImapConnection ImapConnection)
 {
     this.connections.Add(ImapConnection);
     Logger.VerboseFormat("Connection from {0}:{1} to {2}:{3}", ImapConnection.RemoteAddress, ImapConnection.RemotePort, ImapConnection.LocalAddress, ImapConnection.LocalPort);
 }
Exemplo n.º 25
0
 internal void SetImapConnectionFromTestOnly(ImapConnection imapConnection)
 {
     this.ImapConnection = imapConnection;
 }
        private async Task <HealthCheckResult> ExecuteAuthenticatedUserActions(HealthCheckContext context, ImapConnection imapConnection)
        {
            var(User, Password) = _options.AccountOptions.Account;

            if (await imapConnection.AuthenticateAsync(User, Password))
            {
                if (_options.FolderOptions.CheckFolder &&
                    !await imapConnection.SelectFolder(_options.FolderOptions.FolderName))
                {
                    return(new HealthCheckResult(context.Registration.FailureStatus, description: $"Folder {_options.FolderOptions.FolderName} check failed."));
                }

                return(HealthCheckResult.Healthy());
            }
            else
            {
                return(new HealthCheckResult(context.Registration.FailureStatus, description: $"Login on server {_options.Host} failed with configured user"));
            }
        }
Exemplo n.º 27
0
 public ImapMailbox(ImapConnection imapConnection) : base(LocalMailboxFlags.None)
 {
     this.ImapConnection = imapConnection;
 }
Exemplo n.º 28
0
        private IEnumerable <ImapMessageRec> LookupMessagesInfoFromImapServer(ImapConnection imapConnection, LookupMessagesParams lookupParams)
        {
            ImapResultData messageInfoByRange = imapConnection.GetMessageInfoByRange(lookupParams.GetUidFetchString(), null, lookupParams.FetchMessagesFlags.HasFlag(FetchMessagesFlags.FetchByUid), lookupParams.FetchMessagesFlags.HasFlag(FetchMessagesFlags.IncludeExtendedData) ? ImapConnection.MessageInfoDataItemsForNewMessages : ImapConnection.MessageInfoDataItemsForChangesOnly);

            return(this.GetImapMessageRecsFromResultData(messageInfoByRange, lookupParams.FetchMessagesFlags));
        }
Exemplo n.º 29
0
        internal async Task <ICollection <MailMessageContext> > SyncMessagesAsync()
        {
            ICollection <MailMessageContext> contexts;

            lock (_syncMessagesMutex) {
                if (IsSyncingMessages)
                {
                    return(new MailMessageContext[0]);
                }

                IsSyncingMessages = true;
            }

            try {
                var name   = _mailbox.Name;
                var maxUid = await GetMaxUidAsync();

                var account = await GetAccountAsync();

                var messages = new List <MailMessageModel>();

                using (var connection = new ImapConnection {
                    Security = account.ImapSecurity
                }) {
                    using (var auth = await connection.ConnectAsync(account.ImapHost, account.ImapPort)) {
                        using (var session = await auth.LoginAsync(account.ImapUsername, account.ImapPassword)) {
                            var mailbox = await session.SelectAsync(name);

                            messages.AddRange(await SyncChallengesAsync(mailbox, maxUid));
                            messages.AddRange(await SyncNonChallengesAsync(mailbox, maxUid));
                        }
                    }
                }

                if (messages.Count == 0)
                {
                    FetchedEnvelopeCount = 0;

                    lock (_syncMessagesMutex) {
                        IsSyncingMessages = false;
                    }

                    return(new MailMessageContext[0]);
                }

                await SaveContactsAsync(messages);
                await SaveMessagesAsync(messages);

                contexts = messages.Where(x => x.Type == MailType.Message)
                           .Select(x => new MailMessageContext(this, x)).ToArray();

                FetchedEnvelopeCount = 0;

                await Application.Current.Dispatcher
                .InvokeAsync(() => App.Context.NotifyMessagesAdded(contexts));

                await CountNotSeenAsync();
            } finally {
                lock (_syncMessagesMutex) {
                    IsSyncingMessages = false;
                }
            }

            return(contexts);
        }