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 ), mOldPasswordEncoding(false) 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& ) 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 /** 485 * @brief Decode a master password. 486 * 487 * @param aMasterPassword master password to decode. 488 * It must contain RTL_DIGEST_LENGTH_MD5 * 2 characters. 489 * @param code buffer to hold the decoded password. 490 * It must contain RTL_DIGEST_LENGTH_MD5 characters. 491 * @param oldEncoding use the encoding pre-AOO-4.1.12 if true 492 */ 493 static void decodeMasterPassword(const ::rtl::OUString& aMasterPasswd, 494 unsigned char *code, bool oldEncoding) 495 { 496 OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" ); 497 const sal_Unicode *aMasterBuf = aMasterPasswd.getStr(); 498 for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ ) { 499 if (!oldEncoding) { 500 code[ ind ] = (char)((((aMasterBuf[ind * 2] - 'a') & 15) << 4) | 501 ((aMasterBuf[ind * 2 + 1] - 'a') & 15)); 502 } else { 503 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16)); 504 } 505 } 506 } 507 508 //------------------------------------------------------------------------- 509 510 /** Prepare the IV. 511 * 512 * @param iv vector to prepare. Its contents are destroyed. 513 * @param masterPasswdCode master password as output from decodeMasterPassword. 514 * @param name name of the password to decrypt. 515 */ 516 static void prepareIV(std::vector<sal_uInt8>& iv, const unsigned char *masterPasswordCode, const ::rtl::OUString &aName) { 517 std::vector<sal_uInt8> ivSource; 518 ivSource.assign(masterPasswordCode, masterPasswordCode + RTL_DIGEST_LENGTH_MD5); 519 ::rtl::OString encodedName = ::rtl::OUStringToOString(aName, RTL_TEXTENCODING_UTF8 ); 520 ivSource.insert(ivSource.end(), encodedName.getStr(), encodedName.getStr() + encodedName.getLength()); 521 iv.resize(RTL_DIGEST_LENGTH_MD5); 522 rtl_digest_MD5(&ivSource[0], ivSource.size(), 523 &iv[0], iv.size()); 524 } 525 526 //------------------------------------------------------------------------- 527 vector< ::rtl::OUString > PasswordContainer::DecodePasswords(const ::rtl::OUString& aName, const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPasswd ) 528 { 529 if( aMasterPasswd.getLength() ) 530 { 531 rtlCipher aDecoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream ); 532 OSL_ENSURE( aDecoder, "Can't create decoder\n" ); 533 534 if( aDecoder ) 535 { 536 std::vector<sal_uInt8> iv; 537 unsigned char code[RTL_DIGEST_LENGTH_MD5]; 538 decodeMasterPassword(aMasterPasswd, code, mOldPasswordEncoding); 539 if (!mOldPasswordEncoding) { 540 prepareIV(iv, code, aName); 541 } 542 543 rtlCipherError result = rtl_cipher_init ( 544 aDecoder, rtl_Cipher_DirectionDecode, 545 code, RTL_DIGEST_LENGTH_MD5, (iv.size()? &iv[0] : NULL), 546 iv.size() ); 547 if( result == rtl_Cipher_E_None ) 548 { 549 ::rtl::ByteSequence aSeq = getBufFromAsciiLine( aLine ); 550 551 ::rtl::ByteSequence resSeq( aSeq.getLength() ); 552 553 result = rtl_cipher_decode ( aDecoder, (sal_uInt8*)aSeq.getArray(), aSeq.getLength(), 554 (sal_uInt8*)resSeq.getArray(), resSeq.getLength() ); 555 556 ::rtl::OUString aPasswd( ( sal_Char* )resSeq.getArray(), resSeq.getLength(), RTL_TEXTENCODING_UTF8 ); 557 558 rtl_cipher_destroy (aDecoder); 559 560 return getInfoFromInd( aPasswd ); 561 } 562 563 rtl_cipher_destroy (aDecoder); 564 } 565 } 566 else 567 { 568 OSL_ENSURE( sal_False, "No master password provided!\n" ); 569 // throw special exception 570 } 571 572 // problems with decoding 573 OSL_ENSURE( sal_False, "Problem with decoding\n" ); 574 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't decode!" ), Reference< XInterface >() ); 575 } 576 577 578 //------------------------------------------------------------------------- 579 580 ::rtl::OUString PasswordContainer::EncodePasswords( const ::rtl::OUString& aName, vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPasswd ) 581 { 582 if( aMasterPasswd.getLength() ) 583 { 584 ::rtl::OString aSeq = ::rtl::OUStringToOString( createIndex( lines ), RTL_TEXTENCODING_UTF8 ); 585 586 rtlCipher aEncoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream ); 587 OSL_ENSURE( aEncoder, "Can't create encoder\n" ); 588 589 if( aEncoder ) 590 { 591 std::vector<sal_uInt8> iv; 592 unsigned char code[RTL_DIGEST_LENGTH_MD5]; 593 decodeMasterPassword(aMasterPasswd, code, false); 594 if (!mOldPasswordEncoding) { 595 prepareIV(iv, code, aName); 596 } 597 598 rtlCipherError result = rtl_cipher_init ( 599 aEncoder, rtl_Cipher_DirectionEncode, 600 code, RTL_DIGEST_LENGTH_MD5, (iv.size()? &iv[0] : NULL), 601 iv.size() ); 602 603 if( result == rtl_Cipher_E_None ) 604 { 605 ::rtl::ByteSequence resSeq(aSeq.getLength()+1); 606 607 result = rtl_cipher_encode ( aEncoder, (sal_uInt8*)aSeq.getStr(), aSeq.getLength()+1, 608 (sal_uInt8*)resSeq.getArray(), resSeq.getLength() ); 609 610 /* 611 //test 612 rtlCipherError result = rtl_cipher_init ( 613 aEncoder, rtl_Cipher_DirectionDecode, 614 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 ); 615 616 617 if( result == rtl_Cipher_E_None ) 618 { 619 ::rtl::OUString testOU = getAsciiLine( resSeq ); 620 ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU ); 621 622 ::rtl::ByteSequence resSeq1( aSeq1.getLength() ); 623 624 if( resSeq.getLength() == aSeq1.getLength() ) 625 { 626 for( int ind = 0; ind < aSeq1.getLength(); ind++ ) 627 if( resSeq[ind] != aSeq1[ind] ) 628 testOU = ::rtl::OUString(); 629 } 630 631 result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(), 632 (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() ); 633 634 ::rtl::OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 ); 635 } 636 */ 637 638 rtl_cipher_destroy (aEncoder); 639 640 if( result == rtl_Cipher_E_None ) 641 return getAsciiLine( resSeq ); 642 643 } 644 645 rtl_cipher_destroy (aEncoder); 646 } 647 } 648 else 649 { 650 OSL_ENSURE( sal_False, "No master password provided!\n" ); 651 // throw special exception 652 } 653 654 // problems with encoding 655 OSL_ENSURE( sal_False, "Problem with encoding\n" ); 656 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't encode!" ), Reference< XInterface >() ); 657 } 658 659 //------------------------------------------------------------------------- 660 661 662 /** Return the "name" to use for the master password. */ 663 static const ::rtl::OUString& getMasterPasswordName(void) { 664 static const ::rtl::OUString value = ::rtl::OUString::createFromAscii( "Master" ); 665 return value; 666 } 667 668 //------------------------------------------------------------------------- 669 670 void PasswordContainer::doChangeMasterPassword(const ::rtl::OUString& aPass) { 671 // get all the persistent entries if it is possible 672 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() ); 673 674 // remove the master password and the entries persistence 675 removeMasterPassword(); 676 677 // store the new master password 678 m_aMasterPasswd = aPass; 679 vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd ); 680 m_pStorageFile->setEncodedMP( EncodePasswords( getMasterPasswordName(), aMaster, m_aMasterPasswd ) ); 681 682 // store all the entries with the new password 683 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ ) 684 for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ ) 685 addPersistent( aPersistent[nURLInd].Url, 686 aPersistent[nURLInd].UserList[nNameInd].UserName, 687 aPersistent[nURLInd].UserList[nNameInd].Passwords, 688 uno::Reference< task::XInteractionHandler >() ); 689 } 690 691 //------------------------------------------------------------------------- 692 693 void PasswordContainer::UpdateVector( const ::rtl::OUString& aURL, list< NamePassRecord >& toUpdate, NamePassRecord& aRecord, sal_Bool writeFile ) 694 { 695 for( list< NamePassRecord >::iterator aNPIter = toUpdate.begin(); aNPIter != toUpdate.end(); aNPIter++ ) 696 if( aNPIter->GetUserName().equals( aRecord.GetUserName() ) ) 697 { 698 if( aRecord.HasPasswords( MEMORY_RECORD ) ) 699 aNPIter->SetMemPasswords( aRecord.GetMemPasswords() ); 700 701 if( aRecord.HasPasswords( PERSISTENT_RECORD ) ) 702 { 703 aNPIter->SetPersPasswords( aRecord.GetPersPasswords() ); 704 705 if( writeFile ) 706 { 707 // the password must be already encoded 708 m_pStorageFile->update( aURL, aRecord ); // change existing ( aURL, aName ) record in the configfile 709 } 710 } 711 712 return; 713 } 714 715 716 if( aRecord.HasPasswords( PERSISTENT_RECORD ) && writeFile ) 717 { 718 // the password must be already encoded 719 m_pStorageFile->update( aURL, aRecord ); // add new aName to the existing url 720 } 721 722 toUpdate.insert( toUpdate.begin(), aRecord ); 723 } 724 725 //------------------------------------------------------------------------- 726 727 UserRecord PasswordContainer::CopyToUserRecord( const NamePassRecord& aRecord, sal_Bool& io_bTryToDecode, const Reference< XInteractionHandler >& aHandler ) 728 { 729 ::std::vector< ::rtl::OUString > aPasswords; 730 if( aRecord.HasPasswords( MEMORY_RECORD ) ) 731 aPasswords = aRecord.GetMemPasswords(); 732 733 if( io_bTryToDecode && aRecord.HasPasswords( PERSISTENT_RECORD ) ) 734 { 735 try 736 { 737 ::std::vector< ::rtl::OUString > aDecodedPasswords = DecodePasswords( aRecord.GetUserName(), aRecord.GetPersPasswords(), GetMasterPassword( aHandler ) ); 738 aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), aDecodedPasswords.end() ); 739 } 740 catch( NoMasterException& ) 741 { 742 // if master password could not be detected the entry will be just ignored 743 io_bTryToDecode = sal_False; 744 } 745 } 746 747 return UserRecord( aRecord.GetUserName(), copyVectorToSequence( aPasswords ) ); 748 } 749 750 //------------------------------------------------------------------------- 751 752 Sequence< UserRecord > PasswordContainer::CopyToUserRecordSequence( const list< NamePassRecord >& original, const Reference< XInteractionHandler >& aHandler ) 753 { 754 Sequence< UserRecord > aResult( original.size() ); 755 sal_uInt32 nInd = 0; 756 sal_Bool bTryToDecode = sal_True; 757 758 for( list< NamePassRecord >::const_iterator aNPIter = original.begin(); 759 aNPIter != original.end(); 760 aNPIter++, nInd++ ) 761 { 762 aResult[nInd] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler ); 763 } 764 765 return aResult; 766 } 767 768 //------------------------------------------------------------------------- 769 770 void SAL_CALL PasswordContainer::add( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) 771 { 772 ::osl::MutexGuard aGuard( mMutex ); 773 774 PrivateAdd( Url, UserName, Passwords, MEMORY_RECORD, aHandler ); 775 } 776 777 //------------------------------------------------------------------------- 778 779 void SAL_CALL PasswordContainer::addPersistent( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) 780 { 781 ::osl::MutexGuard aGuard( mMutex ); 782 783 PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler ); 784 } 785 786 //------------------------------------------------------------------------- 787 788 void PasswordContainer::PrivateAdd( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, char Mode, const Reference< XInteractionHandler >& aHandler ) 789 { 790 NamePassRecord aRecord( UserName ); 791 ::std::vector< ::rtl::OUString > aStorePass = copySequenceToVector( Passwords ); 792 793 if( Mode == PERSISTENT_RECORD ) 794 aRecord.SetPersPasswords( EncodePasswords( aRecord.GetUserName(), aStorePass, GetMasterPassword( aHandler ) ) ); 795 else if( Mode == MEMORY_RECORD ) 796 aRecord.SetMemPasswords( aStorePass ); 797 else 798 { 799 OSL_ASSERT( "Unexpected persistence status!" ); 800 return; 801 } 802 803 if( !m_aContainer.empty() ) 804 { 805 PassMap::iterator aIter = m_aContainer.find( Url ); 806 807 if( aIter != m_aContainer.end() ) 808 { 809 UpdateVector( aIter->first, aIter->second, aRecord, sal_True ); 810 return; 811 } 812 } 813 814 list< NamePassRecord > listToAdd( 1, aRecord ); 815 m_aContainer.insert( PairUrlRecord( Url, listToAdd ) ); 816 817 if( Mode == PERSISTENT_RECORD && m_pStorageFile && m_pStorageFile->useStorage() ) 818 m_pStorageFile->update( Url, aRecord ); 819 820 } 821 822 //------------------------------------------------------------------------- 823 824 825 UrlRecord SAL_CALL PasswordContainer::find( const ::rtl::OUString& aURL, const Reference< XInteractionHandler >& aHandler ) 826 { 827 return find( aURL, rtl::OUString(), false, aHandler ); 828 } 829 830 //------------------------------------------------------------------------- 831 832 UrlRecord SAL_CALL PasswordContainer::findForName( const ::rtl::OUString& aURL, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) 833 { 834 return find( aURL, aName, true, aHandler ); 835 } 836 837 //------------------------------------------------------------------------- 838 839 Sequence< UserRecord > PasswordContainer::FindUsr( const list< NamePassRecord >& userlist, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) 840 { 841 sal_uInt32 nInd = 0; 842 for( list< NamePassRecord >::const_iterator aNPIter = userlist.begin(); 843 aNPIter != userlist.end(); 844 aNPIter++, nInd++ ) 845 { 846 if( aNPIter->GetUserName().equals( aName ) ) 847 { 848 Sequence< UserRecord > aResult(1); 849 sal_Bool bTryToDecode = sal_True; 850 aResult[0] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler ); 851 852 return aResult; 853 } 854 } 855 856 return Sequence< UserRecord >(); 857 } 858 859 //------------------------------------------------------------------------- 860 861 bool PasswordContainer::createUrlRecord( 862 const PairUrlRecord & rPair, 863 bool bName, 864 const ::rtl::OUString & aName, 865 const Reference< XInteractionHandler >& aHandler, 866 UrlRecord & rRec ) 867 { 868 if ( bName ) 869 { 870 Sequence< UserRecord > aUsrRec 871 = FindUsr( rPair.second, aName, aHandler ); 872 if( aUsrRec.getLength() ) 873 { 874 rRec = UrlRecord( rPair.first, aUsrRec ); 875 return true; 876 } 877 } 878 else 879 { 880 rRec = UrlRecord( 881 rPair.first, 882 CopyToUserRecordSequence( rPair.second, aHandler ) ); 883 return true; 884 } 885 return false; 886 } 887 888 //------------------------------------------------------------------------- 889 890 UrlRecord PasswordContainer::find( 891 const ::rtl::OUString& aURL, 892 const ::rtl::OUString& aName, 893 bool bName, // only needed to support empty user names 894 const Reference< XInteractionHandler >& aHandler ) 895 { 896 ::osl::MutexGuard aGuard( mMutex ); 897 898 if( !m_aContainer.empty() && aURL.getLength() ) 899 { 900 ::rtl::OUString aUrl( aURL ); 901 902 // each iteration remove last '/...' section from the aUrl 903 // while it's possible, up to the most left '://' 904 do 905 { 906 // first look for <url>/somename and then look for <url>/somename/... 907 PassMap::iterator aIter = m_aContainer.find( aUrl ); 908 // Note that this iterator may be invalidated by the 909 // side-effects of createUrlRecord(), so we have to work with a 910 // copy of the pointed elements 911 if( aIter != m_aContainer.end() ) 912 { 913 const PairUrlRecord rPairUrlRecord = *aIter; 914 UrlRecord aRec; 915 if ( createUrlRecord( rPairUrlRecord, bName, aName, aHandler, aRec ) ) 916 return aRec; 917 } 918 else 919 { 920 ::rtl::OUString tmpUrl( aUrl ); 921 if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' ) 922 tmpUrl += ::rtl::OUString::createFromAscii( "/" ); 923 924 aIter = m_aContainer.lower_bound( tmpUrl ); 925 if( aIter != m_aContainer.end() && aIter->first.match( tmpUrl ) ) 926 { 927 const PairUrlRecord rPairUrlRecord = *aIter; 928 UrlRecord aRec; 929 if ( createUrlRecord( rPairUrlRecord, bName, aName, aHandler, aRec ) ) 930 return aRec; 931 } 932 } 933 } 934 while( shorterUrl( aUrl ) && aUrl.getLength() ); 935 } 936 937 return UrlRecord(); 938 } 939 940 //------------------------------------------------------------------------- 941 ::rtl::OUString PasswordContainer::GetDefaultMasterPassword() 942 { 943 ::rtl::OUString aResult; 944 for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ ) 945 aResult += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "aa" ) ); 946 947 return aResult; 948 } 949 950 //------------------------------------------------------------------------- 951 ::rtl::OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler ) 952 { 953 // empty string means that the call was cancelled or just failed 954 ::rtl::OUString aResult; 955 956 if ( xHandler.is() ) 957 { 958 ::rtl::Reference< MasterPasswordRequest_Impl > xRequest = new MasterPasswordRequest_Impl( aRMode ); 959 960 xHandler->handle( xRequest.get() ); 961 962 ::rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection(); 963 964 if ( xSelection.is() ) 965 { 966 Reference< XInteractionAbort > xAbort( xSelection.get(), UNO_QUERY ); 967 if ( !xAbort.is() ) 968 { 969 const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp 970 = xRequest->getAuthenticationSupplier(); 971 972 aResult = xSupp->getPassword(); 973 } 974 } 975 } 976 977 return aResult; 978 } 979 980 //------------------------------------------------------------------------- 981 982 ::rtl::OUString PasswordContainer::GetMasterPassword( const Reference< XInteractionHandler >& aHandler ) 983 { 984 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER; 985 if( !m_pStorageFile || !m_pStorageFile->useStorage() ) 986 throw NoMasterException( ::rtl::OUString::createFromAscii( "Password storing is not active!" ), Reference< XInterface >(), aRMode ); 987 988 if( !m_aMasterPasswd.getLength() && aHandler.is() ) 989 { 990 ::rtl::OUString aEncodedMP; 991 sal_Bool bAskAgain = sal_False; 992 sal_Bool bDefaultPassword = sal_False; 993 994 if( !m_pStorageFile->getEncodedMP( aEncodedMP ) ) 995 aRMode = PasswordRequestMode_PASSWORD_CREATE; 996 else if ( !aEncodedMP.getLength() ) 997 { 998 m_aMasterPasswd = GetDefaultMasterPassword(); 999 bDefaultPassword = sal_True; 1000 } 1001 1002 if ( !bDefaultPassword ) 1003 { 1004 do { 1005 bAskAgain = sal_False; 1006 1007 ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, aHandler ); 1008 if ( aPass.getLength() ) 1009 { 1010 if( aRMode == PasswordRequestMode_PASSWORD_CREATE ) 1011 { 1012 m_aMasterPasswd = aPass; 1013 vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd ); 1014 1015 m_pStorageFile->setEncodedMP( EncodePasswords( getMasterPasswordName(), aMaster, m_aMasterPasswd ) ); 1016 } 1017 else 1018 { 1019 vector< ::rtl::OUString > aRM( DecodePasswords( getMasterPasswordName(), aEncodedMP, aPass ) ); 1020 if( !aRM.size() || !aPass.equals( aRM[0] ) ) 1021 { 1022 // Try the old encoding 1023 mOldPasswordEncoding = true; 1024 try { 1025 aRM = DecodePasswords( getMasterPasswordName(), aEncodedMP, aPass ); 1026 if (aRM.size() && aPass.equals(aRM[0])) { 1027 // Update all passwords to the new encoding 1028 m_aMasterPasswd = aPass; 1029 doChangeMasterPassword(aPass); 1030 } 1031 mOldPasswordEncoding = false; 1032 } catch (...) { 1033 mOldPasswordEncoding = false; 1034 throw; 1035 } 1036 } 1037 if( !aRM.size() || !aPass.equals( aRM[0] ) ) 1038 { 1039 bAskAgain = sal_True; 1040 aRMode = PasswordRequestMode_PASSWORD_REENTER; 1041 } 1042 else 1043 m_aMasterPasswd = aPass; 1044 } 1045 } 1046 1047 } while( bAskAgain ); 1048 } 1049 } 1050 1051 if ( !m_aMasterPasswd.getLength() ) 1052 throw NoMasterException( ::rtl::OUString::createFromAscii( "No master password!" ), Reference< XInterface >(), aRMode ); 1053 1054 return m_aMasterPasswd; 1055 } 1056 1057 //------------------------------------------------------------------------- 1058 1059 void SAL_CALL PasswordContainer::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) 1060 { 1061 ::osl::MutexGuard aGuard( mMutex ); 1062 1063 ::rtl::OUString aUrl( aURL ); 1064 if( !m_aContainer.empty() ) 1065 { 1066 PassMap::iterator aIter = m_aContainer.find( aUrl ); 1067 1068 if( aIter == m_aContainer.end() ) 1069 { 1070 sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) ); 1071 if( aInd > 0 && aUrl.getLength()-1 == aInd ) 1072 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 ); 1073 else 1074 aUrl += ::rtl::OUString::createFromAscii( "/" ); 1075 1076 aIter = m_aContainer.find( aUrl ); 1077 } 1078 1079 if( aIter != m_aContainer.end() ) 1080 { 1081 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) 1082 if( aNPIter->GetUserName().equals( aName ) ) 1083 { 1084 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) && m_pStorageFile ) 1085 m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName ) 1086 1087 // the iterator will not be used any more so it can be removed directly 1088 aIter->second.erase( aNPIter ); 1089 1090 if( aIter->second.begin() == aIter->second.end() ) 1091 m_aContainer.erase( aIter ); 1092 1093 return; 1094 } 1095 } 1096 } 1097 } 1098 1099 //------------------------------------------------------------------------- 1100 1101 void SAL_CALL PasswordContainer::removePersistent( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) 1102 { 1103 ::osl::MutexGuard aGuard( mMutex ); 1104 1105 ::rtl::OUString aUrl( aURL ); 1106 if( !m_aContainer.empty() ) 1107 { 1108 PassMap::iterator aIter = m_aContainer.find( aUrl ); 1109 1110 if( aIter == m_aContainer.end() ) 1111 { 1112 sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) ); 1113 if( aInd > 0 && aUrl.getLength()-1 == aInd ) 1114 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 ); 1115 else 1116 aUrl += ::rtl::OUString::createFromAscii( "/" ); 1117 1118 aIter = m_aContainer.find( aUrl ); 1119 } 1120 1121 if( aIter != m_aContainer.end() ) 1122 { 1123 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) 1124 if( aNPIter->GetUserName().equals( aName ) ) 1125 { 1126 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) 1127 { 1128 // TODO/LATER: should the password be converted to MemoryPassword? 1129 aNPIter->RemovePasswords( PERSISTENT_RECORD ); 1130 1131 if ( m_pStorageFile ) 1132 m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName ) 1133 } 1134 1135 if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) 1136 aIter->second.erase( aNPIter ); 1137 1138 if( aIter->second.begin() == aIter->second.end() ) 1139 m_aContainer.erase( aIter ); 1140 1141 return; 1142 } 1143 } 1144 } 1145 } 1146 //------------------------------------------------------------------------- 1147 1148 void SAL_CALL PasswordContainer::removeAllPersistent() 1149 { 1150 ::osl::MutexGuard aGuard( mMutex ); 1151 1152 if( m_pStorageFile ) 1153 m_pStorageFile->clear(); 1154 1155 for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); ) 1156 { 1157 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ) 1158 { 1159 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) 1160 { 1161 // TODO/LATER: should the password be converted to MemoryPassword? 1162 aNPIter->RemovePasswords( PERSISTENT_RECORD ); 1163 } 1164 1165 if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) 1166 { 1167 list< NamePassRecord >::iterator aIterToDelete( aNPIter ); 1168 aNPIter++; 1169 aIter->second.erase( aIterToDelete ); 1170 } 1171 else 1172 aNPIter++; 1173 } 1174 1175 if( aIter->second.begin() == aIter->second.end() ) 1176 { 1177 PassMap::iterator aIterToDelete( aIter ); 1178 aIter++; 1179 m_aContainer.erase( aIterToDelete ); 1180 } 1181 else 1182 aIter++; 1183 } 1184 } 1185 //------------------------------------------------------------------------- 1186 1187 Sequence< UrlRecord > SAL_CALL PasswordContainer::getAllPersistent( const Reference< XInteractionHandler >& xHandler ) 1188 { 1189 Sequence< UrlRecord > aResult; 1190 1191 ::osl::MutexGuard aGuard( mMutex ); 1192 for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ ) 1193 { 1194 Sequence< UserRecord > aUsers; 1195 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) 1196 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) 1197 { 1198 sal_Int32 oldLen = aUsers.getLength(); 1199 aUsers.realloc( oldLen + 1 ); 1200 aUsers[ oldLen ] = UserRecord( aNPIter->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter->GetUserName(), aNPIter->GetPersPasswords(), GetMasterPassword( xHandler ) ) ) ); 1201 } 1202 1203 if( aUsers.getLength() ) 1204 { 1205 sal_Int32 oldLen = aResult.getLength(); 1206 aResult.realloc( oldLen + 1 ); 1207 aResult[ oldLen ] = UrlRecord( aIter->first, aUsers ); 1208 } 1209 } 1210 1211 return aResult; 1212 } 1213 1214 //------------------------------------------------------------------------- 1215 sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) 1216 { 1217 sal_Bool bResult = sal_False; 1218 ::rtl::OUString aEncodedMP; 1219 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; 1220 ::osl::MutexGuard aGuard( mMutex ); 1221 1222 // the method should fail if there is no master password 1223 if( m_pStorageFile && m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) ) 1224 { 1225 if ( !aEncodedMP.getLength() ) 1226 { 1227 // this is a default master password 1228 // no UI is necessary 1229 bResult = sal_True; 1230 } 1231 else 1232 { 1233 if ( !xTmpHandler.is() ) 1234 { 1235 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); 1236 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); 1237 } 1238 1239 if ( m_aMasterPasswd.getLength() ) 1240 { 1241 // there is a password, it should be just rechecked 1242 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER; 1243 ::rtl::OUString aPass; 1244 1245 do { 1246 aPass = RequestPasswordFromUser( aRMode, xTmpHandler ); 1247 bResult = ( aPass.getLength() && aPass.equals( m_aMasterPasswd ) ); 1248 aRMode = PasswordRequestMode_PASSWORD_REENTER; // further questions with error notification 1249 } while( !bResult && aPass.getLength() ); 1250 } 1251 else 1252 { 1253 try 1254 { 1255 // ask for the password, if user provide no correct password an exception will be thrown 1256 bResult = ( GetMasterPassword( xTmpHandler ).getLength() > 0 ); 1257 } 1258 catch( uno::Exception& ) 1259 {} 1260 } 1261 } 1262 } 1263 1264 return bResult; 1265 } 1266 1267 //------------------------------------------------------------------------- 1268 sal_Bool SAL_CALL PasswordContainer::changeMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) 1269 { 1270 sal_Bool bResult = sal_False; 1271 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; 1272 ::osl::MutexGuard aGuard( mMutex ); 1273 1274 if ( m_pStorageFile && m_pStorageFile->useStorage() ) 1275 { 1276 if ( !xTmpHandler.is() ) 1277 { 1278 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); 1279 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); 1280 } 1281 1282 sal_Bool bCanChangePassword = sal_True; 1283 // if there is already a stored master password it should be entered by the user before the change happen 1284 ::rtl::OUString aEncodedMP; 1285 if( m_aMasterPasswd.getLength() || m_pStorageFile->getEncodedMP( aEncodedMP ) ) 1286 bCanChangePassword = authorizateWithMasterPassword( xTmpHandler ); 1287 1288 if ( bCanChangePassword ) 1289 { 1290 // ask for the new password, but do not set it 1291 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_CREATE; 1292 ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, xTmpHandler ); 1293 1294 if ( aPass.getLength() ) 1295 { 1296 doChangeMasterPassword(aPass); 1297 bResult = sal_True; 1298 } 1299 } 1300 } 1301 1302 return bResult; 1303 } 1304 1305 //------------------------------------------------------------------------- 1306 void SAL_CALL PasswordContainer::removeMasterPassword() 1307 { 1308 // remove all the stored passwords and the master password 1309 removeAllPersistent(); 1310 1311 // Make sure we will not use the older encoding in the future 1312 mOldPasswordEncoding = false; 1313 1314 ::osl::MutexGuard aGuard( mMutex ); 1315 if ( m_pStorageFile ) 1316 { 1317 m_aMasterPasswd = ::rtl::OUString(); 1318 m_pStorageFile->setEncodedMP( ::rtl::OUString() ); // let the master password be removed from configuration 1319 } 1320 } 1321 1322 //------------------------------------------------------------------------- 1323 ::sal_Bool SAL_CALL PasswordContainer::hasMasterPassword( ) 1324 { 1325 ::osl::MutexGuard aGuard( mMutex ); 1326 1327 if ( !m_pStorageFile ) 1328 throw uno::RuntimeException(); 1329 1330 ::rtl::OUString aEncodedMP; 1331 return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) ); 1332 } 1333 1334 //------------------------------------------------------------------------- 1335 ::sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( ::sal_Bool bAllow ) 1336 { 1337 ::osl::MutexGuard aGuard( mMutex ); 1338 1339 if ( !m_pStorageFile ) 1340 throw uno::RuntimeException(); 1341 1342 if ( !bAllow ) 1343 removeMasterPassword(); 1344 1345 if ( m_pStorageFile->useStorage() == bAllow ) 1346 return bAllow; 1347 1348 m_pStorageFile->setUseStorage( bAllow ); 1349 return !bAllow; 1350 } 1351 1352 //------------------------------------------------------------------------- 1353 ::sal_Bool SAL_CALL PasswordContainer::isPersistentStoringAllowed() 1354 { 1355 ::osl::MutexGuard aGuard( mMutex ); 1356 1357 if ( !m_pStorageFile ) 1358 throw uno::RuntimeException(); 1359 1360 return m_pStorageFile->useStorage(); 1361 } 1362 1363 //------------------------------------------------------------------------- 1364 ::sal_Bool SAL_CALL PasswordContainer::useDefaultMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) 1365 { 1366 sal_Bool bResult = sal_False; 1367 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; 1368 ::osl::MutexGuard aGuard( mMutex ); 1369 1370 if ( m_pStorageFile && m_pStorageFile->useStorage() ) 1371 { 1372 if ( !xTmpHandler.is() ) 1373 { 1374 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); 1375 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); 1376 } 1377 1378 sal_Bool bCanChangePassword = sal_True; 1379 // if there is already a stored nondefault master password it should be entered by the user before the change happen 1380 ::rtl::OUString aEncodedMP; 1381 if( m_pStorageFile->getEncodedMP( aEncodedMP ) && aEncodedMP.getLength() ) 1382 bCanChangePassword = authorizateWithMasterPassword( xTmpHandler ); 1383 1384 if ( bCanChangePassword ) 1385 { 1386 // generate the default password 1387 ::rtl::OUString aPass = GetDefaultMasterPassword(); 1388 if ( aPass.getLength() ) 1389 { 1390 // get all the persistent entries if it is possible 1391 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() ); 1392 1393 // remove the master password and the entries persistence 1394 removeMasterPassword(); 1395 1396 // store the empty string to flag the default master password 1397 m_aMasterPasswd = aPass; 1398 m_pStorageFile->setEncodedMP( ::rtl::OUString(), sal_True ); 1399 1400 // store all the entries with the new password 1401 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ ) 1402 for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ ) 1403 addPersistent( aPersistent[nURLInd].Url, 1404 aPersistent[nURLInd].UserList[nNameInd].UserName, 1405 aPersistent[nURLInd].UserList[nNameInd].Passwords, 1406 uno::Reference< task::XInteractionHandler >() ); 1407 1408 bResult = sal_True; 1409 } 1410 } 1411 } 1412 1413 return bResult; 1414 1415 } 1416 1417 //------------------------------------------------------------------------- 1418 ::sal_Bool SAL_CALL PasswordContainer::isDefaultMasterPasswordUsed() 1419 { 1420 ::osl::MutexGuard aGuard( mMutex ); 1421 1422 if ( !m_pStorageFile ) 1423 throw uno::RuntimeException(); 1424 1425 ::rtl::OUString aEncodedMP; 1426 return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) && !aEncodedMP.getLength() ); 1427 } 1428 1429 1430 //------------------------------------------------------------------------- 1431 void SAL_CALL PasswordContainer::addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent ) 1432 { 1433 mUrlContainer.add( Url, MakePersistent ); 1434 } 1435 1436 //------------------------------------------------------------------------- 1437 ::rtl::OUString SAL_CALL PasswordContainer::findUrl( const ::rtl::OUString& Url ) 1438 { 1439 return mUrlContainer.find( Url ); 1440 } 1441 1442 //------------------------------------------------------------------------- 1443 void SAL_CALL PasswordContainer::removeUrl( const ::rtl::OUString& Url ) 1444 { 1445 mUrlContainer.remove( Url ); 1446 } 1447 1448 //------------------------------------------------------------------------- 1449 uno::Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getUrls( ::sal_Bool OnlyPersistent ) 1450 { 1451 return mUrlContainer.list( OnlyPersistent ); 1452 } 1453 1454 //------------------------------------------------------------------------- 1455 1456 void PasswordContainer::Notify() 1457 { 1458 ::osl::MutexGuard aGuard( mMutex ); 1459 1460 PassMap::iterator aIter; 1461 1462 // remove the cached persistent values in the memory 1463 for( aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ ) 1464 { 1465 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ) 1466 { 1467 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) 1468 { 1469 aNPIter->RemovePasswords( PERSISTENT_RECORD ); 1470 1471 if ( m_pStorageFile ) 1472 m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName ) 1473 } 1474 1475 if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) 1476 { 1477 list< NamePassRecord >::iterator aIterToDelete( aNPIter ); 1478 aNPIter++; 1479 aIter->second.erase( aIterToDelete ); 1480 } 1481 else 1482 aNPIter++; 1483 } 1484 } 1485 1486 PassMap addon; 1487 if( m_pStorageFile ) 1488 addon = m_pStorageFile->getInfo(); 1489 1490 for( aIter = addon.begin(); aIter != addon.end(); aIter++ ) 1491 { 1492 PassMap::iterator aSearchIter = m_aContainer.find( aIter->first ); 1493 if( aSearchIter != m_aContainer.end() ) 1494 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) 1495 UpdateVector( aSearchIter->first, aSearchIter->second, *aNPIter, sal_False ); 1496 else 1497 m_aContainer.insert( PairUrlRecord( aIter->first, aIter->second ) ); 1498 } 1499 } 1500 1501 //------------------------------------------------------------------------- 1502 1503 ::rtl::OUString SAL_CALL PasswordContainer::getImplementationName( ) 1504 { 1505 return impl_getStaticImplementationName(); 1506 } 1507 1508 //------------------------------------------------------------------------- 1509 1510 sal_Bool SAL_CALL PasswordContainer::supportsService( const ::rtl::OUString& ServiceName ) 1511 { 1512 if ( ServiceName.compareToAscii("com.sun.star.task.PasswordContainer") == 0 ) 1513 return sal_True; 1514 else 1515 return sal_False; 1516 } 1517 1518 //------------------------------------------------------------------------- 1519 1520 Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getSupportedServiceNames( ) 1521 { 1522 return impl_getStaticSupportedServiceNames(); 1523 } 1524 1525 //------------------------------------------------------------------------- 1526 1527 Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::impl_getStaticSupportedServiceNames( ) 1528 { 1529 Sequence< ::rtl::OUString > aRet(1); 1530 *aRet.getArray() = ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer"); 1531 return aRet; 1532 } 1533 1534 //------------------------------------------------------------------------- 1535 1536 ::rtl::OUString SAL_CALL PasswordContainer::impl_getStaticImplementationName() 1537 { 1538 return ::rtl::OUString::createFromAscii("stardiv.svl.PasswordContainer"); 1539 } 1540 1541 //------------------------------------------------------------------------- 1542 1543 Reference< XInterface > SAL_CALL PasswordContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) 1544 { 1545 return Reference< XInterface >( *new PasswordContainer( xServiceManager ) ); 1546 } 1547 1548 //------------------------------------------------------------------------- 1549 1550 Reference< XSingleServiceFactory > SAL_CALL PasswordContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager ) 1551 { 1552 Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager, 1553 PasswordContainer::impl_getStaticImplementationName(), 1554 PasswordContainer::impl_createInstance, 1555 PasswordContainer::impl_getStaticSupportedServiceNames())); 1556 return xReturn ; 1557 1558 } 1559 1560 //------------------------------------------------------------------------- 1561 //------------------------------------------------------------------------- 1562 1563 MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode ) 1564 { 1565 MasterPasswordRequest aRequest; 1566 1567 aRequest.Classification = InteractionClassification_ERROR; 1568 aRequest.Mode = Mode; 1569 1570 setRequest( makeAny( aRequest ) ); 1571 1572 // Fill continuations... 1573 Sequence< RememberAuthentication > aRememberModes( 1 ); 1574 aRememberModes[ 0 ] = RememberAuthentication_NO; 1575 1576 m_xAuthSupplier 1577 = new ::ucbhelper::InteractionSupplyAuthentication( 1578 this, 1579 sal_False, // bCanSetRealm 1580 sal_False, // bCanSetUserName 1581 sal_True, // bCanSetPassword 1582 sal_False, // bCanSetAccount 1583 aRememberModes, // rRememberPasswordModes 1584 RememberAuthentication_NO, // eDefaultRememberPasswordMode 1585 aRememberModes, // rRememberAccountModes 1586 RememberAuthentication_NO, // eDefaultRememberAccountMode 1587 sal_False, // bCanUseSystemCredentials 1588 sal_False // bDefaultUseSystemCredentials 1589 ); 1590 1591 Sequence< 1592 Reference< XInteractionContinuation > > aContinuations( 3 ); 1593 aContinuations[ 0 ] = new ::ucbhelper::InteractionAbort( this ); 1594 aContinuations[ 1 ] = new ::ucbhelper::InteractionRetry( this ); 1595 aContinuations[ 2 ] = m_xAuthSupplier.get(); 1596 1597 setContinuations( aContinuations ); 1598 } 1599 1600 //------------------------------------------------------------------------- 1601 //------------------------------------------------------------------------- 1602 1603 extern "C" 1604 { 1605 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment ( 1606 const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */) 1607 { 1608 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; 1609 } 1610 1611 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory ( 1612 const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */) 1613 { 1614 void * pResult = 0; 1615 if (pServiceManager) 1616 { 1617 Reference< XSingleServiceFactory > xFactory; 1618 if (PasswordContainer::impl_getStaticImplementationName().compareToAscii (pImplementationName) == 0) 1619 { 1620 xFactory = PasswordContainer::impl_createFactory ( 1621 reinterpret_cast< XMultiServiceFactory* >(pServiceManager)); 1622 } 1623 if (xFactory.is()) 1624 { 1625 xFactory->acquire(); 1626 pResult = xFactory.get(); 1627 } 1628 } 1629 return pResult; 1630 } 1631 1632 } // extern "C" 1633