private void OnHandleMultipartCommand(IncommingMail context, string commandLine) { if (context.IsMultipart && (commandLine == "--" + context.Boundary)) { context.State = SmtpState.Data; } }
private void OnHandleControlCommand(Socket client, IncommingMail context, string commandLine) { if (commandLine.StartsWith("QUIT", StringComparison.InvariantCultureIgnoreCase)) { Send(client, "221 Closing channel"); client.Close(); return; } if (commandLine.StartsWith("EHLO", StringComparison.InvariantCultureIgnoreCase)) { Send(client, "250-AUTH LOGIN"); Send(client, "250 OK"); return; } if (commandLine.StartsWith("HELO", StringComparison.InvariantCultureIgnoreCase)) { Send(client, "250 OK"); return; } if (commandLine.StartsWith("AUTH", StringComparison.InvariantCultureIgnoreCase)) { context.State = SmtpState.Authentication1; Send(client, "334 " + Convert.ToBase64String(Encoding.ASCII.GetBytes("useless"))); return; } if (commandLine.StartsWith("RCPT TO", StringComparison.InvariantCultureIgnoreCase)) { var addr = new Regex(@".*\<([a-zA-Z0-9\.\@_-]+)\>.*").Match(commandLine.Substring(7)); if (addr.Success) { context.Message.To.Add(addr.Groups[1].Value); } Send(client, "250 OK"); return; } if (commandLine.StartsWith("MAIL FROM", StringComparison.InvariantCultureIgnoreCase)) { var addr = new Regex(@".*\<([a-zA-Z0-9\.\@]+)\>.*").Match(commandLine.Substring(7)); if (addr.Success) { context.Message.From = new MailAddress(addr.Groups[1].Value); } Send(client, "250 OK"); return; } if (commandLine.StartsWith("DATA", StringComparison.InvariantCultureIgnoreCase)) { context.State = SmtpState.Data; Send(client, "354 Start mail input"); } }
private void OnHandleBodyCommand(Socket client, IncommingMail context, string commandLine) { // handle mail body if (context.IsMultipart && commandLine.StartsWith("--" + context.Boundary)) { if (context.PartDisposition.Contains("attachment")) { ContentType contentType = null; try { if (!string.IsNullOrEmpty(context.PartContentType)) { contentType = new ContentType(context.PartContentType); } } catch (Exception ex) { Trace.TraceWarning("Invalid ContentType '" + context.PartContentType + "' ignored: " + ex.Message); } var data = new MemoryStream(GetBytes(context.Body, context.PartContentEncoding)); var attachment = (contentType != null) ? new Attachment(data, contentType) : new Attachment(data, context.PartName); if ((attachment.Name == null) && !string.IsNullOrEmpty(context.PartName)) { attachment.Name = context.PartName; } context.Message.Attachments.Add(attachment); } else { context.Message.BodyEncoding = null; context.Message.Body = Encoding.UTF8.GetString(GetBytes(context.Body, context.PartContentEncoding)); context.Message.IsBodyHtml = context.PartContentType.ToLower().Contains("html"); if (context.Message.IsBodyHtml) { context.Message.BodyEncoding = DetectHtmlEncoding(context.Message.Body); } } context.PartContentType = string.Empty; context.PartContentEncoding = string.Empty; context.PartName = string.Empty; context.PartDisposition = string.Empty; context.Body = string.Empty; context.State = SmtpState.Data; return; } if (commandLine == ".") { //message has successfully been received if (!context.IsMultipart) { context.Message.BodyEncoding = null; context.Message.Body = Encoding.UTF8.GetString(GetBytes(context.Body, context.ContentEncoding)); context.Message.IsBodyHtml = context.ContentType.ToLower().Contains("html"); if (context.Message.IsBodyHtml) { context.Message.BodyEncoding = DetectHtmlEncoding(context.Message.Body); } } OnNewMail(context.Message); Send(client, "250 OK"); return; } context.Body += commandLine; }
private void OnHandleDataCommand(IncommingMail context, string commandLine) { // parse header data here if (commandLine == string.Empty) { context.State = SmtpState.Body; return; } if (commandLine.StartsWith("Subject:", StringComparison.InvariantCultureIgnoreCase)) { context.Message.Subject = commandLine.Substring(8).Trim(); if (context.Message.Subject.StartsWith("=") && context.Message.Subject.EndsWith("=")) { var decoder = new QuotedPrintable(); var iso = Encoding.GetEncoding("ISO-8859-1"); context.Message.Subject = iso.GetString(decoder.Decode(context.Message.Subject)); } context.RecentLine = commandLine; return; } if (commandLine.StartsWith("Content-Type:", StringComparison.InvariantCultureIgnoreCase)) { var contentType = commandLine.Substring(13).Trim(); if (context.IsMultipart) { context.PartContentType = contentType; if (contentType.Contains("name=")) { var name = contentType.IndexOf("name=", StringComparison.InvariantCultureIgnoreCase); context.PartName = contentType.Substring(name + 5).Trim(); } if (string.IsNullOrEmpty(context.PartName) && contentType.Contains("file=")) { var file = contentType.IndexOf("file=", StringComparison.InvariantCultureIgnoreCase); context.PartName = contentType.Substring(file + 5).Trim(); } if (string.IsNullOrEmpty(context.PartName) && contentType.Contains("filename=")) { var filename = context.PartDisposition.IndexOf("filename=", StringComparison.InvariantCultureIgnoreCase); context.PartName = context.PartDisposition.Substring(filename + 9).Trim(); } } else { context.ContentType = contentType; if (contentType.Contains("multipart") && contentType.Contains("boundary=")) { var boundary = contentType.IndexOf("boundary=", StringComparison.InvariantCultureIgnoreCase); context.Boundary = contentType.Substring(boundary + 9).Trim(); } } if (context.IsMultipart && commandLine.Contains("boundary=")) { var boundary = commandLine.IndexOf("boundary=", StringComparison.InvariantCultureIgnoreCase); context.Boundary = commandLine.Substring(boundary + 9).Trim(); } context.RecentLine = commandLine; return; } if (commandLine.StartsWith("Content-Disposition:", StringComparison.InvariantCultureIgnoreCase)) { var disposition = commandLine.Substring(20).Trim(); context.PartDisposition = disposition; context.RecentLine = commandLine; return; } if (commandLine.StartsWith("Content-Transfer-Encoding:", StringComparison.InvariantCultureIgnoreCase)) { var encoding = commandLine.Substring(26).Trim(); if (context.IsMultipart) { context.PartContentEncoding = encoding; } else { context.ContentEncoding = encoding; } context.RecentLine = commandLine; } }
private void OnHandleAuthentication2Command(Socket client, IncommingMail context) { context.State = SmtpState.Control; Send(client, "235 Authentication successful."); }
private void OnHandleAuthentication1Command(Socket client, IncommingMail context) { context.State = SmtpState.Authentication2; Send(client, "334 " + Convert.ToBase64String(Encoding.ASCII.GetBytes("useless"))); }