Line data Source code
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 : #include <sal/config.h>
21 :
22 : #include <sal/log.hxx>
23 : #include <unotools/extendedsecurityoptions.hxx>
24 : #include <unotools/configmgr.hxx>
25 : #include <unotools/configitem.hxx>
26 : #include <tools/debug.hxx>
27 : #include <com/sun/star/uno/Any.hxx>
28 : #include <com/sun/star/uno/Sequence.hxx>
29 : #include <rtl/ustrbuf.hxx>
30 : #include <osl/diagnose.h>
31 :
32 : #include <unotools/pathoptions.hxx>
33 :
34 : #include "itemholder1.hxx"
35 :
36 : #include <unordered_map>
37 :
38 : using namespace ::utl;
39 : using namespace ::osl;
40 : using namespace ::com::sun::star::uno;
41 :
42 : #define ROOTNODE_SECURITY OUString("Office.Security")
43 :
44 : #define SECURE_EXTENSIONS_SET OUString("SecureExtensions")
45 : #define EXTENSION_PROPNAME OUString("/Extension")
46 :
47 : #define PROPERTYNAME_HYPERLINKS_OPEN OUString("Hyperlinks/Open")
48 :
49 : #define PROPERTYHANDLE_HYPERLINKS_OPEN 0
50 :
51 : #define PROPERTYCOUNT 1
52 :
53 : typedef std::unordered_map<OUString, sal_Int32, OUStringHash>
54 : ExtensionHashMap;
55 :
56 : class SvtExtendedSecurityOptions_Impl : public ConfigItem
57 : {
58 : public:
59 : SvtExtendedSecurityOptions_Impl();
60 : virtual ~SvtExtendedSecurityOptions_Impl();
61 :
62 : /*-****************************************************************************************************
63 : @short called for notify of configmanager
64 : @descr These method is called from the ConfigManager before application ends or from the
65 : PropertyChangeListener if the sub tree broadcasts changes. You must update your
66 : internal values.
67 :
68 : @seealso baseclass ConfigItem
69 :
70 : @param "seqPropertyNames" is the list of properties which should be updated.
71 : *//*-*****************************************************************************************************/
72 :
73 : virtual void Notify( const Sequence< OUString >& seqPropertyNames ) SAL_OVERRIDE;
74 :
75 0 : SvtExtendedSecurityOptions::OpenHyperlinkMode GetOpenHyperlinkMode() { return m_eOpenHyperlinkMode;}
76 :
77 : private:
78 : virtual void ImplCommit() SAL_OVERRIDE;
79 :
80 : /*-****************************************************************************************************
81 : @short return list of key names of our configuration management which represent oue module tree
82 : @descr These methods return a static const list of key names. We need it to get needed values from our
83 : configuration management.
84 : @return A list of needed configuration keys is returned.
85 : *//*-*****************************************************************************************************/
86 :
87 : static Sequence< OUString > GetPropertyNames();
88 :
89 : /*-****************************************************************************************************
90 : @short Fills the hash map with all extensions known to be secure
91 : @descr These methods fills the given hash map object with all extensions known to be secure.
92 : @param aHashMap
93 : A hash map to be filled with secure extension strings.
94 : *//*-*****************************************************************************************************/
95 : void FillExtensionHashMap( ExtensionHashMap& aHashMap );
96 :
97 : OUString m_aSecureExtensionsSetName;
98 : OUString m_aExtensionPropName;
99 :
100 : SvtExtendedSecurityOptions::OpenHyperlinkMode m_eOpenHyperlinkMode;
101 : bool m_bROOpenHyperlinkMode;
102 : ExtensionHashMap m_aExtensionHashMap;
103 : };
104 :
105 : // constructor
106 :
107 0 : SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl()
108 : // Init baseclasses first
109 : : ConfigItem ( ROOTNODE_SECURITY )
110 : , m_aSecureExtensionsSetName( SECURE_EXTENSIONS_SET )
111 : , m_aExtensionPropName( EXTENSION_PROPNAME )
112 : , m_eOpenHyperlinkMode(SvtExtendedSecurityOptions::OPEN_NEVER)
113 0 : , m_bROOpenHyperlinkMode(false)
114 : // Init member then.
115 : {
116 : // Fill the extension hash map with all secure extension strings
117 0 : FillExtensionHashMap( m_aExtensionHashMap );
118 :
119 0 : Sequence< OUString > seqNames = GetPropertyNames();
120 0 : Sequence< Any > seqValues = GetProperties( seqNames );
121 0 : Sequence< sal_Bool > seqRO = GetReadOnlyStates ( seqNames );
122 :
123 0 : sal_Int32 nPropertyCount = seqValues.getLength();
124 0 : for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
125 : {
126 : // Safe impossible cases.
127 : // Check any for valid value.
128 : DBG_ASSERT( seqValues[nProperty].hasValue(), "SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl()\nInvalid property value detected!\n" );
129 0 : switch( nProperty )
130 : {
131 : case PROPERTYHANDLE_HYPERLINKS_OPEN:
132 : {
133 : DBG_ASSERT( ( seqValues[nProperty].getValueTypeClass() == TypeClass_LONG ), "SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl()\nWho has changed the value type of 'Hyperlink/Open'?" );
134 :
135 0 : sal_Int32 nMode = SvtExtendedSecurityOptions::OPEN_WITHSECURITYCHECK;
136 0 : if ( seqValues[nProperty] >>= nMode )
137 0 : m_eOpenHyperlinkMode = (SvtExtendedSecurityOptions::OpenHyperlinkMode)nMode;
138 : else {
139 : OSL_FAIL("Wrong type for Open mode!");
140 : }
141 0 : m_bROOpenHyperlinkMode = seqRO[nProperty];
142 : }
143 0 : break;
144 : }
145 : }
146 :
147 : // Enable notification mechanism of our baseclass.
148 : // We need it to get information about changes outside these class on our used configuration keys!
149 0 : Sequence< OUString > seqNotifyNames( 1 );
150 0 : seqNotifyNames[0] = m_aSecureExtensionsSetName;
151 0 : EnableNotification( seqNotifyNames );
152 0 : }
153 :
154 : // destructor
155 :
156 0 : SvtExtendedSecurityOptions_Impl::~SvtExtendedSecurityOptions_Impl()
157 : {
158 : assert(!IsModified()); // should have been committed
159 0 : }
160 :
161 : // public method
162 :
163 0 : void SvtExtendedSecurityOptions_Impl::Notify( const Sequence< OUString >& )
164 : {
165 : // Not implemented
166 0 : }
167 :
168 : // public method
169 :
170 0 : void SvtExtendedSecurityOptions_Impl::ImplCommit()
171 : {
172 : // Get names of supported properties, create a list for values and copy current values to it.
173 0 : Sequence< OUString > seqNames = GetPropertyNames ();
174 0 : sal_Int32 nCount = seqNames.getLength();
175 0 : Sequence< Any > seqValues ( nCount );
176 0 : for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
177 : {
178 0 : switch( nProperty )
179 : {
180 : case PROPERTYHANDLE_HYPERLINKS_OPEN: {
181 0 : seqValues[nProperty] <<= (sal_Int32)m_eOpenHyperlinkMode;
182 : }
183 0 : break;
184 : }
185 : }
186 :
187 : // Set properties in configuration.
188 0 : PutProperties( seqNames, seqValues );
189 0 : }
190 :
191 : // public method
192 :
193 :
194 : // private method
195 :
196 0 : void SvtExtendedSecurityOptions_Impl::FillExtensionHashMap( ExtensionHashMap& aHashMap )
197 : {
198 : // Get sequence with secure extensions from configuration
199 0 : Sequence< OUString > seqNodes = GetNodeNames( m_aSecureExtensionsSetName );
200 :
201 0 : OUString aValue;
202 0 : Sequence< Any > aValues;
203 0 : Sequence< OUString > aPropSeq( 1 );
204 0 : for ( int i = 0; i < seqNodes.getLength(); i++ )
205 : {
206 : // Create access name for property
207 0 : OUStringBuffer aExtEntryProp( m_aSecureExtensionsSetName );
208 0 : aExtEntryProp.appendAscii( "/" );
209 0 : aExtEntryProp.append( seqNodes[i] );
210 0 : aExtEntryProp.append( m_aExtensionPropName );
211 :
212 0 : aPropSeq[0] = aExtEntryProp.makeStringAndClear();
213 0 : aValues = GetProperties( aPropSeq );
214 0 : if ( aValues.getLength() == 1 )
215 : {
216 : // Don't use value if sequence has not the correct length
217 0 : if ( aValues[0] >>= aValue )
218 : // Add extension into secure extensions hash map
219 0 : aHashMap.insert( ExtensionHashMap::value_type( aValue.toAsciiLowerCase(), 1 ) );
220 : else
221 : {
222 : SAL_WARN( "unotools.config", "SvtExtendedSecurityOptions_Impl::FillExtensionHashMap(): not string value?" );
223 : }
224 : }
225 0 : }
226 0 : }
227 :
228 : // private method (currently not used)
229 :
230 0 : Sequence< OUString > SvtExtendedSecurityOptions_Impl::GetPropertyNames()
231 : {
232 : // Build list of configuration key names.
233 : const OUString pProperties[] =
234 : {
235 : PROPERTYNAME_HYPERLINKS_OPEN
236 0 : };
237 : // Initialize return sequence with these list ...
238 0 : const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
239 : // ... and return it.
240 0 : return seqPropertyNames;
241 : }
242 :
243 : // initialize static member
244 : // DON'T DO IT IN YOUR HEADER!
245 : // see definition for further information
246 :
247 : SvtExtendedSecurityOptions_Impl* SvtExtendedSecurityOptions::m_pDataContainer = NULL;
248 : sal_Int32 SvtExtendedSecurityOptions::m_nRefCount = 0;
249 :
250 : // constructor
251 :
252 0 : SvtExtendedSecurityOptions::SvtExtendedSecurityOptions()
253 : {
254 : // Global access, must be guarded (multithreading!).
255 0 : MutexGuard aGuard( GetInitMutex() );
256 : // Increase our refcount ...
257 0 : ++m_nRefCount;
258 : // ... and initialize our data container only if it not already exist!
259 0 : if( m_pDataContainer == NULL )
260 : {
261 0 : m_pDataContainer = new SvtExtendedSecurityOptions_Impl;
262 :
263 0 : ItemHolder1::holdConfigItem(E_EXTENDEDSECURITYOPTIONS);
264 0 : }
265 0 : }
266 :
267 : // destructor
268 :
269 0 : SvtExtendedSecurityOptions::~SvtExtendedSecurityOptions()
270 : {
271 : // Global access, must be guarded (multithreading!)
272 0 : MutexGuard aGuard( GetInitMutex() );
273 : // Decrease our refcount.
274 0 : --m_nRefCount;
275 : // If last instance was deleted ...
276 : // we must destroy our static data container!
277 0 : if( m_nRefCount <= 0 )
278 : {
279 0 : delete m_pDataContainer;
280 0 : m_pDataContainer = NULL;
281 0 : }
282 0 : }
283 :
284 : // public method
285 :
286 0 : SvtExtendedSecurityOptions::OpenHyperlinkMode SvtExtendedSecurityOptions::GetOpenHyperlinkMode()
287 : {
288 0 : MutexGuard aGuard( GetInitMutex() );
289 0 : return m_pDataContainer->GetOpenHyperlinkMode();
290 : }
291 :
292 : namespace
293 : {
294 : class theExtendedSecurityOptionsMutex : public rtl::Static<osl::Mutex, theExtendedSecurityOptionsMutex>{};
295 : }
296 :
297 : // private method
298 :
299 0 : Mutex& SvtExtendedSecurityOptions::GetInitMutex()
300 : {
301 0 : return theExtendedSecurityOptionsMutex::get();
302 : }
303 :
304 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|