1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_unotools.hxx"
26
27 //_________________________________________________________________________________________________________________
28 // includes
29 //_________________________________________________________________________________________________________________
30
31 #include <unotools/extendedsecurityoptions.hxx>
32 #include <unotools/configmgr.hxx>
33 #include <unotools/configitem.hxx>
34 #include <tools/debug.hxx>
35 #include <com/sun/star/uno/Any.hxx>
36 #include <com/sun/star/uno/Sequence.hxx>
37 #include <tools/urlobj.hxx>
38 #include <tools/wldcrd.hxx>
39 #include <rtl/ustrbuf.hxx>
40
41 #include <unotools/pathoptions.hxx>
42
43 #include <hash_map>
44
45 #include <rtl/logfile.hxx>
46 #include "itemholder1.hxx"
47
48 //_________________________________________________________________________________________________________________
49 // namespaces
50 //_________________________________________________________________________________________________________________
51
52 using namespace ::utl ;
53 using namespace ::rtl ;
54 using namespace ::osl ;
55 using namespace ::com::sun::star::uno ;
56
57 //_________________________________________________________________________________________________________________
58 // const
59 //_________________________________________________________________________________________________________________
60
61 #define ROOTNODE_SECURITY OUString(RTL_CONSTASCII_USTRINGPARAM("Office.Security"))
62
63 #define SECURE_EXTENSIONS_SET OUString(RTL_CONSTASCII_USTRINGPARAM("SecureExtensions"))
64 #define EXTENSION_PROPNAME OUString(RTL_CONSTASCII_USTRINGPARAM("/Extension"))
65
66 #define PROPERTYNAME_HYPERLINKS_OPEN OUString(RTL_CONSTASCII_USTRINGPARAM("Hyperlinks/Open"))
67
68 #define PROPERTYHANDLE_HYPERLINKS_OPEN 0
69
70 #define PROPERTYCOUNT 1
71
72 //_________________________________________________________________________________________________________________
73 // private declarations!
74 //_________________________________________________________________________________________________________________
75
76 struct OUStringHashCode
77 {
operator ()OUStringHashCode78 size_t operator()( const ::rtl::OUString& sString ) const
79 {
80 return sString.hashCode();
81 }
82 };
83
84 class ExtensionHashMap : public ::std::hash_map< ::rtl::OUString,
85 sal_Int32,
86 OUStringHashCode,
87 ::std::equal_to< ::rtl::OUString > >
88 {
89 public:
free()90 inline void free()
91 {
92 ExtensionHashMap().swap( *this );
93 }
94 };
95
96 class SvtExtendedSecurityOptions_Impl : public ConfigItem
97 {
98 //-------------------------------------------------------------------------------------------------------------
99 // public methods
100 //-------------------------------------------------------------------------------------------------------------
101
102 public:
103
104 //---------------------------------------------------------------------------------------------------------
105 // constructor / destructor
106 //---------------------------------------------------------------------------------------------------------
107
108 SvtExtendedSecurityOptions_Impl();
109 ~SvtExtendedSecurityOptions_Impl();
110
111 //---------------------------------------------------------------------------------------------------------
112 // overloaded methods of baseclass
113 //---------------------------------------------------------------------------------------------------------
114
115 /*-****************************************************************************************************//**
116 @short called for notify of configmanager
117 @descr These method is called from the ConfigManager before application ends or from the
118 PropertyChangeListener if the sub tree broadcasts changes. You must update your
119 internal values.
120
121 @seealso baseclass ConfigItem
122
123 @param "seqPropertyNames" is the list of properties which should be updated.
124 @return -
125
126 @onerror -
127 *//*-*****************************************************************************************************/
128
129 virtual void Notify( const Sequence< OUString >& seqPropertyNames );
130
131 /*-****************************************************************************************************//**
132 @short write changes to configuration
133 @descr These method writes the changed values into the sub tree
134 and should always called in our destructor to guarantee consistency of config data.
135
136 @seealso baseclass ConfigItem
137
138 @param -
139 @return -
140
141 @onerror -
142 *//*-*****************************************************************************************************/
143
144 virtual void Commit();
145
146 //---------------------------------------------------------------------------------------------------------
147 // public interface
148 //---------------------------------------------------------------------------------------------------------
149
150 /*-****************************************************************************************************//**
151 @short Access method to check for security problems
152 @descr Different methods to check for security related problems.
153
154 @seealso -
155
156 @param -
157 @return -
158
159 @onerror -
160 *//*-*****************************************************************************************************/
161
162 sal_Bool IsSecureHyperlink( const rtl::OUString& aURL ) const;
163 Sequence< rtl::OUString > GetSecureExtensionList() const;
164
165 SvtExtendedSecurityOptions::OpenHyperlinkMode GetOpenHyperlinkMode();
166 void SetOpenHyperlinkMode( SvtExtendedSecurityOptions::OpenHyperlinkMode aMode );
167 sal_Bool IsOpenHyperlinkModeReadOnly() const;
168
169 //-------------------------------------------------------------------------------------------------------------
170 // private methods
171 //-------------------------------------------------------------------------------------------------------------
172
173 private:
174
175 /*-****************************************************************************************************//**
176 @short return list of key names of our configuration management which represent our module tree
177 @descr These methods return a static const list of key names. We need it to get needed values from our
178 configuration management.
179
180 @seealso -
181
182 @param -
183 @return A list of needed configuration keys is returned.
184
185 @onerror -
186 *//*-*****************************************************************************************************/
187
188 static Sequence< OUString > GetPropertyNames();
189
190 /*-****************************************************************************************************//**
191 @short Fills the hash map with all extensions known to be secure
192 @descr These methods fills the given hash map object with all extensions known to be secure.
193
194 @seealso -
195
196 @param aHashMap
197 A hash map to be filled with secure extension strings.
198 @return -
199
200 @onerror -
201 *//*-*****************************************************************************************************/
202 void FillExtensionHashMap( ExtensionHashMap& aHashMap );
203
204 //-------------------------------------------------------------------------------------------------------------
205 // private member
206 //-------------------------------------------------------------------------------------------------------------
207
208 private:
209 OUString m_aSecureExtensionsSetName;
210 OUString m_aExtensionPropName;
211
212 SvtExtendedSecurityOptions::OpenHyperlinkMode m_eOpenHyperlinkMode;
213 sal_Bool m_bROOpenHyperlinkMode;
214 ExtensionHashMap m_aExtensionHashMap;
215 };
216
217 //_________________________________________________________________________________________________________________
218 // definitions
219 //_________________________________________________________________________________________________________________
220
221 //*****************************************************************************************************************
222 // constructor
223 //*****************************************************************************************************************
SvtExtendedSecurityOptions_Impl()224 SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl()
225 // Init baseclasses first
226 : ConfigItem ( ROOTNODE_SECURITY ),
227 m_aSecureExtensionsSetName( SECURE_EXTENSIONS_SET ),
228 m_aExtensionPropName( EXTENSION_PROPNAME ),
229 m_bROOpenHyperlinkMode(sal_False)
230 // Init member then.
231 {
232 // Fill the extension hash map with all secure extension strings
233 FillExtensionHashMap( m_aExtensionHashMap );
234
235 Sequence< OUString > seqNames = GetPropertyNames();
236 Sequence< Any > seqValues = GetProperties( seqNames );
237 Sequence< sal_Bool > seqRO = GetReadOnlyStates ( seqNames );
238
239 sal_Int32 nPropertyCount = seqValues.getLength();
240 for( sal_Int32 nProperty=0; nProperty<nPropertyCount; ++nProperty )
241 {
242 // Safe impossible cases.
243 // Check any for valid value.
244 DBG_ASSERT( !(seqValues[nProperty].hasValue()==sal_False), "SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl()\nInvalid property value detected!\n" );
245 switch( nProperty )
246 {
247 case PROPERTYHANDLE_HYPERLINKS_OPEN:
248 {
249 DBG_ASSERT( ( seqValues[nProperty].getValueTypeClass() == TypeClass_LONG ), "SvtExtendedSecurityOptions_Impl::SvtExtendedSecurityOptions_Impl()\nWho has changed the value type of 'Hyperlink/Open'?" );
250
251 sal_Int32 nMode = SvtExtendedSecurityOptions::OPEN_WITHSECURITYCHECK;
252 if ( seqValues[nProperty] >>= nMode )
253 m_eOpenHyperlinkMode = (SvtExtendedSecurityOptions::OpenHyperlinkMode)nMode;
254 else {
255 DBG_ERROR("Wrong type for Open mode!");
256 }
257 m_bROOpenHyperlinkMode = seqRO[nProperty];
258 }
259 break;
260 }
261 }
262
263 // Enable notification mechanism of our baseclass.
264 // We need it to get information about changes outside these class on our used configuration keys!
265 Sequence< OUString > seqNotifyNames( 1 );
266 seqNotifyNames[0] = m_aSecureExtensionsSetName;
267 EnableNotification( seqNotifyNames );
268 }
269
270 //*****************************************************************************************************************
271 // destructor
272 //*****************************************************************************************************************
~SvtExtendedSecurityOptions_Impl()273 SvtExtendedSecurityOptions_Impl::~SvtExtendedSecurityOptions_Impl()
274 {
275 // We must save our current values .. if user forget it!
276 if( IsModified() == sal_True )
277 {
278 Commit();
279 }
280 }
281
282 //*****************************************************************************************************************
283 // public method
284 //*****************************************************************************************************************
Notify(const Sequence<OUString> &)285 void SvtExtendedSecurityOptions_Impl::Notify( const Sequence< OUString >& )
286 {
287 // Not implemented
288 }
289
290 //*****************************************************************************************************************
291 // public method
292 //*****************************************************************************************************************
Commit()293 void SvtExtendedSecurityOptions_Impl::Commit()
294 {
295 // Get names of supported properties, create a list for values and copy current values to it.
296 Sequence< OUString > seqNames = GetPropertyNames ();
297 sal_Int32 nCount = seqNames.getLength();
298 Sequence< Any > seqValues ( nCount );
299 for( sal_Int32 nProperty=0; nProperty<nCount; ++nProperty )
300 {
301 switch( nProperty )
302 {
303 case PROPERTYHANDLE_HYPERLINKS_OPEN: {
304 seqValues[nProperty] <<= (sal_Int32)m_eOpenHyperlinkMode;
305 }
306 break;
307 }
308 }
309
310 // Set properties in configuration.
311 PutProperties( seqNames, seqValues );
312 }
313
314 //*****************************************************************************************************************
315 // public method
316 //*****************************************************************************************************************
IsSecureHyperlink(const OUString & aURL) const317 sal_Bool SvtExtendedSecurityOptions_Impl::IsSecureHyperlink( const OUString& aURL ) const
318 {
319 INetURLObject aURLObject( aURL );
320
321 String aExtension = aURLObject.getExtension();
322 aExtension.ToLowerAscii();
323
324 ExtensionHashMap::const_iterator pIter = m_aExtensionHashMap.find( aExtension );
325 if ( pIter != m_aExtensionHashMap.end() )
326 return sal_True;
327 else
328 return sal_False;
329 }
330
331 //*****************************************************************************************************************
332 // public method
333 //*****************************************************************************************************************
GetSecureExtensionList() const334 Sequence< OUString > SvtExtendedSecurityOptions_Impl::GetSecureExtensionList() const
335 {
336 Sequence< OUString > aResult( m_aExtensionHashMap.size() );
337
338 sal_Int32 nIndex = 0;
339 for ( ExtensionHashMap::const_iterator pIter = m_aExtensionHashMap.begin();
340 pIter != m_aExtensionHashMap.end(); pIter++ )
341 {
342 aResult[nIndex++] = pIter->first;
343 }
344
345 return aResult;
346 }
347
348 //*****************************************************************************************************************
349 // public method
350 //*****************************************************************************************************************
GetOpenHyperlinkMode()351 SvtExtendedSecurityOptions::OpenHyperlinkMode SvtExtendedSecurityOptions_Impl::GetOpenHyperlinkMode()
352 {
353 return m_eOpenHyperlinkMode;
354 }
355 /* -----------------09.07.2003 11:26-----------------
356
357 --------------------------------------------------*/
IsOpenHyperlinkModeReadOnly() const358 sal_Bool SvtExtendedSecurityOptions_Impl::IsOpenHyperlinkModeReadOnly() const
359 {
360 return m_bROOpenHyperlinkMode;
361 }
362
363 //*****************************************************************************************************************
364 // public method
365 //*****************************************************************************************************************
SetOpenHyperlinkMode(SvtExtendedSecurityOptions::OpenHyperlinkMode eNewMode)366 void SvtExtendedSecurityOptions_Impl::SetOpenHyperlinkMode( SvtExtendedSecurityOptions::OpenHyperlinkMode eNewMode )
367 {
368 m_eOpenHyperlinkMode = eNewMode;
369 SetModified();
370 }
371
372 //*****************************************************************************************************************
373 // private method
374 //*****************************************************************************************************************
FillExtensionHashMap(ExtensionHashMap & aHashMap)375 void SvtExtendedSecurityOptions_Impl::FillExtensionHashMap( ExtensionHashMap& aHashMap )
376 {
377 // Get sequence with secure extensions from configuration
378 Sequence< OUString > seqNodes = GetNodeNames( m_aSecureExtensionsSetName );
379
380 OUString aValue;
381 Sequence< Any > aValues;
382 Sequence< OUString > aPropSeq( 1 );
383 for ( int i = 0; i < seqNodes.getLength(); i++ )
384 {
385 // Create access name for property
386 OUStringBuffer aExtEntryProp( m_aSecureExtensionsSetName );
387 aExtEntryProp.appendAscii( "/" );
388 aExtEntryProp.append( seqNodes[i] );
389 aExtEntryProp.append( m_aExtensionPropName );
390
391 aPropSeq[0] = aExtEntryProp.makeStringAndClear();
392 aValues = GetProperties( aPropSeq );
393 if ( aValues.getLength() == 1 )
394 {
395 // Don't use value if sequence has not the correct length
396 if ( aValues[0] >>= aValue )
397 // Add extension into secure extensions hash map
398 aHashMap.insert( ExtensionHashMap::value_type( aValue.toAsciiLowerCase(), 1 ) );
399 else
400 {
401 DBG_ERRORFILE( "SvtExtendedSecurityOptions_Impl::FillExtensionHashMap(): not string value?" );
402 }
403 }
404 }
405 }
406
407 //*****************************************************************************************************************
408 // private method (currently not used)
409 //*****************************************************************************************************************
GetPropertyNames()410 Sequence< OUString > SvtExtendedSecurityOptions_Impl::GetPropertyNames()
411 {
412 // Build static list of configuration key names.
413 static const OUString pProperties[] =
414 {
415 PROPERTYNAME_HYPERLINKS_OPEN
416 };
417 // Initialize return sequence with these list ...
418 static const Sequence< OUString > seqPropertyNames( pProperties, PROPERTYCOUNT );
419 // ... and return it.
420 return seqPropertyNames;
421 }
422
423 //*****************************************************************************************************************
424 // initialize static member
425 // DON'T DO IT IN YOUR HEADER!
426 // see definition for further informations
427 //*****************************************************************************************************************
428 SvtExtendedSecurityOptions_Impl* SvtExtendedSecurityOptions::m_pDataContainer = NULL ;
429 sal_Int32 SvtExtendedSecurityOptions::m_nRefCount = 0 ;
430
431 //*****************************************************************************************************************
432 // constructor
433 //*****************************************************************************************************************
SvtExtendedSecurityOptions()434 SvtExtendedSecurityOptions::SvtExtendedSecurityOptions()
435 {
436 // Global access, must be guarded (multithreading!).
437 MutexGuard aGuard( GetInitMutex() );
438 // Increase our refcount ...
439 ++m_nRefCount;
440 // ... and initialize our data container only if it not already exist!
441 if( m_pDataContainer == NULL )
442 {
443 RTL_LOGFILE_CONTEXT(aLog, "unotools ( ??? ) ::SvtExtendedSecurityOptions_Impl::ctor()");
444 m_pDataContainer = new SvtExtendedSecurityOptions_Impl;
445
446 ItemHolder1::holdConfigItem(E_EXTENDEDSECURITYOPTIONS);
447 }
448 }
449
450 //*****************************************************************************************************************
451 // destructor
452 //*****************************************************************************************************************
~SvtExtendedSecurityOptions()453 SvtExtendedSecurityOptions::~SvtExtendedSecurityOptions()
454 {
455 // Global access, must be guarded (multithreading!)
456 MutexGuard aGuard( GetInitMutex() );
457 // Decrease our refcount.
458 --m_nRefCount;
459 // If last instance was deleted ...
460 // we must destroy our static data container!
461 if( m_nRefCount <= 0 )
462 {
463 delete m_pDataContainer;
464 m_pDataContainer = NULL;
465 }
466 }
467
468 //*****************************************************************************************************************
469 // public method
470 //*****************************************************************************************************************
IsSecureHyperlink(const rtl::OUString & aURL) const471 sal_Bool SvtExtendedSecurityOptions::IsSecureHyperlink( const rtl::OUString& aURL ) const
472 {
473 MutexGuard aGuard( GetInitMutex() );
474 return m_pDataContainer->IsSecureHyperlink( aURL );
475 }
476
477 //*****************************************************************************************************************
478 // public method
479 //*****************************************************************************************************************
GetSecureExtensionList() const480 Sequence< rtl::OUString > SvtExtendedSecurityOptions::GetSecureExtensionList() const
481 {
482 MutexGuard aGuard( GetInitMutex() );
483 return m_pDataContainer->GetSecureExtensionList();
484 }
485
486 //*****************************************************************************************************************
487 // public method
488 //*****************************************************************************************************************
GetOpenHyperlinkMode()489 SvtExtendedSecurityOptions::OpenHyperlinkMode SvtExtendedSecurityOptions::GetOpenHyperlinkMode()
490 {
491 MutexGuard aGuard( GetInitMutex() );
492 return m_pDataContainer->GetOpenHyperlinkMode();
493 }
494 /* -----------------09.07.2003 11:26-----------------
495
496 --------------------------------------------------*/
IsOpenHyperlinkModeReadOnly() const497 sal_Bool SvtExtendedSecurityOptions::IsOpenHyperlinkModeReadOnly() const
498 {
499 return m_pDataContainer->IsOpenHyperlinkModeReadOnly();
500 }
501
502 //*****************************************************************************************************************
503 // public method
504 //*****************************************************************************************************************
SetOpenHyperlinkMode(SvtExtendedSecurityOptions::OpenHyperlinkMode eMode)505 void SvtExtendedSecurityOptions::SetOpenHyperlinkMode( SvtExtendedSecurityOptions::OpenHyperlinkMode eMode )
506 {
507 MutexGuard aGuard( GetInitMutex() );
508 m_pDataContainer->SetOpenHyperlinkMode( eMode );
509 }
510
511 //*****************************************************************************************************************
512 // private method
513 //*****************************************************************************************************************
GetInitMutex()514 Mutex& SvtExtendedSecurityOptions::GetInitMutex()
515 {
516 // Initialize static mutex only for one time!
517 static Mutex* pMutex = NULL;
518 // If these method first called (Mutex not already exist!) ...
519 if( pMutex == NULL )
520 {
521 // ... we must create a new one. Protect follow code with the global mutex -
522 // It must be - we create a static variable!
523 MutexGuard aGuard( Mutex::getGlobalMutex() );
524 // We must check our pointer again - because it can be that another instance of our class will be faster than these!
525 if( pMutex == NULL )
526 {
527 // Create the new mutex and set it for return on static variable.
528 static Mutex aMutex;
529 pMutex = &aMutex;
530 }
531 }
532 // Return new created or already existing mutex object.
533 return *pMutex;
534 }
535