public static string LIST(string FolderName, char delimiter, List <string> attributes) { // Example: C: A101 LIST "" "" // S: * LIST (\Noselect) "/" "" // S: A101 OK LIST Completed // C: A102 LIST #news.comp.mail.misc "" // S: * LIST (\Noselect) "." #news. // S: A102 OK LIST Completed // C: A103 LIST /usr/staff/jones "" // S: * LIST (\Noselect) "/" / // S: A103 OK LIST Completed // C: A202 LIST ~/Mail/ % // S: * LIST (\Noselect) "/" ~/Mail/foo // S: * LIST () "/" ~/Mail/meetings // S: A202 OK LIST completed if (string.IsNullOrEmpty(FolderName)) { return($"* LIST (\\Noselect) \"{delimiter}\" \"\""); } else { string result = "* LIST ("; if (attributes != null && attributes.Count() > 0) { result += string.Join(" ", attributes); } result += ") \"" + delimiter + "\" " + IMAP_Utils.EncodeMailbox(FolderName, IMAP_Mailbox_Encoding.ImapUtf7); return(result); } }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { var folderName = IMAP_Utils.DecodeMailbox(TextUtils.UnQuoteString(args)); if (Folder.ReservedFolder.Any(o => folderName.StartsWith(o.Value, StringComparison.OrdinalIgnoreCase))) { throw new CommandException("NO", "Can not delete reservered folders"); } var folder = session.MailDb.Folders.Get(folderName); if (folder == null) { throw new CommandException("NO", "Folder is not found"); } // Todo: Remove messages // Remove folder session.MailDb.Folders.Delete(folder); if (session.SelectFolder.FolderId == folder.Id) { session.SelectFolder = null; } return(this.NullResult()); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { string[] parts = TextUtils.SplitQuotedString(args, ' ', true); string refName = IMAP_Utils.DecodeMailbox(parts[0]); string folder = IMAP_Utils.DecodeMailbox(parts[1]); // mailbox name is "", return delimiter and root if (folder == String.Empty) { var root = refName.Split(new char[] { '/' })[0]; return(Task.FromResult(new List <ImapResponse> { new ImapResponse(ResultLine.LIST(root, '/', null)) })); } // Match the full mailbox pattern var folderPattern = folder.Replace("*", ".*").Replace("%", "[^/]*"); var pattern = $"^{refName}{folderPattern}$"; var user = Data.GlobalDb.Users.Get(session.AuthenticatedUserIdentity.Name); var result = new List <ImapResponse>(); foreach (var each in GetAllFolders(user)) { if (System.Text.RegularExpressions.Regex.IsMatch(each.Name, pattern, System.Text.RegularExpressions.RegexOptions.IgnoreCase)) { result.Add(new ImapResponse(Response(each.Name, '/', each.Attributes))); } } return(Task.FromResult(result)); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { var parts = TextUtils.SplitQuotedString(args, ' ', false, 2); var fromName = IMAP_Utils.DecodeMailbox(TextUtils.UnQuoteString(parts[0])); var toName = IMAP_Utils.DecodeMailbox(TextUtils.UnQuoteString(parts[1])); if (Folder.ReservedFolder.Any(o => fromName.StartsWith(o.Value, StringComparison.OrdinalIgnoreCase))) { throw new CommandException("NO", "Can not rename reservered folders"); } var folder = session.MailDb.Folders.Get(fromName); if (folder == null) { throw new CommandException("NO", "Folder is not found"); } if (Folder.ReservedFolder.Any(o => toName.StartsWith(o.Value, StringComparison.OrdinalIgnoreCase))) { throw new CommandException("NO", "Can not rename folder to be under reservered folders"); } if (session.MailDb.Folders.Get(Folder.ToId(toName)) != null) { throw new CommandException("NO", "Folder with new name already exist"); } session.MailDb.Folders.Rename(folder, toName); return(this.NullResult()); }
public static AppendArgs ParseArgs(string args) { var parts = args.Split(new char[] { ' ' }, 2); if (parts.Length != 2) { throw new CommandException("BAD", "Error in arguments."); } var result = new AppendArgs { FodlerName = IMAP_Utils.DecodeMailbox(TextUtils.UnQuoteString(parts[0])) }; var restStr = parts[1]; // Flags if (restStr.StartsWith("(")) { var index = restStr.IndexOf(")"); if (index <= 0) { return(null); } result.Flags = restStr.Substring(1, index - 1).Split(' ').Select(o => o.TrimStart('\\')).ToArray(); restStr = parts[1].Substring(index + 1).TrimStart(); } // Internal date if (restStr.StartsWith("\"")) { var index = restStr.LastIndexOf("\""); if (index <= 0) { return(null); } var dateTimeStr = restStr.Substring(1, index - 1); DateTimeOffset time; if (!DateTimeOffset.TryParse(dateTimeStr, out time)) { return(null); } result.InternalDate = time.UtcDateTime; restStr = restStr.Substring(index + 1).TrimStart(); } if (!restStr.StartsWith("{") || !restStr.EndsWith("}")) { return(null); } result.Size = Convert.ToInt32(restStr.Substring(1, restStr.Length - 2)); return(result); }
public static string LSUB(string FolderName, char delimiter, List <string> attributes) { // Example: S: * LSUB (\Noselect) "/" ~/Mail/foo string result = "* LSUB ("; if (attributes != null && attributes.Count() > 0) { result += string.Join(" ", attributes); } result += ") \"" + delimiter + "\" " + IMAP_Utils.EncodeMailbox(FolderName, IMAP_Mailbox_Encoding.ImapUtf7); return(result); }
public static CopyArgs ParseArgs(string args) { var parts = args.Split(new char[] { ' ' }, 2); if (parts.Length != 2) { throw new Exception("Error in arguments."); } return(new CopyArgs { Ranges = ImapHelper.GetSequenceRange(parts[0]), FolderName = IMAP_Utils.DecodeMailbox(TextUtils.UnQuoteString(parts[1])) }); }
/// <summary> /// Gets server user folders and binds them to this, if not binded already. /// </summary> private void Bind() { /* GetUserFolderAcl <virtualServerID> <userID> "<folderName>" * Responses: +OK <sizeOfData> * <data> * + ERR <errorText> */ lock (m_pFolder.User.VirtualServer.Server.LockSynchronizer){ // Call TCP GetUserFolderAcl m_pFolder.User.VirtualServer.Server.TcpClient.TcpStream.WriteLine("GetUserFolderAcl " + m_pFolder.User.VirtualServer.VirtualServerID + " " + m_pFolder.User.UserID + " \"" + m_pFolder.FolderFullPath ); string response = m_pFolder.User.VirtualServer.Server.ReadLine(); if (!response.ToUpper().StartsWith("+OK")) { throw new Exception(response); } int sizeOfData = Convert.ToInt32(response.Split(new char[] { ' ' }, 2)[1]); MemoryStream ms = new MemoryStream(); m_pFolder.User.VirtualServer.Server.TcpClient.TcpStream.ReadFixedCount(ms, sizeOfData); // Decompress dataset DataSet ds = Utils.DecompressDataSet(ms); if (ds.Tables.Contains("ACL")) { foreach (DataRow dr in ds.Tables["ACL"].Rows) { m_pAclEntries.Add(new UserFolderAcl( this, m_pFolder, dr["User"].ToString(), IMAP_Utils.ACL_From_String(dr["Permissions"].ToString()) )); } } } }
/// <summary> /// Gets myrights to specified folder. /// </summary> /// <param name="folderName"></param> /// <returns></returns> public IMAP_ACL_Flags GetFolderMyrights(string folderName) { if (!m_Connected) { throw new Exception("You must connect first !"); } if (!m_Authenticated) { throw new Exception("You must authenticate first !"); } IMAP_ACL_Flags aclFlags = IMAP_ACL_Flags.None; m_pSocket.SendLine("a1 MYRIGHTS \"" + EncodeUtf7(folderName) + "\""); // Must get lines with * and cmdTag + OK or cmdTag BAD/NO string reply = m_pSocket.ReadLine(); if (reply.StartsWith("*")) { // Read multiline response while (reply.StartsWith("*")) { // Get rid of * reply = reply.Substring(1).Trim(); if (reply.ToUpper().IndexOf("MYRIGHTS") > -1) { aclFlags = IMAP_Utils.ACL_From_String(reply.Substring(0, reply.IndexOf(" ")).Trim()); } reply = m_pSocket.ReadLine(); } } reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove Cmd tag if (!reply.ToUpper().StartsWith("OK")) { throw new Exception("Server returned:" + reply); } return(aclFlags); }
// RFC 3501 6.3.1. SELECT Command. public Task <List <ImapResponse> > Execute(ImapSession session, string args) { string[] parts = TextUtils.SplitQuotedString(args, ' '); if (parts.Length >= 2) { // At moment we don't support UTF-8 mailboxes. if (Lib.Helper.StringHelper.IsSameValue(parts[1], "(UTF8)")) { throw new CommandException("NO", "UTF8 name not supported"); } else { throw new CommandException("BAD", "Argument error"); } } List <ImapResponse> Result = new List <ImapResponse>(); string foldername = TextUtils.UnQuoteString(IMAP_Utils.DecodeMailbox(args)); var parsedfolder = Kooboo.Mail.Utility.FolderUtility.ParseFolder(foldername); session.SelectFolder = new SelectFolder(foldername, session.MailDb); var stat = session.SelectFolder.Stat; session.MailDb.Messages.UpdateRecentByMaxId(stat.LastestMsgId); Result.Add(new ImapResponse(ResultLine.EXISTS(stat.Exists))); Result.Add(new ImapResponse(ResultLine.RECENT(stat.Recent))); if (stat.FirstUnSeen > -1) { Result.Add(new ImapResponse(ResultLine.UNSEEN(stat.FirstUnSeen))); } Result.Add(new ImapResponse(ResultLine.UIDNEXT(stat.NextUid))); Result.Add(new ImapResponse(ResultLine.UIDVALIDAITY(stat.FolderUid))); Result.Add(new ImapResponse(ResultLine.FLAGS(Setting.SupportFlags.ToList()))); return(Task.FromResult(Result)); }
/// <summary> /// Updates IMAP message flags. /// </summary> /// <param name="setType">Flags set type.</param> /// <param name="flags">IMAP message flags.</param> /// <exception cref="ArgumentNullException">Is raised when <b>flags</b> is null reference.</exception> internal void UpdateFlags(IMAP_Flags_SetType setType, string[] flags) { if (flags == null) { throw new ArgumentNullException("flags"); } if (setType == IMAP_Flags_SetType.Add) { m_pFlags = IMAP_Utils.MessageFlagsAdd(m_pFlags, flags); } else if (setType == IMAP_Flags_SetType.Remove) { m_pFlags = IMAP_Utils.MessageFlagsRemove(m_pFlags, flags); } else { m_pFlags = flags; } }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { var folderName = IMAP_Utils.DecodeMailbox(TextUtils.UnQuoteString(args)); if (Folder.ReservedFolder.Any(o => folderName.StartsWith(o.Value, StringComparison.OrdinalIgnoreCase))) { throw new CommandException("NO", "Can not create folder under reservered folders"); } var folderId = Folder.ToId(folderName); if (session.MailDb.Folders.Get(folderId) != null) { throw new CommandException("NO", "Folder already exist"); } session.MailDb.Folders.Add(folderName); return(this.NullResult()); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { var folderName = TextUtils.UnQuoteString(IMAP_Utils.DecodeMailbox(args)); if (Folder.ReservedFolder.Any(o => folderName.StartsWith(o.Value, StringComparison.OrdinalIgnoreCase))) { throw new CommandException("NO", "Reserved folders are always subscribed"); } var folder = session.MailDb.Folders.Get(folderName); if (folder == null) { throw new CommandException("NO", "No such a folder"); } session.MailDb.Folders.Subscribe(folder); return(this.NullResult()); }
private void Bind() { lock (this.m_pFolder.User.VirtualServer.Server.LockSynchronizer) { this.m_pFolder.User.VirtualServer.Server.TCP_Client.TcpStream.WriteLine(string.Concat(new string[] { "GetUserFolderAcl ", this.m_pFolder.User.VirtualServer.VirtualServerID, " ", this.m_pFolder.User.UserID, " \"", this.m_pFolder.FolderFullPath })); string text = this.m_pFolder.User.VirtualServer.Server.ReadLine(); if (!text.ToUpper().StartsWith("+OK")) { throw new Exception(text); } int num = Convert.ToInt32(text.Split(new char[] { ' ' }, 2)[1]); MemoryStream memoryStream = new MemoryStream(); this.m_pFolder.User.VirtualServer.Server.TCP_Client.TcpStream.ReadFixedCount(memoryStream, (long)num); DataSet dataSet = Utils.DecompressDataSet(memoryStream); if (dataSet.Tables.Contains("ACL")) { foreach (DataRow dataRow in dataSet.Tables["ACL"].Rows) { this.m_pAclEntries.Add(new UserFolderAcl(this, this.m_pFolder, dataRow["User"].ToString(), IMAP_Utils.ACL_From_String(dataRow["Permissions"].ToString()))); } } } }
public static List <ImapResponse> Execute(MailDb mailDb, string args) { var parts = TextUtils.SplitQuotedString(args, ' ', false, 2); string folderName = IMAP_Utils.DecodeMailbox(TextUtils.UnQuoteString(parts[0])); if (!(parts[1].StartsWith("(") && parts[1].EndsWith(")"))) { throw new Exception("Error in arguments."); } var index = args.IndexOf(" "); var folderArg = args.Substring(0, index); var folder = new SelectFolder(folderName, mailDb); var stat = folder.Stat; var commandReader = new CommandReader(parts[1]); var AllDataItems = commandReader.ReadAllDataItems(); var builder = new StringBuilder() .Append("* STATUS ").Append(folderArg).Append(" ("); var first = true; foreach (var each in AllDataItems) { if (!first) { builder.Append(" "); } switch (each.Name) { case "MESSAGES": builder.Append("MESSAGES ").Append(stat.Exists); break; case "RECENT": builder.Append("RECENT ").Append(stat.Recent); break; case "UIDNEXT": builder.Append("UIDNEXT ").Append(stat.NextUid); break; case "UIDVALIDITY": builder.Append("UIDVALIDITY ").Append(stat.FolderUid); break; case "UNSEEN": builder.Append("UNSEEN ").Append(stat.UnSeen); break; default: break; } if (first) { first = false; } } builder.Append(")"); return(new List <ImapResponse> { new ImapResponse(builder.ToString()) }); }
/// <summary> /// Parses ACL entry from IMAP ACL response string. /// </summary> /// <param name="aclResponseString">IMAP ACL response string.</param> /// <returns></returns> internal static IMAP_Acl Parse(string aclResponseString) { string[] args = TextUtils.SplitQuotedString(aclResponseString, ' ', true); return(new IMAP_Acl(args[1], IMAP_Utils.ACL_From_String(args[2]))); }
private void LoadACL() { this.m_EvensLocked = true; this.m_pTab_Security_UsersOrGroups.Items.Clear(); bool flag = false; if (this.m_pFolder.ACL.Count > 0) { foreach (UserFolderAcl userFolderAcl in this.m_pFolder.ACL) { ListViewItem listViewItem = new ListViewItem(userFolderAcl.UserOrGroup); listViewItem.SubItems.Add(IMAP_Utils.ACL_to_String(userFolderAcl.Permissions)); if (!this.m_pVirtualServer.Groups.Contains(userFolderAcl.UserOrGroup)) { listViewItem.ImageIndex = 0; } else { listViewItem.ImageIndex = 1; } listViewItem.Tag = userFolderAcl; this.m_pTab_Security_UsersOrGroups.Items.Add(listViewItem); } flag = true; } else { UserFolder userFolder = this.m_pFolder; while (userFolder.Parent != null) { userFolder = userFolder.Parent; if (userFolder.ACL.Count > 0) { IEnumerator enumerator2 = userFolder.ACL.GetEnumerator(); try { while (enumerator2.MoveNext()) { UserFolderAcl userFolderAcl2 = (UserFolderAcl)enumerator2.Current; ListViewItem listViewItem2 = new ListViewItem(userFolderAcl2.UserOrGroup); listViewItem2.SubItems.Add(IMAP_Utils.ACL_to_String(userFolderAcl2.Permissions)); if (!this.m_pVirtualServer.Groups.Contains(userFolderAcl2.UserOrGroup)) { listViewItem2.ImageIndex = 0; } else { listViewItem2.ImageIndex = 1; } listViewItem2.Tag = userFolderAcl2; this.m_pTab_Security_UsersOrGroups.Items.Add(listViewItem2); } break; } finally { IDisposable disposable2 = enumerator2 as IDisposable; if (disposable2 != null) { disposable2.Dispose(); } } } } } if (!flag) { this.m_pTab_Security_InheritAcl.Checked = true; this.mt_Tab_Security_UsersOrGroupsToolbar.Enabled = false; this.m_pTab_Security_Permissions.Enabled = false; } else { this.m_pTab_Security_InheritAcl.Checked = false; this.mt_Tab_Security_UsersOrGroupsToolbar.Enabled = true; this.m_pTab_Security_Permissions.Enabled = true; this.m_pTab_Security_UsersOrGroups_SelectedIndexChanged(null, null); } this.m_EvensLocked = false; }
/// <summary> /// Stores message folgs to sepcified messages range. /// </summary> /// <param name="startMsgNo">Start message number.</param> /// <param name="endMsgNo">End message number.</param> /// <param name="uidStore">Sepcifies if message numbers are message UID numbers.</param> /// <param name="msgFlags">Message flags to store.</param> public void StoreMessageFlags(int startMsgNo, int endMsgNo, bool uidStore, IMAP_MessageFlags msgFlags) { if (!m_Connected) { throw new Exception("You must connect first !"); } if (!m_Authenticated) { throw new Exception("You must authenticate first !"); } if (m_SelectedFolder.Length == 0) { throw new Exception("You must select folder first !"); } if (uidStore) { m_pSocket.SendLine("a1 UID STORE " + startMsgNo + ":" + endMsgNo + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")"); } else { m_pSocket.SendLine("a1 STORE " + startMsgNo + ":" + endMsgNo + " FLAGS (" + IMAP_Utils.MessageFlagsToString(msgFlags) + ")"); } // Must get lines with * and cmdTag + OK or cmdTag BAD/NO string reply = m_pSocket.ReadLine(); if (reply.StartsWith("*")) { // Read multiline response while (reply.StartsWith("*")) { // Get rid of * reply = reply.Substring(1).Trim(); reply = m_pSocket.ReadLine(); } } reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove Cmd tag if (!reply.ToUpper().StartsWith("OK")) { throw new Exception("Server returned:" + reply); } }
/// <summary> /// Sets specified user ACL permissions for specified folder. /// </summary> /// <param name="folderName">Folder name which ACL to set.</param> /// <param name="userName">User name who's ACL to set.</param> /// <param name="acl">ACL permissions to set.</param> public void SetFolderACL(string folderName, string userName, IMAP_ACL_Flags acl) { if (!m_Connected) { throw new Exception("You must connect first !"); } if (!m_Authenticated) { throw new Exception("You must authenticate first !"); } m_pSocket.SendLine("a1 SETACL \"" + EncodeUtf7(folderName) + "\" \"" + userName + "\" " + IMAP_Utils.ACL_to_String(acl)); string reply = m_pSocket.ReadLine(); reply = reply.Substring(reply.IndexOf(" ")).Trim(); // Remove Cmd tag if (!reply.ToUpper().StartsWith("OK")) { throw new Exception("Server returned:" + reply); } }
/// <summary> /// Load ACL to UI. /// </summary> private void LoadACL() { m_EvensLocked = true; m_pTab_Security_UsersOrGroups.Items.Clear(); // See if ACL is set to this folder, if not show inhereted ACL bool aclSetToFolder = false; if (m_pFolder.ACL.Count > 0) { foreach (UserFolderAcl acl in m_pFolder.ACL) { ListViewItem it = new ListViewItem(acl.UserOrGroup); it.SubItems.Add(IMAP_Utils.ACL_to_String(acl.Permissions)); if (!m_pVirtualServer.Groups.Contains(acl.UserOrGroup)) { it.ImageIndex = 0; } else { it.ImageIndex = 1; } it.Tag = acl; m_pTab_Security_UsersOrGroups.Items.Add(it); } aclSetToFolder = true; } else { UserFolder folder = m_pFolder; // Try to inherit ACL from parent folder(s) // Move right to left in path. while (folder.Parent != null) { // Move 1 level to right in path folder = folder.Parent; if (folder.ACL.Count > 0) { foreach (UserFolderAcl acl in folder.ACL) { ListViewItem it = new ListViewItem(acl.UserOrGroup); it.SubItems.Add(IMAP_Utils.ACL_to_String(acl.Permissions)); if (!m_pVirtualServer.Groups.Contains(acl.UserOrGroup)) { it.ImageIndex = 0; } else { it.ImageIndex = 1; } it.Tag = acl; m_pTab_Security_UsersOrGroups.Items.Add(it); } // We inhereted all permission, don't look other parent folders anymore break; } } } // ACL isn't set to this folder, disable users ListView if (!aclSetToFolder) { m_pTab_Security_InheritAcl.Checked = true; mt_Tab_Security_UsersOrGroupsToolbar.Enabled = false; //m_pTab_Security_UsersOrGroups.Enabled = false; m_pTab_Security_Permissions.Enabled = false; } else { m_pTab_Security_InheritAcl.Checked = false; mt_Tab_Security_UsersOrGroupsToolbar.Enabled = true; //m_pTab_Security_UsersOrGroups.Enabled = true; m_pTab_Security_Permissions.Enabled = true; m_pTab_Security_UsersOrGroups_SelectedIndexChanged(null, null); } m_EvensLocked = false; }