include/sfx2/classificationhelper.hxx | 6 ++ sfx2/source/view/classificationhelper.cxx | 72 +++++++++++++++++++++++++++--- sw/source/ui/app/app.src | 5 ++ sw/source/uibase/dochdl/swdtflvr.cxx | 25 +++++++++- sw/source/uibase/inc/app.hrc | 3 - 5 files changed, 101 insertions(+), 10 deletions(-)
New commits: commit 32c2a2f8dc04af8a49ad3580af0ea647c45eb877 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Mar 8 17:58:56 2016 +0100 sw: detect copy&paste between different classification levels With this we cover all 4 cases of copy&paste between possibly classified documents. When both are classified, then we also check the classification level, if they have the same scale. Change-Id: I8c02781fc9755114cd6a2fb93be11dca7b3441d0 diff --git a/sw/source/ui/app/app.src b/sw/source/ui/app/app.src index 94b64d7..0b56c96 100644 --- a/sw/source/ui/app/app.src +++ b/sw/source/ui/app/app.src @@ -652,4 +652,9 @@ String STR_TARGET_DOC_NOT_CLASSIFIED Text [ en-US ] = "This document must be classified before the clipboard can be pasted." ; }; +String STR_DOC_CLASSIFICATION_TOO_LOW +{ + Text [ en-US ] = "This document has a lower classificaton level than the clipboard." ; +}; + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/uibase/dochdl/swdtflvr.cxx b/sw/source/uibase/dochdl/swdtflvr.cxx index 84b1af6..04c3ae1 100644 --- a/sw/source/uibase/dochdl/swdtflvr.cxx +++ b/sw/source/uibase/dochdl/swdtflvr.cxx @@ -3222,13 +3222,34 @@ bool lcl_checkClassification(SwDoc* pSourceDoc, SwDoc* pDestinationDoc) if (!pSourceShell || !pDestinationShell) return true; - // Paste from a classified document to a non-classified one -> deny. - if (SfxClassificationHelper::IsClassified(*pSourceShell) && !SfxClassificationHelper::IsClassified(*pDestinationShell)) + bool bSourceClassified = SfxClassificationHelper::IsClassified(*pSourceShell); + if (!bSourceClassified) + // No classification on the source side. Return early, regardless the + // state of the destination side. + return true; + + bool bDestinationClassified = SfxClassificationHelper::IsClassified(*pDestinationShell); + if (bSourceClassified && !bDestinationClassified) { + // Paste from a classified document to a non-classified one -> deny. ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SW_RES(STR_TARGET_DOC_NOT_CLASSIFIED), VCL_MESSAGE_INFO)->Execute(); return false; } + // Remaining case: paste between two classified documents. + SfxClassificationHelper aSource(*pSourceShell); + SfxClassificationHelper aDestination(*pDestinationShell); + if (aSource.GetImpactScale() != aDestination.GetImpactScale()) + // It's possible to compare them if they have the same scale. + return true; + + if (aSource.GetImpactLevel() > aDestination.GetImpactLevel()) + { + // Paste from a doc that has higher classification -> deny. + ScopedVclPtrInstance<MessageDialog>::Create(nullptr, SW_RES(STR_DOC_CLASSIFICATION_TOO_LOW), VCL_MESSAGE_INFO)->Execute(); + return false; + } + return true; } diff --git a/sw/source/uibase/inc/app.hrc b/sw/source/uibase/inc/app.hrc index 9962d0c..aab6fd9 100644 --- a/sw/source/uibase/inc/app.hrc +++ b/sw/source/uibase/inc/app.hrc @@ -92,8 +92,9 @@ #define STR_WRONG_TABLENAME (RC_APP_BEGIN + 138) #define STR_SRTERR (RC_APP_BEGIN + 139) #define STR_TARGET_DOC_NOT_CLASSIFIED (RC_APP_BEGIN + 140) +#define STR_DOC_CLASSIFICATION_TOO_LOW (RC_APP_BEGIN + 141) -#define APP_ACT_END STR_TARGET_DOC_NOT_CLASSIFIED +#define APP_ACT_END STR_DOC_CLASSIFICATION_TOO_LOW #if APP_ACT_END > RC_APP_END #error Resource-Id Ueberlauf in #file, #line commit 740a72e66ddf3efd4028d8268239f9a50f759499 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Tue Mar 8 14:29:15 2016 +0100 sfx2 classification: expose impact scale and level This allows application code to prevent copypaste from a more confidential to a less confidential document. Change-Id: I121c7566c948340e7b41d3f8462b0d65a2441b0f diff --git a/include/sfx2/classificationhelper.hxx b/include/sfx2/classificationhelper.hxx index 5b007020..5c49db7 100644 --- a/include/sfx2/classificationhelper.hxx +++ b/include/sfx2/classificationhelper.hxx @@ -40,9 +40,13 @@ public: std::vector<OUString> GetBACNames(); /// Setting this sets all the other properties, based on the policy. void SetBACName(const OUString& rName); - /// If GetImpactLevelColor() will return something meaningful. + /// If GetImpactScale() and GetImpactLevel*() will return something meaningful. bool HasImpactLevel(); basegfx::BColor GetImpactLevelColor(); + /// Larger value means more confidential. + sal_Int32 GetImpactLevel(); + /// Comparing the GetImpactLevel() result is only meaningful when the impact scale is the same. + OUString GetImpactScale(); OUString GetDocumentWatermark(); /// The selected category has some content for the document header. bool HasDocumentHeader(); diff --git a/sfx2/source/view/classificationhelper.cxx b/sfx2/source/view/classificationhelper.cxx index 349c337..c3161b6 100644 --- a/sfx2/source/view/classificationhelper.cxx +++ b/sfx2/source/view/classificationhelper.cxx @@ -56,6 +56,18 @@ const OUString& PROP_NONE() return sProp; } +const OUString& PROP_IMPACTSCALE() +{ + static OUString sProp("urn:bails:IntellectualProperty:Impact:Scale"); + return sProp; +} + +const OUString& PROP_IMPACTLEVEL() +{ + static OUString sProp("urn:bails:IntellectualProperty:Impact:Level:Confidentiality"); + return sProp; +} + /// Represents one category of a classification policy. class SfxClassificationCategory { @@ -236,7 +248,7 @@ void SAL_CALL SfxClassificationParser::endElement(const OUString& rName) throw ( { m_bInScale = false; if (m_pCategory) - m_pCategory->m_aLabels["urn:bails:IntellectualProperty:Impact:Scale"] = m_aScale; + m_pCategory->m_aLabels[PROP_IMPACTSCALE()] = m_aScale; } else if (rName == "baf:ConfidentalityValue") { @@ -244,7 +256,7 @@ void SAL_CALL SfxClassificationParser::endElement(const OUString& rName) throw ( if (m_pCategory) { std::map<OUString, OUString>& rLabels = m_pCategory->m_aLabels; - rLabels["urn:bails:IntellectualProperty:Impact:Level:Confidentiality"] = m_aConfidentalityValue; + rLabels[PROP_IMPACTLEVEL()] = m_aConfidentalityValue; // Set the two other type of levels as well, if they're not set // yet: they're optional in BAF, but not in BAILS. if (rLabels.find("urn:bails:IntellectualProperty:Impact:Level:Integrity") == rLabels.end()) @@ -451,11 +463,11 @@ const OUString& SfxClassificationHelper::GetBACName() bool SfxClassificationHelper::HasImpactLevel() { - std::map<OUString, OUString>::iterator it = m_pImpl->m_aCategory.m_aLabels.find("urn:bails:IntellectualProperty:Impact:Scale"); + std::map<OUString, OUString>::iterator it = m_pImpl->m_aCategory.m_aLabels.find(PROP_IMPACTSCALE()); if (it == m_pImpl->m_aCategory.m_aLabels.end()) return false; - it = m_pImpl->m_aCategory.m_aLabels.find("urn:bails:IntellectualProperty:Impact:Level:Confidentiality"); + it = m_pImpl->m_aCategory.m_aLabels.find(PROP_IMPACTLEVEL()); if (it == m_pImpl->m_aCategory.m_aLabels.end()) return false; @@ -484,12 +496,12 @@ basegfx::BColor SfxClassificationHelper::GetImpactLevelColor() { basegfx::BColor aRet; - std::map<OUString, OUString>::iterator it = m_pImpl->m_aCategory.m_aLabels.find("urn:bails:IntellectualProperty:Impact:Scale"); + std::map<OUString, OUString>::iterator it = m_pImpl->m_aCategory.m_aLabels.find(PROP_IMPACTSCALE()); if (it == m_pImpl->m_aCategory.m_aLabels.end()) return aRet; OUString aScale = it->second; - it = m_pImpl->m_aCategory.m_aLabels.find("urn:bails:IntellectualProperty:Impact:Level:Confidentiality"); + it = m_pImpl->m_aCategory.m_aLabels.find(PROP_IMPACTLEVEL()); if (it == m_pImpl->m_aCategory.m_aLabels.end()) return aRet; OUString aLevel = it->second; @@ -530,6 +542,54 @@ basegfx::BColor SfxClassificationHelper::GetImpactLevelColor() return aRet; } +sal_Int32 SfxClassificationHelper::GetImpactLevel() +{ + sal_Int32 nRet = -1; + + std::map<OUString, OUString>::iterator it = m_pImpl->m_aCategory.m_aLabels.find(PROP_IMPACTSCALE()); + if (it == m_pImpl->m_aCategory.m_aLabels.end()) + return nRet; + OUString aScale = it->second; + + it = m_pImpl->m_aCategory.m_aLabels.find(PROP_IMPACTLEVEL()); + if (it == m_pImpl->m_aCategory.m_aLabels.end()) + return nRet; + OUString aLevel = it->second; + + if (aScale == "UK-Cabinet") + { + sal_Int32 nValue = aLevel.toInt32(); + if (nValue < 0 || nValue > 3) + return nRet; + nRet = nValue; + } + else if (aScale == "FIPS-199") + { + static std::map<OUString, sal_Int32> aValues; + if (aValues.empty()) + { + aValues["Low"] = 0; + aValues["Moderate"] = 1; + aValues["High"] = 2; + } + std::map<OUString, sal_Int32>::iterator itValues = aValues.find(aLevel); + if (itValues == aValues.end()) + return nRet; + nRet = itValues->second; + } + + return nRet; +} + +OUString SfxClassificationHelper::GetImpactScale() +{ + std::map<OUString, OUString>::iterator it = m_pImpl->m_aCategory.m_aLabels.find(PROP_IMPACTSCALE()); + if (it != m_pImpl->m_aCategory.m_aLabels.end()) + return it->second; + + return OUString(); +} + OUString SfxClassificationHelper::GetDocumentWatermark() { std::map<OUString, OUString>::iterator it = m_pImpl->m_aCategory.m_aLabels.find(SfxClassificationHelper::PROP_DOCWATERMARK()); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits