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_svl.hxx" 26 27 #include "passwordcontainer.hxx" 28 29 #include <unotools/pathoptions.hxx> 30 #include "cppuhelper/factory.hxx" 31 #include <com/sun/star/registry/XSimpleRegistry.hpp> 32 #include <com/sun/star/beans/PropertyValue.hpp> 33 #include <com/sun/star/task/MasterPasswordRequest.hpp> 34 #include <com/sun/star/task/NoMasterException.hpp> 35 36 #include <rtl/cipher.h> 37 #include <rtl/digest.h> 38 #include <rtl/byteseq.hxx> 39 40 #ifndef _TOOLS_INETSTRM_HXX 41 // @@@ #include <inetstrm.hxx> 42 #endif 43 44 using namespace std; 45 using namespace osl; 46 using namespace utl; 47 using namespace com::sun::star; 48 using namespace com::sun::star::uno; 49 using namespace com::sun::star::registry; 50 using namespace com::sun::star::lang; 51 using namespace com::sun::star::task; 52 using namespace com::sun::star::ucb; 53 54 //------------------------------------------------------------------------- 55 //------------------------------------------------------------------------- 56 57 static ::rtl::OUString createIndex( vector< ::rtl::OUString > lines ) 58 { 59 ::rtl::OString aResult; 60 const sal_Char* pLine; 61 62 for( unsigned int i = 0; i < lines.size(); i++ ) 63 { 64 if( i ) 65 aResult += ::rtl::OString( "__" ); 66 ::rtl::OString line = ::rtl::OUStringToOString( lines[i], RTL_TEXTENCODING_UTF8 ); 67 pLine = line.getStr(); 68 69 while( *pLine ) 70 { 71 if( ( *pLine >= 'A' && *pLine <= 'Z' ) 72 || ( *pLine >= 'a' && *pLine <= 'z' ) 73 || ( *pLine >= '0' && *pLine <= '9' ) ) 74 { 75 aResult += ::rtl::OString::valueOf( *pLine ); 76 } 77 else 78 { 79 aResult += ::rtl::OString("_"); 80 aResult += ::rtl::OString::valueOf( (sal_Int32) *pLine, 16 ); 81 } 82 83 pLine++; 84 } 85 } 86 87 return ::rtl::OUString::createFromAscii( aResult.getStr() ); 88 } 89 90 //------------------------------------------------------------------------- 91 92 static vector< ::rtl::OUString > getInfoFromInd( ::rtl::OUString aInd ) 93 { 94 vector< ::rtl::OUString > aResult; 95 sal_Bool aStart = sal_True; 96 97 ::rtl::OString line = ::rtl::OUStringToOString( aInd, RTL_TEXTENCODING_ASCII_US ); 98 const sal_Char* pLine = line.getStr(); 99 do 100 { 101 ::rtl::OUString newItem; 102 if( !aStart ) 103 pLine += 2; 104 else 105 aStart = sal_False; 106 107 while( *pLine && !( pLine[0] == '_' && pLine[1] == '_' )) 108 if( *pLine != '_' ) 109 { 110 newItem += ::rtl::OUString::valueOf( (sal_Unicode) *pLine ); 111 pLine++; 112 } 113 else 114 { 115 ::rtl::OUString aNum; 116 for( int i = 1; i < 3; i++ ) 117 { 118 if( !pLine[i] 119 || ( ( pLine[i] < '0' || pLine[i] > '9' ) 120 && ( pLine[i] < 'a' || pLine[i] > 'f' ) 121 && ( pLine[i] < 'A' || pLine[i] > 'F' ) ) ) 122 { 123 OSL_ENSURE( sal_False, "Wrong index syntax!\n" ); 124 return aResult; 125 } 126 127 aNum += ::rtl::OUString::valueOf( (sal_Unicode) pLine[i] ); 128 } 129 130 newItem += ::rtl::OUString::valueOf( (sal_Unicode) aNum.toInt32( 16 ) ); 131 pLine += 3; 132 } 133 134 aResult.push_back( newItem ); 135 } while( pLine[0] == '_' && pLine[1] == '_' ); 136 137 if( *pLine ) 138 OSL_ENSURE( sal_False, "Wrong index syntax!\n" ); 139 140 return aResult; 141 } 142 143 //------------------------------------------------------------------------- 144 145 static sal_Bool shorterUrl( ::rtl::OUString& aURL ) 146 { 147 sal_Int32 aInd = aURL.lastIndexOf( sal_Unicode( '/' ) ); 148 if( aInd > 0 && aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) ) != aInd-2 ) 149 { 150 aURL = aURL.copy( 0, aInd ); 151 return sal_True; 152 } 153 154 return sal_False; 155 } 156 157 //------------------------------------------------------------------------- 158 159 static ::rtl::OUString getAsciiLine( const ::rtl::ByteSequence& buf ) 160 { 161 ::rtl::OUString aResult; 162 163 ::rtl::ByteSequence outbuf( buf.getLength()*2+1 ); 164 165 for( int ind = 0; ind < buf.getLength(); ind++ ) 166 { 167 outbuf[ind*2] = ( ((sal_uInt8)buf[ind]) >> 4 ) + 'a'; 168 outbuf[ind*2+1] = ( ((sal_uInt8)buf[ind]) & 0x0f ) + 'a'; 169 } 170 outbuf[buf.getLength()*2] = '\0'; 171 172 aResult = ::rtl::OUString::createFromAscii( (sal_Char*)outbuf.getArray() ); 173 174 return aResult; 175 } 176 177 //------------------------------------------------------------------------- 178 179 static ::rtl::ByteSequence getBufFromAsciiLine( ::rtl::OUString line ) 180 { 181 OSL_ENSURE( line.getLength() % 2 == 0, "Wrong syntax!\n" ); 182 ::rtl::OString tmpLine = ::rtl::OUStringToOString( line, RTL_TEXTENCODING_ASCII_US ); 183 ::rtl::ByteSequence aResult(line.getLength()/2); 184 185 for( int ind = 0; ind < tmpLine.getLength()/2; ind++ ) 186 { 187 aResult[ind] = ( (sal_uInt8)( tmpLine.getStr()[ind*2] - 'a' ) << 4 ) | (sal_uInt8)( tmpLine.getStr()[ind*2+1] - 'a' ); 188 } 189 190 return aResult; 191 } 192 193 //------------------------------------------------------------------------- 194 195 static Sequence< ::rtl::OUString > copyVectorToSequence( const vector< ::rtl::OUString >& original ) 196 { 197 Sequence< ::rtl::OUString > newOne ( original.size() ); 198 for( unsigned int i = 0; i < original.size() ; i++ ) 199 newOne[i] = original[i]; 200 201 return newOne; 202 } 203 204 static vector< ::rtl::OUString > copySequenceToVector( const Sequence< ::rtl::OUString >& original ) 205 { 206 vector< ::rtl::OUString > newOne ( original.getLength() ); 207 for( int i = 0; i < original.getLength() ; i++ ) 208 newOne[i] = original[i]; 209 210 return newOne; 211 } 212 213 //------------------------------------------------------------------------- 214 //------------------------------------------------------------------------- 215 216 PassMap StorageItem::getInfo() 217 { 218 PassMap aResult; 219 220 Sequence< ::rtl::OUString > aNodeNames = ConfigItem::GetNodeNames( ::rtl::OUString::createFromAscii("Store") ); 221 sal_Int32 aNodeCount = aNodeNames.getLength(); 222 Sequence< ::rtl::OUString > aPropNames( aNodeCount ); 223 sal_Int32 aNodeInd; 224 225 for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd ) 226 { 227 aPropNames[aNodeInd] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); 228 aPropNames[aNodeInd] += aNodeNames[aNodeInd]; 229 aPropNames[aNodeInd] += ::rtl::OUString::createFromAscii( "']/Password" ); 230 } 231 232 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aPropNames ); 233 234 if( aPropertyValues.getLength() != aNodeNames.getLength() ) 235 { 236 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); 237 return aResult; 238 } 239 240 for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd ) 241 { 242 vector< ::rtl::OUString > aUrlUsr = getInfoFromInd( aNodeNames[aNodeInd] ); 243 244 if( aUrlUsr.size() == 2 ) 245 { 246 ::rtl::OUString aUrl = aUrlUsr[0]; 247 ::rtl::OUString aName = aUrlUsr[1]; 248 249 ::rtl::OUString aEPasswd; 250 aPropertyValues[aNodeInd] >>= aEPasswd; 251 252 PassMap::iterator aIter = aResult.find( aUrl ); 253 if( aIter != aResult.end() ) 254 aIter->second.push_back( NamePassRecord( aName, aEPasswd ) ); 255 else 256 { 257 NamePassRecord aNewRecord( aName, aEPasswd ); 258 list< NamePassRecord > listToAdd( 1, aNewRecord ); 259 260 aResult.insert( PairUrlRecord( aUrl, listToAdd ) ); 261 } 262 } 263 else 264 OSL_ENSURE( sal_False, "Wrong index sintax!\n" ); 265 } 266 267 return aResult; 268 } 269 270 //------------------------------------------------------------------------- 271 272 void StorageItem::setUseStorage( sal_Bool bUse ) 273 { 274 Sequence< ::rtl::OUString > sendNames(1); 275 Sequence< uno::Any > sendVals(1); 276 277 sendNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" ); 278 279 sendVals[0] <<= bUse; 280 281 ConfigItem::SetModified(); 282 ConfigItem::PutProperties( sendNames, sendVals ); 283 } 284 285 //------------------------------------------------------------------------- 286 287 sal_Bool StorageItem::useStorage() 288 { 289 Sequence< ::rtl::OUString > aNodeNames( 1 ); 290 aNodeNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" ); 291 292 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames ); 293 294 if( aPropertyValues.getLength() != aNodeNames.getLength() ) 295 { 296 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); 297 return sal_False; 298 } 299 300 sal_Bool aResult = false; 301 aPropertyValues[0] >>= aResult; 302 303 return aResult; 304 } 305 306 //------------------------------------------------------------------------- 307 308 sal_Bool StorageItem::getEncodedMP( ::rtl::OUString& aResult ) 309 { 310 if( hasEncoded ) 311 { 312 aResult = mEncoded; 313 return sal_True; 314 } 315 316 Sequence< ::rtl::OUString > aNodeNames( 2 ); 317 aNodeNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" ); 318 aNodeNames[1] = ::rtl::OUString::createFromAscii( "Master" ); 319 320 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames ); 321 322 if( aPropertyValues.getLength() != aNodeNames.getLength() ) 323 { 324 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); 325 return sal_False; 326 } 327 328 aPropertyValues[0] >>= hasEncoded; 329 aPropertyValues[1] >>= mEncoded; 330 331 aResult = mEncoded; 332 333 return hasEncoded; 334 } 335 336 //------------------------------------------------------------------------- 337 338 void StorageItem::setEncodedMP( const ::rtl::OUString& aEncoded, sal_Bool bAcceptEmpty ) 339 { 340 Sequence< ::rtl::OUString > sendNames(2); 341 Sequence< uno::Any > sendVals(2); 342 343 sendNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" ); 344 sendNames[1] = ::rtl::OUString::createFromAscii( "Master" ); 345 346 sal_Bool bHasMaster = ( aEncoded.getLength() > 0 || bAcceptEmpty ); 347 sendVals[0] <<= bHasMaster; 348 sendVals[1] <<= aEncoded; 349 350 ConfigItem::SetModified(); 351 ConfigItem::PutProperties( sendNames, sendVals ); 352 353 hasEncoded = bHasMaster; 354 mEncoded = aEncoded; 355 } 356 357 //------------------------------------------------------------------------- 358 359 void StorageItem::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) 360 { 361 vector < ::rtl::OUString > forIndex; 362 forIndex.push_back( aURL ); 363 forIndex.push_back( aName ); 364 365 Sequence< ::rtl::OUString > sendSeq(1); 366 367 sendSeq[0] = createIndex( forIndex ); 368 // sendSeq[0] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); 369 // sendSeq[0] += createIndex( forIndex ); 370 // sendSeq[0] += ::rtl::OUString::createFromAscii( "']" ); 371 372 ConfigItem::ClearNodeElements( ::rtl::OUString::createFromAscii( "Store" ), sendSeq ); 373 } 374 375 //------------------------------------------------------------------------- 376 377 void StorageItem::clear() 378 { 379 Sequence< ::rtl::OUString > sendSeq(1); 380 381 ConfigItem::ClearNodeSet( ::rtl::OUString::createFromAscii( "Store" ) ); 382 } 383 384 //------------------------------------------------------------------------- 385 386 void StorageItem::update( const ::rtl::OUString& aURL, const NamePassRecord& aRecord ) 387 { 388 if ( !aRecord.HasPasswords( PERSISTENT_RECORD ) ) 389 { 390 OSL_ASSERT( "Unexpected storing of a record!" ); 391 return; 392 } 393 394 vector < ::rtl::OUString > forIndex; 395 forIndex.push_back( aURL ); 396 forIndex.push_back( aRecord.GetUserName() ); 397 398 Sequence< beans::PropertyValue > sendSeq(1); 399 400 sendSeq[0].Name = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); 401 sendSeq[0].Name += createIndex( forIndex ); 402 sendSeq[0].Name += ::rtl::OUString::createFromAscii( "']/Password" ); 403 404 sendSeq[0].Value <<= aRecord.GetPersPasswords(); 405 406 ConfigItem::SetModified(); 407 ConfigItem::SetSetProperties( ::rtl::OUString::createFromAscii( "Store" ), sendSeq ); 408 } 409 410 //------------------------------------------------------------------------- 411 412 void StorageItem::Notify( const Sequence< ::rtl::OUString >& ) 413 { 414 // this feature still should not be used 415 if( mainCont ) 416 mainCont->Notify(); 417 } 418 419 //------------------------------------------------------------------------- 420 421 void StorageItem::Commit() 422 { 423 // Do nothing, we stored everything we want already 424 } 425 426 //------------------------------------------------------------------------- 427 //------------------------------------------------------------------------- 428 429 PasswordContainer::PasswordContainer( const Reference<XMultiServiceFactory>& xServiceFactory ): 430 m_pStorageFile( NULL ) 431 { 432 // m_pStorageFile->Notify() can be called 433 ::osl::MutexGuard aGuard( mMutex ); 434 435 mComponent = Reference< XComponent >( xServiceFactory, UNO_QUERY ); 436 mComponent->addEventListener( this ); 437 438 m_pStorageFile = new StorageItem( this, ::rtl::OUString::createFromAscii( "Office.Common/Passwords" ) ); 439 if( m_pStorageFile ) 440 if( m_pStorageFile->useStorage() ) 441 m_aContainer = m_pStorageFile->getInfo(); 442 } 443 444 //------------------------------------------------------------------------- 445 446 PasswordContainer::~PasswordContainer() 447 { 448 ::osl::MutexGuard aGuard( mMutex ); 449 450 if( m_pStorageFile ) 451 { 452 delete m_pStorageFile; 453 m_pStorageFile = NULL; 454 } 455 456 if( mComponent.is() ) 457 { 458 mComponent->removeEventListener(this); 459 mComponent = Reference< XComponent >(); 460 } 461 } 462 463 //------------------------------------------------------------------------- 464 465 void SAL_CALL PasswordContainer::disposing( const EventObject& ) throw(RuntimeException) 466 { 467 ::osl::MutexGuard aGuard( mMutex ); 468 469 if( m_pStorageFile ) 470 { 471 delete m_pStorageFile; 472 m_pStorageFile = NULL; 473 } 474 475 if( mComponent.is() ) 476 { 477 //mComponent->removeEventListener(this); 478 mComponent = Reference< XComponent >(); 479 } 480 } 481 482 //------------------------------------------------------------------------- 483 484 vector< ::rtl::OUString > PasswordContainer::DecodePasswords( const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException) 485 { 486 if( aMasterPasswd.getLength() ) 487 { 488 rtlCipher aDecoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream ); 489 OSL_ENSURE( aDecoder, "Can't create decoder\n" ); 490 491 if( aDecoder ) 492 { 493 OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" ); 494 495 unsigned char code[RTL_DIGEST_LENGTH_MD5]; 496 for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ ) 497 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16)); 498 499 rtlCipherError result = rtl_cipher_init ( 500 aDecoder, rtl_Cipher_DirectionDecode, 501 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 ); 502 503 if( result == rtl_Cipher_E_None ) 504 { 505 ::rtl::ByteSequence aSeq = getBufFromAsciiLine( aLine ); 506 507 ::rtl::ByteSequence resSeq( aSeq.getLength() ); 508 509 result = rtl_cipher_decode ( aDecoder, (sal_uInt8*)aSeq.getArray(), aSeq.getLength(), 510 (sal_uInt8*)resSeq.getArray(), resSeq.getLength() ); 511 512 ::rtl::OUString aPasswd( ( sal_Char* )resSeq.getArray(), resSeq.getLength(), RTL_TEXTENCODING_UTF8 ); 513 514 rtl_cipher_destroy (aDecoder); 515 516 return getInfoFromInd( aPasswd ); 517 } 518 519 rtl_cipher_destroy (aDecoder); 520 } 521 } 522 else 523 { 524 OSL_ENSURE( sal_False, "No master password provided!\n" ); 525 // throw special exception 526 } 527 528 // problems with decoding 529 OSL_ENSURE( sal_False, "Problem with decoding\n" ); 530 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't decode!" ), Reference< XInterface >() ); 531 } 532 533 534 //------------------------------------------------------------------------- 535 536 ::rtl::OUString PasswordContainer::EncodePasswords( vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException) 537 { 538 if( aMasterPasswd.getLength() ) 539 { 540 ::rtl::OString aSeq = ::rtl::OUStringToOString( createIndex( lines ), RTL_TEXTENCODING_UTF8 ); 541 542 rtlCipher aEncoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream ); 543 OSL_ENSURE( aEncoder, "Can't create encoder\n" ); 544 545 if( aEncoder ) 546 { 547 OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" ); 548 549 unsigned char code[RTL_DIGEST_LENGTH_MD5]; 550 for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ ) 551 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16)); 552 553 rtlCipherError result = rtl_cipher_init ( 554 aEncoder, rtl_Cipher_DirectionEncode, 555 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 ); 556 557 if( result == rtl_Cipher_E_None ) 558 { 559 ::rtl::ByteSequence resSeq(aSeq.getLength()+1); 560 561 result = rtl_cipher_encode ( aEncoder, (sal_uInt8*)aSeq.getStr(), aSeq.getLength()+1, 562 (sal_uInt8*)resSeq.getArray(), resSeq.getLength() ); 563 564 /* 565 //test 566 rtlCipherError result = rtl_cipher_init ( 567 aEncoder, rtl_Cipher_DirectionDecode, 568 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 ); 569 570 571 if( result == rtl_Cipher_E_None ) 572 { 573 ::rtl::OUString testOU = getAsciiLine( resSeq ); 574 ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU ); 575 576 ::rtl::ByteSequence resSeq1( aSeq1.getLength() ); 577 578 if( resSeq.getLength() == aSeq1.getLength() ) 579 { 580 for( int ind = 0; ind < aSeq1.getLength(); ind++ ) 581 if( resSeq[ind] != aSeq1[ind] ) 582 testOU = ::rtl::OUString(); 583 } 584 585 result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(), 586 (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() ); 587 588 ::rtl::OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 ); 589 } 590 */ 591 592 rtl_cipher_destroy (aEncoder); 593 594 if( result == rtl_Cipher_E_None ) 595 return getAsciiLine( resSeq ); 596 597 } 598 599 rtl_cipher_destroy (aEncoder); 600 } 601 } 602 else 603 { 604 OSL_ENSURE( sal_False, "No master password provided!\n" ); 605 // throw special exception 606 } 607 608 // problems with encoding 609 OSL_ENSURE( sal_False, "Problem with encoding\n" ); 610 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't encode!" ), Reference< XInterface >() ); 611 } 612 613 //------------------------------------------------------------------------- 614 615 void PasswordContainer::UpdateVector( const ::rtl::OUString& aURL, list< NamePassRecord >& toUpdate, NamePassRecord& aRecord, sal_Bool writeFile ) throw(RuntimeException) 616 { 617 for( list< NamePassRecord >::iterator aNPIter = toUpdate.begin(); aNPIter != toUpdate.end(); aNPIter++ ) 618 if( aNPIter->GetUserName().equals( aRecord.GetUserName() ) ) 619 { 620 if( aRecord.HasPasswords( MEMORY_RECORD ) ) 621 aNPIter->SetMemPasswords( aRecord.GetMemPasswords() ); 622 623 if( aRecord.HasPasswords( PERSISTENT_RECORD ) ) 624 { 625 aNPIter->SetPersPasswords( aRecord.GetPersPasswords() ); 626 627 if( writeFile ) 628 { 629 // the password must be already encoded 630 m_pStorageFile->update( aURL, aRecord ); // change existing ( aURL, aName ) record in the configfile 631 } 632 } 633 634 return; 635 } 636 637 638 if( aRecord.HasPasswords( PERSISTENT_RECORD ) && writeFile ) 639 { 640 // the password must be already encoded 641 m_pStorageFile->update( aURL, aRecord ); // add new aName to the existing url 642 } 643 644 toUpdate.insert( toUpdate.begin(), aRecord ); 645 } 646 647 //------------------------------------------------------------------------- 648 649 UserRecord PasswordContainer::CopyToUserRecord( const NamePassRecord& aRecord, sal_Bool& io_bTryToDecode, const Reference< XInteractionHandler >& aHandler ) 650 { 651 ::std::vector< ::rtl::OUString > aPasswords; 652 if( aRecord.HasPasswords( MEMORY_RECORD ) ) 653 aPasswords = aRecord.GetMemPasswords(); 654 655 if( io_bTryToDecode && aRecord.HasPasswords( PERSISTENT_RECORD ) ) 656 { 657 try 658 { 659 ::std::vector< ::rtl::OUString > aDecodedPasswords = DecodePasswords( aRecord.GetPersPasswords(), GetMasterPassword( aHandler ) ); 660 aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), aDecodedPasswords.end() ); 661 } 662 catch( NoMasterException& ) 663 { 664 // if master password could not be detected the entry will be just ignored 665 io_bTryToDecode = sal_False; 666 } 667 } 668 669 return UserRecord( aRecord.GetUserName(), copyVectorToSequence( aPasswords ) ); 670 } 671 672 //------------------------------------------------------------------------- 673 674 Sequence< UserRecord > PasswordContainer::CopyToUserRecordSequence( const list< NamePassRecord >& original, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 675 { 676 Sequence< UserRecord > aResult( original.size() ); 677 sal_uInt32 nInd = 0; 678 sal_Bool bTryToDecode = sal_True; 679 680 for( list< NamePassRecord >::const_iterator aNPIter = original.begin(); 681 aNPIter != original.end(); 682 aNPIter++, nInd++ ) 683 { 684 aResult[nInd] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler ); 685 } 686 687 return aResult; 688 } 689 690 //------------------------------------------------------------------------- 691 692 void SAL_CALL PasswordContainer::add( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 693 { 694 ::osl::MutexGuard aGuard( mMutex ); 695 696 PrivateAdd( Url, UserName, Passwords, MEMORY_RECORD, aHandler ); 697 } 698 699 //------------------------------------------------------------------------- 700 701 void SAL_CALL PasswordContainer::addPersistent( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 702 { 703 ::osl::MutexGuard aGuard( mMutex ); 704 705 PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler ); 706 } 707 708 //------------------------------------------------------------------------- 709 710 void PasswordContainer::PrivateAdd( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, char Mode, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 711 { 712 NamePassRecord aRecord( UserName ); 713 ::std::vector< ::rtl::OUString > aStorePass = copySequenceToVector( Passwords ); 714 715 if( Mode == PERSISTENT_RECORD ) 716 aRecord.SetPersPasswords( EncodePasswords( aStorePass, GetMasterPassword( aHandler ) ) ); 717 else if( Mode == MEMORY_RECORD ) 718 aRecord.SetMemPasswords( aStorePass ); 719 else 720 { 721 OSL_ASSERT( "Unexpected persistence status!" ); 722 return; 723 } 724 725 if( !m_aContainer.empty() ) 726 { 727 PassMap::iterator aIter = m_aContainer.find( Url ); 728 729 if( aIter != m_aContainer.end() ) 730 { 731 UpdateVector( aIter->first, aIter->second, aRecord, sal_True ); 732 return; 733 } 734 } 735 736 list< NamePassRecord > listToAdd( 1, aRecord ); 737 m_aContainer.insert( PairUrlRecord( Url, listToAdd ) ); 738 739 if( Mode == PERSISTENT_RECORD && m_pStorageFile && m_pStorageFile->useStorage() ) 740 m_pStorageFile->update( Url, aRecord ); 741 742 } 743 744 //------------------------------------------------------------------------- 745 746 747 UrlRecord SAL_CALL PasswordContainer::find( const ::rtl::OUString& aURL, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 748 { 749 return find( aURL, rtl::OUString(), false, aHandler ); 750 } 751 752 //------------------------------------------------------------------------- 753 754 UrlRecord SAL_CALL PasswordContainer::findForName( const ::rtl::OUString& aURL, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 755 { 756 return find( aURL, aName, true, aHandler ); 757 } 758 759 //------------------------------------------------------------------------- 760 761 Sequence< UserRecord > PasswordContainer::FindUsr( const list< NamePassRecord >& userlist, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 762 { 763 sal_uInt32 nInd = 0; 764 for( list< NamePassRecord >::const_iterator aNPIter = userlist.begin(); 765 aNPIter != userlist.end(); 766 aNPIter++, nInd++ ) 767 { 768 if( aNPIter->GetUserName().equals( aName ) ) 769 { 770 Sequence< UserRecord > aResult(1); 771 sal_Bool bTryToDecode = sal_True; 772 aResult[0] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler ); 773 774 return aResult; 775 } 776 } 777 778 return Sequence< UserRecord >(); 779 } 780 781 //------------------------------------------------------------------------- 782 783 bool PasswordContainer::createUrlRecord( 784 const PassMap::iterator & rIter, 785 bool bName, 786 const ::rtl::OUString & aName, 787 const Reference< XInteractionHandler >& aHandler, 788 UrlRecord & rRec ) 789 throw( RuntimeException ) 790 { 791 if ( bName ) 792 { 793 Sequence< UserRecord > aUsrRec 794 = FindUsr( rIter->second, aName, aHandler ); 795 if( aUsrRec.getLength() ) 796 { 797 rRec = UrlRecord( rIter->first, aUsrRec ); 798 return true; 799 } 800 } 801 else 802 { 803 rRec = UrlRecord( 804 rIter->first, 805 CopyToUserRecordSequence( rIter->second, aHandler ) ); 806 return true; 807 } 808 return false; 809 } 810 811 //------------------------------------------------------------------------- 812 813 UrlRecord PasswordContainer::find( 814 const ::rtl::OUString& aURL, 815 const ::rtl::OUString& aName, 816 bool bName, // only needed to support empty user names 817 const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 818 { 819 ::osl::MutexGuard aGuard( mMutex ); 820 821 if( !m_aContainer.empty() && aURL.getLength() ) 822 { 823 ::rtl::OUString aUrl( aURL ); 824 825 // each iteration remove last '/...' section from the aUrl 826 // while it's possible, up to the most left '://' 827 do 828 { 829 // first look for <url>/somename and then look for <url>/somename/... 830 PassMap::iterator aIter = m_aContainer.find( aUrl ); 831 if( aIter != m_aContainer.end() ) 832 { 833 UrlRecord aRec; 834 if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) ) 835 return aRec; 836 } 837 else 838 { 839 ::rtl::OUString tmpUrl( aUrl ); 840 if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' ) 841 tmpUrl += ::rtl::OUString::createFromAscii( "/" ); 842 843 aIter = m_aContainer.lower_bound( tmpUrl ); 844 if( aIter != m_aContainer.end() && aIter->first.match( tmpUrl ) ) 845 { 846 UrlRecord aRec; 847 if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) ) 848 return aRec; 849 } 850 } 851 } 852 while( shorterUrl( aUrl ) && aUrl.getLength() ); 853 } 854 855 return UrlRecord(); 856 } 857 858 //------------------------------------------------------------------------- 859 ::rtl::OUString PasswordContainer::GetDefaultMasterPassword() 860 { 861 ::rtl::OUString aResult; 862 for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ ) 863 aResult += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "aa" ) ); 864 865 return aResult; 866 } 867 868 //------------------------------------------------------------------------- 869 ::rtl::OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler ) 870 { 871 // empty string means that the call was cancelled or just failed 872 ::rtl::OUString aResult; 873 874 if ( xHandler.is() ) 875 { 876 ::rtl::Reference< MasterPasswordRequest_Impl > xRequest = new MasterPasswordRequest_Impl( aRMode ); 877 878 xHandler->handle( xRequest.get() ); 879 880 ::rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection(); 881 882 if ( xSelection.is() ) 883 { 884 Reference< XInteractionAbort > xAbort( xSelection.get(), UNO_QUERY ); 885 if ( !xAbort.is() ) 886 { 887 const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp 888 = xRequest->getAuthenticationSupplier(); 889 890 aResult = xSupp->getPassword(); 891 } 892 } 893 } 894 895 return aResult; 896 } 897 898 //------------------------------------------------------------------------- 899 900 ::rtl::OUString PasswordContainer::GetMasterPassword( const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) 901 { 902 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER; 903 if( !m_pStorageFile || !m_pStorageFile->useStorage() ) 904 throw NoMasterException( ::rtl::OUString::createFromAscii( "Password storing is not active!" ), Reference< XInterface >(), aRMode ); 905 906 if( !m_aMasterPasswd.getLength() && aHandler.is() ) 907 { 908 ::rtl::OUString aEncodedMP; 909 sal_Bool bAskAgain = sal_False; 910 sal_Bool bDefaultPassword = sal_False; 911 912 if( !m_pStorageFile->getEncodedMP( aEncodedMP ) ) 913 aRMode = PasswordRequestMode_PASSWORD_CREATE; 914 else if ( !aEncodedMP.getLength() ) 915 { 916 m_aMasterPasswd = GetDefaultMasterPassword(); 917 bDefaultPassword = sal_True; 918 } 919 920 if ( !bDefaultPassword ) 921 { 922 do { 923 bAskAgain = sal_False; 924 925 ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, aHandler ); 926 if ( aPass.getLength() ) 927 { 928 if( aRMode == PasswordRequestMode_PASSWORD_CREATE ) 929 { 930 m_aMasterPasswd = aPass; 931 vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd ); 932 933 m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) ); 934 } 935 else 936 { 937 vector< ::rtl::OUString > aRM( DecodePasswords( aEncodedMP, aPass ) ); 938 if( !aRM.size() || !aPass.equals( aRM[0] ) ) 939 { 940 bAskAgain = sal_True; 941 aRMode = PasswordRequestMode_PASSWORD_REENTER; 942 } 943 else 944 m_aMasterPasswd = aPass; 945 } 946 } 947 948 } while( bAskAgain ); 949 } 950 } 951 952 if ( !m_aMasterPasswd.getLength() ) 953 throw NoMasterException( ::rtl::OUString::createFromAscii( "No master password!" ), Reference< XInterface >(), aRMode ); 954 955 return m_aMasterPasswd; 956 } 957 958 //------------------------------------------------------------------------- 959 960 void SAL_CALL PasswordContainer::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException) 961 { 962 ::osl::MutexGuard aGuard( mMutex ); 963 964 ::rtl::OUString aUrl( aURL ); 965 if( !m_aContainer.empty() ) 966 { 967 PassMap::iterator aIter = m_aContainer.find( aUrl ); 968 969 if( aIter == m_aContainer.end() ) 970 { 971 sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) ); 972 if( aInd > 0 && aUrl.getLength()-1 == aInd ) 973 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 ); 974 else 975 aUrl += ::rtl::OUString::createFromAscii( "/" ); 976 977 aIter = m_aContainer.find( aUrl ); 978 } 979 980 if( aIter != m_aContainer.end() ) 981 { 982 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) 983 if( aNPIter->GetUserName().equals( aName ) ) 984 { 985 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) && m_pStorageFile ) 986 m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName ) 987 988 // the iterator will not be used any more so it can be removed directly 989 aIter->second.erase( aNPIter ); 990 991 if( aIter->second.begin() == aIter->second.end() ) 992 m_aContainer.erase( aIter ); 993 994 return; 995 } 996 } 997 } 998 } 999 1000 //------------------------------------------------------------------------- 1001 1002 void SAL_CALL PasswordContainer::removePersistent( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException) 1003 { 1004 ::osl::MutexGuard aGuard( mMutex ); 1005 1006 ::rtl::OUString aUrl( aURL ); 1007 if( !m_aContainer.empty() ) 1008 { 1009 PassMap::iterator aIter = m_aContainer.find( aUrl ); 1010 1011 if( aIter == m_aContainer.end() ) 1012 { 1013 sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) ); 1014 if( aInd > 0 && aUrl.getLength()-1 == aInd ) 1015 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 ); 1016 else 1017 aUrl += ::rtl::OUString::createFromAscii( "/" ); 1018 1019 aIter = m_aContainer.find( aUrl ); 1020 } 1021 1022 if( aIter != m_aContainer.end() ) 1023 { 1024 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) 1025 if( aNPIter->GetUserName().equals( aName ) ) 1026 { 1027 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) 1028 { 1029 // TODO/LATER: should the password be converted to MemoryPassword? 1030 aNPIter->RemovePasswords( PERSISTENT_RECORD ); 1031 1032 if ( m_pStorageFile ) 1033 m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName ) 1034 } 1035 1036 if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) 1037 aIter->second.erase( aNPIter ); 1038 1039 if( aIter->second.begin() == aIter->second.end() ) 1040 m_aContainer.erase( aIter ); 1041 1042 return; 1043 } 1044 } 1045 } 1046 } 1047 //------------------------------------------------------------------------- 1048 1049 void SAL_CALL PasswordContainer::removeAllPersistent() throw(RuntimeException) 1050 { 1051 ::osl::MutexGuard aGuard( mMutex ); 1052 1053 if( m_pStorageFile ) 1054 m_pStorageFile->clear(); 1055 1056 for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); ) 1057 { 1058 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ) 1059 { 1060 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) 1061 { 1062 // TODO/LATER: should the password be converted to MemoryPassword? 1063 aNPIter->RemovePasswords( PERSISTENT_RECORD ); 1064 1065 if ( m_pStorageFile ) 1066 m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName ) 1067 } 1068 1069 if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) 1070 { 1071 list< NamePassRecord >::iterator aIterToDelete( aNPIter ); 1072 aNPIter++; 1073 aIter->second.erase( aIterToDelete ); 1074 } 1075 else 1076 aNPIter++; 1077 } 1078 1079 if( aIter->second.begin() == aIter->second.end() ) 1080 { 1081 PassMap::iterator aIterToDelete( aIter ); 1082 aIter++; 1083 m_aContainer.erase( aIterToDelete ); 1084 } 1085 else 1086 aIter++; 1087 } 1088 } 1089 //------------------------------------------------------------------------- 1090 1091 Sequence< UrlRecord > SAL_CALL PasswordContainer::getAllPersistent( const Reference< XInteractionHandler >& xHandler ) throw(RuntimeException) 1092 { 1093 Sequence< UrlRecord > aResult; 1094 1095 ::osl::MutexGuard aGuard( mMutex ); 1096 for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ ) 1097 { 1098 Sequence< UserRecord > aUsers; 1099 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) 1100 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) 1101 { 1102 sal_Int32 oldLen = aUsers.getLength(); 1103 aUsers.realloc( oldLen + 1 ); 1104 aUsers[ oldLen ] = UserRecord( aNPIter->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter->GetPersPasswords(), GetMasterPassword( xHandler ) ) ) ); 1105 } 1106 1107 if( aUsers.getLength() ) 1108 { 1109 sal_Int32 oldLen = aResult.getLength(); 1110 aResult.realloc( oldLen + 1 ); 1111 aResult[ oldLen ] = UrlRecord( aIter->first, aUsers ); 1112 } 1113 } 1114 1115 return aResult; 1116 } 1117 1118 //------------------------------------------------------------------------- 1119 sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) 1120 throw (uno::RuntimeException) 1121 { 1122 sal_Bool bResult = sal_False; 1123 ::rtl::OUString aEncodedMP; 1124 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; 1125 ::osl::MutexGuard aGuard( mMutex ); 1126 1127 // the method should fail if there is no master password 1128 if( m_pStorageFile && m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) ) 1129 { 1130 if ( !aEncodedMP.getLength() ) 1131 { 1132 // this is a default master password 1133 // no UI is necessary 1134 bResult = sal_True; 1135 } 1136 else 1137 { 1138 if ( !xTmpHandler.is() ) 1139 { 1140 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); 1141 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); 1142 } 1143 1144 if ( m_aMasterPasswd.getLength() ) 1145 { 1146 // there is a password, it should be just rechecked 1147 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER; 1148 ::rtl::OUString aPass; 1149 1150 do { 1151 aPass = RequestPasswordFromUser( aRMode, xTmpHandler ); 1152 bResult = ( aPass.getLength() && aPass.equals( m_aMasterPasswd ) ); 1153 aRMode = PasswordRequestMode_PASSWORD_REENTER; // further questions with error notification 1154 } while( !bResult && aPass.getLength() ); 1155 } 1156 else 1157 { 1158 try 1159 { 1160 // ask for the password, if user provide no correct password an exception will be thrown 1161 bResult = ( GetMasterPassword( xTmpHandler ).getLength() > 0 ); 1162 } 1163 catch( uno::Exception& ) 1164 {} 1165 } 1166 } 1167 } 1168 1169 return bResult; 1170 } 1171 1172 //------------------------------------------------------------------------- 1173 sal_Bool SAL_CALL PasswordContainer::changeMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) 1174 throw (uno::RuntimeException) 1175 { 1176 sal_Bool bResult = sal_False; 1177 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; 1178 ::osl::MutexGuard aGuard( mMutex ); 1179 1180 if ( m_pStorageFile && m_pStorageFile->useStorage() ) 1181 { 1182 if ( !xTmpHandler.is() ) 1183 { 1184 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); 1185 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); 1186 } 1187 1188 sal_Bool bCanChangePassword = sal_True; 1189 // if there is already a stored master password it should be entered by the user before the change happen 1190 ::rtl::OUString aEncodedMP; 1191 if( m_aMasterPasswd.getLength() || m_pStorageFile->getEncodedMP( aEncodedMP ) ) 1192 bCanChangePassword = authorizateWithMasterPassword( xTmpHandler ); 1193 1194 if ( bCanChangePassword ) 1195 { 1196 // ask for the new password, but do not set it 1197 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_CREATE; 1198 ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, xTmpHandler ); 1199 1200 if ( aPass.getLength() ) 1201 { 1202 // get all the persistent entries if it is possible 1203 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() ); 1204 1205 // remove the master password and the entries persistence 1206 removeMasterPassword(); 1207 1208 // store the new master password 1209 m_aMasterPasswd = aPass; 1210 vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd ); 1211 m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) ); 1212 1213 // store all the entries with the new password 1214 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ ) 1215 for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ ) 1216 addPersistent( aPersistent[nURLInd].Url, 1217 aPersistent[nURLInd].UserList[nNameInd].UserName, 1218 aPersistent[nURLInd].UserList[nNameInd].Passwords, 1219 uno::Reference< task::XInteractionHandler >() ); 1220 1221 bResult = sal_True; 1222 } 1223 } 1224 } 1225 1226 return bResult; 1227 } 1228 1229 //------------------------------------------------------------------------- 1230 void SAL_CALL PasswordContainer::removeMasterPassword() 1231 throw (uno::RuntimeException) 1232 { 1233 // remove all the stored passwords and the master password 1234 removeAllPersistent(); 1235 1236 ::osl::MutexGuard aGuard( mMutex ); 1237 if ( m_pStorageFile ) 1238 { 1239 m_aMasterPasswd = ::rtl::OUString(); 1240 m_pStorageFile->setEncodedMP( ::rtl::OUString() ); // let the master password be removed from configuration 1241 } 1242 } 1243 1244 //------------------------------------------------------------------------- 1245 ::sal_Bool SAL_CALL PasswordContainer::hasMasterPassword( ) 1246 throw (::com::sun::star::uno::RuntimeException) 1247 { 1248 ::osl::MutexGuard aGuard( mMutex ); 1249 1250 if ( !m_pStorageFile ) 1251 throw uno::RuntimeException(); 1252 1253 ::rtl::OUString aEncodedMP; 1254 return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) ); 1255 } 1256 1257 //------------------------------------------------------------------------- 1258 ::sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( ::sal_Bool bAllow ) 1259 throw (::com::sun::star::uno::RuntimeException) 1260 { 1261 ::osl::MutexGuard aGuard( mMutex ); 1262 1263 if ( !m_pStorageFile ) 1264 throw uno::RuntimeException(); 1265 1266 if ( !bAllow ) 1267 removeMasterPassword(); 1268 1269 if ( m_pStorageFile->useStorage() == bAllow ) 1270 return bAllow; 1271 1272 m_pStorageFile->setUseStorage( bAllow ); 1273 return !bAllow; 1274 } 1275 1276 //------------------------------------------------------------------------- 1277 ::sal_Bool SAL_CALL PasswordContainer::isPersistentStoringAllowed() 1278 throw (::com::sun::star::uno::RuntimeException) 1279 { 1280 ::osl::MutexGuard aGuard( mMutex ); 1281 1282 if ( !m_pStorageFile ) 1283 throw uno::RuntimeException(); 1284 1285 return m_pStorageFile->useStorage(); 1286 } 1287 1288 //------------------------------------------------------------------------- 1289 ::sal_Bool SAL_CALL PasswordContainer::useDefaultMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) 1290 throw ( uno::RuntimeException ) 1291 { 1292 sal_Bool bResult = sal_False; 1293 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; 1294 ::osl::MutexGuard aGuard( mMutex ); 1295 1296 if ( m_pStorageFile && m_pStorageFile->useStorage() ) 1297 { 1298 if ( !xTmpHandler.is() ) 1299 { 1300 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); 1301 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); 1302 } 1303 1304 sal_Bool bCanChangePassword = sal_True; 1305 // if there is already a stored nondefault master password it should be entered by the user before the change happen 1306 ::rtl::OUString aEncodedMP; 1307 if( m_pStorageFile->getEncodedMP( aEncodedMP ) && aEncodedMP.getLength() ) 1308 bCanChangePassword = authorizateWithMasterPassword( xTmpHandler ); 1309 1310 if ( bCanChangePassword ) 1311 { 1312 // generate the default password 1313 ::rtl::OUString aPass = GetDefaultMasterPassword(); 1314 if ( aPass.getLength() ) 1315 { 1316 // get all the persistent entries if it is possible 1317 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() ); 1318 1319 // remove the master password and the entries persistence 1320 removeMasterPassword(); 1321 1322 // store the empty string to flag the default master password 1323 m_aMasterPasswd = aPass; 1324 m_pStorageFile->setEncodedMP( ::rtl::OUString(), sal_True ); 1325 1326 // store all the entries with the new password 1327 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ ) 1328 for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ ) 1329 addPersistent( aPersistent[nURLInd].Url, 1330 aPersistent[nURLInd].UserList[nNameInd].UserName, 1331 aPersistent[nURLInd].UserList[nNameInd].Passwords, 1332 uno::Reference< task::XInteractionHandler >() ); 1333 1334 bResult = sal_True; 1335 } 1336 } 1337 } 1338 1339 return bResult; 1340 1341 } 1342 1343 //------------------------------------------------------------------------- 1344 ::sal_Bool SAL_CALL PasswordContainer::isDefaultMasterPasswordUsed() 1345 throw ( uno::RuntimeException ) 1346 { 1347 ::osl::MutexGuard aGuard( mMutex ); 1348 1349 if ( !m_pStorageFile ) 1350 throw uno::RuntimeException(); 1351 1352 ::rtl::OUString aEncodedMP; 1353 return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) && !aEncodedMP.getLength() ); 1354 } 1355 1356 1357 //------------------------------------------------------------------------- 1358 void SAL_CALL PasswordContainer::addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent ) 1359 throw (uno::RuntimeException) 1360 { 1361 mUrlContainer.add( Url, MakePersistent ); 1362 } 1363 1364 //------------------------------------------------------------------------- 1365 ::rtl::OUString SAL_CALL PasswordContainer::findUrl( const ::rtl::OUString& Url ) 1366 throw (uno::RuntimeException) 1367 { 1368 return mUrlContainer.find( Url ); 1369 } 1370 1371 //------------------------------------------------------------------------- 1372 void SAL_CALL PasswordContainer::removeUrl( const ::rtl::OUString& Url ) 1373 throw (uno::RuntimeException) 1374 { 1375 mUrlContainer.remove( Url ); 1376 } 1377 1378 //------------------------------------------------------------------------- 1379 uno::Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getUrls( ::sal_Bool OnlyPersistent ) 1380 throw (uno::RuntimeException) 1381 { 1382 return mUrlContainer.list( OnlyPersistent ); 1383 } 1384 1385 //------------------------------------------------------------------------- 1386 1387 void PasswordContainer::Notify() 1388 { 1389 ::osl::MutexGuard aGuard( mMutex ); 1390 1391 PassMap::iterator aIter; 1392 1393 // remove the cached persistent values in the memory 1394 for( aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ ) 1395 { 1396 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ) 1397 { 1398 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) 1399 { 1400 aNPIter->RemovePasswords( PERSISTENT_RECORD ); 1401 1402 if ( m_pStorageFile ) 1403 m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName ) 1404 } 1405 1406 if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) 1407 { 1408 list< NamePassRecord >::iterator aIterToDelete( aNPIter ); 1409 aNPIter++; 1410 aIter->second.erase( aIterToDelete ); 1411 } 1412 else 1413 aNPIter++; 1414 } 1415 } 1416 1417 PassMap addon; 1418 if( m_pStorageFile ) 1419 addon = m_pStorageFile->getInfo(); 1420 1421 for( aIter = addon.begin(); aIter != addon.end(); aIter++ ) 1422 { 1423 PassMap::iterator aSearchIter = m_aContainer.find( aIter->first ); 1424 if( aSearchIter != m_aContainer.end() ) 1425 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) 1426 UpdateVector( aSearchIter->first, aSearchIter->second, *aNPIter, sal_False ); 1427 else 1428 m_aContainer.insert( PairUrlRecord( aIter->first, aIter->second ) ); 1429 } 1430 } 1431 1432 //------------------------------------------------------------------------- 1433 1434 ::rtl::OUString SAL_CALL PasswordContainer::getImplementationName( ) throw(uno::RuntimeException) 1435 { 1436 return impl_getStaticImplementationName(); 1437 } 1438 1439 //------------------------------------------------------------------------- 1440 1441 sal_Bool SAL_CALL PasswordContainer::supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException) 1442 { 1443 if ( ServiceName.compareToAscii("com.sun.star.task.PasswordContainer") == 0 ) 1444 return sal_True; 1445 else 1446 return sal_False; 1447 } 1448 1449 //------------------------------------------------------------------------- 1450 1451 Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getSupportedServiceNames( ) throw(uno::RuntimeException) 1452 { 1453 return impl_getStaticSupportedServiceNames(); 1454 } 1455 1456 //------------------------------------------------------------------------- 1457 1458 Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::impl_getStaticSupportedServiceNames( ) throw(uno::RuntimeException) 1459 { 1460 Sequence< ::rtl::OUString > aRet(1); 1461 *aRet.getArray() = ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer"); 1462 return aRet; 1463 } 1464 1465 //------------------------------------------------------------------------- 1466 1467 ::rtl::OUString SAL_CALL PasswordContainer::impl_getStaticImplementationName() throw(uno::RuntimeException) 1468 { 1469 return ::rtl::OUString::createFromAscii("stardiv.svl.PasswordContainer"); 1470 } 1471 1472 //------------------------------------------------------------------------- 1473 1474 Reference< XInterface > SAL_CALL PasswordContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( RuntimeException ) 1475 { 1476 return Reference< XInterface >( *new PasswordContainer( xServiceManager ) ); 1477 } 1478 1479 //------------------------------------------------------------------------- 1480 1481 Reference< XSingleServiceFactory > SAL_CALL PasswordContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager ) throw(RuntimeException) 1482 { 1483 Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager, 1484 PasswordContainer::impl_getStaticImplementationName(), 1485 PasswordContainer::impl_createInstance, 1486 PasswordContainer::impl_getStaticSupportedServiceNames())); 1487 return xReturn ; 1488 1489 } 1490 1491 //------------------------------------------------------------------------- 1492 //------------------------------------------------------------------------- 1493 1494 MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode ) 1495 { 1496 MasterPasswordRequest aRequest; 1497 1498 aRequest.Classification = InteractionClassification_ERROR; 1499 aRequest.Mode = Mode; 1500 1501 setRequest( makeAny( aRequest ) ); 1502 1503 // Fill continuations... 1504 Sequence< RememberAuthentication > aRememberModes( 1 ); 1505 aRememberModes[ 0 ] = RememberAuthentication_NO; 1506 1507 m_xAuthSupplier 1508 = new ::ucbhelper::InteractionSupplyAuthentication( 1509 this, 1510 sal_False, // bCanSetRealm 1511 sal_False, // bCanSetUserName 1512 sal_True, // bCanSetPassword 1513 sal_False, // bCanSetAccount 1514 aRememberModes, // rRememberPasswordModes 1515 RememberAuthentication_NO, // eDefaultRememberPasswordMode 1516 aRememberModes, // rRememberAccountModes 1517 RememberAuthentication_NO, // eDefaultRememberAccountMode 1518 sal_False, // bCanUseSystemCredentials 1519 sal_False // bDefaultUseSystemCredentials 1520 ); 1521 1522 Sequence< 1523 Reference< XInteractionContinuation > > aContinuations( 3 ); 1524 aContinuations[ 0 ] = new ::ucbhelper::InteractionAbort( this ); 1525 aContinuations[ 1 ] = new ::ucbhelper::InteractionRetry( this ); 1526 aContinuations[ 2 ] = m_xAuthSupplier.get(); 1527 1528 setContinuations( aContinuations ); 1529 } 1530 1531 //------------------------------------------------------------------------- 1532 //------------------------------------------------------------------------- 1533 1534 extern "C" 1535 { 1536 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment ( 1537 const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */) 1538 { 1539 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 1540 } 1541 1542 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory ( 1543 const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */) 1544 { 1545 void * pResult = 0; 1546 if (pServiceManager) 1547 { 1548 Reference< XSingleServiceFactory > xFactory; 1549 if (PasswordContainer::impl_getStaticImplementationName().compareToAscii (pImplementationName) == 0) 1550 { 1551 xFactory = PasswordContainer::impl_createFactory ( 1552 reinterpret_cast< XMultiServiceFactory* >(pServiceManager)); 1553 } 1554 if (xFactory.is()) 1555 { 1556 xFactory->acquire(); 1557 pResult = xFactory.get(); 1558 } 1559 } 1560 return pResult; 1561 } 1562 1563 } // extern "C" 1564