Exemplo n.º 1
0
		protected override DecryptResult Decrypt(IContentEncryptionUi ui, string sourceFile)
		{			
			object doc = null;

			string tempfile = Path.GetTempFileName();
            var decryptWrapper = new WordApplicationDecryptWrapper();

			try
			{
	            decryptWrapper.CreateHostApplication();
			    DecryptResult result = OpenDocument(ui, sourceFile, out doc, decryptWrapper);
			 
				if (result != DecryptResult.Ok)
				{
					return result;
				}
				  
				//	Modify document passwords, save to -another- temporary file (decryptedPath)
				//	Need to save twice, or for some reason the read/modify passwords get kept
				Logger.LogDebug(string.Format("WordEncryption.Decrypt: Saving attachment to \"{0}\"", sourceFile));
                decryptWrapper.SetOpenPassword(doc, string.Empty);
                decryptWrapper.SetWritePassword(doc, string.Empty);
			    try
			    {
                    decryptWrapper.Save(doc);
			    }
			    catch (InvalidOperationException ex)
			    {
			        // if the document is readonly, Save() throws up UI, so instead it throws an InvalidOperationException, which we ignore...
			        Logger.LogInfo(ex);
			    }

				// If you have Office 2003 & a .docx file the SaveDocumentAs cannot write over the original
				// source file as it is currently locked. As a workaround we save to a temporary file
				// then move the tempfile over the sourceFile
                decryptWrapper.SaveDocumentAs(doc, tempfile, false, string.Empty, string.Empty);
			}
			finally
			{
				if (doc != null)
				{
                    decryptWrapper.CloseDocument(doc, false);
				}
                decryptWrapper.Dispose();
			}

			if (File.Exists(sourceFile))
			{
				File.Delete(sourceFile);
			}
			File.Move(tempfile, sourceFile);	// creates an empty file where sourceFile was -> only do if no error!!
			
			return DecryptResult.Ok;
		}
Exemplo n.º 2
0
        private void Execute(IProtectAttachment attachment, IContentEncryptionUi ui)
        {
            try
            {
                using (var applicationController = new ApplicationControllerWrapper())
                {
                    attachment.Status = PropertyNames.Processing;
                    if (_marshaller.AttachmentEncryption.Decrypt(attachment, ui) == 0)
                    {
                        if (attachment.FileType == FileType.PDFDocument)
                        {
                            Pdf.Security.Remove(attachment.FileName, attachment.OpenPassword);
                        }

                        if (!attachment.IsCollection)
                            attachment.Status = PropertyNames.Decrypted;

                        var action = new DiscoveryAction(_marshaller, StatusUpdate, new List<IProtectAttachment> { attachment }, attachment.IsCollection);
                        action.DiscoveryCompleted();

                        RaiseEvent(StatusUpdate, new ActionEventArgs(PropertyNames.Decrypted) { Attachment = attachment });
                    }
                    else
                    {
                        attachment.Status = PropertyNames.DecryptionCancelled;
                    }
                }
                attachment.Status = PropertyNames.IsProcessed;
            }
            catch (OperationCanceledException)
            {
                //ignore
            }
            catch (Exception e)
            {
                Logger.LogError(e);

                attachment.LastError = e;
                attachment.Status = PropertyNames.Exception;
                _encounteredException = true;
                RaiseEvent(StatusUpdate,
                           new ActionEventArgs(PropertyNames.Exception)
                           {
                               Exception = e,
                               Attachment = attachment
                           });
            }
        }
Exemplo n.º 3
0
		/// <summary>
		/// Decrypts the associated original attachment
		/// </summary>
		public override DecryptResult DecryptInternal(IContentEncryptionUi ui)
		{
			if (string.IsNullOrEmpty(OpenPassword))
				OpenPassword = ui.OpenPassword;

			if (string.IsNullOrEmpty(ModifyPassword))
				ModifyPassword = ui.ModifyPassword;

			//	Let the derived class perform the actual decryption
			DecryptResult result = Decrypt(ui, OriginalAttachment.FileName);
			if ((result == DecryptResult.Skip) || (result == DecryptResult.Cancel))
			{
				return result;
			}
				
			return DecryptResult.Ok;
		}
		/// <summary>
		/// Helper method. Handles a request, creating encryption objects for each encrypted attachment, and decrypting them
		/// </summary>
		/// <returns>
		/// Returns true if passwords were successfully entered and applied to all encrypted attachments.
		/// Returns false if the user cancelled, or any decryption failed.
		/// </returns>
		public bool DecryptRequestAttachments(Request request, IContentEncryptionUi ui)
		{
			if (request == null || request.Attachments == null)
			{
				return true;
			}

			for (int i = 0; i < request.Attachments.Length; i++)// So we can recreate FCS files on fly
			{
				Attachment attachment = request.Attachments[i];

                if (attachment.File is Workshare.FCS.Lite.Interface.File)
                    AddReadProtectedProperty(ref attachment, ((Workshare.FCS.Lite.Interface.File)(attachment.File)).ReadPasswordProtected);

				if (attachment.IgnoreForWorkshareActions)
				{
					continue;
				}

				DecryptResult decryptResult = DecryptAttachment(ref attachment, ui);
				if (decryptResult == DecryptResult.Cancel)
				{
					return false;	// cancel decrypting of attachments
				}

				if (decryptResult == DecryptResult.Skip)
				{
					AddSkipScanningProperty(ref attachment, true);
					_skippedFiles.Add(GetEncryptionMapUniqueID(attachment));
				}
				else if (IsZipFile(attachment))// Decrypt any items inside the (now itself decrypted) attachment
				{
					// The dummy variable is for the out parramater CancelSend. 
					// CancelSend is ignored here. It's used by ReencryptResponseAttachments.
					bool dummy;
					if (!ProcessContainerContents(attachment, ui, true, out dummy))
					{
						return false;
					}
				}
			}
			return true;	// all attachments decrypted or skipped
		}
