/// <summary>
        /// Deletes IMAP folder.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what to delete. For example: Inbox,Public Folders/Documnets .</param>
        public void DeleteFolder(string accessingUser,string folderOwnerUser,string folder)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Don't allow to delete shared folders root folder.
                   For BoundedUser root don't allow root folder only,
                   for UsersShared root don't allow root + user name.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'c' permission.
                   There is builtin user system, skip ACL for it.
                *) Create folder.
            */

            // Don't allow to delete inbox
            if(folder.ToLower() == "inbox"){
                throw new Exception("Can't delete inbox");
            }

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                /* Don't allow to delete shared folders root folder.
                   For BoundedUser root don't allow root folder only,
                   for UsersShared root don't allow root + user name.
                */

                // Main shared folder root.
                if(mappedFolder.SharedRootName.ToLower() == originalFolder.ToLower()){
                    throw new ArgumentException("Can't delete shared root folder '" + originalFolder + "' !");
                }
                // Users shared folder: root/username -> no folder
                if(folder == ""){
                    throw new ArgumentException("Can't delete shared root folder '" + originalFolder + "' !");
                }

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder doesn't exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'c' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.c) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Recycle bin handling ----------------------------------------------------------------------//
            if(Convert.ToBoolean(GetRecycleBinSettings().Rows[0]["DeleteToRecycleBin"])){
                IMAP_MessageCollection messages = new IMAP_MessageCollection();
                GetMessagesInfo("system",folderOwnerUser,folder,messages);
                foreach(IMAP_Message message in messages){
                    EmailMessageItems msgItems = new EmailMessageItems(message.ID,IMAP_MessageItems_enum.Message);
                    GetMessageItems("system",folderOwnerUser,folder,msgItems);
                    if(msgItems.MessageExists){
                        string subject = "<none>";
                        try{
                            subject = MimeUtils.ParseHeaderField("Subject:",msgItems.MessageStream);
                            subject = subject.Replace("\r","");
                            subject = subject.Replace("\n","");
                        }
                        catch{
                        }
                        msgItems.MessageStream.Position = 0;
                        byte[] data = new byte[msgItems.MessageStream.Length];
                        msgItems.MessageStream.Read(data,0,data.Length);

                        using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreRecycleBinMessage")){
                            sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,Guid.NewGuid().ToString());
                            sqlCmd.AddParameter("_user"      ,NpgsqlDbType.Varchar,folderOwnerUser);
                            sqlCmd.AddParameter("_folder"    ,NpgsqlDbType.Varchar,folder);
                            sqlCmd.AddParameter("_subject"   ,NpgsqlDbType.Varchar,subject);
                            sqlCmd.AddParameter("_data"      ,NpgsqlDbType.Bytea  ,data);

                            DataSet ds = sqlCmd.Execute();
                        }
                    }
                }
            }
            //----------------------------------------------------------------------------------------------//

            //--- Delete folder
            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_DeleteFolder")){
                sqlCmd.AddParameter("_folderOwnerUser",NpgsqlDbType.Varchar,folderOwnerUser);
                sqlCmd.AddParameter("_folderName"     ,NpgsqlDbType.Varchar,folder);

                DataSet ds = sqlCmd.Execute();
            }
        }
        /// <summary>
        /// Gets message header + number of specified lines.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what message top lines to get. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="msgID">MessageID.</param>
        /// <param name="nrLines">Number of lines to retrieve. NOTE: line counting starts at the end of header.</param>
        /// <returns>Returns message header + number of specified lines.</returns>
        public byte[] GetMessageTopLines(string accessingUser,string folderOwnerUser,string folder,string msgID,int nrLines)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'r' permission.
                    There is builtin user system, skip ACL for it.
                *) Get message top lines.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(msgID);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'r' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.r) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Get message top lines
            if(nrLines < 50){
                using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMessageTopLines")){
                    sqlCmd.AddParameter("_userName"  ,NpgsqlDbType.Varchar,folderOwnerUser);
                    sqlCmd.AddParameter("_folder"    ,NpgsqlDbType.Varchar,folder);
                    sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,msgID);

                    return GetTopLines(new MemoryStream((byte[])sqlCmd.ExecuteScalar()),nrLines);
                }
            }
            else{
                EmailMessageItems msgItems = new EmailMessageItems(msgID,IMAP_MessageItems_enum.Message);
                GetMessageItems(accessingUser,folderOwnerUser,folder,msgItems);
                byte[] topLines = GetTopLines(msgItems.MessageStream,nrLines);
                msgItems.MessageStream.Dispose();
                return topLines;
            }
        }
        /// <summary>
        /// Creates copy of message to destination IMAP folder.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what contains message to copy. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="destFolderUser">Destination IMAP folder owner user name.</param>
        /// <param name="destFolder">Destination IMAP folder name.</param>
        /// <param name="message">IMAP message which to copy.</param>
        public void CopyMessage(string accessingUser,string folderOwnerUser,string folder,string destFolderUser,string destFolder,LumiSoft.Net.IMAP.Server.IMAP_Message message)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) We don't need to map shared folder, check security, it done by GetMessage and StoreMessage methods.
                *) Copy message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateUserName(destFolderUser);
            ArgsValidator.ValidateFolder(destFolder);
            ArgsValidator.ValidateNotNull(message);
            //---------------------------------------//

            //--- Copy message
            //--- Copy message
            EmailMessageItems msgItems = new EmailMessageItems(message.ID,IMAP_MessageItems_enum.Message);
            GetMessageItems(accessingUser,folderOwnerUser,folder,msgItems);
            StoreMessage("system",destFolderUser,destFolder,msgItems.MessageStream,message.InternalDate,message.Flags);
            msgItems.MessageStream.Dispose();
        }
        /// <summary>
        /// Deletes message from mailbox.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="messageID">Message ID.</param>
        /// <param name="uid">Message UID value.</param>
        public void DeleteMessage(string accessingUser,string folderOwnerUser,string folder,string messageID,int uid)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'd' permission.
                    There is builtin user system, skip ACL for it.
                *) Fill messages info.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(messageID);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'd' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.d) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Recycle bin handling ----------------------------------------------------------------------//
            if(Convert.ToBoolean(GetRecycleBinSettings().Rows[0]["DeleteToRecycleBin"])){
                EmailMessageItems msgItems = new EmailMessageItems(messageID,IMAP_MessageItems_enum.Message | IMAP_MessageItems_enum.Envelope);
                GetMessageItems("system",folderOwnerUser,folder,msgItems);
                if(msgItems.MessageExists){
                    byte[] data = new byte[msgItems.MessageStream.Length];
                    msgItems.MessageStream.Read(data,0,data.Length);

                    using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_StoreRecycleBinMessage")){
                        sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,Guid.NewGuid().ToString());
                        sqlCmd.AddParameter("_user"      ,NpgsqlDbType.Varchar,folderOwnerUser);
                        sqlCmd.AddParameter("_folder"    ,NpgsqlDbType.Varchar,folder);
                        sqlCmd.AddParameter("_size"      ,NpgsqlDbType.Bigint ,data.Length);
                        sqlCmd.AddParameter("_envelope"  ,NpgsqlDbType.Varchar,msgItems.Envelope);
                        sqlCmd.AddParameter("_data"      ,NpgsqlDbType.Bytea  ,data);

                        DataSet ds = sqlCmd.Execute();
                    }
                }
            }
            //----------------------------------------------------------------------------------------------//

            //--- Delete message
            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_DeleteMessage")){
                sqlCmd.AddParameter("_userName"  ,NpgsqlDbType.Varchar,folderOwnerUser);
                sqlCmd.AddParameter("_folder"    ,NpgsqlDbType.Varchar,folder);
                sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,messageID);

                DataSet ds = sqlCmd.Execute();
            }
        }
        /// <summary>
        /// Gets specified message specified items.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="e">MessageItems info.</param>
        public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'r' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(e);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'r' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.r) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Get message
            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMessagesItems")){
                sqlCmd.AddParameter("_userName"  ,NpgsqlDbType.Varchar,folderOwnerUser);
                sqlCmd.AddParameter("_folder"    ,NpgsqlDbType.Varchar,folder);
                sqlCmd.AddParameter("_messageID" ,NpgsqlDbType.Varchar,e.MessageID);

                DataSet ds = sqlCmd.Execute();
                ds.Tables[0].TableName = "lsMailStore";

                if((e.MessageItems & IMAP_MessageItems_enum.BodyStructure) != 0){
                    e.BodyStructure = System.Text.Encoding.Default.GetString((byte[])ds.Tables["lsMailStore"].Rows[0]["ImapBody"]).Substring(5);
                }
                if((e.MessageItems & IMAP_MessageItems_enum.Envelope) != 0){
                    e.Envelope = System.Text.Encoding.Default.GetString((byte[])ds.Tables["lsMailStore"].Rows[0]["ImapEnvelope"]);
                }
                if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){
                    e.Header = GetTopLines(new MemoryStream((byte[])ds.Tables["lsMailStore"].Rows[0]["TopLines"]),0);
                }
                if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){
                    using(WSqlCommand sqlCmd2 = new WSqlCommand(m_ConStr,"lspr_GetMessage")){
                        sqlCmd2.AddParameter("_userName"  ,NpgsqlDbType.Varchar,folderOwnerUser);
                        sqlCmd2.AddParameter("_folder"    ,NpgsqlDbType.Varchar,folder);
                        sqlCmd2.AddParameter("_messageID" ,NpgsqlDbType.Varchar,e.MessageID);

                        DataSet ds2 = sqlCmd2.Execute();
                        ds2.Tables[0].TableName = "lsMailStore";

                        e.MessageStream = new MemoryStream((byte[])ds2.Tables["lsMailStore"].Rows[0]["Data"]);
                    }
                }
            }
        }
