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; }
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 }); } }
/// <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 }
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; } }
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; } }
// 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; } }
/// <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; }
/// <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; }
/// <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); } }
/// <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; }
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; }
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; }
/// <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; }
/// <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; }
/// <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; }
/// <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; }
public DecryptionAction(IActionQueueMarshaller marshaller, EventHandler<ActionEventArgs> statusUpdate, IProtectAttachment attachment, IContentEncryptionUi ui) : base(marshaller, statusUpdate) { Execute(attachment, ui); }
/// <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; }
internal void DecryptAttachment(IProtectAttachment protectAttachment, IContentEncryptionUi ctrl) { _model.DecryptAttachment(protectAttachment,ctrl); }
/// <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; }
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; }
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; }
/// <summary> /// Decrypts an office file /// </summary> protected abstract DecryptResult Decrypt(IContentEncryptionUi ui, string sourceFile);
/// <summary> /// Decrypts the associated original attachment /// </summary> public abstract DecryptResult DecryptInternal(IContentEncryptionUi ui);
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; } }
/// <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; }
public void DecryptAttachment(IProtectAttachment attachment, IContentEncryptionUi ui) { _tasks.Add(new NamedTask(() => new DecryptionAction(_marshaller, StatusUpdate, attachment, ui), TaskNames.DecryptAttachment)); }
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; }
/// <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; }