imap init

This commit is contained in:
BlubbFish 2010-07-10 17:45:10 +00:00
parent 77efe9973d
commit ec84451b4d
28 changed files with 1178 additions and 47 deletions

View File

@ -1,5 +1,7 @@
using System;
using MailServer.Misc;
namespace MailServer.IMAP.Server
{
/// <summary>

View File

@ -0,0 +1,346 @@
using System;
using System.IO;
using System.Collections;
using System.Text;
using MailServer.Misc.MIME;
using MailServer.Misc.Mail;
namespace MailServer.IMAP.Server
{
/// <summary>
/// FETCH command helper methods.
/// </summary>
internal class FetchHelper
{
#region method ParseHeaderFields
/// <summary>
/// Returns requested header fields lines.
/// Note: Header terminator blank line is included.
/// </summary>
/// <param name="fieldsStr">Header fields to get.</param>
/// <param name="entity">Entity which header field lines to get.</param>
/// <returns></returns>
public static byte[] ParseHeaderFields(string fieldsStr, MIME_Entity entity)
{
return ParseHeaderFields(fieldsStr, System.Text.Encoding.Default.GetBytes(entity.Header.ToString()));
}
/// <summary>
/// Returns requested header fields lines.
/// Note: Header terminator blank line is included.
/// </summary>
/// <param name="fieldsStr">Header fields to get.</param>
/// <param name="data">Message data.</param>
/// <returns></returns>
public static byte[] ParseHeaderFields(string fieldsStr, byte[] data)
{
fieldsStr = fieldsStr.Trim();
if (fieldsStr.StartsWith("("))
{
fieldsStr = fieldsStr.Substring(1, fieldsStr.Length - 1);
}
if (fieldsStr.EndsWith(")"))
{
fieldsStr = fieldsStr.Substring(0, fieldsStr.Length - 1);
}
string retVal = "";
string[] fields = fieldsStr.Split(' ');
using (MemoryStream mStrm = new MemoryStream(data))
{
TextReader r = new StreamReader(mStrm);
string line = r.ReadLine();
bool fieldFound = false;
// Loop all header lines
while (line != null)
{
// End of header
if (line.Length == 0)
{
break;
}
// Field continues
if (fieldFound && line.StartsWith("\t"))
{
retVal += line + "\r\n";
}
else
{
fieldFound = false;
// Check if wanted field
foreach (string field in fields)
{
if (line.Trim().ToLower().StartsWith(field.Trim().ToLower()))
{
retVal += line + "\r\n";
fieldFound = true;
}
}
}
line = r.ReadLine();
}
}
// Add header terminating blank line
retVal += "\r\n";
return System.Text.Encoding.ASCII.GetBytes(retVal);
}
#endregion
#region method ParseHeaderFieldsNot
/// <summary>
/// Returns header fields lines except requested.
/// Note: Header terminator blank line is included.
/// </summary>
/// <param name="fieldsStr">Header fields to skip.</param>
/// <param name="entity">Entity which header field lines to get.</param>
/// <returns></returns>
public static byte[] ParseHeaderFieldsNot(string fieldsStr, MIME_Entity entity)
{
return ParseHeaderFieldsNot(fieldsStr, System.Text.Encoding.Default.GetBytes(entity.Header.ToString()));
}
/// <summary>
/// Returns header fields lines except requested.
/// Note: Header terminator blank line is included.
/// </summary>
/// <param name="fieldsStr">Header fields to skip.</param>
/// <param name="data">Message data.</param>
/// <returns></returns>
public static byte[] ParseHeaderFieldsNot(string fieldsStr, byte[] data)
{
fieldsStr = fieldsStr.Trim();
if (fieldsStr.StartsWith("("))
{
fieldsStr = fieldsStr.Substring(1, fieldsStr.Length - 1);
}
if (fieldsStr.EndsWith(")"))
{
fieldsStr = fieldsStr.Substring(0, fieldsStr.Length - 1);
}
string retVal = "";
string[] fields = fieldsStr.Split(' ');
using (MemoryStream mStrm = new MemoryStream(data))
{
TextReader r = new StreamReader(mStrm);
string line = r.ReadLine();
bool fieldFound = false;
// Loop all header lines
while (line != null)
{
// End of header
if (line.Length == 0)
{
break;
}
// Filed continues
if (fieldFound && line.StartsWith("\t"))
{
retVal += line + "\r\n";
}
else
{
fieldFound = false;
// Check if wanted field
foreach (string field in fields)
{
if (line.Trim().ToLower().StartsWith(field.Trim().ToLower()))
{
fieldFound = true;
}
}
if (!fieldFound)
{
retVal += line + "\r\n";
}
}
line = r.ReadLine();
}
}
return System.Text.Encoding.ASCII.GetBytes(retVal);
}
#endregion
#region static method GetMimeEntity
/// <summary>
/// Gets specified mime entity. Returns null if specified mime entity doesn't exist.
/// </summary>
/// <param name="message">Mail message.</param>
/// <param name="mimeEntitySpecifier">Mime entity specifier. Nested mime entities are pointed by '.'.
/// For example: 1,1.1,2.1, ... .</param>
/// <returns></returns>
public static MIME_Entity GetMimeEntity(Mail_Message message, string mimeEntitySpecifier)
{
// TODO: nested rfc 822 message
// For single part message there is only one entity with value 1.
// Example:
// header
// entity -> 1
// For multipart message, entity counting starts from MainEntity.ChildEntities
// Example:
// header
// multipart/mixed
// text/plain -> 1
// application/pdf -> 2
// ...
// Single part
if (message.ContentType == null || message.ContentType.Type.ToLower() != "multipart")
{
if (Convert.ToInt32(mimeEntitySpecifier) == 1)
{
return message;
}
else
{
return null;
}
}
// multipart
else
{
/*
MIME_Entity currentEntity = message;
string[] parts = mimeEntitySpecifier.Split('.');
for(int i=0;i<parts.Length;i++){
int partSpecifier = Convert.ToInt32(parts[i]) - 1; // Enitites are zero base, mimeEntitySpecifier is 1 based.
currentEntity
// Last mime part.
if(i == (parts.Length - 1)){
}
// Not a last mime part.
else{
}
}*/
MIME_Entity entity = message;
string[] parts = mimeEntitySpecifier.Split('.');
foreach (string part in parts)
{
int mEntryNo = Convert.ToInt32(part) - 1; // Enitites are zero base, mimeEntitySpecifier is 1 based.
if (entity.Body is MIME_b_Multipart)
{
MIME_b_Multipart multipart = (MIME_b_Multipart)entity.Body;
if (mEntryNo > -1 && mEntryNo < multipart.BodyParts.Count)
{
entity = multipart.BodyParts[mEntryNo];
}
else
{
return null;
}
}
else
{
return null;
}
}
return entity;
}
}
#endregion
#region static method GetMimeEntityHeader
/// <summary>
/// Gets specified mime entity header.
/// Note: Header terminator blank line is included.
/// </summary>
/// <param name="entity">Mime entity.</param>
/// <returns></returns>
public static byte[] GetMimeEntityHeader(MIME_Entity entity)
{
return System.Text.Encoding.ASCII.GetBytes(entity.Header.ToString() + "\r\n");
}
/// <summary>
/// Gets requested mime entity header. Returns null if specified mime entity doesn't exist.
/// Note: Header terminator blank line is included.
/// </summary>
/// <param name="message">Mail message.</param>
/// <param name="mimeEntitySpecifier">Mime entity specifier. Nested mime entities are pointed by '.'.
/// For example: 1,1.1,2.1, ... .</param>
/// <returns>Returns requested mime entity data or NULL if requested entry doesn't exist.</returns>
public static byte[] GetMimeEntityHeader(Mail_Message message, string mimeEntitySpecifier)
{
MIME_Entity mEntry = GetMimeEntity(message, mimeEntitySpecifier);
if (mEntry != null)
{
return GetMimeEntityHeader(mEntry);
}
else
{
return null;
}
}
#endregion
#region static method GetMimeEntityData
/// <summary>
/// Gets requested mime entity data. Returns null if specified mime entity doesn't exist.
/// </summary>
/// <param name="message">Mail message.</param>
/// <param name="mimeEntitySpecifier">Mime entity specifier. Nested mime entities are pointed by '.'.
/// For example: 1,1.1,2.1, ... .</param>
/// <returns>Returns requested mime entity data or NULL if requested entry doesn't exist.</returns>
public static byte[] GetMimeEntityData(Mail_Message message, string mimeEntitySpecifier)
{
MIME_Entity entity = GetMimeEntity(message, mimeEntitySpecifier);
if (entity != null)
{
if (entity.Body is MIME_b_SinglepartBase)
{
return ((MIME_b_SinglepartBase)entity.Body).EncodedData;
}
}
return null;
}
#endregion
#region static method Escape
private static string Escape(string text)
{
text = text.Replace("\\", "\\\\");
text = text.Replace("\"", "\\\"");
return text;
}
#endregion
}
}

View File

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MailServer.IMAP.Server
{
/// <summary>
/// Specifies message itmes.
/// </summary>
public enum IMAP_MessageItems_enum
{
/// <summary>
/// None.
/// </summary>
None = 0,
/// <summary>
/// Message main header.
/// </summary>
Header = 2,
/// <summary>
/// IMAP ENVELOPE structure.
/// </summary>
Envelope = 4,
/// <summary>
/// IMAP BODYSTRUCTURE structure.
/// </summary>
BodyStructure = 8,
/// <summary>
/// Full message.
/// </summary>
Message = 16,
}
}

View File

@ -2,6 +2,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using MailServer.Misc;
namespace MailServer.IMAP.Server
{

View File

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using MailServer.Misc;
namespace MailServer.IMAP.Server
{
public partial class IMAP_Server

View File

@ -3,6 +3,9 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using MailServer.Misc.Auth;
using MailServer.Misc.SocketServer;
namespace MailServer.IMAP.Server
{
public partial class IMAP_Server

View File

@ -1,7 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Sockets;
using MailServer.Misc;
using MailServer.Misc.SocketServer;
namespace MailServer.IMAP.Server
{

View File

@ -1,4 +1,5 @@
using MailServer.Misc.SocketServer;
using MailServer.Misc.Auth;
using MailServer.Misc;
using System.Net;

View File

@ -9,6 +9,8 @@ using System.Text;
using MailServer.Misc.SocketServer;
using MailServer.Misc;
using MailServer.Misc.Auth;
using MailServer.Misc.Mail;
using MailServer.Misc.MIME;
namespace MailServer.IMAP.Server
@ -2974,7 +2976,7 @@ namespace MailServer.IMAP.Server
SearchGroup searchCriteria = new SearchGroup();
try
{
searchCriteria.Parse(new Misc.StringReader(argsText));
searchCriteria.Parse(new StringReader(argsText));
}
catch (Exception x)
{

View File

@ -0,0 +1,246 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
namespace MailServer.IMAP.Server
{
/// <summary>
/// Provides data to event GetMessageItems.
/// </summary>
public class IMAP_eArgs_MessageItems
{
private IMAP_Session m_pSession = null;
private IMAP_Message m_pMessageInfo = null;
private IMAP_MessageItems_enum m_MessageItems = IMAP_MessageItems_enum.Message;
private bool m_CloseMessageStream = true;
private Stream m_MessageStream = null;
private long m_MessageStartOffset = 0;
private byte[] m_Header = null;
private string m_Envelope = null;
private string m_BodyStructure = null;
private bool m_MessageExists = true;
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="session">Reference to current IMAP session.</param>
/// <param name="messageInfo">Message info what message items to get.</param>
/// <param name="messageItems">Specifies message items what must be filled.</param>
public IMAP_eArgs_MessageItems(IMAP_Session session, IMAP_Message messageInfo, IMAP_MessageItems_enum messageItems)
{
m_pSession = session;
m_pMessageInfo = messageInfo;
m_MessageItems = messageItems;
}
/// <summary>
/// Default deconstructor.
/// </summary>
~IMAP_eArgs_MessageItems()
{
Dispose();
}
#region method Dispose
/// <summary>
/// Clean up any resources being used.
/// </summary>
public void Dispose()
{
if (m_CloseMessageStream && m_MessageStream != null)
{
m_MessageStream.Dispose();
m_MessageStream = null;
}
}
#endregion
#region internal method Validate
/// <summary>
/// Checks that all required data items are provided, if not throws exception.
/// </summary>
internal void Validate()
{
if ((m_MessageItems & IMAP_MessageItems_enum.BodyStructure) != 0 && m_BodyStructure == null)
{
throw new Exception("IMAP BODYSTRUCTURE is required, but not provided to IMAP server component !");
}
if ((m_MessageItems & IMAP_MessageItems_enum.Envelope) != 0 && m_Envelope == null)
{
throw new Exception("IMAP ENVELOPE is required, but not provided to IMAP server component !");
}
if ((m_MessageItems & IMAP_MessageItems_enum.Header) != 0 && m_Header == null)
{
throw new Exception("Message header is required, but not provided to IMAP server component !");
}
if ((m_MessageItems & IMAP_MessageItems_enum.Message) != 0 && m_MessageStream == null)
{
throw new Exception("Full message is required, but not provided to IMAP server component !");
}
}
#endregion
#region Properties Implementation
/// <summary>
/// Gets reference to current IMAP session.
/// </summary>
public IMAP_Session Session
{
get { return m_pSession; }
}
/// <summary>
/// Gets message info what message items to get.
/// </summary>
public IMAP_Message MessageInfo
{
get { return m_pMessageInfo; }
}
/// <summary>
/// Gets what message items must be filled.
/// </summary>
public IMAP_MessageItems_enum MessageItems
{
get { return m_MessageItems; }
}
/// <summary>
/// Gets or sets if message stream is closed automatically if all actions on it are completed.
/// Default value is true.
/// </summary>
public bool CloseMessageStream
{
get { return m_CloseMessageStream; }
set { m_CloseMessageStream = value; }
}
/// <summary>
/// Gets or sets message stream. When setting this property Stream position must be where message begins.
/// Fill this property only if IMAP_MessageItems_enum.Message flag is specified.
/// </summary>
public Stream MessageStream
{
get
{
if (m_MessageStream != null)
{
m_MessageStream.Position = m_MessageStartOffset;
}
return m_MessageStream;
}
set
{
if (value == null)
{
throw new ArgumentNullException("Property MessageStream value can't be null !");
}
if (!value.CanSeek)
{
throw new Exception("Stream must support seeking !");
}
m_MessageStream = value;
m_MessageStartOffset = m_MessageStream.Position;
}
}
/// <summary>
/// Gets message size in bytes.
/// </summary>
public long MessageSize
{
get
{
if (m_MessageStream == null)
{
throw new Exception("You must set MessageStream property first to use this property !");
}
else
{
return m_MessageStream.Length - m_MessageStream.Position;
}
}
}
/// <summary>
/// Gets or sets message main header.
/// Fill this property only if IMAP_MessageItems_enum.Header flag is specified.
/// </summary>
public byte[] Header
{
get { return m_Header; }
set
{
if (value == null)
{
throw new ArgumentNullException("Property Header value can't be null !");
}
m_Header = value;
}
}
/// <summary>
/// Gets or sets IMAP ENVELOPE string.
/// Fill this property only if IMAP_MessageItems_enum.Envelope flag is specified.
/// </summary>
public string Envelope
{
get { return m_Envelope; }
set
{
if (value == null)
{
throw new ArgumentNullException("Property Envelope value can't be null !");
}
m_Envelope = value;
}
}
/// <summary>
/// Gets or sets IMAP BODYSTRUCTURE string.
/// Fill this property only if IMAP_MessageItems_enum.BodyStructure flag is specified.
/// </summary>
public string BodyStructure
{
get { return m_BodyStructure; }
set
{
if (value == null)
{
throw new ArgumentNullException("Property BodyStructure value can't be null !");
}
m_BodyStructure = value;
}
}
/// <summary>
/// Gets or sets if message exists. Set this false, if message actually doesn't exist any more.
/// </summary>
public bool MessageExists
{
get { return m_MessageExists; }
set { m_MessageExists = value; }
}
#endregion
}
}

View File

@ -0,0 +1,69 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MailServer.IMAP.Server
{
/// <summary>
/// Provides data for IMAP events.
/// </summary>
public class Mailbox_EventArgs
{
private string m_Folder = "";
private string m_NewFolder = "";
private string m_Error = null;
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="folder"></param>
public Mailbox_EventArgs(string folder)
{
m_Folder = folder;
}
/// <summary>
/// Folder rename constructor.
/// </summary>
/// <param name="folder"></param>
/// <param name="newFolder"></param>
public Mailbox_EventArgs(string folder, string newFolder)
{
m_Folder = folder;
m_NewFolder = newFolder;
}
#region Properties Implementation
/// <summary>
/// Gets folder.
/// </summary>
public string Folder
{
get { return m_Folder; }
}
/// <summary>
/// Gets new folder name, this is available for rename only.
/// </summary>
public string NewFolder
{
get { return m_NewFolder; }
}
/// <summary>
/// Gets or sets custom error text, which is returned to client.
/// </summary>
public string ErrorText
{
get { return m_Error; }
set { m_Error = value; }
}
#endregion
}
}

View File

@ -0,0 +1,114 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MailServer.IMAP.Server
{
/// <summary>
/// Provides data for message related events.
/// </summary>
public class Message_EventArgs
{
private IMAP_Message m_pMessage = null;
private string m_Folder = "";
private string m_CopyLocation = "";
private byte[] m_MessageData = null;
private bool m_HeadersOnly = false;
private string m_ErrorText = null;
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="folder">IMAP folder which message is.</param>
/// <param name="msg"></param>
public Message_EventArgs(string folder, IMAP_Message msg)
{
m_Folder = folder;
m_pMessage = msg;
}
/// <summary>
/// Copy constructor.
/// </summary>
/// <param name="folder">IMAP folder which message is.</param>
/// <param name="msg"></param>
/// <param name="copyLocation"></param>
public Message_EventArgs(string folder, IMAP_Message msg, string copyLocation)
{
m_Folder = folder;
m_pMessage = msg;
m_CopyLocation = copyLocation;
}
/// <summary>
/// GetMessage constructor.
/// </summary>
/// <param name="folder">IMAP folder which message is.</param>
/// <param name="msg"></param>
/// <param name="headersOnly">Specifies if messages headers or full message is needed.</param>
public Message_EventArgs(string folder, IMAP_Message msg, bool headersOnly)
{
m_Folder = folder;
m_pMessage = msg;
m_HeadersOnly = headersOnly;
}
#region Properties Implementation
/// <summary>
/// Gets IMAP folder.
/// </summary>
public string Folder
{
get { return m_Folder; }
}
/// <summary>
/// Gets IMAP message info.
/// </summary>
public IMAP_Message Message
{
get { return m_pMessage; }
}
/// <summary>
/// Gets message new location. NOTE: this is available for copy command only.
/// </summary>
public string CopyLocation
{
get { return m_CopyLocation; }
}
/// <summary>
/// Gets or sets message data. NOTE: this is available for GetMessage and StoreMessage event only.
/// </summary>
public byte[] MessageData
{
get { return m_MessageData; }
set { m_MessageData = value; }
}
/// <summary>
/// Gets if message headers or full message wanted. NOTE: this is available for GetMessage event only.
/// </summary>
public bool HeadersOnly
{
get { return m_HeadersOnly; }
}
/// <summary>
/// Gets or sets custom error text, which is returned to client.
/// </summary>
public string ErrorText
{
get { return m_ErrorText; }
set { m_ErrorText = value; }
}
#endregion
}
}

View File

@ -0,0 +1,55 @@
using System;
namespace MailServer.IMAP.Server
{
/// <summary>
/// Summary description for SharedRootFolders_EventArgs.
/// </summary>
public class SharedRootFolders_EventArgs
{
private IMAP_Session m_pSession = null;
private string[] m_SharedRootFolders = null;
private string[] m_PublicRootFolders = null;
/// <summary>
/// Default constructor.
/// </summary>
public SharedRootFolders_EventArgs(IMAP_Session session)
{
m_pSession = session;
}
#region Properties Implementation
/// <summary>
/// Gets reference to smtp session.
/// </summary>
public IMAP_Session Session
{
get { return m_pSession; }
}
/// <summary>
/// Gets or sets users shared root folders. Ususaly there is only one root folder 'Shared Folders'.
/// </summary>
public string[] SharedRootFolders
{
get { return m_SharedRootFolders; }
set { m_SharedRootFolders = value; }
}
/// <summary>
/// Gets or sets public root folders. Ususaly there is only one root folder 'Public Folders'.
/// </summary>
public string[] PublicRootFolders
{
get { return m_PublicRootFolders; }
set { m_PublicRootFolders = value; }
}
#endregion
}
}

View File

@ -1,6 +1,8 @@
namespace MailServer
using MailServer.IMAP.Server;
namespace MailServer
{
partial class Service1
partial class IMAP_s
{
/// <summary>
/// Erforderliche Designervariable.
@ -29,7 +31,8 @@
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "Service1";
this.ServiceName = "IMAP_Server";
this.server = new IMAP_Server();
}
#endregion

60
MailServer/IMAP_s.cs Normal file
View File

@ -0,0 +1,60 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using MailServer.IMAP.Server;
namespace MailServer
{
public partial class IMAP_s : ServiceBase
{
private IMAP_Server server;
public IMAP_s()
{
InitializeComponent();
putEvents();
}
private void putEvents()
{
this.server.AuthUser += new AuthUserEventHandler(server_AuthUser);
this.server.CopyMessage += new MessageEventHandler(server_CopyMessage);
this.server.CreateFolder += new FolderEventHandler(server_CreateFolder);
this.server.DeleteFolder += new FolderEventHandler(server_DeleteFolder);
this.server.DeleteFolderACL += new DeleteFolderACLEventHandler(server_DeleteFolderACL);
this.server.DeleteMessage += new MessageEventHandler(server_DeleteMessage);
this.server.GetFolderACL += new GetFolderACLEventHandler(server_GetFolderACL);
this.server.GetFolders += new FoldersEventHandler(server_GetFolders);
this.server.GetMessageItems += new MessagesItemsEventHandler(server_GetMessageItems);
this.server.GetMessagesInfo += new MessagesEventHandler(server_GetMessagesInfo);
this.server.GetSharedRootFolders += new SharedRootFoldersEventHandler(server_GetSharedRootFolders);
this.server.GetSubscribedFolders += new FoldersEventHandler(server_GetSubscribedFolders);
this.server.GetUserACL += new GetUserACLEventHandler(server_GetUserACL);
this.server.GetUserQuota += new GetUserQuotaHandler(server_GetUserQuota);
this.server.RenameFolder += new FolderEventHandler(server_RenameFolder);
this.server.SessionLog += new Misc.LogEventHandler(server_SessionLog);
this.server.SetFolderACL += new SetFolderACLEventHandler(server_SetFolderACL);
this.server.StoreMessage += new MessageEventHandler(server_StoreMessage);
this.server.StoreMessageFlags += new MessageEventHandler(server_StoreMessageFlags);
this.server.SubscribeFolder += new FolderEventHandler(server_SubscribeFolder);
this.server.SysError += new Misc.ErrorEventHandler(server_SysError);
this.server.UnSubscribeFolder += new FolderEventHandler(server_UnSubscribeFolder);
this.server.ValidateIPAddress += new Misc.ValidateIPHandler(server_ValidateIPAddress);
}
protected override void OnStart(string[] args)
{
this.server.StartServer();
}
protected override void OnStop()
{
}
}
}

View File

@ -49,15 +49,18 @@
<Compile Include="IMAP\IMAP_SequenceSet.cs" />
<Compile Include="IMAP\IMAP_Utils.cs" />
<Compile Include="IMAP\Server\AuthUser_EventArgs\AuthUser_EventArgs.cs" />
<Compile Include="IMAP\Server\FetchHelper\FetchHelper.cs" />
<Compile Include="IMAP\Server\IMAP_DELETEACL_eArgs\IMAP_DELETEACL_eArgs.cs" />
<Compile Include="IMAP\Server\IMAP_eArgs_GetMessagesInfo\IMAP_eArgs_GetMessagesInfo.cs" />
<Compile Include="IMAP\Server\IMAP_eArgs_GetQuota\IMAP_eArgs_GetQuota.cs" />
<Compile Include="IMAP\Server\IMAP_eArgs_MessageItems\IMAP_eArgs_MessageItems.cs" />
<Compile Include="IMAP\Server\IMAP_Folders\IMAP_Folders.cs" />
<Compile Include="IMAP\Server\IMAP_Folder\IMAP_Folder.cs" />
<Compile Include="IMAP\Server\IMAP_GETACL_eArgs\IMAP_GETACL_eArgs.cs" />
<Compile Include="IMAP\Server\IMAP_GetUserACL_eArgs\IMAP_GetUserACL_eArgs.cs" />
<Compile Include="IMAP\Server\IMAP_MessageCollection\IMAP_MessageCollection.cs" />
<Compile Include="IMAP\Server\IMAP_MessageFlags.cs" />
<Compile Include="IMAP\Server\IMAP_MessageItems_enum.cs" />
<Compile Include="IMAP\Server\IMAP_Message\IMAP_Message.cs" />
<Compile Include="IMAP\Server\IMAP_SelectedFolder\IMAP_SelectedFolder.cs" />
<Compile Include="IMAP\Server\IMAP_Session\IMAP_Session.cs" />
@ -78,11 +81,15 @@
<SubType>Component</SubType>
</Compile>
<Compile Include="IMAP\Server\IMAP_SETACL_eArgs\IMAP_SETACL_eArgs.cs" />
<Compile Include="IMAP\Server\Mailbox_EventArgs\Mailbox_EventArgs.cs" />
<Compile Include="IMAP\Server\Message_EventArgs\Message_EventArgs.cs" />
<Compile Include="IMAP\Server\SearchGroup\SearchGroup.cs" />
<Compile Include="IMAP\Server\SearchKey\SearchKey.cs" />
<Compile Include="IMAP\Server\SharedRootFolders_EventArgs\SharedRootFolders_EventArgs.cs" />
<Compile Include="Misc\AsyncOP.cs" />
<Compile Include="Misc\Auth\AuthHelper\AuthHelper.cs" />
<Compile Include="Misc\Auth\SaslAuthTypes.cs" />
<Compile Include="Misc\Core\ValidateIP_EventArgs.cs" />
<Compile Include="Misc\EventArgs.cs" />
<Compile Include="Misc\IO\Base64Stream\Base64Stream.cs" />
<Compile Include="Misc\IO\Base64\Base64.cs" />
@ -113,12 +120,25 @@
<Compile Include="Misc\IO\DataSizeExceededException.cs" />
<Compile Include="Misc\IO\IncompleteDataException.cs" />
<Compile Include="Misc\IO\LineSizeExceededException.cs" />
<Compile Include="Misc\IO\OuotedPrintableStream\QuotedPrintableStream.cs" />
<Compile Include="Misc\IO\QuotedPrintableStream\QuotedPrintableStream.cs" />
<Compile Include="Misc\IO\ReadWriteControlledStream.cs" />
<Compile Include="Misc\IO\SizeExceededAction.cs" />
<Compile Include="Misc\IO\SmartStream\SmartStream.cs" />
<Compile Include="Misc\IPBindInfo\IPBindInfo.cs" />
<Compile Include="Misc\Mail\Mail_h_AddressList.cs" />
<Compile Include="Misc\Mail\Mail_h_DispositionNotificationOptions.cs" />
<Compile Include="Misc\Mail\Mail_h_Mailbox.cs" />
<Compile Include="Misc\Mail\Mail_h_MailboxList.cs" />
<Compile Include="Misc\Mail\Mail_h_Received.cs" />
<Compile Include="Misc\Mail\Mail_h_ReturnPath.cs" />
<Compile Include="Misc\Mail\Mail_Message\Mail_Message.cs" />
<Compile Include="Misc\Mail\Mail_t_Address.cs" />
<Compile Include="Misc\Mail\Mail_t_AddressList.cs" />
<Compile Include="Misc\Mail\Mail_t_Group.cs" />
<Compile Include="Misc\Mail\Mail_t_Mailbox.cs" />
<Compile Include="Misc\Mail\Mail_t_MailboxList.cs" />
<Compile Include="Misc\Mail\Mail_t_TcpInfo.cs" />
<Compile Include="Misc\Mail\Mail_Utils.cs" />
<Compile Include="Misc\MIME\MIME_b.cs" />
<Compile Include="Misc\MIME\MIME_b_Application.cs" />
<Compile Include="Misc\MIME\MIME_b_Audio.cs" />
@ -162,7 +182,7 @@
<Compile Include="Misc\MIME\MIME_Utils.cs" />
<Compile Include="Misc\Net_Utils\Net_Utils.cs" />
<Compile Include="Misc\ParseException.cs" />
<Compile Include="Misc\SaslAuthTypes.cs" />
<Compile Include="Misc\SocketBufferedWriter.cs" />
<Compile Include="Misc\SocketServer\Log_EventArgs\Log_EventArgs.cs" />
<Compile Include="Misc\SocketServer\ReadExecption\ReadExecption.cs" />
<Compile Include="Misc\SocketServer\SocketCallBackResult.cs" />
@ -203,7 +223,7 @@
</Compile>
<Compile Include="Misc\SSLMode.cs" />
<Compile Include="Misc\StreamLineReader\StreamLineReader.cs" />
<Compile Include="Misc\StringReader\StringReader.cs" />
<Compile Include="Types\StringReader\StringReader.cs" />
<Compile Include="Misc\TextUtils\TextUtils.cs" />
<Compile Include="Misc\TimerEx\TimerEx.cs">
<SubType>Component</SubType>

View File

@ -3,7 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace MailServer.Misc
namespace MailServer.Misc.Auth
{
/// <summary>
/// SASL authentications

View File

@ -555,7 +555,7 @@ namespace MailServer.Misc
/// </summary>
/// <param name="data">Data which to encode.</param>
/// <returns></returns>
[Obsolete("Use MIME_Utils.QuotedPrintableDecode instead of it")]
//[Obsolete("Use MIME_Utils.QuotedPrintableDecode instead of it")]
public static byte[] QuotedPrintableDecode(byte[] data)
{
/* RFC 2045 6.7. Quoted-Printable Content-Transfer-Encoding
@ -678,7 +678,7 @@ namespace MailServer.Misc
/// <param name="encoding">Input string encoding.</param>
/// <param name="data">String which to encode.</param>
/// <returns>Returns decoded string.</returns>
[Obsolete("Use MIME_Utils.QDecode instead of it")]
//[Obsolete("Use MIME_Utils.QDecode instead of it")]
public static string QDecode(System.Text.Encoding encoding, string data)
{
return encoding.GetString(QuotedPrintableDecode(System.Text.Encoding.ASCII.GetBytes(data.Replace("_", " "))));
@ -1042,7 +1042,7 @@ namespace MailServer.Misc
/// </summary>
/// <param name="data"></param>
/// <returns></returns>
[Obsolete("Use Net_Utils.IsAscii instead of it")]
//[Obsolete("Use Net_Utils.IsAscii instead of it")]
public static bool IsAscii(string data)
{
foreach (char c in data)
@ -1318,7 +1318,7 @@ namespace MailServer.Misc
/// </summary>
/// <param name="hexData">Hex data.</param>
/// <returns></returns>
[Obsolete("Use Net_Utils.FromHex instead of it")]
//[Obsolete("Use Net_Utils.FromHex instead of it")]
public static byte[] FromHex(byte[] hexData)
{
if (hexData.Length < 2 || (hexData.Length / (double)2 != Math.Floor(hexData.Length / (double)2)))

View File

@ -0,0 +1,88 @@
using System;
using System.Net;
namespace MailServer.Misc
{
/// <summary>
/// Provides data for the ValidateIPAddress event for servers.
/// </summary>
public class ValidateIP_EventArgs
{
private IPEndPoint m_pLocalEndPoint = null;
private IPEndPoint m_pRemoteEndPoint = null;
private bool m_Validated = true;
private object m_SessionTag = null;
private string m_ErrorText = "";
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="localEndPoint">Server IP.</param>
/// <param name="remoteEndPoint">Connected client IP.</param>
public ValidateIP_EventArgs(IPEndPoint localEndPoint, IPEndPoint remoteEndPoint)
{
m_pLocalEndPoint = localEndPoint;
m_pRemoteEndPoint = remoteEndPoint;
}
#region Properties Implementation
/// <summary>
/// IP address of computer, which is sending mail to here.
/// </summary>
public string ConnectedIP
{
get { return m_pRemoteEndPoint.Address.ToString(); }
}
/// <summary>
/// Gets local endpoint.
/// </summary>
public IPEndPoint LocalEndPoint
{
get { return m_pLocalEndPoint; }
}
/// <summary>
/// Gets remote endpoint.
/// </summary>
public IPEndPoint RemoteEndPoint
{
get { return m_pRemoteEndPoint; }
}
/// <summary>
/// Gets or sets if IP is allowed access.
/// </summary>
public bool Validated
{
get { return m_Validated; }
set { m_Validated = value; }
}
/// <summary>
/// Gets or sets user data what is stored to session.Tag property.
/// </summary>
public object SessionTag
{
get { return m_SessionTag; }
set { m_SessionTag = value; }
}
/// <summary>
/// Gets or sets error text what is sent to connected socket. NOTE: This is only used if Validated = false.
/// </summary>
public string ErrorText
{
get { return m_ErrorText; }
set { m_ErrorText = value; }
}
#endregion
}
}

View File

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using MailServer.Misc.IO;
namespace MailServer.Misc
{

View File

@ -0,0 +1,95 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Text;
using MailServer.Misc.SocketServer;
namespace MailServer.Misc
{
/// <summary>
/// Implements buffered writer for socket.
/// </summary>
//[Obsolete("Get rid of it.")]
public class SocketBufferedWriter
{
private SocketEx m_pSocket = null;
private int m_BufferSize = 8000;
private byte[] m_Buffer = null;
private int m_AvailableInBuffer = 0;
/// <summary>
/// Default constructor.
/// </summary>
/// <param name="socket">Socket where to write data.</param>
public SocketBufferedWriter(SocketEx socket)
{
m_pSocket = socket;
m_Buffer = new byte[m_BufferSize];
}
#region method Flush
/// <summary>
/// Forces to send all data in buffer to destination host.
/// </summary>
public void Flush()
{
if (m_AvailableInBuffer > 0)
{
m_pSocket.Write(m_Buffer, 0, m_AvailableInBuffer);
m_AvailableInBuffer = 0;
}
}
#endregion
#region method Write
/// <summary>
/// Queues specified data to write buffer. If write buffer is full, buffered data will be sent to detination host.
/// </summary>
/// <param name="data">Data to queue.</param>
public void Write(string data)
{
Write(System.Text.Encoding.UTF8.GetBytes(data));
}
/// <summary>
/// Queues specified data to write buffer. If write buffer is full, buffered data will be sent to detination host.
/// </summary>
/// <param name="data">Data to queue.</param>
public void Write(byte[] data)
{
// There is no room to accomodate data to buffer
if ((m_AvailableInBuffer + data.Length) > m_BufferSize)
{
// Send buffer data
m_pSocket.Write(m_Buffer, 0, m_AvailableInBuffer);
m_AvailableInBuffer = 0;
// Store new data to buffer
if (data.Length < m_BufferSize)
{
Array.Copy(data, m_Buffer, data.Length);
m_AvailableInBuffer = data.Length;
}
// Buffer is smaller than data, send it directly
else
{
m_pSocket.Write(data);
}
}
// Store data to buffer
else
{
Array.Copy(data, 0, m_Buffer, m_AvailableInBuffer, data.Length);
m_AvailableInBuffer += data.Length;
}
}
#endregion
}
}

View File

@ -8,7 +8,7 @@ namespace MailServer.Misc.SocketServer
/// <summary>
/// This class implements extended socket, provides usefull methods for reading and writing data to socket.
/// </summary>
[Obsolete("Use TCP_Client or TCP_Server instead.")]
//[Obsolete("Use TCP_Client or TCP_Server instead.")]
public partial class SocketEx : IDisposable
{
private Socket m_pSocket = null;

View File

@ -7,7 +7,7 @@ namespace MailServer.Misc.SocketServer
/// <summary>
/// This is base class for Socket and Session based servers.
/// </summary>
[Obsolete("Use TCP_Server class instead")]
//[Obsolete("Use TCP_Server class instead")]
public abstract partial class SocketServer : System.ComponentModel.Component
{
private List<SocketServerSession> m_pSessions = null;

View File

@ -6,7 +6,7 @@ namespace MailServer.Misc.SocketServer
/// <summary>
/// This is base class for SocketServer sessions.
/// </summary>
[Obsolete("Use TCP_Server class instead")]
//[Obsolete("Use TCP_Server class instead")]
public abstract partial class SocketServerSession
{
private string m_SessionID = "";

View File

@ -12,4 +12,11 @@ namespace MailServer.Misc
/// <param name="sender">Delegate caller.</param>
/// <param name="e">Event data.</param>
public delegate void ErrorEventHandler(object sender, Error_EventArgs e);
/// <summary>
/// Represents the method that will handle the <see href="LumiSoftMailServerSMTPSMTP_ServerValidateIPAddressFieldOrEvent.html">SMTP_Server.ValidateIPAddress</see> and <see href="LumiSoftMailServerPOP3POP3_ServerValidateIPAddressFieldOrEvent.html">POP3_Server.ValidateIPAddress</see>event.
/// </summary>
/// <param name="sender">The source of the event. </param>
/// <param name="e">A <see href="LumiSoftMailServerValidateIP_EventArgs.html">ValidateIP_EventArgs</see> that contains the event data.</param>
public delegate void ValidateIPHandler(object sender, ValidateIP_EventArgs e);
}

View File

@ -22,7 +22,7 @@ namespace MailServer
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
new IMAP_s()
};
ServiceBase.Run(ServicesToRun);
/*

View File

@ -1,27 +0,0 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
namespace MailServer
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}
}

View File

@ -1,7 +1,9 @@
using System;
using System.Text;
namespace MailServer.Misc
using MailServer.Misc;
namespace MailServer
{
/// <summary>
/// String reader.