tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / xmlsecurity / source / dialogs / macrosecurity.cxx
blob6e11410afe8b4f56e8226347ded7a5dfdb84ece6
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>
24 #include <resourcemanager.hxx>
25 #include <strings.hrc>
27 #include <o3tl/safeint.hxx>
28 #include <osl/file.hxx>
29 #include <sal/log.hxx>
31 #include <com/sun/star/ui/dialogs/XFolderPicker2.hpp>
32 #include <com/sun/star/xml/crypto/XSecurityEnvironment.hpp>
33 #include <comphelper/processfactory.hxx>
34 #include <comphelper/xmlsechelper.hxx>
35 #include <com/sun/star/uno/Exception.hpp>
36 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
37 #include <sfx2/filedlghelper.hxx>
38 #include <comphelper/diagnose_ex.hxx>
39 #include <tools/urlobj.hxx>
40 #include <unotools/datetime.hxx>
42 #include <utility>
43 #include <vcl/svapp.hxx>
45 using namespace comphelper;
46 using namespace ::com::sun::star;
49 IMPL_LINK_NOARG(MacroSecurity, OkBtnHdl, weld::Button&, void)
51 m_xLevelTP->ClosePage();
52 m_xTrustSrcTP->ClosePage();
53 m_xDialog->response(RET_OK);
56 MacroSecurity::MacroSecurity(weld::Window* pParent,
57 css::uno::Reference<css::xml::crypto::XSecurityEnvironment> xSecurityEnvironment)
58 : GenericDialogController(pParent, u"xmlsec/ui/macrosecuritydialog.ui"_ustr, u"MacroSecurityDialog"_ustr)
59 , m_xSecurityEnvironment(std::move(xSecurityEnvironment))
60 , m_xTabCtrl(m_xBuilder->weld_notebook(u"tabcontrol"_ustr))
61 , m_xOkBtn(m_xBuilder->weld_button(u"ok"_ustr))
62 , m_xResetBtn(m_xBuilder->weld_button(u"reset"_ustr))
64 m_xTabCtrl->connect_enter_page(LINK(this, MacroSecurity, ActivatePageHdl));
66 m_xLevelTP.reset(new MacroSecurityLevelTP(m_xTabCtrl->get_page(u"SecurityLevelPage"_ustr), this));
67 m_xTrustSrcTP.reset(new MacroSecurityTrustedSourcesTP(m_xTabCtrl->get_page(u"SecurityTrustPage"_ustr), this));
69 m_xTabCtrl->set_current_page(u"SecurityLevelPage"_ustr);
70 m_xOkBtn->connect_clicked(LINK(this, MacroSecurity, OkBtnHdl));
73 IMPL_LINK(MacroSecurity, ActivatePageHdl, const OUString&, rPage, void)
75 if (rPage == "SecurityLevelPage")
76 m_xLevelTP->ActivatePage();
77 else if (rPage == "SecurityTrustPage")
78 m_xTrustSrcTP->ActivatePage();
81 MacroSecurityTP::MacroSecurityTP(weld::Container* pParent, const OUString& rUIXMLDescription,
82 const OUString& rID, MacroSecurity* pDlg)
83 : m_xBuilder(Application::CreateBuilder(pParent, rUIXMLDescription))
84 , m_xContainer(m_xBuilder->weld_container(rID))
85 , m_pDlg(pDlg)
89 void MacroSecurityTP::ActivatePage()
93 MacroSecurityTP::~MacroSecurityTP()
97 MacroSecurityLevelTP::MacroSecurityLevelTP(weld::Container* pParent, MacroSecurity* pDlg)
98 : MacroSecurityTP(pParent, u"xmlsec/ui/securitylevelpage.ui"_ustr, u"SecurityLevelPage"_ustr, pDlg)
99 , m_xVeryHighRB(m_xBuilder->weld_radio_button(u"vhigh"_ustr))
100 , m_xHighRB(m_xBuilder->weld_radio_button(u"high"_ustr))
101 , m_xMediumRB(m_xBuilder->weld_radio_button(u"med"_ustr))
102 , m_xLowRB(m_xBuilder->weld_radio_button(u"low"_ustr))
103 , m_xVHighImg(m_xBuilder->weld_widget(u"vhighimg"_ustr))
104 , m_xHighImg(m_xBuilder->weld_widget(u"highimg"_ustr))
105 , m_xMedImg(m_xBuilder->weld_widget(u"medimg"_ustr))
106 , m_xLowImg(m_xBuilder->weld_widget(u"lowimg"_ustr))
107 , m_xWarningLb(m_xBuilder->weld_label(u"warningmsg"_ustr))
108 , m_xWarningImg(m_xBuilder->weld_image(u"warningimg"_ustr))
109 , m_xWarningBox(m_xBuilder->weld_box(u"warningbox"_ustr))
111 m_xLowRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
112 m_xMediumRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
113 m_xHighRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
114 m_xVeryHighRB->connect_toggled( LINK( this, MacroSecurityLevelTP, RadioButtonHdl ) );
116 int nPrefWidth(std::max({m_xVeryHighRB->get_preferred_size().Width(),
117 m_xHighRB->get_preferred_size().Width(),
118 m_xMediumRB->get_preferred_size().Width(),
119 m_xLowRB->get_preferred_size().Width()}));
120 int nMaxWidth = m_xLowRB->get_approximate_digit_width() * 60;
121 if (nPrefWidth > nMaxWidth)
123 m_xLowRB->set_label_wrap(true);
124 m_xLowRB->set_size_request(nMaxWidth, -1);
125 m_xMediumRB->set_label_wrap(true);
126 m_xMediumRB->set_size_request(nMaxWidth, -1);
127 m_xHighRB->set_label_wrap(true);
128 m_xHighRB->set_size_request(nMaxWidth, -1);
129 m_xVeryHighRB->set_label_wrap(true);
130 m_xVeryHighRB->set_size_request(nMaxWidth, -1);
133 mnCurLevel = static_cast<sal_uInt16>(SvtSecurityOptions::GetMacroSecurityLevel());
134 mnInitialLevel = mnCurLevel;
135 bool bReadonly = SvtSecurityOptions::IsReadOnly( SvtSecurityOptions::EOption::MacroSecLevel );
137 weld::RadioButton* pCheck = nullptr;
138 weld::Widget* pImage = nullptr;
139 switch (mnCurLevel)
141 case 3:
142 pCheck = m_xVeryHighRB.get();
143 pImage = m_xVHighImg.get();
144 break;
145 case 2:
146 pCheck = m_xHighRB.get();
147 pImage = m_xHighImg.get();
148 break;
149 case 1:
150 pCheck = m_xMediumRB.get();
151 pImage = m_xMedImg.get();
152 break;
153 case 0:
154 pCheck = m_xLowRB.get();
155 pImage = m_xLowImg.get();
156 break;
158 if (pCheck)
159 pCheck->set_active(true);
160 else
162 OSL_FAIL("illegal macro security level");
164 if (bReadonly && pImage)
166 pImage->show();
167 m_xVeryHighRB->set_sensitive(false);
168 m_xHighRB->set_sensitive(false);
169 m_xMediumRB->set_sensitive(false);
170 m_xLowRB->set_sensitive(false);
173 SetWarningLabel(u""_ustr);
174 // Use same font color as in InfobarType::WARNING
175 m_xWarningLb->set_font_color(Color(0x70, 0x43, 0x00));
176 m_xWarningImg->set_size_request(24, 24);
179 void MacroSecurityLevelTP::SetWarningLabel(const OUString& sMsg)
181 m_xWarningLb->set_label(sMsg);
182 if (!sMsg.isEmpty())
184 m_xWarningLb->show();
185 m_xWarningImg->show();
186 m_xWarningBox->set_background(Color(0xFE, 0xEF, 0xB3));
188 else
190 m_xWarningLb->hide();
191 m_xWarningImg->hide();
192 m_xWarningBox->set_background(COL_TRANSPARENT);
196 IMPL_LINK_NOARG(MacroSecurityLevelTP, RadioButtonHdl, weld::Toggleable&, void)
198 sal_uInt16 nNewLevel = 0;
199 if( m_xVeryHighRB->get_active() )
200 nNewLevel = 3;
201 else if( m_xHighRB->get_active() )
202 nNewLevel = 2;
203 else if( m_xMediumRB->get_active() )
204 nNewLevel = 1;
206 if ( nNewLevel != mnCurLevel )
208 mnCurLevel = nNewLevel;
209 m_pDlg->EnableReset();
212 // Show warning message if a different security level is chosen
213 if (nNewLevel != mnInitialLevel)
214 SetWarningLabel(XsResId(STR_RELOAD_FILE_WARNING));
215 else
217 SetWarningLabel(u""_ustr);
221 void MacroSecurityLevelTP::ClosePage()
223 SvtSecurityOptions::SetMacroSecurityLevel( mnCurLevel );
226 void MacroSecurityTrustedSourcesTP::ImplCheckButtons()
228 bool bCertSelected = m_xTrustCertLB->get_selected_index() != -1;
229 m_xViewCertPB->set_sensitive( bCertSelected );
230 m_xRemoveCertPB->set_sensitive( bCertSelected && !mbAuthorsReadonly);
232 bool bLocationSelected = m_xTrustFileLocLB->get_selected_index() != -1;
233 m_xRemoveLocPB->set_sensitive( bLocationSelected && !mbURLsReadonly);
236 void MacroSecurityTrustedSourcesTP::ShowBrokenCertificateError(std::u16string_view rData)
238 OUString aMsg = XsResId(STR_BROKEN_MACRO_CERTIFICATE_DATA);
239 aMsg = aMsg.replaceFirst("%{data}", rData);
240 std::unique_ptr<weld::MessageDialog> xErrorBox(Application::CreateMessageDialog(m_pDlg->getDialog(),
241 VclMessageType::Error, VclButtonsType::Ok, aMsg));
242 xErrorBox->run();
245 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, ViewCertPBHdl, weld::Button&, void)
247 int nEntry = m_xTrustCertLB->get_selected_index();
248 if (nEntry == -1)
249 return;
251 const sal_uInt16 nSelected = m_xTrustCertLB->get_id(nEntry).toUInt32();
252 uno::Reference< css::security::XCertificate > xCert;
255 xCert = m_pDlg->m_xSecurityEnvironment->getCertificate(m_aTrustedAuthors[nSelected].SubjectName,
256 xmlsecurity::numericStringToBigInteger(m_aTrustedAuthors[nSelected].SerialNumber));
258 catch (...)
260 TOOLS_WARN_EXCEPTION("xmlsecurity.dialogs", "matching certificate not found for: " << m_aTrustedAuthors[nSelected].SubjectName);
263 if (!xCert.is())
267 xCert = m_pDlg->m_xSecurityEnvironment->createCertificateFromAscii(m_aTrustedAuthors[nSelected].RawData);
269 catch (...)
271 TOOLS_WARN_EXCEPTION("xmlsecurity.dialogs", "certificate data couldn't be parsed: " << m_aTrustedAuthors[nSelected].RawData);
275 if ( xCert.is() )
277 CertificateViewer aViewer(m_pDlg->getDialog(), m_pDlg->m_xSecurityEnvironment, xCert, false, nullptr);
278 aViewer.run();
280 else
281 // should never happen, as we parsed the certificate data when we added it!
282 ShowBrokenCertificateError(m_aTrustedAuthors[nSelected].RawData);
285 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, RemoveCertPBHdl, weld::Button&, void)
287 int nEntry = m_xTrustCertLB->get_selected_index();
288 if (nEntry != -1)
290 sal_uInt16 nAuthor = m_xTrustCertLB->get_id(nEntry).toUInt32();
291 m_aTrustedAuthors.erase(m_aTrustedAuthors.begin() + nAuthor);
293 FillCertLB();
294 ImplCheckButtons();
298 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, AddLocPBHdl, weld::Button&, void)
302 const uno::Reference < uno::XComponentContext >& xContext( ::comphelper::getProcessComponentContext() );
303 uno::Reference < ui::dialogs::XFolderPicker2 > xFolderPicker = sfx2::createFolderPicker(xContext, m_pDlg->getDialog());
305 short nRet = xFolderPicker->execute();
307 if( ui::dialogs::ExecutableDialogResults::OK != nRet )
308 return;
310 OUString aPathStr = xFolderPicker->getDirectory();
311 INetURLObject aNewObj( aPathStr );
312 aNewObj.removeFinalSlash();
314 // then the new path also a URL else system path
315 OUString aSystemFileURL = ( aNewObj.GetProtocol() != INetProtocol::NotValid ) ?
316 aPathStr : aNewObj.getFSysPath( FSysStyle::Detect );
318 OUString aNewPathStr(aSystemFileURL);
320 if ( osl::FileBase::getSystemPathFromFileURL( aSystemFileURL, aSystemFileURL ) == osl::FileBase::E_None )
321 aNewPathStr = aSystemFileURL;
323 if (m_xTrustFileLocLB->find_text(aNewPathStr) == -1)
324 m_xTrustFileLocLB->append_text(aNewPathStr);
326 ImplCheckButtons();
328 catch( uno::Exception& )
330 TOOLS_WARN_EXCEPTION( "xmlsecurity.dialogs", "MacroSecurityTrustedSourcesTP::AddLocPBHdl(): exception from folder picker" );
334 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, RemoveLocPBHdl, weld::Button&, void)
336 sal_Int32 nSel = m_xTrustFileLocLB->get_selected_index();
337 if (nSel == -1)
338 return;
340 m_xTrustFileLocLB->remove(nSel);
341 // Trusted Path could not be removed (#i33584#)
342 // after remove an entry, select another one if exists
343 int nNewCount = m_xTrustFileLocLB->n_children();
344 if (nNewCount > 0)
346 if (nSel >= nNewCount)
347 nSel = nNewCount - 1;
348 m_xTrustFileLocLB->select(nSel);
350 ImplCheckButtons();
353 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, TrustCertLBSelectHdl, weld::TreeView&, void)
355 ImplCheckButtons();
358 IMPL_LINK_NOARG(MacroSecurityTrustedSourcesTP, TrustFileLocLBSelectHdl, weld::TreeView&, void)
360 ImplCheckButtons();
363 void MacroSecurityTrustedSourcesTP::FillCertLB(const bool bShowWarnings)
365 m_xTrustCertLB->clear();
367 sal_uInt32 nEntries = m_aTrustedAuthors.size();
369 if ( !(nEntries && m_pDlg->m_xSecurityEnvironment.is()) )
370 return;
372 for( sal_uInt32 nEntry = 0 ; nEntry < nEntries ; ++nEntry )
374 SvtSecurityOptions::Certificate& rEntry = m_aTrustedAuthors[ nEntry ];
378 // create from RawData
379 uno::Reference< css::security::XCertificate > xCert = m_pDlg->m_xSecurityEnvironment->createCertificateFromAscii(rEntry.RawData);
380 m_xTrustCertLB->append(OUString::number(nEntry), xmlsec::GetContentPart(xCert->getSubjectName(), xCert->getCertificateKind()));
381 m_xTrustCertLB->set_text(nEntry, xmlsec::GetContentPart(xCert->getIssuerName(), xCert->getCertificateKind()), 1);
382 m_xTrustCertLB->set_text(nEntry, utl::GetDateTimeString(xCert->getNotValidAfter()), 2);
384 catch (...)
386 if (bShowWarnings)
388 TOOLS_WARN_EXCEPTION("xmlsecurity.dialogs", "certificate data couldn't be parsed: " << rEntry.RawData);
389 OUString sData = rEntry.RawData;
390 css::uno::Any tools_warn_exception(DbgGetCaughtException());
391 OUString sException = OStringToOUString(exceptionToString(tools_warn_exception), RTL_TEXTENCODING_UTF8);
392 if (!sException.isEmpty())
393 sData += " / " + sException;
394 ShowBrokenCertificateError(sData);
400 MacroSecurityTrustedSourcesTP::MacroSecurityTrustedSourcesTP(weld::Container* pParent, MacroSecurity* pDlg)
401 : MacroSecurityTP(pParent, u"xmlsec/ui/securitytrustpage.ui"_ustr, u"SecurityTrustPage"_ustr, pDlg)
402 , m_xTrustCertROFI(m_xBuilder->weld_image(u"lockcertimg"_ustr))
403 , m_xTrustCertLB(m_xBuilder->weld_tree_view(u"certificates"_ustr))
404 , m_xViewCertPB(m_xBuilder->weld_button(u"viewcert"_ustr))
405 , m_xRemoveCertPB(m_xBuilder->weld_button(u"removecert"_ustr))
406 , m_xTrustFileROFI(m_xBuilder->weld_image(u"lockfileimg"_ustr))
407 , m_xTrustFileLocLB(m_xBuilder->weld_tree_view(u"locations"_ustr))
408 , m_xAddLocPB(m_xBuilder->weld_button(u"addfile"_ustr))
409 , m_xRemoveLocPB(m_xBuilder->weld_button(u"removefile"_ustr))
411 auto nColWidth = m_xTrustCertLB->get_approximate_digit_width() * 12;
412 std::vector<int> aWidths
414 o3tl::narrowing<int>(nColWidth * 2),
415 o3tl::narrowing<int>(nColWidth * 2)
417 m_xTrustCertLB->set_column_fixed_widths(aWidths);
418 m_xTrustCertLB->set_size_request(nColWidth * 5.5, m_xTrustCertLB->get_height_rows(5));
420 m_xTrustCertLB->connect_selection_changed(
421 LINK(this, MacroSecurityTrustedSourcesTP, TrustCertLBSelectHdl));
422 m_xViewCertPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, ViewCertPBHdl ) );
423 m_xViewCertPB->set_sensitive(false);
424 m_xRemoveCertPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, RemoveCertPBHdl ) );
425 m_xRemoveCertPB->set_sensitive(false);
427 m_xTrustFileLocLB->connect_selection_changed(
428 LINK(this, MacroSecurityTrustedSourcesTP, TrustFileLocLBSelectHdl));
429 m_xTrustFileLocLB->set_size_request(nColWidth * 5, m_xTrustFileLocLB->get_height_rows(5));
430 m_xAddLocPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, AddLocPBHdl ) );
431 m_xRemoveLocPB->connect_clicked( LINK( this, MacroSecurityTrustedSourcesTP, RemoveLocPBHdl ) );
432 m_xRemoveLocPB->set_sensitive(false);
434 m_aTrustedAuthors = SvtSecurityOptions::GetTrustedAuthors();
435 mbAuthorsReadonly = SvtSecurityOptions::IsReadOnly( SvtSecurityOptions::EOption::MacroTrustedAuthors );
436 m_xTrustCertROFI->set_visible(mbAuthorsReadonly);
438 FillCertLB(true);
440 std::vector< OUString > aSecureURLs = SvtSecurityOptions::GetSecureURLs();
441 mbURLsReadonly = SvtSecurityOptions::IsReadOnly( SvtSecurityOptions::EOption::SecureUrls );
442 m_xTrustFileROFI->set_visible(mbURLsReadonly);
443 m_xAddLocPB->set_sensitive(!mbURLsReadonly);
445 for (const auto& rSecureURL : aSecureURLs)
447 OUString aSystemFileURL( rSecureURL );
448 osl::FileBase::getSystemPathFromFileURL( aSystemFileURL, aSystemFileURL );
449 m_xTrustFileLocLB->append_text(aSystemFileURL);
453 void MacroSecurityTrustedSourcesTP::ActivatePage()
455 m_pDlg->EnableReset( false );
456 FillCertLB();
459 void MacroSecurityTrustedSourcesTP::ClosePage()
461 sal_Int32 nEntryCnt = m_xTrustFileLocLB->n_children();
462 if( nEntryCnt )
464 std::vector< OUString > aSecureURLs;
465 for (sal_Int32 i = 0; i < nEntryCnt; ++i)
467 OUString aURL(m_xTrustFileLocLB->get_text(i));
468 osl::FileBase::getFileURLFromSystemPath( aURL, aURL );
469 aSecureURLs.push_back(aURL);
472 SvtSecurityOptions::SetSecureURLs( std::move(aSecureURLs) );
474 // Trusted Path could not be removed (#i33584#)
475 // don't forget to remove the old saved SecureURLs
476 else
477 SvtSecurityOptions::SetSecureURLs( std::vector< OUString >() );
479 SvtSecurityOptions::SetTrustedAuthors( m_aTrustedAuthors );
482 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */