LibreOffice Module cui (master)  1
certpath.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 
10 #include <officecfg/Office/Common.hxx>
11 #include <osl/file.hxx>
12 #include <osl/security.hxx>
13 #include <sfx2/filedlghelper.hxx>
14 #include <tools/diagnose_ex.h>
15 #include "certpath.hxx"
16 
17 #include <com/sun/star/xml/crypto/NSSInitializer.hpp>
18 #include <com/sun/star/ui/dialogs/ExecutableDialogResults.hpp>
19 #include <com/sun/star/ui/dialogs/FolderPicker.hpp>
21 
22 using namespace ::com::sun::star;
23 
25  : GenericDialogController(pParent, "cui/ui/certdialog.ui", "CertDialog")
26  , m_xManualButton(m_xBuilder->weld_button("add"))
27  , m_xOKButton(m_xBuilder->weld_button("ok"))
28  , m_xCertPathList(m_xBuilder->weld_tree_view("paths"))
29  , m_sAddDialogText(m_xBuilder->weld_label("certdir")->get_label())
30  , m_sManualLabel(m_xBuilder->weld_label("manual")->get_label())
31 {
32  m_xCertPathList->set_size_request(m_xCertPathList->get_approximate_digit_width() * 70,
33  m_xCertPathList->get_height_rows(6));
34 
35  m_xCertPathList->enable_toggle_buttons(weld::ColumnToggleType::Radio);
36  m_xCertPathList->connect_toggled(LINK(this, CertPathDialog, CheckHdl_Impl));
37 
38  m_xManualButton->connect_clicked( LINK( this, CertPathDialog, ManualHdl_Impl ) );
39  m_xOKButton->connect_clicked( LINK( this, CertPathDialog, OKHdl_Impl ) );
40 }
41 
43 {
44  m_xCertPathList->clear();
45  m_xCertPathList->set_sensitive(true);
46 
47  try
48  {
49  uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
50  uno::Reference<xml::crypto::XNSSInitializer> xCipherContextSupplier = xml::crypto::NSSInitializer::create(xContext);
51 
52  OUString sActivePath = xCipherContextSupplier->getNSSPath();
53  auto aProductList = xCipherContextSupplier->getNSSProfiles();
54 
55  // these map to the integer values of mozilla::MozillaProductType
56  const char* const productNames[4] = {
57  "",
58  "mozilla",
59  "firefox",
60  "thunderbird"
61  };
62 
63  for (const auto& rNSSProfile : std::as_const(aProductList))
64  {
65  if (rNSSProfile.Type == mozilla::MozillaProductType_Default)
66  {
67  if (rNSSProfile.Name == "MOZILLA_CERTIFICATE_FOLDER" && !rNSSProfile.Path.isEmpty())
68  {
69  AddCertPath("$MOZILLA_CERTIFICATE_FOLDER", rNSSProfile.Path);
70  m_xCertPathList->set_sensitive(false);
71  }
72  else if (rNSSProfile.Name == "MANUAL")
73  AddManualCertPath(rNSSProfile.Path);
74  }
75  else
76  {
77  OUString sEntry = OUString::createFromAscii(
78  productNames[static_cast<int>(rNSSProfile.Type)]) + ":" + rNSSProfile.Name;
79  AddCertPath(sEntry, rNSSProfile.Path, rNSSProfile.Path == sActivePath);
80  }
81  }
82 
83  OUString sManualCertPath = officecfg::Office::Common::Security::Scripting::ManualCertDir::get();
84  if (!sManualCertPath.isEmpty())
85  AddManualCertPath(sManualCertPath, false);
86  }
87  catch (const uno::Exception&)
88  {
89  }
90 }
91 
92 void CertPathDialog::AddManualCertPath(const OUString& sUserSetCertPath, bool bSelect)
93 {
94  if (sUserSetCertPath.isEmpty())
95  return;
96 
97  ::osl::DirectoryItem aUserPathItem;
98  OUString sUserSetCertURLPath;
99  osl::FileBase::getFileURLFromSystemPath(sUserSetCertPath, sUserSetCertURLPath);
100  if (::osl::FileBase::E_None == ::osl::DirectoryItem::get(sUserSetCertURLPath, aUserPathItem))
101  {
102  ::osl::FileStatus aStatus( osl_FileStatus_Mask_Validate );
103  if (::osl::FileBase::E_None == aUserPathItem.getFileStatus(aStatus))
104  // the cert path exists
105  AddCertPath(m_sManualLabel, sUserSetCertPath, bSelect);
106  }
107 }
108 
110 {
111  try
112  {
113  std::shared_ptr< comphelper::ConfigurationChanges > batch(
115  const int nEntry = m_xCertPathList->get_selected_index();
116  officecfg::Office::Common::Security::Scripting::CertDir::set(
117  nEntry == -1 ? OUString() : m_xCertPathList->get_id(nEntry), batch);
118  officecfg::Office::Common::Security::Scripting::ManualCertDir::set(m_sManualPath, batch);
119  batch->commit();
120  }
121  catch (const uno::Exception &)
122  {
123  TOOLS_WARN_EXCEPTION("cui.options", "CertPathDialog::OKHdl_Impl()");
124  }
125 
126  m_xDialog->response(RET_OK);
127 }
128 
130 {
131  int nEntry = m_xCertPathList->get_selected_index();
132  if (nEntry == -1)
133  return true;
134 
135  try
136  {
137  uno::Reference<uno::XComponentContext> xContext = comphelper::getProcessComponentContext();
138  uno::Reference<xml::crypto::XNSSInitializer> xCipherContextSupplier = xml::crypto::NSSInitializer::create(xContext);
139 
140  if (!xCipherContextSupplier->getIsNSSinitialized())
141  return true;
142  return (xCipherContextSupplier->getNSSPath() == m_xCertPathList->get_id(nEntry));
143  }
144  catch (const uno::Exception&)
145  {
146  return false;
147  }
148 }
149 
151 {
152 }
153 
154 IMPL_LINK(CertPathDialog, CheckHdl_Impl, const weld::TreeView::iter_col&, rRowCol, void)
155 {
156  HandleEntryChecked(m_xCertPathList->get_iter_index_in_parent(rRowCol.first));
157 }
158 
160 {
161  const bool bChecked = m_xCertPathList->get_toggle(nRow) == TRISTATE_TRUE;
162  if (bChecked)
163  {
164  // we have radio button behavior -> so uncheck the other entries
165  m_xCertPathList->select(nRow);
166  const int nCount = m_xCertPathList->n_children();
167  for (int i = 0; i < nCount; ++i)
168  {
169  if (i != nRow)
170  m_xCertPathList->set_toggle(i, TRISTATE_FALSE);
171  }
172  }
173 }
174 
175 void CertPathDialog::AddCertPath(const OUString &rProfile, const OUString &rPath, const bool bSelect)
176 {
177  int nRow = -1;
178  for (int i = 0, nCount = m_xCertPathList->n_children(); i < nCount; ++i)
179  {
180  OUString sCertPath = m_xCertPathList->get_id(i);
181  //already exists, just select the original one
182  if (sCertPath == rPath)
183  {
184  const bool bWantSelected = bSelect || m_xCertPathList->get_toggle(i);
185  m_xCertPathList->set_toggle(i, bWantSelected ? TRISTATE_TRUE : TRISTATE_FALSE);
187  return;
188  }
189  else if (m_xCertPathList->get_text(i, 0) == rProfile)
190  nRow = i;
191  }
192 
193  if (m_sManualLabel == rProfile)
194  m_sManualPath = rPath;
195 
196  if (nRow < 0)
197  {
198  m_xCertPathList->append();
199  nRow = m_xCertPathList->n_children() - 1;
200  }
201  m_xCertPathList->set_toggle(nRow, bSelect ? TRISTATE_TRUE : TRISTATE_FALSE);
202  m_xCertPathList->set_text(nRow, rProfile, 0);
203  m_xCertPathList->set_text(nRow, rPath, 1);
204  m_xCertPathList->set_id(nRow, rPath);
205  HandleEntryChecked(nRow);
206 }
207 
209 {
210  try
211  {
212  uno::Reference<ui::dialogs::XFolderPicker2> xFolderPicker = sfx2::createFolderPicker(
214 
215  OUString sURL;
216  if (!m_sManualPath.isEmpty())
217  osl::FileBase::getFileURLFromSystemPath(m_sManualPath, sURL);
218  if (sURL.isEmpty())
219  osl::Security().getHomeDir(sURL);
220  xFolderPicker->setDisplayDirectory(sURL);
221  xFolderPicker->setDescription(m_sAddDialogText);
222 
223  if (xFolderPicker->execute() == ui::dialogs::ExecutableDialogResults::OK)
224  {
225  sURL = xFolderPicker->getDirectory();
226  OUString aPath;
227  if (osl::FileBase::E_None == osl::FileBase::getSystemPathFromFileURL(sURL, aPath))
228  AddCertPath(m_sManualLabel, aPath);
229  }
230  }
231  catch (const uno::Exception &)
232  {
233  TOOLS_WARN_EXCEPTION("cui.options", "");
234  }
235 }
236 
237 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void HandleEntryChecked(int nRow)
Definition: certpath.cxx:159
void AddManualCertPath(const OUString &sUserSetCertPath, bool bSelect=true)
Definition: certpath.cxx:92
TRISTATE_TRUE
std::unique_ptr< weld::Button > m_xOKButton
std::pair< const TreeIter &, int > iter_col
std::unique_ptr< weld::Button > m_xOKButton
Definition: certpath.hxx:17
int nCount
void AddCertPath(const OUString &rProfile, const OUString &rPath, bool bSelect=true)
Definition: certpath.cxx:175
static std::shared_ptr< ConfigurationChanges > create(css::uno::Reference< css::uno::XComponentContext > const &context=comphelper::getProcessComponentContext())
OUString m_sManualPath
Definition: certpath.hxx:21
IMPL_LINK(CertPathDialog, CheckHdl_Impl, const weld::TreeView::iter_col &, rRowCol, void)
Definition: certpath.cxx:154
virtual ~CertPathDialog() override
Definition: certpath.cxx:150
#define TOOLS_WARN_EXCEPTION(area, stream)
std::unique_ptr< weld::TreeView > m_xCertPathList
Definition: certpath.hxx:18
int i
TRISTATE_FALSE
bool isActiveServicePath() const
Definition: certpath.cxx:129
IMPL_LINK_NOARG(CertPathDialog, OKHdl_Impl, weld::Button &, void)
Definition: certpath.cxx:109
css::uno::Reference< css::ui::dialogs::XFolderPicker2 > createFolderPicker(const css::uno::Reference< css::uno::XComponentContext > &rContext, weld::Window *pPreferredParent)
RET_OK
Reference< XExecutableDialog > m_xDialog
Reference< XComponentContext > getProcessComponentContext()
std::unique_ptr< weld::Button > m_xManualButton
Definition: certpath.hxx:16
CertPathDialog(weld::Window *pParent)
Definition: certpath.cxx:24
OUString m_sManualLabel
Definition: certpath.hxx:20