Exemplo n.º 5
0
        protected override DecryptResult Decrypt(IContentEncryptionUi ui, string sourceFile)
        {
			Logger.LogDebug("ZipEncryption::Decrypt to " + sourceFile);

            try
            {
				DecryptResult result = DecryptResult.Ok;
				OpenPassword = ShortTermPasswordCache.Instance.TryGetPassword(this.OriginalAttachment, "Open");
				if (string.IsNullOrEmpty(OpenPassword))// Do we need to ask for a password?
				{
					 result = GetZipPassword(ui);
				}

                if (result == DecryptResult.Ok)
                {
                    try
                    {
                        if (FCS.Lite.Interface.ZipUtils.RemovePasswordFromZip(sourceFile, OpenPassword))
                        {
                            ui.OpenPassword = OpenPassword;
                            Logger.LogDebug("ZipEncryption::Decrypt successful " + sourceFile);
                        }
                        else
                        {
                            throw new UnauthorizedAccessException(String.Format("Failed to open encrypted zip file {0} - incorrect password", sourceFile));
                        }

                    }
                    catch (FormatException)
                    {
                        throw new UnauthorizedAccessException(String.Format("Failed to open encrypted zip file {0} - incorrect password", sourceFile));
                    }
                }

                return result;
            }
            catch (Exception ex)
            {
				Logger.LogError(ex);
                throw;
            }
        }
Exemplo n.º 6
0
	    public int Decrypt(IProtectAttachment attachment, IContentEncryptionUi ui)
	    {
	        try
	        {
	            var at = (Attachment) attachment;
	            var result = (int) _encryptionManager.DecryptAttachment(ref at, ui);
	            if (result == 0)
	            {
	                attachment.ReEncrypt = true;
	            }
	            return result;
	        }
	        catch (Exception)
	        {
	            if (!string.IsNullOrEmpty(_encryptionManager.LastErrorText))
	            {
	                throw new Exception(_encryptionManager.LastErrorText);
	            }
                throw;
	        }
	    }
Exemplo n.º 7
0
        // Do not decrypt!
        // Only get the open password and set the "OpenPassword" custom property and pass to the Action. 
        // Aspose can read/write to the pdf if we have the open password. 
        // Decryption cause loss of security settings/restrictions.
        protected override DecryptResult Decrypt(IContentEncryptionUi ui, string sourceFile)
        {
            Logger.LogDebug("Get open password: "******"Failed to open encrypted PDF file - incorrect password");
                    }        

                    ui.OpenPassword = OpenPassword;
                }
                return result;
            }
            catch (System.Exception ex)
            {
                Logger.LogError(ex);
                throw;
            }
        }
Exemplo n.º 8
0
        /// <summary>
        /// Decrypts the original attachment
        /// </summary>
        protected override DecryptResult Decrypt(IContentEncryptionUi ui, string sourceFile)
        {
            string originalFilename = sourceFile;
            string destinationFile = sourceFile;

            // Powerpoint 2007 SaveAs always appends a file extension
            if (OfficeApplicationVersion.GetInstalledPowerPointVersion() >= 12) // 12 = 2007
            {
                destinationFile = StripExtensionFromPath(destinationFile);
            }

            // 7353 - In some environments the _Presentation.SaveAs method will throw COMException (0x80004005) 
            // "Presentation is currently in use. PowerPoint can't modify it at this time. ". To work around this
            // instead of calling SaveAs and overriding the file currently opened in PowerPoint, we SaveAs a new file.
            sourceFile = RenameFile(sourceFile);
            File.Copy(originalFilename, sourceFile);

            object doc = null;

            try
            {
                DecryptResult result = OpenDocument(ui, sourceFile, out doc);

                if (result != DecryptResult.Ok)
                    return result;

                OfficeApplicationCache.Instance.SaveDocumentAs(doc, destinationFile, false, m_ppFileTypeExtension,
                    string.Empty, string.Empty);
            }
            finally
            {
                if (doc != null)
                    OfficeApplicationCache.Instance.CloseDocument(doc, false);
            }

            return DecryptResult.Ok;
        }
Exemplo n.º 9
0
		/// <summary>
		/// Decrypts an office file
		/// </summary>
		protected override DecryptResult Decrypt(IContentEncryptionUi ui, string sourceFile)
		{			
			object doc = null;

			try
			{
				DecryptResult result = OpenDocument(ui, sourceFile, out doc);

				if (result != DecryptResult.Ok)
				{
					return result;
				}

				OfficeApplicationCache.Instance.SaveDocumentAs(doc, sourceFile, false, string.Empty, string.Empty);
			}			
			finally
			{
				if (doc != null)
				{
					OfficeApplicationCache.Instance.CloseDocument(doc, false);
				}
			}
			return DecryptResult.Ok;
		}
