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) { return(Task.FromResult(new List <ImapResponse> { new ImapResponse(ResultLine.CAPABILITY(session.Capabilities)) })); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { var spl = args.Split(new char[] { ' ' }, 2); var subCommand = spl[0].ToUpperInvariant(); List <ImapResponse> result; switch (subCommand) { case "FETCH": result = FetchCommand.FetchResponse.GenerateByUid(session.MailDb, session.SelectFolder, spl[1]); break; case "STORE": result = STORE.ExecuteByUid(session.MailDb, session.SelectFolder, spl[1]); break; case "COPY": result = COPY.ExecuteByUid(session.MailDb, session.SelectFolder, spl[1]); break; case "MOVE": result = MOVE.ExecuteByUid(session.MailDb, session.SelectFolder, spl[1]); break; case "SEARCH": result = SearchCommand.Search.ExecuteByUid(session.MailDb, session.SelectFolder, spl[1]); break; default: throw new Exception("Not support for UID " + subCommand); } 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 Task <List <ImapResponse> > Execute(ImapSession session, string args) { List <ImapResponse> result = new List <ImapResponse>(); if (session.SelectFolder == null) { return(this.NullResult()); } var deletedSeqNo = session.SelectFolder.EXPUNGE(); foreach (var item in deletedSeqNo) { result.Add(new ImapResponse(ResultLine.EXPUNGE(item))); } session.SelectFolder.Stat = session.MailDb.Messages.GetStat(session.SelectFolder.Folder); var stat = session.SelectFolder.Stat; result.Add(new ImapResponse(ResultLine.EXISTS(stat.Exists))); result.Add(new ImapResponse(ResultLine.RECENT(stat.Recent))); result.Add(new ImapResponse(ResultLine.UIDNEXT(stat.NextUid))); result.Add(new ImapResponse(ResultLine.UIDVALIDAITY(stat.FolderUid))); return(Task.FromResult(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) { var result = new List <ImapResponse>() { new ImapResponse("* BYE IMAP4rev1 Server logging out") }; return(Task.FromResult(result)); }
public static async Task SendResponse(ImapSession session, List <ImapResponse> response) { if (response != null && response.Count() > 0) { foreach (var item in response) { // send partial response.. await SendResponse(session, item); } } }
public static async Task SendResponse(ImapSession session, ImapResponse response) { if (response.Line == null) { await session.Stream.WriteAsync(response.Binary); } else { await session.Stream.WriteLineAsync(response.Line); } }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { List <ImapResponse> result = new List <ImapResponse>(); var deletedSeqNo = session.SelectFolder.EXPUNGE(); foreach (var item in deletedSeqNo) { result.Add(new ImapResponse(ResultLine.EXPUNGE(item))); } return(Task.FromResult(result)); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { if (string.IsNullOrEmpty(args)) { throw new Exception("User Or Password not provided"); } string[] user_pass = TextUtils.SplitQuotedString(args, ' ', true); if (user_pass.Length != 2) { throw new Exception("Error in arguments"); } Guid OrganizationId = default(Guid); // user may have multiple orgs. string username = user_pass[0]; if (username.IndexOf("@") > -1 && Utility.AddressUtility.IsValidEmailAddress(username)) { var emailadd = Utility.AddressUtility.GetEmailAddress(username); if (emailadd == null) { throw new Exception("LOGIN Failed"); } else { username = Data.GlobalDb.Users.GetUserName(emailadd.UserId); OrganizationId = emailadd.OrgId; } } var user = Kooboo.Data.GlobalDb.Users.Validate(username, user_pass[1]); if (user == null) { throw new Exception("LOGIN Failed"); } if (OrganizationId == default(Guid)) { OrganizationId = user.CurrentOrgId; } session.AuthenticatedUserIdentity = new GenericIdentity(user.UserName, "IMAP-LOGIN"); session.MailDb = Kooboo.Mail.Factory.DBFactory.UserMailDb(user.Id, OrganizationId); return(this.NullResult()); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { if (session.IsSecureConnection) { throw new CommandException("NO", "Already in secure connection"); } if (session.Server.SslMode != SslMode.StartTLS) { throw new CommandException("NO", "StartTLS not supported"); } throw new StartTlsException(); }
// 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)); }
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()); }
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 async Task <List <ImapResponse> > Execute(ImapSession session, string args) { var appendArgs = ParseArgs(args); if (appendArgs == null) { throw new CommandException("BAD", "Error in arguments"); } await session.Stream.WriteLineAsync("+ Continue"); var bytes = await session.Stream.ReadAsync(appendArgs.Size); var content = SmtpUtility.GetString(bytes); await session.Stream.ReadLineAsync(); var message = MessageUtility.ParseMeta(content); message.FolderId = session.SelectFolder.FolderId; message.UserId = session.MailDb.UserId; var folderName = session.SelectFolder.Folder.ToLower(); if (folderName == "sent" || folderName == "drafts") { var user = Data.GlobalDb.Users.Get(session.MailDb.UserId); var orgDb = Kooboo.Mail.Factory.DBFactory.OrgDb(user.CurrentOrgId); var address = orgDb.EmailAddress.Get(Mail_t_Mailbox.Parse(message.From).Address); if (address != null) { message.AddressId = address.Id; } } session.MailDb.Messages.Add(message, content); return(null); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { return(Task.FromResult(ExecuteBySeqNo(session.MailDb, session.SelectFolder, args))); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { session.SelectFolder.EXPUNGE(); return(this.NullResult()); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { var result = FetchCommand.FetchResponse.GenerateBySeqId(session.MailDb, session.SelectFolder, args); return(Task.FromResult(result)); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { var result = SearchCommand.Search.ExecuteBySeqNo(session.MailDb, session.SelectFolder, args); return(Task.FromResult(result)); }
public static Task ResponseEnd(ImapSession session, string RequestTag, string TagResult, string message) { return(session.Stream.WriteLineAsync(RequestTag + " " + TagResult + " " + message)); }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { return(this.NullResult()); }
public static async Task Execute(ImapSession session, string RequestTag, string CommandName, string arg) { var command = GetCommand(CommandName); if (command == null) { await ResponseEnd(session, RequestTag, "NO", CommandName + " Command Not Supported"); return; } if (command.RequireAuth && !session.IsAuthenticated) { await ResponseEnd(session, RequestTag, "NO", CommandName + " Authentication required"); return; } if (command.RequireFolder && session.SelectFolder == null) { await ResponseEnd(session, RequestTag, "NO", CommandName + " Command requires Select state"); return; } if (command.RequireTwoPartCommand) { string[] parts = TextUtils.SplitQuotedString(arg, ' ', true); if (parts.Length != 2) { await ResponseEnd(session, RequestTag, "BAD", "Error in arguments, " + arg); return; } } try { var response = await command.Execute(session, arg); await SendResponse(session, response); var message = new StringBuilder(); if (!String.IsNullOrEmpty(command.AdditionalResponse)) { message.Append(command.AdditionalResponse).Append(" "); } message.Append(CommandName).Append(" Command Completed!"); await ResponseEnd(session, RequestTag, "OK", message.ToString()); } catch (StartTlsException) { await session.Stream.WriteLineAsync($"{RequestTag} OK Begin TLS negotiation now"); await session.StartSecureConnection(); } catch (SessionCloseException ex) { await SendResponse(session, ex.Response); await ResponseEnd(session, RequestTag, "OK", $"{CommandName} Command Completed!"); throw; } catch (CommandException ex) { if (ex.Tag == null) { ex.Tag = "BAD"; } await ResponseEnd(session, RequestTag, ex.Tag, ex.ErrorMessage); } catch (Exception ex) { await ResponseEnd(session, RequestTag, "BAD", ex.Message); } }
public Task <List <ImapResponse> > Execute(ImapSession session, string args) { return(Task.FromResult(Execute(session.MailDb, args))); }
private void HandleClientMessage(object agrument) { //một phiên làm việc với một client TcpClient client = (TcpClient)agrument; string clientIP = ((IPEndPoint)client.Client.RemoteEndPoint).Address.ToString(); string clientPort = ((IPEndPoint)client.Client.RemoteEndPoint).Port.ToString(); // try-cacth lỗi client try { // khởi tạo luồng đọc ghi StreamReader sr = new StreamReader(client.GetStream()); StreamWriter sw = new StreamWriter(client.GetStream()); NetworkStream ns = client.GetStream(); // cài đặt timeout = 30 phút sr.BaseStream.ReadTimeout = 1800000; // tạo sessionImap ImapSession session = new ImapSession(); string msg = "t"; string resposed = session.GetResposed("default"); // int msgLength; byte[] encryptMsgLength = new byte[16]; sw.WriteLine(resposed); sw.Flush(); // kiểm tra client đang kết nối while (client.Connected) { // try-cacth timeout try { if (session.GetStartTLS()) { // đọc kích thước chuỗi mã hóa được gửi từ client ns.Read(encryptMsgLength, 0, 16); if (!Int32.TryParse(session.DecryptWithDefaultKey_IV(encryptMsgLength), out msgLength)) { break; } byte[] encryptCommand = new byte[msgLength]; // đọc thông điệp mã hóa ns.Read(encryptCommand, 0, msgLength); byte[] encResponse = session.GetEncrytionResponse(encryptCommand); byte[] numSendBytes = session.EncryptWithDefaultKey_IV(encResponse.Length.ToString()); // gửi đi trước thông tin mã hóa chứa độ dài của thông điệp mã hóa cần gửi ns.Write(numSendBytes, 0, 16); ns.Flush(); // gửi thông điệp dưới dạng mã hóa ns.Write(encResponse, 0, encResponse.Length); ns.Flush(); // in console server Console.WriteLine("Messages is Encrypted"); } else { msg = sr.ReadLine(); // có thể sinh ra exception trong winform xảy ra khi client đột ngột ngắt kết nối if (msg == null) { break; //msg = null khi client đột ngột ngắt kết nối chỉ trên console } // trả lời lại các lệnh của client trong session hiện tại // in console server Console.WriteLine(msg); resposed = session.GetResposed(msg); if (resposed == "") { continue; } sw.WriteLine(resposed); sw.Flush(); // in console server Console.WriteLine(resposed); } sr.BaseStream.ReadTimeout = 1800000; if (session.GetState() == "Logout") { break; } } catch (IOException ex) { Console.WriteLine(ex.Message); sr.Dispose(); sr.Close(); sw.Dispose(); sw.Close(); ns.Dispose(); ns.Close(); // thông báo timeout cho client sw.WriteLine("* BYE connection timed out"); sw.Flush(); break; } } Console.WriteLine(clientIP + " : " + clientPort + " disconnected"); // giải phóng stream và TCPclient connection client.Dispose(); client.Close(); sr.Dispose(); sr.Close(); sw.Dispose(); sw.Close(); ns.Dispose(); ns.Close(); clientconnectionList.Remove(client); } catch (Exception ex) { Console.WriteLine(ex.Message); client.Dispose(); client.Close(); clientconnectionList.Remove(client); Console.WriteLine(clientIP + " : " + clientPort + " disconnected"); } }