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 { 78 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: 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 ouer configuration management which represent oue 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 //***************************************************************************************************************** 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 ouer used configuration keys! 265 Sequence< OUString > seqNotifyNames( 1 ); 266 seqNotifyNames[0] = m_aSecureExtensionsSetName; 267 EnableNotification( seqNotifyNames ); 268 } 269 270 //***************************************************************************************************************** 271 // destructor 272 //***************************************************************************************************************** 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 //***************************************************************************************************************** 285 void SvtExtendedSecurityOptions_Impl::Notify( const Sequence< OUString >& ) 286 { 287 // Not implemented 288 } 289 290 //***************************************************************************************************************** 291 // public method 292 //***************************************************************************************************************** 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 //***************************************************************************************************************** 317 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 //***************************************************************************************************************** 334 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 //***************************************************************************************************************** 351 SvtExtendedSecurityOptions::OpenHyperlinkMode SvtExtendedSecurityOptions_Impl::GetOpenHyperlinkMode() 352 { 353 return m_eOpenHyperlinkMode; 354 } 355 /* -----------------09.07.2003 11:26----------------- 356 357 --------------------------------------------------*/ 358 sal_Bool SvtExtendedSecurityOptions_Impl::IsOpenHyperlinkModeReadOnly() const 359 { 360 return m_bROOpenHyperlinkMode; 361 } 362 363 //***************************************************************************************************************** 364 // public method 365 //***************************************************************************************************************** 366 void SvtExtendedSecurityOptions_Impl::SetOpenHyperlinkMode( SvtExtendedSecurityOptions::OpenHyperlinkMode eNewMode ) 367 { 368 m_eOpenHyperlinkMode = eNewMode; 369 SetModified(); 370 } 371 372 //***************************************************************************************************************** 373 // private method 374 //***************************************************************************************************************** 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 //***************************************************************************************************************** 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 //***************************************************************************************************************** 434 SvtExtendedSecurityOptions::SvtExtendedSecurityOptions() 435 { 436 // Global access, must be guarded (multithreading!). 437 MutexGuard aGuard( GetInitMutex() ); 438 // Increase ouer refcount ... 439 ++m_nRefCount; 440 // ... and initialize ouer 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 //***************************************************************************************************************** 453 SvtExtendedSecurityOptions::~SvtExtendedSecurityOptions() 454 { 455 // Global access, must be guarded (multithreading!) 456 MutexGuard aGuard( GetInitMutex() ); 457 // Decrease ouer refcount. 458 --m_nRefCount; 459 // If last instance was deleted ... 460 // we must destroy ouer 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 //***************************************************************************************************************** 471 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 //***************************************************************************************************************** 480 Sequence< rtl::OUString > SvtExtendedSecurityOptions::GetSecureExtensionList() const 481 { 482 MutexGuard aGuard( GetInitMutex() ); 483 return m_pDataContainer->GetSecureExtensionList(); 484 } 485 486 //***************************************************************************************************************** 487 // public method 488 //***************************************************************************************************************** 489 SvtExtendedSecurityOptions::OpenHyperlinkMode SvtExtendedSecurityOptions::GetOpenHyperlinkMode() 490 { 491 MutexGuard aGuard( GetInitMutex() ); 492 return m_pDataContainer->GetOpenHyperlinkMode(); 493 } 494 /* -----------------09.07.2003 11:26----------------- 495 496 --------------------------------------------------*/ 497 sal_Bool SvtExtendedSecurityOptions::IsOpenHyperlinkModeReadOnly() const 498 { 499 return m_pDataContainer->IsOpenHyperlinkModeReadOnly(); 500 } 501 502 //***************************************************************************************************************** 503 // public method 504 //***************************************************************************************************************** 505 void SvtExtendedSecurityOptions::SetOpenHyperlinkMode( SvtExtendedSecurityOptions::OpenHyperlinkMode eMode ) 506 { 507 MutexGuard aGuard( GetInitMutex() ); 508 m_pDataContainer->SetOpenHyperlinkMode( eMode ); 509 } 510 511 //***************************************************************************************************************** 512 // private method 513 //***************************************************************************************************************** 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 ouer class will be fastr then 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