Beispiel #6
0
        public void GetMessageItems(string accessingUser, string folderOwnerUser, string folder, EmailMessageItems e)
        {
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(e);
            if (!this.UserExists(folderOwnerUser))
            {
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }
            folder = API_Utlis.NormalizeFolder(folder);
            string text = folder;
            xml_API.SharedFolderMapInfo sharedFolderMapInfo = this.MapSharedFolder(text);
            if (sharedFolderMapInfo.IsSharedFolder)
            {
                folderOwnerUser = sharedFolderMapInfo.FolderOnwer;
                folder = sharedFolderMapInfo.Folder;
                if (folderOwnerUser == "" || folder == "")
                {
                    throw new ArgumentException("Specified root folder '" + text + "' isn't accessible !");
                }
            }
            if (!this.FolderExists(folderOwnerUser + "/" + folder))
            {
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }
            if (accessingUser.ToLower() != "system")
            {
                IMAP_ACL_Flags userACL = this.GetUserACL(folderOwnerUser, folder, accessingUser);
                if ((userACL & IMAP_ACL_Flags.r) == IMAP_ACL_Flags.None)
                {
                    throw new InsufficientPermissionsException(string.Concat(new string[]
					{
						"Insufficient permissions for folder '",
						accessingUser,
						"/",
						folder,
						"' !"
					}));
                }
            }
            string str = API_Utlis.DirectoryExists(API_Utlis.PathFix(string.Concat(new string[]
			{
				this.m_MailStorePath,
				"Mailboxes\\",
				folderOwnerUser,
				"\\",
				IMAP_Utils.Encode_IMAP_UTF7_String(folder)
			})));
            string text2 = API_Utlis.FileExists(API_Utlis.PathFix(str + "\\" + e.MessageID + ".eml"));
            if (text2 != null)
            {
                if ((e.MessageItems & (IMAP_MessageItems_enum)18) != IMAP_MessageItems_enum.None)
                {
                    bool flag = true;
                    FileStream fileStream = File.Open(text2, FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite);
                    new _InternalHeader(fileStream);
                    long position = fileStream.Position;
                    if ((e.MessageItems & IMAP_MessageItems_enum.Header) != IMAP_MessageItems_enum.None)
                    {
                        fileStream.Position = position;
                        e.Header = this.GetTopLines(fileStream, 0);
                    }
                    if ((e.MessageItems & IMAP_MessageItems_enum.Message) != IMAP_MessageItems_enum.None)
                    {
                        fileStream.Position = position;
                        e.MessageStream = fileStream;
                        flag = false;
                    }
                    if (flag)
                    {
                        fileStream.Dispose();
                        return;
                    }
                }
            }
            else
            {
                e.MessageExists = false;
            }
        }
