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