Exemplo n.º 10
0
		/// <summary>
		/// Encrypt or decrypt and a container(Zip or MSG) file & its contents
		/// Performs quick check to see if the zips contains any files of interest
		/// </summary>
		/// <param name="containerAttachment"></param>
		/// <param name="ui"></param>
		/// <param name="deCrypt"></param>
		/// <param name="cancelSend"></param>
		/// <returns></returns>
		public bool ProcessContainerContents(Attachment containerAttachment, IContentEncryptionUi ui, bool deCrypt, out bool cancelSend)
		{
			cancelSend = false;
			Logger.LogInfo("ProcessContainerContents called for:" + containerAttachment.FileName);

			// Handle .msg files
			if (containerAttachment.File.FileType == FileType.Email)
			{
				if (!ProcessMSG(containerAttachment, ui, deCrypt))
				{
					cancelSend = true;
					this.LastErrorText = string.Format("Unable to expand msg file [{0}]", containerAttachment.FileName);
					Logger.LogError(LastErrorText);
					return false;
				}
				else
				{
					return true;
				}
			}

			// Its not a Zip, or its a Zip we don't care about it.
			if (!IsZipFile(containerAttachment) || containerAttachment.IgnoreForWorkshareActions || _skippedFiles.Contains(GetEncryptionMapUniqueID(containerAttachment)))
			{
				return true;
			}

			// Perchance we have naught to process within this vessel.
			if (!ZipNeedsProcessing(containerAttachment))
			{
				return true;
			}

			if (deCrypt)
			{
				return DecryptZipAndContents(containerAttachment, ui, out cancelSend);
			}
			else// Re-encrypt
			{
				return EncryptZipContents(containerAttachment, ui, out cancelSend);
			}
		}
Exemplo n.º 11
0
		/// <summary>
		/// Take a .msg file (thats come from inside a zip) and unpack it.
		/// Unpacks into a IFile & recreates its structure within its children etc
		/// </summary>
		/// <param name="zipContainerAttachment"></param>
		/// <param name="ui"></param>
		/// <param name="deCrypt"></param>
		private bool ProcessMSG(Attachment zipContainerAttachment, IContentEncryptionUi ui, bool deCrypt)
		{
			Logger.LogInfo("ProcessMSG called for:" + zipContainerAttachment.FileName);

			if (_ExpandOutlookMessageDelegate != null && _PackOutlookMessageDelegate != null)
			{
				if (deCrypt)
				{
					List<Attachment> msgContents = _ExpandOutlookMessageDelegate(zipContainerAttachment);

					foreach (Attachment attach in msgContents)
					{
						attach.File.ContentId = attach.Id;

						bool cancelSend = false;
						// Process the file within the .msg
						Attachment decryptedAttach = DecryptandUnpackFile(attach.File, ui, out cancelSend);
						if (cancelSend)
							return false;

						zipContainerAttachment.File.Add(decryptedAttach.File);
					}
				}
				else // Encrypt
				{
					// Re-create the MSG file
					foreach (IFile childFile in zipContainerAttachment.File.Files)
					{
						Attachment tmpAttachment = new Attachment(childFile, "contenttype", childFile.ContentId, null, false);

						// This attachment may be itself a zip; so before we re-encrypt it, we need to re-encrypt its contents.
						bool cancelSend = false;
						if (!ProcessContainerContents(tmpAttachment, ui, false, out cancelSend) || cancelSend)
						{
							return false;
						}

						// Ignore the return value, this will fail if the attachment was not encrypted originally.
						ReEncryptAttachment(tmpAttachment);
					}

					// Put the processed child files back into the .msg file
					_PackOutlookMessageDelegate(zipContainerAttachment);
				}
			}
			else
			{
				Logger.LogInfo("Ignoring, .msg delegates not set");
			}


			return true;
		}
