Version 6.4.0.0.beta1, tag libreoffice-6.4.0.0.beta1
[LibreOffice.git] / xmlsecurity / source / dialogs / macrosecurity.cxx
blobbb1015586cf401104339f2429f63280bfc4c546d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <macrosecurity.hxx>
22 #include <certificateviewer.hxx>
23 #include <biginteger.hxx>
25 #include <osl/file.hxx>
26 #include <sal/log.hxx>
28 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
29 #include <comphelper/sequence.hxx>
30 #include <comphelper/processfactory.hxx>
31 #include <comphelper/xmlsechelper.hxx>
32 #include <com/sun/star/uno/Exception.hpp>
33 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
34 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
35 #include <tools/diagnose_ex.h>
36 #include <tools/urlobj.hxx>
37 #include <unotools/datetime.hxx>
39 #include <vcl/svapp.hxx>
41 using namespace comphelper;
42 using namespace ::com::sun::star;
45 IMPL_LINK_NOARG(MacroSecurity, OkBtnHdl, weld::Button&, void)
47 m_xLevelTP->ClosePage();
48 m_xTrustSrcTP->ClosePage();
49 m_xDialog->response(RET_OK);
52 MacroSecurity::MacroSecurity(weld::Window* pParent,
53 const css::uno::Reference<css::xml::crypto::XSecurityEnvironment>& rxSecurityEnvironment)
54 : GenericDialogController(pParent, "xmlsec/ui/macrosecuritydialog.ui", "MacroSecurityDialog")
55 , m_xSecurityEnvironment(rxSecurityEnvironment)
56 , m_xTabCtrl(m_xBuilder->weld_notebook("tabcontrol"))
57 , m_xOkBtn(m_xBuilder->weld_button("ok"))
58 , m_xResetBtn(m_xBuilder->weld_button("reset"))
60 m_xTabCtrl->connect_enter_page(LINK(this, MacroSecurity, ActivatePageHdl));
62 m_xLevelTP.reset(new MacroSecurityLevelTP(m_xTabCtrl->get_page("SecurityLevelPage"), this));
63 m_xTrustSrcTP.reset(new MacroSecurityTrustedSourcesTP(m_xTabCtrl->get_page("SecurityTrustPage"), this));
65 m_xTabCtrl->set_current_page("SecurityLevelPage");
66 m_xOkBtn->connect_clicked(LINK(this, MacroSecurity, OkBtnHdl));
69 IMPL_LINK(MacroSecurity, ActivatePageHdl, const OString&, rPage, void)
71 if (rPage == "SecurityLevelPage")
72 m_xLevelTP->ActivatePage();
73 else if (rPage == "SecurityTrustPage")
74 m_xTrustSrcTP->ActivatePage();
77 MacroSecurityTP::MacroSecurityTP(weld::Container* pParent, const OUString& rUIXMLDescription,
78 const OString& rID, MacroSecurity* pDlg)
79 : m_xBuilder(Application::CreateBuilder(pParent, rUIXMLDescription))
80 , m_xContainer(m_xBuilder->weld_container(rID))
81 , m_pDlg(pDlg)
85 void MacroSecurityTP::ActivatePage()
89 MacroSecurityTP::~MacroSecurityTP()
93 MacroSecurityLevelTP::MacroSecurityLevelTP(weld::Container* pParent, MacroSecurity* pDlg)
94 : MacroSecurityTP(pParent, "xmlsec/ui/securitylevelpage.ui", "SecurityLevelPage", pDlg)
95 , m_xVeryHighRB(m_xBuilder->weld_radio_button("vhigh"))
96 , m_xHighRB(m_xBuilder->weld_radio_button("high"))
97 , m_xMediumRB(m_xBuilder->weld_radio_button("med"))
98 , m_xLowRB(m_xBuilder->weld_radio_button("low"))
99 , m_xVHighImg(m_xBuilder->weld_widget("vhighimg"))
100 , m_xHighImg(m_xBuilder->weld_widget("highimg"))
101 , m_xMedImg(m_xBuilder->weld_widget("medimg"))
102 , m_xLowImg(m_xBuilder->weld_widget("lowimg"))
104 m_xLowRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
105 m_xMediumRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
106 m_xHighRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
107 m_xVeryHighRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
109 int nPrefWidth(std::max({m_xVeryHighRB->get_preferred_size().Width(),
110 m_xHighRB->get_preferred_size().Width(),
111 m_xMediumRB->get_preferred_size().Width(),
112 m_xLowRB->get_preferred_size().Width()}));
113 int nMaxWidth = m_xLowRB->get_approximate_digit_width() * 60;
114 if (nPrefWidth > nMaxWidth)
116 m_xLowRB->set_label_line_wrap(true);
117 m_xLowRB->set_size_request(nMaxWidth, -1);
118 m_xMediumRB->set_label_line_wrap(true);
119 m_xMediumRB->set_size_request(nMaxWidth, -1);
120 m_xHighRB->set_label_line_wrap(true);
121 m_xHighRB->set_size_request(nMaxWidth, -1);
122 m_xVeryHighRB->set_label_line_wrap(true);
123 m_xVeryHighRB->set_size_request(nMaxWidth, -1);
126 mnCurLevel = static_cast<sal_uInt16>(m_pDlg->m_aSecOptions.GetMacroSecurityLevel());
127 bool bReadonly = m_pDlg->m_aSecOptions.IsReadOnly( SvtSecurityOptions::EOption::MacroSecLevel );
129 weld::RadioButton* pCheck = nullptr;
130 weld::Widget* pImage = nullptr;
131 switch (mnCurLevel)
133 case 3:
134 pCheck = m_xVeryHighRB.get();
135 pImage = m_xVHighImg.get();
136 break;
137 case 2:
138 pCheck = m_xHighRB.get();
139 pImage = m_xHighImg.get();
140 break;
141 case 1:
142 pCheck = m_xMediumRB.get();
143 pImage = m_xMedImg.get();
144 break;
145 case 0:
146 pCheck = m_xLowRB.get();
147 pImage = m_xLowImg.get();
148 break;
150 if (pCheck)
151 pCheck->set_active(true);
152 else
154 OSL_FAIL("illegal macro security level");
156 if (bReadonly && pImage)
158 pImage->show();
159 m_xVeryHighRB->set_sensitive(false);
160 m_xHighRB->set_sensitive(false);
161 m_xMediumRB->set_sensitive(false);
162 m_xLowRB->set_sensitive(false);
166 IMPL_LINK_NOARG(MacroSecurityLevelTP, RadioButtonHdl, weld::ToggleButton&, void)
168 sal_uInt16 nNewLevel = 0;
169 if( m_xVeryHighRB->get_active() )
170 nNewLevel = 3;
171 else if( m_xHighRB->get_active() )
172 nNewLevel = 2;
173 else if( m_xMediumRB->get_active() )
174 nNewLevel = 1;
176 if ( nNewLevel != mnCurLevel )
178 mnCurLevel = nNewLevel;
179 m_pDlg->EnableReset();
183 void MacroSecurityLevelTP::ClosePage()
185 m_pDlg->m_aSecOptions.SetMacroSecurityLevel( mnCurLevel );
188 void MacroSecurityTrustedSourcesTP::ImplCheckButtons()
190 bool bCertSelected = m_xTrustCertLB->get_selected_index() != -1;
191 m_xViewCertPB->set_sensitive( bCertSelected );
192 m_xRemoveCertPB->set_sensitive( bCertSelected && !mbAuthorsReadonly);
194 bool bLocationSelected = m_xTrustFileLocLB->get_selected_index() != -1;
195 m_xRemoveLocPB->set_sensitive( bLocationSelected && !mbURLsReadonly);
199 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, ViewCertPBHdl, weld::Button&, void)
201 int nEntry = m_xTrustCertLB->get_selected_index();
202 if (nEntry != -1)
204 sal_uInt16 nSelected = m_xTrustCertLB->get_id(nEntry).toUInt32();
206 uno::Reference< css::security::XCertificate > xCert = m_pDlg->m_xSecurityEnvironment->getCertificate( m_aTrustedAuthors[nSelected][0], xmlsecurity::numericStringToBigInteger( m_aTrustedAuthors[nSelected][1] ) );
208 // If we don't get it, create it from signature data:
209 if ( !xCert.is() )
210 xCert = m_pDlg->m_xSecurityEnvironment->createCertificateFromAscii( m_aTrustedAuthors[nSelected][2] ) ;
212 SAL_WARN_IF( !xCert.is(), "xmlsecurity.dialogs", "*MacroSecurityTrustedSourcesTP::ViewCertPBHdl(): Certificate not found and can't be created!" );
214 if ( xCert.is() )
216 CertificateViewer aViewer(m_pDlg->getDialog(), m_pDlg->m_xSecurityEnvironment, xCert, false, nullptr);
217 aViewer.run();
222 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, RemoveCertPBHdl, weld::Button&, void)
224 int nEntry = m_xTrustCertLB->get_selected_index();
225 if (nEntry != -1)
227 sal_uInt16 nAuthor = m_xTrustCertLB->get_id(nEntry).toUInt32();
228 ::comphelper::removeElementAt( m_aTrustedAuthors, nAuthor );
230 FillCertLB();
231 ImplCheckButtons();
235 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, AddLocPBHdl, weld::Button&, void)
239 uno::Reference < uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
240 uno::Reference < ui::dialogs::XFolderPicker2 > xFolderPicker = ui::dialogs::FolderPicker::create(xContext);
242 short nRet = xFolderPicker->execute();
244 if( ui::dialogs::ExecutableDialogResults::OK != nRet )
245 return;
247 OUString aPathStr = xFolderPicker->getDirectory();
248 INetURLObject aNewObj( aPathStr );
249 aNewObj.removeFinalSlash();
251 // then the new path also a URL else system path
252 OUString aSystemFileURL = ( aNewObj.GetProtocol() != INetProtocol::NotValid ) ?
253 aPathStr : aNewObj.getFSysPath( FSysStyle::Detect );
255 OUString aNewPathStr(aSystemFileURL);
257 if ( osl::FileBase::getSystemPathFromFileURL( aSystemFileURL, aSystemFileURL ) == osl::FileBase::E_None )
258 aNewPathStr = aSystemFileURL;
260 if (m_xTrustFileLocLB->find_text(aNewPathStr) == -1)
261 m_xTrustFileLocLB->append_text(aNewPathStr);
263 ImplCheckButtons();
265 catch( uno::Exception& )
267 TOOLS_WARN_EXCEPTION( "xmlsecurity.dialogs", "MacroSecurityTrustedSourcesTP::AddLocPBHdl(): exception from folder picker" );
271 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, RemoveLocPBHdl, weld::Button&, void)
273 sal_Int32 nSel = m_xTrustFileLocLB->get_selected_index();
274 if (nSel != -1)
276 m_xTrustFileLocLB->remove(nSel);
277 // Trusted Path could not be removed (#i33584#)
278 // after remove an entry, select another one if exists
279 int nNewCount = m_xTrustFileLocLB->n_children();
280 if (nNewCount > 0)
282 if (nSel >= nNewCount)
283 nSel = nNewCount - 1;
284 m_xTrustFileLocLB->select(nSel);
286 ImplCheckButtons();
290 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, TrustCertLBSelectHdl, weld::TreeView&, void)
292 ImplCheckButtons();
295 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, TrustFileLocLBSelectHdl, weld::TreeView&, void)
297 ImplCheckButtons();
300 void MacroSecurityTrustedSourcesTP::FillCertLB()
302 m_xTrustCertLB->clear();
304 sal_uInt32 nEntries = m_aTrustedAuthors.getLength();
306 if ( nEntries && m_pDlg->m_xSecurityEnvironment.is() )
308 for( sal_uInt32 nEntry = 0 ; nEntry < nEntries ; ++nEntry )
310 css::uno::Sequence< OUString >& rEntry = m_aTrustedAuthors[ nEntry ];
312 // create from RawData
313 uno::Reference< css::security::XCertificate > xCert = m_pDlg->m_xSecurityEnvironment->createCertificateFromAscii( rEntry[ 2 ] );
315 m_xTrustCertLB->append(OUString::number(nEntry), xmlsec::GetContentPart(xCert->getSubjectName()));
316 m_xTrustCertLB->set_text(nEntry, xmlsec::GetContentPart(xCert->getIssuerName()), 1);
317 m_xTrustCertLB->set_text(nEntry, utl::GetDateTimeString(xCert->getNotValidAfter()), 2);
322 MacroSecurityTrustedSourcesTP::MacroSecurityTrustedSourcesTP(weld::Container* pParent, MacroSecurity* pDlg)
323 : MacroSecurityTP(pParent, "xmlsec/ui/securitytrustpage.ui", "SecurityTrustPage", pDlg)
324 , m_xTrustCertROFI(m_xBuilder->weld_image("lockcertimg"))
325 , m_xTrustCertLB(m_xBuilder->weld_tree_view("certificates"))
326 , m_xViewCertPB(m_xBuilder->weld_button("viewcert"))
327 , m_xRemoveCertPB(m_xBuilder->weld_button("removecert"))
328 , m_xTrustFileROFI(m_xBuilder->weld_image("lockfileimg"))
329 , m_xTrustFileLocLB(m_xBuilder->weld_tree_view("locations"))
330 , m_xAddLocPB(m_xBuilder->weld_button("addfile"))
331 , m_xRemoveLocPB(m_xBuilder->weld_button("removefile"))
333 auto nColWidth = m_xTrustCertLB->get_approximate_digit_width() * 12;
334 std::vector<int> aWidths;
335 aWidths.push_back(nColWidth * 2);
336 aWidths.push_back(nColWidth * 2);
337 m_xTrustCertLB->set_column_fixed_widths(aWidths);
338 m_xTrustCertLB->set_size_request(nColWidth * 5.5, m_xTrustCertLB->get_height_rows(5));
340 m_xTrustCertLB->connect_changed( LINK( this, MacroSecurityTrustedSourcesTP, TrustCertLBSelectHdl ) );
341 m_xViewCertPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, ViewCertPBHdl ) );
342 m_xViewCertPB->set_sensitive(false);
343 m_xRemoveCertPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, RemoveCertPBHdl ) );
344 m_xRemoveCertPB->set_sensitive(false);
346 m_xTrustFileLocLB->connect_changed( LINK( this, MacroSecurityTrustedSourcesTP, TrustFileLocLBSelectHdl ) );
347 m_xTrustFileLocLB->set_size_request(nColWidth * 5, m_xTrustFileLocLB->get_height_rows(5));
348 m_xAddLocPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, AddLocPBHdl ) );
349 m_xRemoveLocPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, RemoveLocPBHdl ) );
350 m_xRemoveLocPB->set_sensitive(false);
352 m_aTrustedAuthors = m_pDlg->m_aSecOptions.GetTrustedAuthors();
353 mbAuthorsReadonly = m_pDlg->m_aSecOptions.IsReadOnly( SvtSecurityOptions::EOption::MacroTrustedAuthors );
354 m_xTrustCertROFI->set_visible(mbAuthorsReadonly);
355 m_xTrustCertLB->set_sensitive(!mbAuthorsReadonly);
357 FillCertLB();
359 const css::uno::Sequence< OUString > aSecureURLs = m_pDlg->m_aSecOptions.GetSecureURLs();
360 mbURLsReadonly = m_pDlg->m_aSecOptions.IsReadOnly( SvtSecurityOptions::EOption::SecureUrls );
361 m_xTrustFileROFI->set_visible(mbURLsReadonly);
362 m_xTrustFileLocLB->set_sensitive(!mbURLsReadonly);
363 m_xAddLocPB->set_sensitive(!mbURLsReadonly);
365 for (const auto& rSecureURL : aSecureURLs)
367 OUString aSystemFileURL( rSecureURL );
368 osl::FileBase::getSystemPathFromFileURL( aSystemFileURL, aSystemFileURL );
369 m_xTrustFileLocLB->append_text(aSystemFileURL);
373 void MacroSecurityTrustedSourcesTP::ActivatePage()
375 m_pDlg->EnableReset( false );
376 FillCertLB();
379 void MacroSecurityTrustedSourcesTP::ClosePage()
381 sal_Int32 nEntryCnt = m_xTrustFileLocLB->n_children();
382 if( nEntryCnt )
384 css::uno::Sequence< OUString > aSecureURLs( nEntryCnt );
385 for (sal_Int32 i = 0; i < nEntryCnt; ++i)
387 OUString aURL(m_xTrustFileLocLB->get_text(i));
388 osl::FileBase::getFileURLFromSystemPath( aURL, aURL );
389 aSecureURLs[ i ] = aURL;
392 m_pDlg->m_aSecOptions.SetSecureURLs( aSecureURLs );
394 // Trusted Path could not be removed (#i33584#)
395 // don't forget to remove the old saved SecureURLs
396 else
397 m_pDlg->m_aSecOptions.SetSecureURLs( css::uno::Sequence< OUString >() );
399 m_pDlg->m_aSecOptions.SetTrustedAuthors( m_aTrustedAuthors );
402 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */