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