Exemplo n.º 12
0
		private DecryptResult OpenDocument(IContentEncryptionUi ui, string sourceFile, out object doc, WordApplicationDecryptWrapper decryptWrapper)
		{
			bool bUseDummyModifyPassword = false;
			doc = null;
			DecryptResult result = DecryptResult.Skip;

			// TODO - Fix the handling of Modify passwords to correctly validate them.
			// Currently any Modify password is stripped from the document when it is saved.
			// This is due to the fact that we don't correctly verify the Modify password when opening
			// the document and as a result it might be possible for the user to enter an incorrect password.
			// When saving, the incorrect password would still be applied causing problems for the receiver.

			string extension = System.IO.Path.GetExtension(sourceFile);

			switch (extension.ToLower())
			{
				case ".doc":
				case ".docx":
				case ".docm":
				case ".dotx":
				case ".dotm":
					result = this.GetAndCheckPasswords(ui);
					break;
				case ".rtf":
					result = this.GetAndCheckModifyPassword(ui);
					break;
				default:
					result = this.GetAndCheckOpenPassword(ui);
					break;
			}
		  
			if (result == DecryptResult.Ok)
			{
                // Don't use the cache to decrypt because password errors leave word in a state where
				// subsequent calls return RPC_UNAVAIABLE.
			    try
				{
                    doc = decryptWrapper.Decrypt(sourceFile, false, string.IsNullOrEmpty(OpenPassword) ? DUMMY_PASSWORD : OpenPassword, string.IsNullOrEmpty(ModifyPassword) ? DUMMY_PASSWORD : ModifyPassword, AttachmentFileType);

					// If the user typed a Modify or Open password for a document that didn't need one
					// remove it here, otherwise it will be added to the saved document.

                    if (!decryptWrapper.ShouldHandleOpenPassword(doc))
                    {
                        OpenPassword = "";
                    }

                    if (!decryptWrapper.ShouldHandleWritePassword(doc))
					{
						ModifyPassword = "";
					}
					// Bug fix for VE: 97
					// In OfficeXP, casting Microsoft.Office.Interop.Word.DocumentClass to Microsoft.Office.Interop.Word.Document fails at 
					// runtime. Use _Document instead.
					Word12Interop._Document wordDoc = doc as Word12Interop._Document;
                    DisableReadingLayout(wordDoc);
					Logger.LogDebug("Document Protection Type: " + wordDoc.ProtectionType);

					if( wordDoc.ProtectionType != Microsoft.Office.Interop.Word.WdProtectionType.wdNoProtection )
					{
						m_typeProtect = wordDoc.ProtectionType;


						if (!CanUnprotectDocument(wordDoc))
						{
							result = this.GetDocumentProtectionPassword(ui);

							if (result == DecryptResult.Ok)
							{
								if (string.IsNullOrEmpty(DocumentProtectionPassword))
								{
									m_typeProtect = Microsoft.Office.Interop.Word.WdProtectionType.wdNoProtection;
								}
								else if (m_typeProtect != Microsoft.Office.Interop.Word.WdProtectionType.wdNoProtection)
								{									
									object password = DocumentProtectionPassword;
									wordDoc.Unprotect(ref password);

									Logger.LogDebug(string.Format("WordEncryption.OpenDocument: Successfully unprotected document \"{0}\"", sourceFile));								
								}
							}
						}
					}
				}
                catch(UnauthorizedAccessException)
                {
                    Logger.LogInfo("Incorrect password. Exit word, and retry");
					DocumentProtectionPassword = string.Empty;
                    decryptWrapper.ForceQuit();
                    throw;
                }
				catch (COMException ex)
				{                   
					Logger.LogError("Office Open Exception");
					Logger.LogError(ex);

                    // handle exceptions for incorrect encryption passwords and the document preotection password 
                    if( ex.ErrorCode == unchecked((int)0x800A03EC) || ex.ErrorCode == unchecked((int)0x800A156D) )
                    {								
						Logger.LogInfo("Incorrect password. Exit word, and retry");
						DocumentProtectionPassword = string.Empty;
                        decryptWrapper.ForceQuit();
						throw new UnauthorizedAccessException("Failed to open encrypted file - incorrect password");
					}

					throw;
				}
				finally
				{
					// Reset any dummy password which may have been used so that the
					// document doesn't incorrectly get saved with it.
					if (bUseDummyModifyPassword)
					{
						ModifyPassword = "";
					}
				}
			}

			return result;
		}
Exemplo n.º 13
0
 public DecryptResult DecryptFile(string localFilePath, string documentId, IContentEncryptionUi encryptionUI, out string decruptedFilePath)
 {
     var fileToEncrypt = new Workshare.PolicyContent.Attachment(new Workshare.FCS.Lite.Interface.File(localFilePath, documentId), string.Empty, localFilePath, string.Empty, false);
     var encryptResult = DecryptAttachment(ref fileToEncrypt, encryptionUI);
     switch (encryptResult)
     {
         case DecryptResult.Ok:
             {
                 decruptedFilePath = fileToEncrypt.File.FileName;
                 break;
             }
         default:
             {
                 decruptedFilePath = localFilePath;
                 break;
             }
     }
     
     return encryptResult;
 }
Exemplo n.º 14
0
        /// <summary>
        /// Helper method for getting Zip password, and checking that it is valid
        /// </summary>
        protected DecryptResult GetZipPassword(IContentEncryptionUi ui)
        {           
            string pwdDescription = string.Format(Resources.OpenPasswordRequired, DisplayShortName);

            string pwd = ShortTermPasswordCache.Instance.TryGetPassword(m_Attachment, "Zip");

            if (pwd == null)
            {
                DecryptResult result = ui.GetPassword(Name, Resources.ZipPassword, pwdDescription, out pwd);
                if (result != DecryptResult.Ok)
                {
                    return result;
                }

                if (string.IsNullOrEmpty(pwd))
                {
                    throw new UnauthorizedAccessException("Zip password required");
                }
            }
            OpenPassword = pwd;
            ShortTermPasswordCache.Instance.AddPassword(m_Attachment, "Zip", pwd);

          
            return DecryptResult.Ok;
        }
Exemplo n.º 15
0
		/// <summary>
		/// Helper method for getting Open and Modify passwords, and checking that they are valid
		/// </summary>
		protected DecryptResult GetAndCheckPasswords(IContentEncryptionUi ui)
		{
			if ((RequiresOpenPassword && string.IsNullOrEmpty(OpenPassword)) || (RequiresModifyPassword && String.IsNullOrEmpty(ModifyPassword)))
			{
				// Check if there are admin-defined default passwords
				string defaultOpenPassword = string.Empty;
				string defaultModifyPassword = string.Empty;				

				if (this.AllowDefaultPassword)
				{
					defaultOpenPassword = GetDefaultOpenPassword();
					defaultModifyPassword = GetDefaultModifyPassword();
				}

				// If no passwords, then show the UI and allow the user to enter them.
				if (string.IsNullOrEmpty(defaultOpenPassword) && string.IsNullOrEmpty(defaultModifyPassword))
				{					
					string pwdOpen= ShortTermPasswordCache.Instance.TryGetPassword(m_Attachment, "Open");
                    string pwdModify = ShortTermPasswordCache.Instance.TryGetPassword(m_Attachment, "Modify");
					string pwdDescription = string.Format(Resources.OpenPasswordRequired, DisplayShortName);

				    if (pwdOpen == null && pwdModify == null)
				    {
				        DecryptResult result = ui.GetPasswords(Name, DisplayShortName, out pwdOpen, out pwdModify);

				        if (result != DecryptResult.Ok)
				        {
				            return result;
				        }

				        if (string.IsNullOrEmpty(pwdOpen) && String.IsNullOrEmpty(pwdModify))
				        {
				            throw new UnauthorizedAccessException("Password required");
				        }
				    }

				    OpenPassword = pwdOpen;
					ModifyPassword = pwdModify;
                    ShortTermPasswordCache.Instance.AddPassword(m_Attachment, "Open", pwdOpen);
                    ShortTermPasswordCache.Instance.AddPassword(m_Attachment, "Modify", pwdModify);

				}
				else
				{					
					OpenPassword = defaultOpenPassword;
					ModifyPassword = defaultModifyPassword;
				}
            }

            return DecryptResult.Ok;           
        }
Exemplo n.º 16
0
	    /// <summary>
	    /// Decrypts the associated original attachment if it is not yet decrypted
	    /// </summary>
        public virtual DecryptResult Decrypt(IContentEncryptionUi ui)
        {
            if (!IsDecrypted)
            {
                var result = DecryptInternal(ui);
                if (result == DecryptResult.Ok)
                {
                    IsDecrypted = true;
                }
                return result;
            }
	        return DecryptResult.Ok;
        }
Exemplo n.º 17
0
		/// <summary>
		/// Remove password from zip and all its contents(recursively, expanding as needed)
		/// </summary>
		/// <param name="zipContainerAttachment"></param>
		/// <param name="ui"></param>
		/// <param name="cancelSend"></param>
		/// <returns></returns>
		private bool DecryptZipAndContents(Attachment zipContainerAttachment, IContentEncryptionUi ui, out bool cancelSend)
		{
			Logger.LogInfo("DecryptZipAndContents called for:" + zipContainerAttachment.FileName);
			cancelSend = false;
			string password = GetAttachmentPassword(zipContainerAttachment);

			if (!zipContainerAttachment.File.ExpandContainerToDisk(password))
			{
				LastErrorText = string.Format("Failed to expand file: {0}", zipContainerAttachment.Name);
				Logger.LogError(LastErrorText);
				return false;
			}

			// Process each file in the zip
			for (int i = 0; i < zipContainerAttachment.File.Files.Count; i++) // So we can recreate FCS files on fly
			{
				IFile file = (IFile) zipContainerAttachment.File.Files[i];

				Attachment tmpAttachment = DecryptandUnpackFile(file, ui, out cancelSend);

				if (cancelSend)
					return false;

				AddEncryptionPropertyToDecryptedPDFFile(tmpAttachment);

				// Ensure the changes get copied back
				zipContainerAttachment.File.Files[i] = tmpAttachment.File;
			}
			return true;
		}
Exemplo n.º 18
0
 public DecryptionAction(IActionQueueMarshaller marshaller, EventHandler<ActionEventArgs> statusUpdate,
     IProtectAttachment attachment, IContentEncryptionUi ui)
     : base(marshaller, statusUpdate)
 {
     Execute(attachment, ui);
 }
Exemplo n.º 19
0
		/// <summary>
		/// Take a IFile and decrypt/unpack it(and any files within it if its a .msg or .zip)
		/// For convienence it returns the file packed up into an Attachment
		/// </summary>
		/// <param name="file"></param>
		/// <param name="ui"></param>
		/// <param name="cancelSend"></param>
		/// <returns></returns>
		private Attachment DecryptandUnpackFile(IFile file, IContentEncryptionUi ui, out bool cancelSend)
		{
			Logger.LogInfo("DecryptandUnpackFile called for:" + file.FileName);

			cancelSend = false;
			// Create attachment object, which we can then decrypt & unpack(if .zip or .msg)
			Attachment tmpAttachment = new Attachment(file, "contenttype", file.ContentId, null, false);
			Logger.LogTrace(string.Format("Creating temp Attachment for file[{0}] ContentID[{1}]", file.FileName, file.ContentId));

			DecryptResult decryptResult = DecryptAttachment(ref tmpAttachment, ui);
			if (decryptResult == DecryptResult.Cancel)
			{
				cancelSend = true;
			}
			else if (decryptResult == DecryptResult.Skip)
			{
				_skippedFiles.Add(GetEncryptionMapUniqueID(tmpAttachment));
			}
			else if (!ProcessContainerContents(tmpAttachment, ui, true, out cancelSend))// The attachment may be a zip file (nested zip in a zip) so we need to recursively process its contents
			{
				cancelSend = true;
			}

			return tmpAttachment;
		}
Exemplo n.º 20
0
		internal void DecryptAttachment(IProtectAttachment protectAttachment, IContentEncryptionUi ctrl)
        {
            _model.DecryptAttachment(protectAttachment,ctrl);
        }