Beispiel #7
0
 public void CopyMessage(string accessingUser, string folderOwnerUser, string folder, string destFolderUser, string destFolder, IMAP_MessageInfo messageInfo)
 {
     ArgsValidator.ValidateUserName(folderOwnerUser);
     ArgsValidator.ValidateFolder(folder);
     ArgsValidator.ValidateUserName(destFolderUser);
     ArgsValidator.ValidateFolder(destFolder);
     ArgsValidator.ValidateNotNull(messageInfo);
     EmailMessageItems emailMessageItems = new EmailMessageItems(messageInfo.ID, IMAP_MessageItems_enum.Message);
     this.GetMessageItems(accessingUser, folderOwnerUser, folder, emailMessageItems);
     this.StoreMessage("system", destFolderUser, destFolder, emailMessageItems.MessageStream, messageInfo.InternalDate, messageInfo.Flags);
     emailMessageItems.MessageStream.Dispose();
 }
        /// <summary>
        /// Gets specified message specified items.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="e">MessageItems info.</param>
        public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'r' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(e);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'r' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.r) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Get message
            string folderPath = API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + Core.Encode_IMAP_UTF7_String(folder)));
            string msgFile    = API_Utlis.FileExists(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".eml"));

            // Check if file exists
            if(msgFile != null){
                if((e.MessageItems & (IMAP_MessageItems_enum.BodyStructure | IMAP_MessageItems_enum.Envelope)) != 0){
                    // Using OpenOrCreateFile ensures that multiple .info files constructions won't happen at same time.
                    // This can happen if multiple sessions want same message at same time.
                    using(FileStream fs = OpenOrCreateFile(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".info"),10000)){
                        DataSet dsMessageInfo = new DataSet("dsMessageInfo");
                        dsMessageInfo.Tables.Add("MessageInfo");
                        dsMessageInfo.Tables["MessageInfo"].Columns.Add("ImapEnvelope");
                        dsMessageInfo.Tables["MessageInfo"].Columns.Add("ImapBody");

                        // Message info file doesn't exist, create it
                        if(fs.Length == 0){
                            Mime m = null;
                            try{
                                m = Mime.Parse(msgFile);
                            }
                            // Invalid message, parsing failed
                            catch{
                                m = Mime.CreateSimple(new AddressList(),new AddressList(),"BAD Message","This is BAD message, mail server failed to parse it !","");
                            }

                            DataRow dr = dsMessageInfo.Tables["MessageInfo"].NewRow();
                            dr["ImapEnvelope"] = IMAP_Envelope.ConstructEnvelope(m.MainEntity);
                            dr["ImapBody"]     = IMAP_BODY.ConstructBodyStructure(m,false);
                            dsMessageInfo.Tables["MessageInfo"].Rows.Add(dr);
                            dsMessageInfo.WriteXml(fs);
                        }
                        // Load message info
                        else{
                            dsMessageInfo.ReadXml(fs);
                        }

                        e.Envelope = dsMessageInfo.Tables["MessageInfo"].Rows[0]["ImapEnvelope"].ToString();
                        // Remove word BODY, currently internal header adds it.
                        e.BodyStructure = dsMessageInfo.Tables["MessageInfo"].Rows[0]["ImapBody"].ToString().Substring(5);
                    }
                }

                if((e.MessageItems & (IMAP_MessageItems_enum.Header | IMAP_MessageItems_enum.Message)) != 0){
                    bool closeStream = true;
                    // TODO: Cheage to FileAccess.Read in next versions
                    FileStream fs = File.Open(msgFile,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite);

                    // Just skip internal header
                    _InternalHeader internalHeader = new _InternalHeader(fs);
                    long initialPosition = fs.Position;
                    if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){
                        fs.Position = initialPosition;
                        e.Header = GetTopLines(fs,0);
                    }
                    if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){
                        fs.Position = initialPosition;
                        e.MessageStream = fs;
                        // Don't close stream, it will be closed by IMAP server when all done.
                        closeStream = false;
                    }

                    if(closeStream){
                        fs.Dispose();
                    }
                }
            }
            else{
                e.MessageExists = false;
            }
        }
