public ImapMailbox Add(ImapMailbox mailbox) { mailbox.AttachToSession(session); mailboxes[mailbox.Name] = mailbox; return mailbox; }
private static async Task ProcessChallengeAsync(ImapEnvelope envelope, ImapMailbox mailbox) { var bytes = await mailbox.FetchMessageBodyAsync(envelope.Uid); var message = new MailMessageReader(bytes); var token = string.Empty; var nonce = string.Empty; var publicKey = string.Empty; const string pattern = @"\s|\t|\n|\r"; var xHeaders = message.Headers.UnknownHeaders; for (var i = 0; i < xHeaders.Keys.Count; i++) { var key = xHeaders.Keys[i]; var values = xHeaders.GetValues(i); if (values == null) { throw new NullReferenceException(Resources.ChallengeCorruptException); } if (string.Compare(key, ParanoiaHeaderKeys.Token, StringComparison.InvariantCultureIgnoreCase) == 0) { token = values.FirstOrDefault() ?? string.Empty; token = Regex.Replace(token, pattern, string.Empty); continue; } if (string.Compare(key, ParanoiaHeaderKeys.Nonce, StringComparison.InvariantCultureIgnoreCase) == 0) { nonce = values.FirstOrDefault() ?? string.Empty; nonce = Regex.Replace(nonce, pattern, string.Empty); continue; } if (string.Compare(key, ParanoiaHeaderKeys.PublicKey, StringComparison.InvariantCultureIgnoreCase) == 0) { publicKey = values.FirstOrDefault() ?? string.Empty; publicKey = Regex.Replace(publicKey, pattern, string.Empty); } } if (string.IsNullOrEmpty(token) || string.IsNullOrEmpty(nonce) || string.IsNullOrEmpty(publicKey)) { throw new InvalidDataException(Resources.ChallengeCorruptException); } var data = App.Context.KeyContainer.DecryptWithPrivateKey( Convert.FromBase64String(token), Convert.FromBase64String(publicKey), Convert.FromBase64String(nonce)); await RespondToChallengeAsync(Encoding.UTF8.GetString(data)); }
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))); } } } }
public bool ExistChildrenOf(ImapMailbox mailbox) { if (mailbox.Flags.Has(ImapMailboxFlag.HasChildren)) return true; if (string.IsNullOrEmpty(mailbox.HierarchyDelimiter)) // mailbox has no hierarchy return false; var inferiorNamePrefix = mailbox.Name + mailbox.HierarchyDelimiter; foreach (var mailboxName in mailboxes.Keys) { if (mailboxName.StartsWith(inferiorNamePrefix, StringComparison.Ordinal)) return true; } return false; }
private async Task <IEnumerable <MailMessageModel> > SyncNonChallengesAsync(ImapMailbox mailbox, long uid) { var criteria = string.Format("{0}:* NOT HEADER \"{1}\" \"{2}\"", uid, ParanoiaHeaderKeys.Type, MailType.Challenge); var uids = await mailbox.SearchAsync(criteria); if (!uids.Any()) { return(new MailMessageModel[0]); } FetchedEnvelopeCount = 0; TotalEnvelopeCount = uids.Count; mailbox.EnvelopeFetched += OnEnvelopeFetched; var envelopes = (await mailbox.FetchEnvelopesAsync(uids)).ToArray(); if (envelopes.Length == 0) { return(new MailMessageModel[0]); } mailbox.EnvelopeFetched -= OnEnvelopeFetched; if (envelopes.Length == 1 && envelopes.First().Uid == uid) { return(new MailMessageModel[0]); } var messages = new List <MailMessageModel>(); foreach (var envelope in envelopes) { try { var message = envelope.ToMailMessage(MailType.Message); messages.Add(message); } catch (Exception ex) { Logger.Error(ex); } } return(messages); }
private void TransitStateTo(ImapSessionState newState) { if (newState == state) return; switch (newState) { case ImapSessionState.NotConnected: authority = null; selectedMailbox = null; if (mailboxManager != null) { mailboxManager.DetachFromSession(); mailboxManager = null; } TraceInfo("now in non-connected state"); break; case ImapSessionState.NotAuthenticated: UpdateAuthority(null, null); if (state == ImapSessionState.Selected || state == ImapSessionState.Authenticated) { mailboxManager.DetachFromSession(); mailboxManager = null; TraceInfo("logged out"); } TraceInfo("now in non-authenticated state"); break; case ImapSessionState.Authenticated: TraceInfo("now in authenticated state"); if (state == ImapSessionState.NotAuthenticated || state == ImapSessionState.NotConnected) { mailboxManager = new ImapMailboxManager(this); TraceInfo("logged in"); } break; case ImapSessionState.Selected: TraceInfo("now in selected state (selected '{0}')", selectedMailbox.Name); break; } state = newState; }
/// <summary>sends extended LIST command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult ListExtended(string mailboxNamePattern, ImapListSelectionOptions selectionOptions, ImapListReturnOptions returnOptions, out ImapMailbox[] mailboxes) { if (selectionOptions == null) throw new ArgumentNullException("selectionOptions"); if (returnOptions == null) throw new ArgumentNullException("returnOptions"); return ListExtendedInternalNoRefName(mailboxNamePattern, null, selectionOptions, returnOptions, out mailboxes); }
/// <summary>sends extended LIST command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult ListExtended(string mailboxNamePattern, out ImapMailbox[] mailboxes) { return ListExtendedInternalNoRefName(mailboxNamePattern, null, null, null, out mailboxes); }
/// <summary>sends RENAME command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult Rename(ImapMailbox existingMailbox, string newMailboxName) { ValidateMailboxRelationship(existingMailbox); ImapMailbox discard; return Rename(existingMailbox.Name, newMailboxName, out discard); }
/// <summary>sends GETMETADATA command</summary> /// <remarks> /// valid in authenticated/selected state. /// this method will fail if server does not support METADATA extension. /// </remarks> public ImapCommandResult GetMetadata(ImapMailbox mailbox, string[] entrySpecifiers, ImapGetMetadataOptions options, out ImapMetadata[] metadata) { if (options == null) throw new ArgumentNullException("options"); ValidateMailboxRelationship(mailbox); return GetMetadataInternal(mailbox.Name, false, entrySpecifiers, options, out metadata); }
/// <summary>sends SETMETADATA command</summary> /// <remarks> /// valid in authenticated/selected state. /// this method will fail if server does not support METADATA extension. /// </remarks> public ImapCommandResult SetMetadata(ImapMailbox mailbox, params ImapMetadata[] metadata) { ValidateMailboxRelationship(mailbox); return SetMetadataInternal(mailbox.Name, false, metadata); }
/// <summary>sends RLSUB command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult RLsub(string referenceName, string mailboxName, out ImapMailbox[] mailboxes) { if (mailboxName == null) throw new ArgumentNullException("mailboxName"); return RLsubInternal(referenceName, new ImapMailboxNameString(mailboxName), out mailboxes); }
public ImapMailbox Rename(ImapMailbox existingMailbox, string newMailboxName) { mailboxes.Remove(existingMailbox.Name); existingMailbox.Name = newMailboxName; mailboxes[existingMailbox.Name] = existingMailbox; return existingMailbox; }
/// <summary>sends RLIST command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult RList(string mailboxName, out ImapMailbox[] mailboxes) { if (mailboxName == null) throw new ArgumentNullException("mailboxName"); return RListInternal(string.Empty, new ImapMailboxNameString(mailboxName), out mailboxes); }
/// <summary>sends RLSUB command</summary> /// <remarks> /// valid in authenticated state /// This method sends LIST command with an empty reference name and a wildcard "*" as mailbox name /// </remarks> public ImapCommandResult RLsub(out ImapMailbox[] mailboxes) { return RLsubInternal(string.Empty, "*", out mailboxes); }
/// <summary>sends APPEND command</summary> /// <remarks> /// valid in authenticated state. /// this method tries to automatically create the mailbox when server sent [TRYCREATE] response code. /// the out parameter <paramref name="appendedUids"/> will be set if the server supports UIDPLUS extension and returns [APPENDUID] responce code, otherwise null. /// </remarks> public ImapCommandResult Append(IImapAppendMessage message, string mailboxName, out ImapAppendedUidSet appendedUids, out ImapMailbox createdMailbox) { return AppendInternal(new[] {message}, false, mailboxName, out appendedUids, out createdMailbox); }
/// <summary>sends RENAME command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult Rename(string existingMailboxName, string newMailboxName, out ImapMailbox renamedMailbox) { RejectNonAuthenticatedState(); RejectInvalidMailboxNameArgument(existingMailboxName); RejectInvalidMailboxNameArgument(newMailboxName); if (ImapMailbox.NameEquals(existingMailboxName, newMailboxName)) throw new ArgumentException("An existing mailbox name and a new mailbox name are same.", "newMailboxName"); /* * 6.3.5. RENAME Command * It is * an error to attempt to rename from a mailbox name that does not * exist or to a mailbox name that already exists. */ var existingRenameToMailbox = mailboxManager.GetExist(newMailboxName); if (ImapMailbox.IsNameInbox(newMailboxName) || (existingRenameToMailbox != null && !existingRenameToMailbox.Flags.Has(ImapMailboxFlag.NonExistent))) throw new ImapProtocolViolationException(string.Format("It is an error to attempt to rename to a mailbox name that already exists. (newMailboxName: '{0}')", newMailboxName)); renamedMailbox = null; using (var t = new RenameTransaction(connection)) { /* * RFC 4466 - Collected Extensions to IMAP4 ABNF * http://tools.ietf.org/html/rfc4466 * * rename = "RENAME" SP mailbox SP mailbox * [rename-params] * ;; Use of INBOX as a destination gives * ;; a NO error, unless rename-params * ;; is not empty. * rename-params = SP "(" rename-param *( SP rename-param) ")" * rename-param = rename-param-name [SP rename-param-value] * rename-param-name = tagged-ext-label * rename-param-value= tagged-ext-val * ;; This non-terminal shows recommended syntax * ;; for future extensions. */ t.RequestArguments["existing mailbox name"] = new ImapMailboxNameString(existingMailboxName); t.RequestArguments["new mailbox name"] = new ImapMailboxNameString(newMailboxName); // rename-params //t.RequestArguments["rename parameters"] = new ImapParenthesizedString(); if (ProcessTransaction(t).Succeeded) renamedMailbox = mailboxManager.Rename(existingMailboxName, newMailboxName); else ProcessMailboxRefferalResponse(t.Result.TaggedStatusResponse); return t.Result; } }
/// <summary>sends RENAME command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult Rename(ImapMailbox existingMailbox, string newMailboxName, out ImapMailbox renamedMailbox) { ValidateMailboxRelationship(existingMailbox); return Rename(existingMailbox.Name, newMailboxName, out renamedMailbox); }
private void ValidateMailboxRelationship(ImapMailbox mailbox) { if (mailbox == null) throw new ArgumentNullException("mailbox"); if (mailbox.Session != this) throw new ArgumentException("mailbox is not attached to current session", "mailbox"); }
public ImapMailbox Rename(string existingMailboxName, string newMailboxName) { var mailbox = GetExist(existingMailboxName); if (mailbox == null) { var newMailbox = new ImapMailbox(newMailboxName); Add(newMailbox); return newMailbox; } if (mailbox.IsInbox) { /* * 6.3.5. RENAME Command * Renaming INBOX is permitted, and has special behavior. It moves * all messages in INBOX to a new mailbox with the given name, * leaving INBOX empty. If the server implementation supports * inferior hierarchical names of INBOX, these are unaffected by a * rename of INBOX. */ Add(new ImapMailbox(ImapMailbox.Inbox)); return Rename(mailbox, newMailboxName); } else { if (!string.IsNullOrEmpty(mailbox.HierarchyDelimiter)) { /* * 6.3.5. RENAME Command * If the name has inferior hierarchical names, then the inferior * hierarchical names MUST also be renamed. For example, a rename of * "foo" to "zap" will rename "foo/bar" (assuming "/" is the * hierarchy delimiter character) to "zap/bar". */ var existingNamePrefix = mailbox.Name + mailbox.HierarchyDelimiter; var newNamePrefix = newMailboxName + mailbox.HierarchyDelimiter; var inferiorNames = new List<string>(); foreach (var mailboxName in mailboxes.Keys) { if (mailboxName.StartsWith(existingNamePrefix, StringComparison.Ordinal)) inferiorNames.Add(mailboxName); } foreach (var inferiorName in inferiorNames) { var inferior = mailboxes[inferiorName]; Rename(inferior, newNamePrefix + inferior.Name.Substring(existingNamePrefix.Length)); } } return Rename(mailbox, newMailboxName); } }
/// <remarks> /// valid in authenticated/selected state. /// this method will fail if server does not support METADATA extension. /// </remarks> public ImapCommandResult GetMetadata(ImapMailbox mailbox, string[] entrySpecifiers, out ImapMetadata[] metadata) { ValidateMailboxRelationship(mailbox); return GetMetadataInternal(mailbox.Name, false, entrySpecifiers, null, out metadata); }
/// <summary>sends extended LIST command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult ListExtended(string referenceName, string[] mailboxNamePatterns, ImapListSelectionOptions selectionOptions, ImapListReturnOptions returnOptions, out ImapMailbox[] mailboxes) { if (referenceName == null) throw new ArgumentNullException("referenceName"); if (mailboxNamePatterns == null) throw new ArgumentNullException("mailboxNamePatterns"); else if (mailboxNamePatterns.Length == 0) throw new ArgumentException("must be non-empty array", "mailboxNamePatterns"); if (selectionOptions == null) throw new ArgumentNullException("selectionOptions"); if (returnOptions == null) throw new ArgumentNullException("returnOptions"); return ListExtendedInternal(referenceName, mailboxNamePatterns, selectionOptions, returnOptions, out mailboxes); }
/// <summary>sends GETQUOTAROOT command</summary> /// <remarks>valid in authenticated/selected state (undocumented)</remarks> public ImapCommandResult GetQuotaRoot(ImapMailbox mailbox, out IDictionary<string, ImapQuota[]> quotaRoots) { ValidateMailboxRelationship(mailbox); return GetQuotaRoot(mailbox.Name, out quotaRoots); }
internal ImapOpenedMailboxInfo(ImapClient client, ImapMailbox mailbox) : base(client, mailbox) { }
/// <summary>sends SETMETADATA command and sets NIL value to remove entries</summary> /// <remarks> /// valid in authenticated/selected state. /// this method will fail if server does not support METADATA extension. /// </remarks> public ImapCommandResult SetMetadata(ImapMailbox mailbox, params string[] entrySpecifiers) { ValidateMailboxRelationship(mailbox); return SetMetadataInternal(mailbox.Name, false, Array.ConvertAll<string, ImapMetadata>(entrySpecifiers, ImapMetadata.CreateNil)); }
public WaitForMessageArrivalContext(int pollingInterval, ImapMailbox mailbox, ImapMessageFetchAttributeOptions fetchOptions) { this.PollingInterval = pollingInterval; this.Mailbox = mailbox; this.CurrentMessageCount = mailbox.ExistsMessage; this.FetchOptions = fetchOptions; }
private static async Task <IEnumerable <MailMessageModel> > SyncChallengesAsync(ImapMailbox mailbox, long uid) { var criteria = string.Format("{0}:* HEADER \"{1}\" \"{2}\"", uid, ParanoiaHeaderKeys.Type, MailType.Challenge); var uids = await mailbox.SearchAsync(criteria); if (!uids.Any()) { return(new MailMessageModel[0]); } var envelopes = (await mailbox.FetchEnvelopesAsync(uids)).ToArray(); if (envelopes.Length == 0) { return(new MailMessageModel[0]); } if (envelopes.Length == 1 && envelopes.First().Uid == uid) { return(new MailMessageModel[0]); } var now = DateTime.Now; foreach (var envelope in envelopes.Where(x => x.InternalDate.HasValue && now.Subtract(x.InternalDate.Value) < TimeSpan.FromHours(1))) { try { await ProcessChallengeAsync(envelope, mailbox); } catch (Exception ex) { Logger.Error(ex); } } var messages = new List <MailMessageModel>(); foreach (var envelope in envelopes) { try { var message = envelope.ToMailMessage(MailType.Challenge); messages.Add(message); } catch (Exception ex) { Logger.Error(ex); } } return(messages); }
/// <summary>sends LSUB command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult Lsub(ImapMailbox mailbox) { ValidateMailboxRelationship(mailbox); ImapMailbox[] discard; return LsubInternal(string.Empty, new ImapMailboxNameString(mailbox.Name), out discard); }
public ExamineTransaction(ImapConnection connection, ImapMailbox selectingMailbox, ImapCapability selectParametersCapabilityRequirement) : base(connection, selectingMailbox, selectParametersCapabilityRequirement) { }
internal IEnumerable<ImapMailboxInfo> GetMailboxes(ImapMailbox mailbox, ImapMailboxListOptions options) { return GetMailboxes(mailbox.Name, mailbox.HierarchyDelimiter, true, mailbox.Flags.Has(ImapMailboxFlag.NoInferiors), // ignore HasNoChildren options); }
public WaitForMessageArrivalAsyncResult(int pollingInterval, ImapMailbox mailbox, ImapMessageFetchAttributeOptions fetchOptions, WaitForMessageArrivalProc proc, object asyncState, AsyncCallback asyncCallback) : base(pollingInterval, mailbox, fetchOptions) { this.proc = proc; this.AsyncState = asyncState; this.asyncCallback = asyncCallback; }
protected SelectTransactionBase(ImapConnection connection, ImapMailbox selectingMailbox, ImapCapability selectParametersCapabilityRequirement) : base(connection) { this.selectingMailbox = selectingMailbox; this.selectParametersCapabilityRequirement = selectParametersCapabilityRequirement; }
internal ImapMailboxInfo(ImapClient client, ImapMailbox mailbox) { this.client = client; this.mailbox = mailbox; }
/// <summary>sends extended LIST command</summary> /// <remarks>valid in authenticated state</remarks> public ImapCommandResult ListExtended(ImapListReturnOptions returnOptions, out ImapMailbox[] mailboxes, string mailboxNamePattern, params string[] mailboxNamePatterns) { if (returnOptions == null) throw new ArgumentNullException("returnOptions"); return ListExtendedInternalNoRefName(mailboxNamePattern, mailboxNamePatterns, null, returnOptions, out mailboxes); }