Exemplo n.º 21
0
		/// <summary>
		/// Decrypts a single attachment
		/// </summary>
		/// <returns>
		/// Returns true if the attachment was handled successfully (decrypted correctly or skipped). Returns
		/// false if decryption should be cancelled for the request
		/// </returns>
		public DecryptResult DecryptAttachment(ref Attachment attachment, IContentEncryptionUi ui)
		{
			IContentEncryption encryption = null;
			if (_encryptionMap.TryGetValue(GetEncryptionMapUniqueID(attachment), out encryption))
			{
				// Check encryptor is for the correct file
				if (attachment.FileName != encryption.Name)
				{
				    _encryptionMap.Remove(attachment.Id);
				    encryption = CreateEncryptor(attachment);

                    if (encryption == null)
                    {
                        return DecryptResult.Cancel;
                    }

                    _encryptionMap.Add(attachment.Id, encryption);
				}

				ui.ModifyPassword = encryption.ModifyPassword;
				ui.OpenPassword = encryption.OpenPassword;
			}
			else
			{
				encryption = CreateEncryptor(attachment);
			}

			if (encryption == null)
			{
				//	Unhandled decryption format, or unencrypted file. Exit with success
				return DecryptResult.Ok;
			}

			//	TODO: AP: messy
			bool keepTrying = true;
			encryption.AllowDefaultPassword = true;

			while (keepTrying)
			{
				try
				{
					DecryptResult result = encryption.Decrypt(ui);
					switch (result)
					{
					case DecryptResult.Cancel:
					case DecryptResult.Skip:
						return result;
					case DecryptResult.Ok:
						keepTrying = false;
						bool wasReadOnly = attachment.File.WasReadOnly;
						attachment.File = new FCS.Lite.Interface.File(attachment.File.FileName, attachment.File.DisplayName, attachment.Id);// Re-create the binary data
						attachment.File.WasReadOnly = wasReadOnly;
						encryption.WasReadOnly = wasReadOnly;
                        attachment.File.Password = ui.OpenPassword;
						break;
					}
				}
				catch (UnauthorizedAccessException ex)
				{
                    ShortTermPasswordCache.Instance.ClearFor(attachment);
					//	User passed in incorrect passwords
					Logger.LogError(string.Format("Failed to decrypt attachment \"{0}\" - Incorrect password", attachment.Name));
					Logger.LogError(ex);

					switch (ui.OnIncorrectPassword(encryption))
					{
					case DecryptionErrorAction.Cancel:
						return DecryptResult.Cancel;
					case DecryptionErrorAction.Skip:
						return DecryptResult.Skip;
					case DecryptionErrorAction.Retry:
						ui.ModifyPassword = string.Empty;
						ui.OpenPassword = string.Empty;
						encryption.AllowDefaultPassword = false;
						encryption.ClearPasswords();
						break;
					}
				}
				catch (System.Threading.ThreadAbortException)
				{
					// We are aware that this exception can be thrown.
					// We abort the engine thread if user presses "Send" before discovery is complete.
					// Calling "Abort" causes ThreadAbortException.
					// So nothing to worry about.
					;
				}
				catch (Exception ex)
				{
                    Logger.LogError(ex);

                    System.Runtime.InteropServices.COMException comex = null;

                    if (ex is System.Runtime.InteropServices.COMException)
                        comex = (System.Runtime.InteropServices.COMException)ex;

                    if (comex != null && (uint)(comex.ErrorCode) == 0x800a11fd)
                    {
                        LastErrorText =
                            "Unable to clean or convert - file is password-protected and marked as Final.";
                    }
				    else
				    {
				        //	Some problem occurred during encryption
				        string errorTxt = string.Format("Failed to decrypt attachment \"{0}\"", attachment.Name);
				        Logger.LogError(errorTxt);
				        LastErrorText = errorTxt;
				    }


				    switch (ui.OnDecryptionError(encryption))
					{
					case DecryptionErrorAction.Cancel:
						return DecryptResult.Cancel;
					case DecryptionErrorAction.Skip:
						return DecryptResult.Skip;
					case DecryptionErrorAction.Retry:
						ui.ModifyPassword = string.Empty;
						ui.OpenPassword = string.Empty;
						encryption.ClearPasswords();
						break;
					}
				}
			}

			//	Decryption succeeded - associate the decryptor with the attachment, so it can be
			//	re-encrypted after scanning
			ui.ModifyPassword = string.Empty;
			ui.OpenPassword = string.Empty;
			string uniqueID = GetEncryptionMapUniqueID(attachment);
			AssociateEncryptorWithData(uniqueID, encryption);
			AddEncryptionProperty(ref attachment, encryption);

			return DecryptResult.Ok;
		}
Exemplo n.º 22
0
		public ProcessResult ProcessRequestForProtectSimple(bool displayProgress, bool isCorporateAccount)
		{
			try
			{
				ShowProgress = displayProgress;
				m_bUpdateProcessResult = true;
				m_encryptionUi = m_uiManager.CreateContentEncryptionUi();

                m_bUseServerProfiles = isCorporateAccount && !OptionApi.GetBool("UseClientProfiles");

				var psd = new NewProtectSimpleDialog(m_bUseServerProfiles)
				{
				    MRUProfile = GetClientProfileMru(),
				    ShowInTaskbar = false
				};
			    m_policyClientProgressDialog = psd;
				m_policyClientProgressDialog.ShouldShowProgress = displayProgress;

				psd.ProtectSimpleProfiles = this.ProtectSimpleProfiles;

				if (psd.ShouldShowTheDialog)
				{
					psd.OnProcessProfile += OnProtectSimpleProcessProfile;

					if (IsSendForReview && IsLotusNotesMailClient)
					{
						Logger.LogInfo("Detected Lotus Notes - Showing window as Always on Top");
						psd.Topmost = true;
					}
					else
					{
						new System.Windows.Interop.WindowInteropHelper(psd).Owner = m_uiManager.ParentHwnd;
					}
		
					bool? dr = psd.ShowDialog();

					if (m_bUpdateProcessResult)
					{
						m_processResult = ProcessRequestErrors(dr, psd.DialogResultEx);
						if (m_processResult == ClientManager.ProcessResult.PROCESSED)
						{
							UpdateClientProfileMru(psd.MRUProfile);
						}
					}
				}
				else
				{
					m_processResult = ProcessResult.NO_ACTIONS;
				}
			}
			catch (Exception ex)
			{
				if (m_policyClientProgressDialog != null)
				{
					// m_policyClientProgressDialog in this case is pointing to Protect Simple Dialog, psd assigned above.
					// If an exception is thrown while the dialog is still on the screen, sometimes the dialog does not get
					// dismissed properly. Thats why we need to call close here.
					m_policyClientProgressDialog.Close();
				}

				Logger.LogError(ex);

				StringBuilder sb = new StringBuilder(Resources.CRITICAL_EXCEPTION);
				sb.Append(' ');
				sb.Append(Resources.CONTACT_SYSTEM_ADMIN);

				m_errors.Add(sb.ToString());
				m_exceptions.Add(ex);

				m_processResult = ProcessResult.EXCEPTION;
			}
			finally
			{
				StartOfficeApplicationTimeout();

				if (m_uiManager != null)
				{
					m_processResult = m_uiManager.HandleInvalidProcessResult(m_processResult, Errors, Exceptions);
				}

				ResetPolicyCache();

				if (m_encryptionUi != null)
				{
					m_encryptionUi.OnShowDialog -= new ShowDialogEvent(m_encryptionUi_OnShowDialog);
				}
			}

			return m_processResult;
		}