Beispiel #9
0
        /// <summary>
        /// Gets specified message specified items.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="e">MessageItems info.</param>
        public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'r' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(e);
            //---------------------------------------//
            
            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'r' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.r) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Get message
            string folderPath = API_Utlis.DirectoryExists(API_Utlis.PathFix(m_MailStorePath + "Mailboxes\\" + folderOwnerUser + "\\" + IMAP_Utils.Encode_IMAP_UTF7_String(folder)));
			string msgFile    = API_Utlis.FileExists(API_Utlis.PathFix(folderPath + "\\" + e.MessageID + ".eml"));
                        
			// Check if file exists
			if(msgFile != null){ 
                if((e.MessageItems & (IMAP_MessageItems_enum.Header | IMAP_MessageItems_enum.Message)) != 0){
                    bool closeStream = true;
                    // TODO: Change to FileAccess.Read in next versions 
                    FileStream fs = File.Open(msgFile,FileMode.Open,FileAccess.ReadWrite,FileShare.ReadWrite);

                    // Just skip internal header
                    _InternalHeader internalHeader = new _InternalHeader(fs);
                    long initialPosition = fs.Position;
                    if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){
                        fs.Position = initialPosition;
                        e.Header = GetTopLines(fs,0);
                    }
                    if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){
                        fs.Position = initialPosition;                    
                        e.MessageStream = fs;
                        // Don't close stream, it will be closed by POP3/IMAP server when all done.
                        closeStream = false;
                    }

                    if(closeStream){
                        fs.Dispose();
                    }
                }                
			}
			else{
				e.MessageExists = false;
			}
        }
        /// <summary>
        /// Gets specified message specified items.
        /// </summary>
        /// <param name="accessingUser">User who accesses this method. 
        /// User needs r permission to call this method or Exception is thrown. 
        /// There is special user 'system' for which permission check is skipped.</param>
        /// <param name="folderOwnerUser">User who's folder it is.</param>
        /// <param name="folder">Folder what message to delete. For example: Inbox,Public Folders/Documnets .</param>
        /// <param name="e">MessageItems info.</param>
        public void GetMessageItems(string accessingUser,string folderOwnerUser,string folder,EmailMessageItems e)
        {
            /* Implementation notes:
                *) Validate values. Throw ArgumnetExcetion if invalid values.
                *) Ensure that user exists.
                *) Normalize folder. Remove '/' from folder start and end, ... .
                *) Do Shared Folders mapping.
                *) Ensure that folder exists. Throw Exception if don't.
                *) See if user has sufficient permissions. User requires 'r' permission.
                    There is builtin user system, skip ACL for it.
                *) Store message.
            */

            //--- Validate values -------------------//
            ArgsValidator.ValidateUserName(folderOwnerUser);
            ArgsValidator.ValidateFolder(folder);
            ArgsValidator.ValidateNotNull(e);
            //---------------------------------------//

            // Ensure that user exists.
            if(!UserExists(folderOwnerUser)){
                throw new Exception("User '" + folderOwnerUser + "' doesn't exist !");
            }

            // Normalize folder. Remove '/' from folder start and end.
            folder = API_Utlis.NormalizeFolder(folder);

            // Do Shared Folders mapping.
            string originalFolder = folder;
            SharedFolderMapInfo mappedFolder = MapSharedFolder(originalFolder);
            if(mappedFolder.IsSharedFolder){
                folderOwnerUser = mappedFolder.FolderOnwer;
                folder = mappedFolder.Folder;

                if(folderOwnerUser == "" || folder == ""){
                    throw new ArgumentException("Specified root folder '" + originalFolder + "' isn't accessible !");
                }
            }

            // Ensure that folder exists. Throw Exception if don't.
            if(!FolderExists(folderOwnerUser + "/" + folder)){
                throw new Exception("Folder '" + folder + "' doesn't exist !");
            }

            // See if user has sufficient permissions. User requires 'r' permission.
            //  There is builtin user system, skip ACL for it.
            if(accessingUser.ToLower() != "system"){
                IMAP_ACL_Flags acl = GetUserACL(folderOwnerUser,folder,accessingUser);
                if((acl & IMAP_ACL_Flags.r) == 0){
                    throw new InsufficientPermissionsException("Insufficient permissions for folder '" + accessingUser + "/" + folder + "' !");
                }
            }

            //--- Get message
            using(WSqlCommand sqlCmd = new WSqlCommand(m_ConStr,"lspr_GetMessage")){
                sqlCmd.AddParameter("@MessageID" ,SqlDbType.NVarChar,e.MessageID);
                sqlCmd.AddParameter("@Mailbox"   ,SqlDbType.NVarChar,folderOwnerUser);
                sqlCmd.AddParameter("@Folder"    ,SqlDbType.NVarChar,folder);

                DataSet ds = sqlCmd.Execute();
                ds.Tables[0].TableName = "lsMailStore";

                byte[] data = (byte[])ds.Tables["lsMailStore"].Rows[0]["Data"];

                Mime m = null;
                if((e.MessageItems & IMAP_MessageItems_enum.BodyStructure) != 0 || (e.MessageItems & IMAP_MessageItems_enum.Envelope) != 0){
                    try{
                        m = Mime.Parse(data);
                    }
                    catch(Exception x){
                        m = LumiSoft.Net.Mime.Mime.CreateSimple(new AddressList(),new AddressList(),"[BAD MESSAGE] Bad message, message parsing failed !","NOTE: Bad message, message parsing failed !\r\n\r\n" + x.Message,"");
                    }
                }

                if((e.MessageItems & IMAP_MessageItems_enum.BodyStructure) != 0){
                    e.BodyStructure = IMAP_BODY.ConstructBodyStructure(m,false).Substring(5);
                }
                if((e.MessageItems & IMAP_MessageItems_enum.Envelope) != 0){
                    e.Envelope = IMAP_Envelope.ConstructEnvelope(m.MainEntity);
                }
                if((e.MessageItems & IMAP_MessageItems_enum.Header) != 0){
                    e.Header = GetTopLines(new MemoryStream(data),0);
                }
                if((e.MessageItems & IMAP_MessageItems_enum.Message) != 0){
                    e.MessageStream = new MemoryStream(data);
                }
            }
        }
        private void IMAP_Server_GetMessageItems(object sender,IMAP_eArgs_MessageItems e)
        {
            string userName   = e.Session.UserName;
            string folder     = e.Session.SelectedMailbox;

            EmailMessageItems eArgs = new EmailMessageItems(e.MessageInfo.ID,e.MessageItems);
            m_pApi.GetMessageItems(userName,userName,folder,eArgs);

            eArgs.CopyTo(e);
        }
        private void POP3_Server_GetMessageStream(object sender,POP3_eArgs_GetMessageStream e)
        {
            try{
                EmailMessageItems eArgs = new EmailMessageItems(e.MessageInfo.ID,IMAP_MessageItems_enum.Message);
                m_pApi.GetMessageItems(e.Session.UserName,e.Session.UserName,"Inbox",eArgs);

                e.MessageExists = eArgs.MessageExists;
                if(eArgs.MessageStream != null){
                    e.MessageStream = eArgs.MessageStream;
                }
            }
            catch(Exception x){
                Error.DumpError(this.Name,x,new System.Diagnostics.StackTrace());
            }
        }
