LibreOffice Module xmlsecurity (master) 1
macrosecurity.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <macrosecurity.hxx>
22#include <certificateviewer.hxx>
23#include <biginteger.hxx>
24#include <resourcemanager.hxx>
25#include <strings.hrc>
26
27#include <o3tl/safeint.hxx>
28#include <osl/file.hxx>
29#include <sal/log.hxx>
30
31#include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
35#include <com/sun/star/uno/Exception.hpp>
36#include <com/sun/star/ui/dialogs/FolderPicker.hpp>
37#include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
40#include <tools/urlobj.hxx>
41#include <unotools/datetime.hxx>
42
43#include <utility>
44#include <vcl/svapp.hxx>
45
46using namespace comphelper;
47using namespace ::com::sun::star;
48
49
51{
52 m_xLevelTP->ClosePage();
53 m_xTrustSrcTP->ClosePage();
54 m_xDialog->response(RET_OK);
55}
56
58 css::uno::Reference<css::xml::crypto::XSecurityEnvironment> xSecurityEnvironment)
59 : GenericDialogController(pParent, "xmlsec/ui/macrosecuritydialog.ui", "MacroSecurityDialog")
60 , m_xSecurityEnvironment(std::move(xSecurityEnvironment))
61 , m_xTabCtrl(m_xBuilder->weld_notebook("tabcontrol"))
62 , m_xOkBtn(m_xBuilder->weld_button("ok"))
63 , m_xResetBtn(m_xBuilder->weld_button("reset"))
64{
65 m_xTabCtrl->connect_enter_page(LINK(this, MacroSecurity, ActivatePageHdl));
66
67 m_xLevelTP.reset(new MacroSecurityLevelTP(m_xTabCtrl->get_page("SecurityLevelPage"), this));
68 m_xTrustSrcTP.reset(new MacroSecurityTrustedSourcesTP(m_xTabCtrl->get_page("SecurityTrustPage"), this));
69
70 m_xTabCtrl->set_current_page("SecurityLevelPage");
71 m_xOkBtn->connect_clicked(LINK(this, MacroSecurity, OkBtnHdl));
72}
73
74IMPL_LINK(MacroSecurity, ActivatePageHdl, const OUString&, rPage, void)
75{
76 if (rPage == "SecurityLevelPage")
77 m_xLevelTP->ActivatePage();
78 else if (rPage == "SecurityTrustPage")
79 m_xTrustSrcTP->ActivatePage();
80}
81
82MacroSecurityTP::MacroSecurityTP(weld::Container* pParent, const OUString& rUIXMLDescription,
83 const OUString& rID, MacroSecurity* pDlg)
84 : m_xBuilder(Application::CreateBuilder(pParent, rUIXMLDescription))
85 , m_xContainer(m_xBuilder->weld_container(rID))
86 , m_pDlg(pDlg)
87{
88}
89
91{
92}
93
95{
96}
97
99 : MacroSecurityTP(pParent, "xmlsec/ui/securitylevelpage.ui", "SecurityLevelPage", pDlg)
100 , m_xVeryHighRB(m_xBuilder->weld_radio_button("vhigh"))
101 , m_xHighRB(m_xBuilder->weld_radio_button("high"))
102 , m_xMediumRB(m_xBuilder->weld_radio_button("med"))
103 , m_xLowRB(m_xBuilder->weld_radio_button("low"))
104 , m_xVHighImg(m_xBuilder->weld_widget("vhighimg"))
105 , m_xHighImg(m_xBuilder->weld_widget("highimg"))
106 , m_xMedImg(m_xBuilder->weld_widget("medimg"))
107 , m_xLowImg(m_xBuilder->weld_widget("lowimg"))
108{
109 m_xLowRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
110 m_xMediumRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
111 m_xHighRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
112 m_xVeryHighRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
113
114 int nPrefWidth(std::max({m_xVeryHighRB->get_preferred_size().Width(),
115 m_xHighRB->get_preferred_size().Width(),
116 m_xMediumRB->get_preferred_size().Width(),
117 m_xLowRB->get_preferred_size().Width()}));
118 int nMaxWidth = m_xLowRB->get_approximate_digit_width() * 60;
119 if (nPrefWidth > nMaxWidth)
120 {
121 m_xLowRB->set_label_wrap(true);
122 m_xLowRB->set_size_request(nMaxWidth, -1);
123 m_xMediumRB->set_label_wrap(true);
124 m_xMediumRB->set_size_request(nMaxWidth, -1);
125 m_xHighRB->set_label_wrap(true);
126 m_xHighRB->set_size_request(nMaxWidth, -1);
127 m_xVeryHighRB->set_label_wrap(true);
128 m_xVeryHighRB->set_size_request(nMaxWidth, -1);
129 }
130
131 mnCurLevel = static_cast<sal_uInt16>(SvtSecurityOptions::GetMacroSecurityLevel());
133
134 weld::RadioButton* pCheck = nullptr;
135 weld::Widget* pImage = nullptr;
136 switch (mnCurLevel)
137 {
138 case 3:
139 pCheck = m_xVeryHighRB.get();
140 pImage = m_xVHighImg.get();
141 break;
142 case 2:
143 pCheck = m_xHighRB.get();
144 pImage = m_xHighImg.get();
145 break;
146 case 1:
147 pCheck = m_xMediumRB.get();
148 pImage = m_xMedImg.get();
149 break;
150 case 0:
151 pCheck = m_xLowRB.get();
152 pImage = m_xLowImg.get();
153 break;
154 }
155 if (pCheck)
156 pCheck->set_active(true);
157 else
158 {
159 OSL_FAIL("illegal macro security level");
160 }
161 if (bReadonly && pImage)
162 {
163 pImage->show();
164 m_xVeryHighRB->set_sensitive(false);
165 m_xHighRB->set_sensitive(false);
166 m_xMediumRB->set_sensitive(false);
167 m_xLowRB->set_sensitive(false);
168 }
169}
170
172{
173 sal_uInt16 nNewLevel = 0;
174 if( m_xVeryHighRB->get_active() )
175 nNewLevel = 3;
176 else if( m_xHighRB->get_active() )
177 nNewLevel = 2;
178 else if( m_xMediumRB->get_active() )
179 nNewLevel = 1;
180
181 if ( nNewLevel != mnCurLevel )
182 {
183 mnCurLevel = nNewLevel;
184 m_pDlg->EnableReset();
185 }
186}
187
189{
191}
192
194{
195 bool bCertSelected = m_xTrustCertLB->get_selected_index() != -1;
196 m_xViewCertPB->set_sensitive( bCertSelected );
197 m_xRemoveCertPB->set_sensitive( bCertSelected && !mbAuthorsReadonly);
198
199 bool bLocationSelected = m_xTrustFileLocLB->get_selected_index() != -1;
200 m_xRemoveLocPB->set_sensitive( bLocationSelected && !mbURLsReadonly);
201}
202
204{
205 OUString aMsg = XsResId(STR_BROKEN_MACRO_CERTIFICATE_DATA);
206 aMsg = aMsg.replaceFirst("%{data}", rData);
207 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDlg->getDialog(),
208 VclMessageType::Error, VclButtonsType::Ok, aMsg));
209 xErrorBox->run();
210}
211
213{
214 int nEntry = m_xTrustCertLB->get_selected_index();
215 if (nEntry == -1)
216 return;
217
218 const sal_uInt16 nSelected = m_xTrustCertLB->get_id(nEntry).toUInt32();
219 uno::Reference< css::security::XCertificate > xCert;
220 try
221 {
222 xCert = m_pDlg->m_xSecurityEnvironment->getCertificate(m_aTrustedAuthors[nSelected].SubjectName,
223 xmlsecurity::numericStringToBigInteger(m_aTrustedAuthors[nSelected].SerialNumber));
224 }
225 catch (...)
226 {
227 TOOLS_WARN_EXCEPTION("xmlsecurity.dialogs", "matching certificate not found for: " << m_aTrustedAuthors[nSelected].SubjectName);
228 }
229
230 if (!xCert.is())
231 {
232 try
233 {
234 xCert = m_pDlg->m_xSecurityEnvironment->createCertificateFromAscii(m_aTrustedAuthors[nSelected].RawData);
235 }
236 catch (...)
237 {
238 TOOLS_WARN_EXCEPTION("xmlsecurity.dialogs", "certificate data couldn't be parsed: " << m_aTrustedAuthors[nSelected].RawData);
239 }
240 }
241
242 if ( xCert.is() )
243 {
244 CertificateViewer aViewer(m_pDlg->getDialog(), m_pDlg->m_xSecurityEnvironment, xCert, false, nullptr);
245 aViewer.run();
246 }
247 else
248 // should never happen, as we parsed the certificate data when we added it!
249 ShowBrokenCertificateError(m_aTrustedAuthors[nSelected].RawData);
250}
251
253{
254 int nEntry = m_xTrustCertLB->get_selected_index();
255 if (nEntry != -1)
256 {
257 sal_uInt16 nAuthor = m_xTrustCertLB->get_id(nEntry).toUInt32();
258 m_aTrustedAuthors.erase(m_aTrustedAuthors.begin() + nAuthor);
259
260 FillCertLB();
261 ImplCheckButtons();
262 }
263}
264
266{
267 try
268 {
269 uno::Reference < uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
270 uno::Reference < ui::dialogs::XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, m_pDlg->getDialog());
271
272 short nRet = xFolderPicker->execute();
273
274 if( ui::dialogs::ExecutableDialogResults::OK != nRet )
275 return;
276
277 OUString aPathStr = xFolderPicker->getDirectory();
278 INetURLObject aNewObj( aPathStr );
279 aNewObj.removeFinalSlash();
280
281 // then the new path also a URL else system path
282 OUString aSystemFileURL = ( aNewObj.GetProtocol() != INetProtocol::NotValid ) ?
283 aPathStr : aNewObj.getFSysPath( FSysStyle::Detect );
284
285 OUString aNewPathStr(aSystemFileURL);
286
287 if ( osl::FileBase::getSystemPathFromFileURL( aSystemFileURL, aSystemFileURL ) == osl::FileBase::E_None )
288 aNewPathStr = aSystemFileURL;
289
290 if (m_xTrustFileLocLB->find_text(aNewPathStr) == -1)
291 m_xTrustFileLocLB->append_text(aNewPathStr);
292
293 ImplCheckButtons();
294 }
295 catch( uno::Exception& )
296 {
297 TOOLS_WARN_EXCEPTION( "xmlsecurity.dialogs", "MacroSecurityTrustedSourcesTP::AddLocPBHdl(): exception from folder picker" );
298 }
299}
300
302{
303 sal_Int32 nSel = m_xTrustFileLocLB->get_selected_index();
304 if (nSel == -1)
305 return;
306
307 m_xTrustFileLocLB->remove(nSel);
308 // Trusted Path could not be removed (#i33584#)
309 // after remove an entry, select another one if exists
310 int nNewCount = m_xTrustFileLocLB->n_children();
311 if (nNewCount > 0)
312 {
313 if (nSel >= nNewCount)
314 nSel = nNewCount - 1;
315 m_xTrustFileLocLB->select(nSel);
316 }
317 ImplCheckButtons();
318}
319
321{
322 ImplCheckButtons();
323}
324
326{
327 ImplCheckButtons();
328}
329
330void MacroSecurityTrustedSourcesTP::FillCertLB(const bool bShowWarnings)
331{
332 m_xTrustCertLB->clear();
333
334 sal_uInt32 nEntries = m_aTrustedAuthors.size();
335
336 if ( !(nEntries && m_pDlg->m_xSecurityEnvironment.is()) )
337 return;
338
339 for( sal_uInt32 nEntry = 0 ; nEntry < nEntries ; ++nEntry )
340 {
342
343 try
344 {
345 // create from RawData
346 uno::Reference< css::security::XCertificate > xCert = m_pDlg->m_xSecurityEnvironment->createCertificateFromAscii(rEntry.RawData);
347 m_xTrustCertLB->append(OUString::number(nEntry), xmlsec::GetContentPart(xCert->getSubjectName(), xCert->getCertificateKind()));
348 m_xTrustCertLB->set_text(nEntry, xmlsec::GetContentPart(xCert->getIssuerName(), xCert->getCertificateKind()), 1);
349 m_xTrustCertLB->set_text(nEntry, utl::GetDateTimeString(xCert->getNotValidAfter()), 2);
350 }
351 catch (...)
352 {
353 if (bShowWarnings)
354 {
355 TOOLS_WARN_EXCEPTION("xmlsecurity.dialogs", "certificate data couldn't be parsed: " << rEntry.RawData);
356 OUString sData = rEntry.RawData;
357 css::uno::Any tools_warn_exception(DbgGetCaughtException());
358 OUString sException = OStringToOUString(exceptionToString(tools_warn_exception), RTL_TEXTENCODING_UTF8);
359 if (!sException.isEmpty())
360 sData += " / " + sException;
362 }
363 }
364 }
365}
366
368 : MacroSecurityTP(pParent, "xmlsec/ui/securitytrustpage.ui", "SecurityTrustPage", pDlg)
369 , m_xTrustCertROFI(m_xBuilder->weld_image("lockcertimg"))
370 , m_xTrustCertLB(m_xBuilder->weld_tree_view("certificates"))
371 , m_xViewCertPB(m_xBuilder->weld_button("viewcert"))
372 , m_xRemoveCertPB(m_xBuilder->weld_button("removecert"))
373 , m_xTrustFileROFI(m_xBuilder->weld_image("lockfileimg"))
374 , m_xTrustFileLocLB(m_xBuilder->weld_tree_view("locations"))
375 , m_xAddLocPB(m_xBuilder->weld_button("addfile"))
376 , m_xRemoveLocPB(m_xBuilder->weld_button("removefile"))
377{
378 auto nColWidth = m_xTrustCertLB->get_approximate_digit_width() * 12;
379 std::vector<int> aWidths
380 {
381 o3tl::narrowing<int>(nColWidth * 2),
382 o3tl::narrowing<int>(nColWidth * 2)
383 };
384 m_xTrustCertLB->set_column_fixed_widths(aWidths);
385 m_xTrustCertLB->set_size_request(nColWidth * 5.5, m_xTrustCertLB->get_height_rows(5));
386
387 m_xTrustCertLB->connect_changed( LINK( this, MacroSecurityTrustedSourcesTP, TrustCertLBSelectHdl ) );
388 m_xViewCertPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, ViewCertPBHdl ) );
389 m_xViewCertPB->set_sensitive(false);
390 m_xRemoveCertPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, RemoveCertPBHdl ) );
391 m_xRemoveCertPB->set_sensitive(false);
392
393 m_xTrustFileLocLB->connect_changed( LINK( this, MacroSecurityTrustedSourcesTP, TrustFileLocLBSelectHdl ) );
394 m_xTrustFileLocLB->set_size_request(nColWidth * 5, m_xTrustFileLocLB->get_height_rows(5));
395 m_xAddLocPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, AddLocPBHdl ) );
396 m_xRemoveLocPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, RemoveLocPBHdl ) );
397 m_xRemoveLocPB->set_sensitive(false);
398
402
403 FillCertLB(true);
404
405 std::vector< OUString > aSecureURLs = SvtSecurityOptions::GetSecureURLs();
407 m_xTrustFileROFI->set_visible(mbURLsReadonly);
408 m_xAddLocPB->set_sensitive(!mbURLsReadonly);
409
410 for (const auto& rSecureURL : aSecureURLs)
411 {
412 OUString aSystemFileURL( rSecureURL );
413 osl::FileBase::getSystemPathFromFileURL( aSystemFileURL, aSystemFileURL );
414 m_xTrustFileLocLB->append_text(aSystemFileURL);
415 }
416}
417
419{
420 m_pDlg->EnableReset( false );
421 FillCertLB();
422}
423
425{
426 sal_Int32 nEntryCnt = m_xTrustFileLocLB->n_children();
427 if( nEntryCnt )
428 {
429 std::vector< OUString > aSecureURLs;
430 for (sal_Int32 i = 0; i < nEntryCnt; ++i)
431 {
432 OUString aURL(m_xTrustFileLocLB->get_text(i));
433 osl::FileBase::getFileURLFromSystemPath( aURL, aURL );
434 aSecureURLs.push_back(aURL);
435 }
436
437 SvtSecurityOptions::SetSecureURLs( std::move(aSecureURLs) );
438 }
439 // Trusted Path could not be removed (#i33584#)
440 // don't forget to remove the old saved SecureURLs
441 else
442 SvtSecurityOptions::SetSecureURLs( std::vector< OUString >() );
443
445}
446
447/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Reference< XExecutableDialog > m_xDialog
static weld::MessageDialog * CreateMessageDialog(weld::Widget *pParent, VclMessageType eMessageType, VclButtonsType eButtonType, const OUString &rPrimaryMessage, const ILibreOfficeKitNotifier *pNotifier=nullptr)
bool removeFinalSlash()
INetProtocol GetProtocol() const
OUString getFSysPath(FSysStyle eStyle, sal_Unicode *pDelimiter=nullptr) const
std::unique_ptr< weld::RadioButton > m_xHighRB
std::unique_ptr< weld::RadioButton > m_xLowRB
MacroSecurityLevelTP(weld::Container *pParent, MacroSecurity *pDlg)
std::unique_ptr< weld::Widget > m_xVHighImg
std::unique_ptr< weld::Widget > m_xLowImg
virtual void ClosePage() override
std::unique_ptr< weld::RadioButton > m_xMediumRB
std::unique_ptr< weld::RadioButton > m_xVeryHighRB
std::unique_ptr< weld::Widget > m_xMedImg
std::unique_ptr< weld::Widget > m_xHighImg
virtual ~MacroSecurityTP()
virtual void ActivatePage()
MacroSecurity * m_pDlg
MacroSecurityTP(weld::Container *pParent, const OUString &rUIXMLDescription, const OUString &rID, MacroSecurity *pDlg)
std::unique_ptr< weld::Button > m_xAddLocPB
std::unique_ptr< weld::TreeView > m_xTrustCertLB
std::unique_ptr< weld::Button > m_xRemoveCertPB
void FillCertLB(const bool bShowWarnings=false)
std::unique_ptr< weld::TreeView > m_xTrustFileLocLB
MacroSecurityTrustedSourcesTP(weld::Container *pParent, MacroSecurity *pDlg)
std::unique_ptr< weld::Image > m_xTrustCertROFI
virtual void ActivatePage() override
virtual void ClosePage() override
std::vector< SvtSecurityOptions::Certificate > m_aTrustedAuthors
std::unique_ptr< weld::Button > m_xRemoveLocPB
std::unique_ptr< weld::Image > m_xTrustFileROFI
void ShowBrokenCertificateError(std::u16string_view rData)
std::unique_ptr< weld::Button > m_xViewCertPB
MacroSecurity(weld::Window *pParent, css::uno::Reference< css::xml::crypto::XSecurityEnvironment > xSecurityEnvironment)
std::unique_ptr< weld::Notebook > m_xTabCtrl
css::uno::Reference< css::xml::crypto::XSecurityEnvironment > m_xSecurityEnvironment
void EnableReset(bool bEnable=true)
friend class MacroSecurityTrustedSourcesTP
friend class MacroSecurityLevelTP
std::unique_ptr< weld::Button > m_xOkBtn
std::unique_ptr< MacroSecurityTP > m_xLevelTP
std::unique_ptr< MacroSecurityTP > m_xTrustSrcTP
virtual short run()
virtual Dialog * getDialog() override
virtual void set_active(bool active)=0
virtual void show()=0
OString exceptionToString(const css::uno::Any &caught)
#define TOOLS_WARN_EXCEPTION(area, stream)
css::uno::Any DbgGetCaughtException()
URL aURL
IMPL_LINK(MacroSecurity, ActivatePageHdl, const OUString &, rPage, void)
IMPL_LINK_NOARG(MacroSecurity, OkBtnHdl, weld::Button &, void)
void SetMacroSecurityLevel(sal_Int32 _nLevel)
bool IsReadOnly(EOption eOption)
void SetSecureURLs(std::vector< OUString > &&urlList)
void SetTrustedAuthors(const std::vector< Certificate > &rAuthors)
sal_Int32 GetMacroSecurityLevel()
std::vector< SvtSecurityOptions::Certificate > GetTrustedAuthors()
std::vector< OUString > GetSecureURLs()
int i
css::uno::Reference< css::ui::dialogs::XFolderPicker2 > createFolderPicker(const css::uno::Reference< css::uno::XComponentContext > &rContext, weld::Window *pPreferredParent)
OUString GetDateTimeString(const css::util::DateTime &_rDT)
Sequence< sal_Int8 > numericStringToBigInteger(std::u16string_view numeral)
Definition: biginteger.cxx:32
Reference< XNameAccess > m_xContainer
OUString XsResId(TranslateId aId)
RET_OK