Exemplo n.º 23
0
		public ProcessResult ProcessRequest(IPolicyClientProgressDialog progress, bool showProgress, bool enableDynamicDiscovery)
		{
			Logger.LogDebug("Workshare.Policy.ClientManager.RequestManager.ProcessRequest()");

			if (m_request == null)
			{
				m_processResult = ProcessResult.NO_VIOLATIONS;
				return m_processResult;
			}

            if (!AllowActionForLargeAttachments(m_profileLocation))
            {
                return m_processResult;
            }

            // copy over large attachments, if any
            CopyLargeAttachments();

			bool progressCreatedLocally = false;
		    try
			{
				bool hasAttachments = HasSignificantAttachments();
				if (enableDynamicDiscovery && !hasAttachments)
				{
					showProgress = false;
				}

				ShowProgress = showProgress;
				m_encryptionUi = m_uiManager.CreateContentEncryptionUi();
				m_enableDynamicDiscovery = enableDynamicDiscovery;
				m_skipDiscovery = false;

                DialogResult dialogResult;
			    if (m_enableDynamicDiscovery && !this.SendAndProtect && hasAttachments)
				{
					dialogResult = LoadDynamicDiscoveryDialog(false);
				}
				else
				{
					m_policyClientProgressDialog = progress;
					dialogResult = LoadStaticDiscoveryDialog(ref progressCreatedLocally, false);
				}

                if (dialogResult == DialogResult.None && m_processResult != ProcessResult.UNDEFINED)
                {
                    return m_processResult;
                }

                while (m_policyClientDialog.AbortActions)
                {
                    m_policyClientDialog.AbortActions = false;
                    m_policyClientDialog.ContentPanelStyle = ContentPanelStyleEnum.PolicySummary;
                    dialogResult = m_policyClientDialog.ShowDialog(new ParentWindow(m_uiManager.ParentHwnd));
                }

				m_processResult = ProcessRequestErrors(dialogResult);
			}
			catch (Exception ex)
			{
				Logger.LogError(ex);

				StringBuilder sb = new StringBuilder(Resources.CRITICAL_EXCEPTION);
				sb.Append(' ');
				sb.Append(Resources.CONTACT_SYSTEM_ADMIN);

				m_errors.Add(sb.ToString());
				m_exceptions.Add(ex);

				m_processResult = ProcessResult.EXCEPTION;
			}
			finally
			{
				m_engineThread = null;

				StartOfficeApplicationTimeout();

				if (m_policyClientDialog != null)
				{
					m_policyClientDialog.ProcessResponseActions -= responseDialog_ProcessResponseActions;
					m_policyClientDialog.PreviewResponseAction -= policyClientDialog_PreviewResponseAction;
				}

				// If we're creating this locally, we need to make sure Dispose is called on it
				// See comment at top for further information
				if (progressCreatedLocally)
				{
					m_policyClientProgressDialog.Refresh();
					m_policyClientProgressDialog.Close();
					IDisposable disp = m_policyClientProgressDialog;
					if (disp != null)
					{
						disp.Dispose();
					}
				}
			}

			if (m_uiManager != null)
			{
				m_processResult = m_uiManager.HandleInvalidProcessResult(m_processResult, Errors, Exceptions);
			}

			return m_processResult;
		}
Exemplo n.º 24
0
		/// <summary>
		/// Decrypts an office file
		/// </summary>
		protected abstract DecryptResult Decrypt(IContentEncryptionUi ui, string sourceFile);
Exemplo n.º 25
0
 /// <summary>
 /// Decrypts the associated original attachment
 /// </summary>
 public abstract DecryptResult DecryptInternal(IContentEncryptionUi ui);
Exemplo n.º 26
0
		private DecryptResult OpenDocument(IContentEncryptionUi ui, string sourceFile, out object doc)
		{
			doc = null;

			var hasOpenOrModifyPass = true;

			try
			{
				doc = (Workbook)OfficeApplicationCache.Instance.OpenDocument(sourceFile, false, DUMMY_PASSWORD, DUMMY_PASSWORD, AttachmentFileType);
				hasOpenOrModifyPass = false;
			}
			catch (Exception ex)
			{
				Logger.LogTrace(ex);
			}

			if (hasOpenOrModifyPass)
			{
				DecryptResult result = GetAndCheckPasswords(ui);
				if (result != DecryptResult.Ok)
				{
					return result;
				}
			}

			try
			{
				doc = doc ?? OfficeApplicationCache.Instance.OpenDocument(sourceFile, false, string.IsNullOrEmpty(OpenPassword) ? DUMMY_PASSWORD : OpenPassword, string.IsNullOrEmpty(ModifyPassword) ? DUMMY_PASSWORD : ModifyPassword, AttachmentFileType);

				// If the user typed a Modify or Open password for a document that didn't need one
				// remove it here, otherwise it will be added to the saved document.

				if (!OfficeApplicationCache.Instance.ShouldHandleOpenPassword(doc))
				{
					OpenPassword = "";
				}

				if (!OfficeApplicationCache.Instance.ShouldHandleWritePassword(doc))
				{
					ModifyPassword = "";
				}

				return UnProtect(doc, ui);
			}
			catch (COMException ex)
			{
				Logger.LogError("Excel Open Exception");
				Logger.LogError(ex);
				if (ex.ErrorCode == unchecked((int) 0x800A03EC))
				{
					throw new UnauthorizedAccessException("Failed to open encrypted file - incorrect password");
				}
				throw;
			}
		}
Exemplo n.º 27
0
        /// <summary>
        /// Helper method for getting Document Protection password, and checking that it is valid
        /// </summary>
        protected DecryptResult GetDocumentProtectionPassword(IContentEncryptionUi ui)
        {
            if( RequiresDocumentProtectionPassword && string.IsNullOrEmpty(DocumentProtectionPassword) )
            {
				// Check if there is an admin-defined default password
				string defaultDocumentPassword = string.Empty;

				if (this.AllowDefaultPassword)
				{
					defaultDocumentPassword = GetDefaultProtectionPassword();
				}

				// If no password, then show the UI and allow the user to enter one.
				if( string.IsNullOrEmpty(defaultDocumentPassword) )
				{
					string pwdDescription = string.Format(Resources.DocumentProtectionPasswordRequired, ShortName);
                    string pwd = ShortTermPasswordCache.Instance.TryGetPassword(m_Attachment, "Protection");

				    if (pwd == null)
				    {
				        DecryptResult result = ui.GetPassword(Name, Resources.DocumentProtectionPassword, pwdDescription, out pwd);

				        if (result != DecryptResult.Ok)
				        {
				            return result;
				        }

				        if (string.IsNullOrEmpty(pwd))
				        {
				            throw new UnauthorizedAccessException("Document Protection password required");
				        }
				    }

				    DocumentProtectionPassword = pwd;
                    ShortTermPasswordCache.Instance.AddPassword(m_Attachment, "Protection", pwd);

				}
				else
				{					
					DocumentProtectionPassword = defaultDocumentPassword;
				}
            }

            return DecryptResult.Ok;
        }
Exemplo n.º 28
0
		public void DecryptAttachment(IProtectAttachment attachment, IContentEncryptionUi ui)
		{
            _tasks.Add(new NamedTask(() => new DecryptionAction(_marshaller, StatusUpdate, attachment, ui), TaskNames.DecryptAttachment));
		}
Exemplo n.º 29
0
		private DecryptResult UnProtect(object doc, IContentEncryptionUi ui)
		{
			InitPasswordsList(doc);
			if (m_Passwords.Count > 0)
				return ui.GetPasswords(OriginalAttachment.Name, OriginalAttachment.Name, m_Passwords, OnPropertyChanged);

			return DecryptResult.Ok;
		}
Exemplo n.º 30
0
		/// <summary>
		/// Re-apply password to zip contents(recursively)
		/// Remove temp files generated by original zip unpacking (and used by action processing)
		/// Note: We do NOT re-apply the zip files password here, ReEncryptAttachment() does it at higher level
		/// </summary>
		/// <param name="zipContainerAttachment"></param>
		/// <param name="ui"></param>
		/// <param name="cancelSend"></param>
		/// <returns></returns>
		private bool EncryptZipContents(Attachment zipContainerAttachment, IContentEncryptionUi ui, out bool cancelSend)
		{
			Logger.LogInfo("EncryptZipContents called for:" + zipContainerAttachment.FileName);

			cancelSend = false;

			using (var tempFileController = new TempFileController()) // Remember the temp files we generated.
			{
				for (int i = 0; i < zipContainerAttachment.File.Files.Count; i++) // So we can recreate FCS files on fly
				{
					IFile file = (IFile) zipContainerAttachment.File.Files[i];
					Attachment tmpAttachment = new Attachment(file, "contenttype", file.ContentId, null, false);

					// This attachment may be itself a zip; so before we re-encrypt it, we need to re-encrypt its contents.
					if (!ProcessContainerContents(tmpAttachment, ui, false, out cancelSend))
					{
						return false;
					}

					// Ignore the return value, this will fail if the attachment was not encrypted originally.
					ReEncryptAttachment(tmpAttachment);

					// Ensure the changes get copied back
					zipContainerAttachment.File.Files[i] = tmpAttachment.File;
					tempFileController.Add(file.FileName);
				}

				// Re-create the actual zip file with the now processed files
				if (!zipContainerAttachment.File.PackContainer(string.Empty))
				// Don't specify a password at this point, allow ReEncryptAttachment()
				{
					LastErrorText = string.Format("Unable to repack [{0}]", zipContainerAttachment.File.FileName);
					Logger.LogError(LastErrorText);
					return false;
				}
			}

			return true;
		}