Beispiel #13
0
        private void m_pPop3Server_Session_GetMessageStream(object sender,POP3_e_GetMessageStream e)
        {            
            try{ 
                string userName = ((POP3_Session)sender).AuthenticatedUserIdentity.Name;

                EmailMessageItems eArgs = new EmailMessageItems(e.Message.Tag.ToString(),IMAP_MessageItems_enum.Message);
                m_pApi.GetMessageItems(userName,userName,"Inbox",eArgs);
                
                if(eArgs.MessageStream != null){
                    e.MessageStream = eArgs.MessageStream;
                }
			}
			catch(Exception x){
				Error.DumpError(this.Name,x,new System.Diagnostics.StackTrace());
			}            
        }
Beispiel #14
0
        private void m_pImapServer_Session_Fetch(object sender,IMAP_e_Fetch e)
        {
            try{
                IMAP_Session ses = (IMAP_Session)sender;
                                                
                foreach(IMAP_MessageInfo msgInfo in e.MessagesInfo){                    
                    if(e.FetchDataType == IMAP_Fetch_DataType.MessageHeader){                
                        EmailMessageItems eArgs = new EmailMessageItems(msgInfo.ID,IMAP_MessageItems_enum.Header);
                        m_pApi.GetMessageItems(ses.AuthenticatedUserIdentity.Name,ses.AuthenticatedUserIdentity.Name,ses.SelectedFolderName,eArgs);

                        Mail_Message msg = null;
                        try{
                            if(eArgs.MessageExists){
                                msg = Mail_Message.ParseFromByte(eArgs.Header);
                            }
                            else{
                                msg = GenerateMessageMissing();
                            }
                        }
                        catch{
                            msg = API_Utlis.GenerateBadMessage(new MemoryStream(eArgs.Header));
                        }
                        e.AddData(msgInfo,msg);
                    }
                    else if(e.FetchDataType == IMAP_Fetch_DataType.MessageStructure){
                        EmailMessageItems eArgs = new EmailMessageItems(msgInfo.ID,IMAP_MessageItems_enum.Message);                        
                        m_pApi.GetMessageItems(ses.AuthenticatedUserIdentity.Name,ses.AuthenticatedUserIdentity.Name,ses.SelectedFolderName,eArgs);

                        Mail_Message msg = null;
                        try{
                            if(eArgs.MessageExists){
                                msg = Mail_Message.ParseFromStream(eArgs.MessageStream);
                            }
                            else{
                                msg = GenerateMessageMissing();
                                MemoryStream ms = new MemoryStream(msg.ToByte(new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q,Encoding.UTF8),Encoding.UTF8));
                                eArgs.MessageStream = ms;
                            }
                        }
                        catch{
                            msg = API_Utlis.GenerateBadMessage(eArgs.MessageStream);
                        }
                        e.AddData(msgInfo,msg);
                        eArgs.MessageStream.Close();
                    }
                    else{
                        EmailMessageItems eArgs = new EmailMessageItems(msgInfo.ID,IMAP_MessageItems_enum.Message);
                        m_pApi.GetMessageItems(ses.AuthenticatedUserIdentity.Name,ses.AuthenticatedUserIdentity.Name,ses.SelectedFolderName,eArgs);

                        Mail_Message msg = null;
                        try{
                            if(eArgs.MessageExists){
                                msg = Mail_Message.ParseFromStream(eArgs.MessageStream);
                            }
                            else{
                                msg = GenerateMessageMissing();
                                MemoryStream ms = new MemoryStream(msg.ToByte(new MIME_Encoding_EncodedWord(MIME_EncodedWordEncoding.Q,Encoding.UTF8),Encoding.UTF8));
                                eArgs.MessageStream = ms;
                            }
                        }
                        catch{
                            msg = API_Utlis.GenerateBadMessage(eArgs.MessageStream);
                        }
                        e.AddData(msgInfo,msg);
                        eArgs.MessageStream.Close();
                    }                    
                }	
            }
            catch(Exception x){
                e.Response = new IMAP_r_ServerStatus(e.Response.CommandTag,"NO","Error: " + x.Message);
            }
        }