/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_svl.hxx" #include "passwordcontainer.hxx" #include #include "cppuhelper/factory.hxx" #include #include #include #include #include #include #include #ifndef _TOOLS_INETSTRM_HXX // @@@ #include #endif using namespace std; using namespace osl; using namespace utl; using namespace com::sun::star; using namespace com::sun::star::uno; using namespace com::sun::star::registry; using namespace com::sun::star::lang; using namespace com::sun::star::task; using namespace com::sun::star::ucb; //------------------------------------------------------------------------- //------------------------------------------------------------------------- static ::rtl::OUString createIndex( vector< ::rtl::OUString > lines ) { ::rtl::OString aResult; const sal_Char* pLine; for( unsigned int i = 0; i < lines.size(); i++ ) { if( i ) aResult += ::rtl::OString( "__" ); ::rtl::OString line = ::rtl::OUStringToOString( lines[i], RTL_TEXTENCODING_UTF8 ); pLine = line.getStr(); while( *pLine ) { if( ( *pLine >= 'A' && *pLine <= 'Z' ) || ( *pLine >= 'a' && *pLine <= 'z' ) || ( *pLine >= '0' && *pLine <= '9' ) ) { aResult += ::rtl::OString::valueOf( *pLine ); } else { aResult += ::rtl::OString("_"); aResult += ::rtl::OString::valueOf( (sal_Int32) *pLine, 16 ); } pLine++; } } return ::rtl::OUString::createFromAscii( aResult.getStr() ); } //------------------------------------------------------------------------- static vector< ::rtl::OUString > getInfoFromInd( ::rtl::OUString aInd ) { vector< ::rtl::OUString > aResult; sal_Bool aStart = sal_True; ::rtl::OString line = ::rtl::OUStringToOString( aInd, RTL_TEXTENCODING_ASCII_US ); const sal_Char* pLine = line.getStr(); do { ::rtl::OUString newItem; if( !aStart ) pLine += 2; else aStart = sal_False; while( *pLine && !( pLine[0] == '_' && pLine[1] == '_' )) if( *pLine != '_' ) { newItem += ::rtl::OUString::valueOf( (sal_Unicode) *pLine ); pLine++; } else { ::rtl::OUString aNum; for( int i = 1; i < 3; i++ ) { if( !pLine[i] || ( ( pLine[i] < '0' || pLine[i] > '9' ) && ( pLine[i] < 'a' || pLine[i] > 'f' ) && ( pLine[i] < 'A' || pLine[i] > 'F' ) ) ) { OSL_ENSURE( sal_False, "Wrong index syntax!\n" ); return aResult; } aNum += ::rtl::OUString::valueOf( (sal_Unicode) pLine[i] ); } newItem += ::rtl::OUString::valueOf( (sal_Unicode) aNum.toInt32( 16 ) ); pLine += 3; } aResult.push_back( newItem ); } while( pLine[0] == '_' && pLine[1] == '_' ); if( *pLine ) OSL_ENSURE( sal_False, "Wrong index syntax!\n" ); return aResult; } //------------------------------------------------------------------------- static sal_Bool shorterUrl( ::rtl::OUString& aURL ) { sal_Int32 aInd = aURL.lastIndexOf( sal_Unicode( '/' ) ); if( aInd > 0 && aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) ) != aInd-2 ) { aURL = aURL.copy( 0, aInd ); return sal_True; } return sal_False; } //------------------------------------------------------------------------- static ::rtl::OUString getAsciiLine( const ::rtl::ByteSequence& buf ) { ::rtl::OUString aResult; ::rtl::ByteSequence outbuf( buf.getLength()*2+1 ); for( int ind = 0; ind < buf.getLength(); ind++ ) { outbuf[ind*2] = ( ((sal_uInt8)buf[ind]) >> 4 ) + 'a'; outbuf[ind*2+1] = ( ((sal_uInt8)buf[ind]) & 0x0f ) + 'a'; } outbuf[buf.getLength()*2] = '\0'; aResult = ::rtl::OUString::createFromAscii( (sal_Char*)outbuf.getArray() ); return aResult; } //------------------------------------------------------------------------- static ::rtl::ByteSequence getBufFromAsciiLine( ::rtl::OUString line ) { OSL_ENSURE( line.getLength() % 2 == 0, "Wrong syntax!\n" ); ::rtl::OString tmpLine = ::rtl::OUStringToOString( line, RTL_TEXTENCODING_ASCII_US ); ::rtl::ByteSequence aResult(line.getLength()/2); for( int ind = 0; ind < tmpLine.getLength()/2; ind++ ) { aResult[ind] = ( (sal_uInt8)( tmpLine.getStr()[ind*2] - 'a' ) << 4 ) | (sal_uInt8)( tmpLine.getStr()[ind*2+1] - 'a' ); } return aResult; } //------------------------------------------------------------------------- static Sequence< ::rtl::OUString > copyVectorToSequence( const vector< ::rtl::OUString >& original ) { Sequence< ::rtl::OUString > newOne ( original.size() ); for( unsigned int i = 0; i < original.size() ; i++ ) newOne[i] = original[i]; return newOne; } static vector< ::rtl::OUString > copySequenceToVector( const Sequence< ::rtl::OUString >& original ) { vector< ::rtl::OUString > newOne ( original.getLength() ); for( int i = 0; i < original.getLength() ; i++ ) newOne[i] = original[i]; return newOne; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- PassMap StorageItem::getInfo() { PassMap aResult; Sequence< ::rtl::OUString > aNodeNames = ConfigItem::GetNodeNames( ::rtl::OUString::createFromAscii("Store") ); sal_Int32 aNodeCount = aNodeNames.getLength(); Sequence< ::rtl::OUString > aPropNames( aNodeCount ); sal_Int32 aNodeInd; for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd ) { aPropNames[aNodeInd] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); aPropNames[aNodeInd] += aNodeNames[aNodeInd]; aPropNames[aNodeInd] += ::rtl::OUString::createFromAscii( "']/Password" ); } Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aPropNames ); if( aPropertyValues.getLength() != aNodeNames.getLength() ) { OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); return aResult; } for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd ) { vector< ::rtl::OUString > aUrlUsr = getInfoFromInd( aNodeNames[aNodeInd] ); if( aUrlUsr.size() == 2 ) { ::rtl::OUString aUrl = aUrlUsr[0]; ::rtl::OUString aName = aUrlUsr[1]; ::rtl::OUString aEPasswd; aPropertyValues[aNodeInd] >>= aEPasswd; PassMap::iterator aIter = aResult.find( aUrl ); if( aIter != aResult.end() ) aIter->second.push_back( NamePassRecord( aName, aEPasswd ) ); else { NamePassRecord aNewRecord( aName, aEPasswd ); list< NamePassRecord > listToAdd( 1, aNewRecord ); aResult.insert( PairUrlRecord( aUrl, listToAdd ) ); } } else OSL_ENSURE( sal_False, "Wrong index sintax!\n" ); } return aResult; } //------------------------------------------------------------------------- void StorageItem::setUseStorage( sal_Bool bUse ) { Sequence< ::rtl::OUString > sendNames(1); Sequence< uno::Any > sendVals(1); sendNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" ); sendVals[0] <<= bUse; ConfigItem::SetModified(); ConfigItem::PutProperties( sendNames, sendVals ); } //------------------------------------------------------------------------- sal_Bool StorageItem::useStorage() { Sequence< ::rtl::OUString > aNodeNames( 1 ); aNodeNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" ); Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames ); if( aPropertyValues.getLength() != aNodeNames.getLength() ) { OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); return sal_False; } sal_Bool aResult = false; aPropertyValues[0] >>= aResult; return aResult; } //------------------------------------------------------------------------- sal_Bool StorageItem::getEncodedMP( ::rtl::OUString& aResult ) { if( hasEncoded ) { aResult = mEncoded; return sal_True; } Sequence< ::rtl::OUString > aNodeNames( 2 ); aNodeNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" ); aNodeNames[1] = ::rtl::OUString::createFromAscii( "Master" ); Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames ); if( aPropertyValues.getLength() != aNodeNames.getLength() ) { OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" ); return sal_False; } aPropertyValues[0] >>= hasEncoded; aPropertyValues[1] >>= mEncoded; aResult = mEncoded; return hasEncoded; } //------------------------------------------------------------------------- void StorageItem::setEncodedMP( const ::rtl::OUString& aEncoded, sal_Bool bAcceptEmpty ) { Sequence< ::rtl::OUString > sendNames(2); Sequence< uno::Any > sendVals(2); sendNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" ); sendNames[1] = ::rtl::OUString::createFromAscii( "Master" ); sal_Bool bHasMaster = ( aEncoded.getLength() > 0 || bAcceptEmpty ); sendVals[0] <<= bHasMaster; sendVals[1] <<= aEncoded; ConfigItem::SetModified(); ConfigItem::PutProperties( sendNames, sendVals ); hasEncoded = bHasMaster; mEncoded = aEncoded; } //------------------------------------------------------------------------- void StorageItem::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) { vector < ::rtl::OUString > forIndex; forIndex.push_back( aURL ); forIndex.push_back( aName ); Sequence< ::rtl::OUString > sendSeq(1); sendSeq[0] = createIndex( forIndex ); // sendSeq[0] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); // sendSeq[0] += createIndex( forIndex ); // sendSeq[0] += ::rtl::OUString::createFromAscii( "']" ); ConfigItem::ClearNodeElements( ::rtl::OUString::createFromAscii( "Store" ), sendSeq ); } //------------------------------------------------------------------------- void StorageItem::clear() { Sequence< ::rtl::OUString > sendSeq(1); ConfigItem::ClearNodeSet( ::rtl::OUString::createFromAscii( "Store" ) ); } //------------------------------------------------------------------------- void StorageItem::update( const ::rtl::OUString& aURL, const NamePassRecord& aRecord ) { if ( !aRecord.HasPasswords( PERSISTENT_RECORD ) ) { OSL_ASSERT( "Unexpected storing of a record!" ); return; } vector < ::rtl::OUString > forIndex; forIndex.push_back( aURL ); forIndex.push_back( aRecord.GetUserName() ); Sequence< beans::PropertyValue > sendSeq(1); sendSeq[0].Name = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" ); sendSeq[0].Name += createIndex( forIndex ); sendSeq[0].Name += ::rtl::OUString::createFromAscii( "']/Password" ); sendSeq[0].Value <<= aRecord.GetPersPasswords(); ConfigItem::SetModified(); ConfigItem::SetSetProperties( ::rtl::OUString::createFromAscii( "Store" ), sendSeq ); } //------------------------------------------------------------------------- void StorageItem::Notify( const Sequence< ::rtl::OUString >& ) { // this feature still should not be used if( mainCont ) mainCont->Notify(); } //------------------------------------------------------------------------- void StorageItem::Commit() { // Do nothing, we stored everything we want already } //------------------------------------------------------------------------- //------------------------------------------------------------------------- PasswordContainer::PasswordContainer( const Reference& xServiceFactory ): m_pStorageFile( NULL ), mOldPasswordEncoding(false) { // m_pStorageFile->Notify() can be called ::osl::MutexGuard aGuard( mMutex ); mComponent = Reference< XComponent >( xServiceFactory, UNO_QUERY ); mComponent->addEventListener( this ); m_pStorageFile = new StorageItem( this, ::rtl::OUString::createFromAscii( "Office.Common/Passwords" ) ); if( m_pStorageFile ) if( m_pStorageFile->useStorage() ) m_aContainer = m_pStorageFile->getInfo(); } //------------------------------------------------------------------------- PasswordContainer::~PasswordContainer() { ::osl::MutexGuard aGuard( mMutex ); if( m_pStorageFile ) { delete m_pStorageFile; m_pStorageFile = NULL; } if( mComponent.is() ) { mComponent->removeEventListener(this); mComponent = Reference< XComponent >(); } } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::disposing( const EventObject& ) throw(RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); if( m_pStorageFile ) { delete m_pStorageFile; m_pStorageFile = NULL; } if( mComponent.is() ) { //mComponent->removeEventListener(this); mComponent = Reference< XComponent >(); } } //------------------------------------------------------------------------- /** * @brief Decode a master password. * * @param aMasterPassword master password to decode. * It must contain RTL_DIGEST_LENGTH_MD5 * 2 characters. * @param code buffer to hold the decoded password. * It must contain RTL_DIGEST_LENGTH_MD5 characters. * @param oldEncoding use the encoding pre-AOO-4.1.12 if true */ static void decodeMasterPassword(const ::rtl::OUString& aMasterPasswd, unsigned char *code, bool oldEncoding) { OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" ); const sal_Unicode *aMasterBuf = aMasterPasswd.getStr(); for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ ) { if (!oldEncoding) { code[ ind ] = (char)((((aMasterBuf[ind * 2] - 'a') & 15) << 4) | ((aMasterBuf[ind * 2 + 1] - 'a') & 15)); } else { code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16)); } } } //------------------------------------------------------------------------- /** Prepare the IV. * * @param iv vector to prepare. Its contents are destroyed. * @param masterPasswdCode master password as output from decodeMasterPassword. * @param name name of the password to decrypt. */ static void prepareIV(std::vector& iv, const unsigned char *masterPasswordCode, const ::rtl::OUString &aName) { std::vector ivSource; ivSource.assign(masterPasswordCode, masterPasswordCode + RTL_DIGEST_LENGTH_MD5); ::rtl::OString encodedName = ::rtl::OUStringToOString(aName, RTL_TEXTENCODING_UTF8 ); ivSource.insert(ivSource.end(), encodedName.getStr(), encodedName.getStr() + encodedName.getLength()); iv.resize(RTL_DIGEST_LENGTH_MD5); rtl_digest_MD5(&ivSource[0], ivSource.size(), &iv[0], iv.size()); } //------------------------------------------------------------------------- vector< ::rtl::OUString > PasswordContainer::DecodePasswords(const ::rtl::OUString& aName, const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException) { if( aMasterPasswd.getLength() ) { rtlCipher aDecoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream ); OSL_ENSURE( aDecoder, "Can't create decoder\n" ); if( aDecoder ) { std::vector iv; unsigned char code[RTL_DIGEST_LENGTH_MD5]; decodeMasterPassword(aMasterPasswd, code, mOldPasswordEncoding); if (!mOldPasswordEncoding) { prepareIV(iv, code, aName); } rtlCipherError result = rtl_cipher_init ( aDecoder, rtl_Cipher_DirectionDecode, code, RTL_DIGEST_LENGTH_MD5, (iv.size()? &iv[0] : NULL), iv.size() ); if( result == rtl_Cipher_E_None ) { ::rtl::ByteSequence aSeq = getBufFromAsciiLine( aLine ); ::rtl::ByteSequence resSeq( aSeq.getLength() ); result = rtl_cipher_decode ( aDecoder, (sal_uInt8*)aSeq.getArray(), aSeq.getLength(), (sal_uInt8*)resSeq.getArray(), resSeq.getLength() ); ::rtl::OUString aPasswd( ( sal_Char* )resSeq.getArray(), resSeq.getLength(), RTL_TEXTENCODING_UTF8 ); rtl_cipher_destroy (aDecoder); return getInfoFromInd( aPasswd ); } rtl_cipher_destroy (aDecoder); } } else { OSL_ENSURE( sal_False, "No master password provided!\n" ); // throw special exception } // problems with decoding OSL_ENSURE( sal_False, "Problem with decoding\n" ); throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't decode!" ), Reference< XInterface >() ); } //------------------------------------------------------------------------- ::rtl::OUString PasswordContainer::EncodePasswords( const ::rtl::OUString& aName, vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException) { if( aMasterPasswd.getLength() ) { ::rtl::OString aSeq = ::rtl::OUStringToOString( createIndex( lines ), RTL_TEXTENCODING_UTF8 ); rtlCipher aEncoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream ); OSL_ENSURE( aEncoder, "Can't create encoder\n" ); if( aEncoder ) { std::vector iv; unsigned char code[RTL_DIGEST_LENGTH_MD5]; decodeMasterPassword(aMasterPasswd, code, false); if (!mOldPasswordEncoding) { prepareIV(iv, code, aName); } rtlCipherError result = rtl_cipher_init ( aEncoder, rtl_Cipher_DirectionEncode, code, RTL_DIGEST_LENGTH_MD5, (iv.size()? &iv[0] : NULL), iv.size() ); if( result == rtl_Cipher_E_None ) { ::rtl::ByteSequence resSeq(aSeq.getLength()+1); result = rtl_cipher_encode ( aEncoder, (sal_uInt8*)aSeq.getStr(), aSeq.getLength()+1, (sal_uInt8*)resSeq.getArray(), resSeq.getLength() ); /* //test rtlCipherError result = rtl_cipher_init ( aEncoder, rtl_Cipher_DirectionDecode, code, RTL_DIGEST_LENGTH_MD5, NULL, 0 ); if( result == rtl_Cipher_E_None ) { ::rtl::OUString testOU = getAsciiLine( resSeq ); ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU ); ::rtl::ByteSequence resSeq1( aSeq1.getLength() ); if( resSeq.getLength() == aSeq1.getLength() ) { for( int ind = 0; ind < aSeq1.getLength(); ind++ ) if( resSeq[ind] != aSeq1[ind] ) testOU = ::rtl::OUString(); } result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(), (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() ); ::rtl::OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 ); } */ rtl_cipher_destroy (aEncoder); if( result == rtl_Cipher_E_None ) return getAsciiLine( resSeq ); } rtl_cipher_destroy (aEncoder); } } else { OSL_ENSURE( sal_False, "No master password provided!\n" ); // throw special exception } // problems with encoding OSL_ENSURE( sal_False, "Problem with encoding\n" ); throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't encode!" ), Reference< XInterface >() ); } //------------------------------------------------------------------------- /** Return the "name" to use for the master password. */ static const ::rtl::OUString& getMasterPasswordName(void) { static const ::rtl::OUString value = ::rtl::OUString::createFromAscii( "Master" ); return value; } //------------------------------------------------------------------------- void PasswordContainer::doChangeMasterPassword(const ::rtl::OUString& aPass) { // get all the persistent entries if it is possible Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() ); // remove the master password and the entries persistence removeMasterPassword(); // store the new master password m_aMasterPasswd = aPass; vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd ); m_pStorageFile->setEncodedMP( EncodePasswords( getMasterPasswordName(), aMaster, m_aMasterPasswd ) ); // store all the entries with the new password for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ ) for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ ) addPersistent( aPersistent[nURLInd].Url, aPersistent[nURLInd].UserList[nNameInd].UserName, aPersistent[nURLInd].UserList[nNameInd].Passwords, uno::Reference< task::XInteractionHandler >() ); } //------------------------------------------------------------------------- void PasswordContainer::UpdateVector( const ::rtl::OUString& aURL, list< NamePassRecord >& toUpdate, NamePassRecord& aRecord, sal_Bool writeFile ) throw(RuntimeException) { for( list< NamePassRecord >::iterator aNPIter = toUpdate.begin(); aNPIter != toUpdate.end(); aNPIter++ ) if( aNPIter->GetUserName().equals( aRecord.GetUserName() ) ) { if( aRecord.HasPasswords( MEMORY_RECORD ) ) aNPIter->SetMemPasswords( aRecord.GetMemPasswords() ); if( aRecord.HasPasswords( PERSISTENT_RECORD ) ) { aNPIter->SetPersPasswords( aRecord.GetPersPasswords() ); if( writeFile ) { // the password must be already encoded m_pStorageFile->update( aURL, aRecord ); // change existing ( aURL, aName ) record in the configfile } } return; } if( aRecord.HasPasswords( PERSISTENT_RECORD ) && writeFile ) { // the password must be already encoded m_pStorageFile->update( aURL, aRecord ); // add new aName to the existing url } toUpdate.insert( toUpdate.begin(), aRecord ); } //------------------------------------------------------------------------- UserRecord PasswordContainer::CopyToUserRecord( const NamePassRecord& aRecord, sal_Bool& io_bTryToDecode, const Reference< XInteractionHandler >& aHandler ) { ::std::vector< ::rtl::OUString > aPasswords; if( aRecord.HasPasswords( MEMORY_RECORD ) ) aPasswords = aRecord.GetMemPasswords(); if( io_bTryToDecode && aRecord.HasPasswords( PERSISTENT_RECORD ) ) { try { ::std::vector< ::rtl::OUString > aDecodedPasswords = DecodePasswords( aRecord.GetUserName(), aRecord.GetPersPasswords(), GetMasterPassword( aHandler ) ); aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), aDecodedPasswords.end() ); } catch( NoMasterException& ) { // if master password could not be detected the entry will be just ignored io_bTryToDecode = sal_False; } } return UserRecord( aRecord.GetUserName(), copyVectorToSequence( aPasswords ) ); } //------------------------------------------------------------------------- Sequence< UserRecord > PasswordContainer::CopyToUserRecordSequence( const list< NamePassRecord >& original, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { Sequence< UserRecord > aResult( original.size() ); sal_uInt32 nInd = 0; sal_Bool bTryToDecode = sal_True; for( list< NamePassRecord >::const_iterator aNPIter = original.begin(); aNPIter != original.end(); aNPIter++, nInd++ ) { aResult[nInd] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler ); } return aResult; } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::add( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); PrivateAdd( Url, UserName, Passwords, MEMORY_RECORD, aHandler ); } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::addPersistent( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler ); } //------------------------------------------------------------------------- void PasswordContainer::PrivateAdd( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, char Mode, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { NamePassRecord aRecord( UserName ); ::std::vector< ::rtl::OUString > aStorePass = copySequenceToVector( Passwords ); if( Mode == PERSISTENT_RECORD ) aRecord.SetPersPasswords( EncodePasswords( aRecord.GetUserName(), aStorePass, GetMasterPassword( aHandler ) ) ); else if( Mode == MEMORY_RECORD ) aRecord.SetMemPasswords( aStorePass ); else { OSL_ASSERT( "Unexpected persistence status!" ); return; } if( !m_aContainer.empty() ) { PassMap::iterator aIter = m_aContainer.find( Url ); if( aIter != m_aContainer.end() ) { UpdateVector( aIter->first, aIter->second, aRecord, sal_True ); return; } } list< NamePassRecord > listToAdd( 1, aRecord ); m_aContainer.insert( PairUrlRecord( Url, listToAdd ) ); if( Mode == PERSISTENT_RECORD && m_pStorageFile && m_pStorageFile->useStorage() ) m_pStorageFile->update( Url, aRecord ); } //------------------------------------------------------------------------- UrlRecord SAL_CALL PasswordContainer::find( const ::rtl::OUString& aURL, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { return find( aURL, rtl::OUString(), false, aHandler ); } //------------------------------------------------------------------------- UrlRecord SAL_CALL PasswordContainer::findForName( const ::rtl::OUString& aURL, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { return find( aURL, aName, true, aHandler ); } //------------------------------------------------------------------------- Sequence< UserRecord > PasswordContainer::FindUsr( const list< NamePassRecord >& userlist, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { sal_uInt32 nInd = 0; for( list< NamePassRecord >::const_iterator aNPIter = userlist.begin(); aNPIter != userlist.end(); aNPIter++, nInd++ ) { if( aNPIter->GetUserName().equals( aName ) ) { Sequence< UserRecord > aResult(1); sal_Bool bTryToDecode = sal_True; aResult[0] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler ); return aResult; } } return Sequence< UserRecord >(); } //------------------------------------------------------------------------- bool PasswordContainer::createUrlRecord( const PairUrlRecord & rPair, bool bName, const ::rtl::OUString & aName, const Reference< XInteractionHandler >& aHandler, UrlRecord & rRec ) throw( RuntimeException ) { if ( bName ) { Sequence< UserRecord > aUsrRec = FindUsr( rPair.second, aName, aHandler ); if( aUsrRec.getLength() ) { rRec = UrlRecord( rPair.first, aUsrRec ); return true; } } else { rRec = UrlRecord( rPair.first, CopyToUserRecordSequence( rPair.second, aHandler ) ); return true; } return false; } //------------------------------------------------------------------------- UrlRecord PasswordContainer::find( const ::rtl::OUString& aURL, const ::rtl::OUString& aName, bool bName, // only needed to support empty user names const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); if( !m_aContainer.empty() && aURL.getLength() ) { ::rtl::OUString aUrl( aURL ); // each iteration remove last '/...' section from the aUrl // while it's possible, up to the most left '://' do { // first look for /somename and then look for /somename/... PassMap::iterator aIter = m_aContainer.find( aUrl ); // Note that this iterator may be invalidated by the // side-effects of createUrlRecord(), so we have to work with a // copy of the pointed elements if( aIter != m_aContainer.end() ) { const PairUrlRecord rPairUrlRecord = *aIter; UrlRecord aRec; if ( createUrlRecord( rPairUrlRecord, bName, aName, aHandler, aRec ) ) return aRec; } else { ::rtl::OUString tmpUrl( aUrl ); if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' ) tmpUrl += ::rtl::OUString::createFromAscii( "/" ); aIter = m_aContainer.lower_bound( tmpUrl ); if( aIter != m_aContainer.end() && aIter->first.match( tmpUrl ) ) { const PairUrlRecord rPairUrlRecord = *aIter; UrlRecord aRec; if ( createUrlRecord( rPairUrlRecord, bName, aName, aHandler, aRec ) ) return aRec; } } } while( shorterUrl( aUrl ) && aUrl.getLength() ); } return UrlRecord(); } //------------------------------------------------------------------------- ::rtl::OUString PasswordContainer::GetDefaultMasterPassword() { ::rtl::OUString aResult; for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ ) aResult += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "aa" ) ); return aResult; } //------------------------------------------------------------------------- ::rtl::OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler ) { // empty string means that the call was cancelled or just failed ::rtl::OUString aResult; if ( xHandler.is() ) { ::rtl::Reference< MasterPasswordRequest_Impl > xRequest = new MasterPasswordRequest_Impl( aRMode ); xHandler->handle( xRequest.get() ); ::rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection(); if ( xSelection.is() ) { Reference< XInteractionAbort > xAbort( xSelection.get(), UNO_QUERY ); if ( !xAbort.is() ) { const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp = xRequest->getAuthenticationSupplier(); aResult = xSupp->getPassword(); } } } return aResult; } //------------------------------------------------------------------------- ::rtl::OUString PasswordContainer::GetMasterPassword( const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException) { PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER; if( !m_pStorageFile || !m_pStorageFile->useStorage() ) throw NoMasterException( ::rtl::OUString::createFromAscii( "Password storing is not active!" ), Reference< XInterface >(), aRMode ); if( !m_aMasterPasswd.getLength() && aHandler.is() ) { ::rtl::OUString aEncodedMP; sal_Bool bAskAgain = sal_False; sal_Bool bDefaultPassword = sal_False; if( !m_pStorageFile->getEncodedMP( aEncodedMP ) ) aRMode = PasswordRequestMode_PASSWORD_CREATE; else if ( !aEncodedMP.getLength() ) { m_aMasterPasswd = GetDefaultMasterPassword(); bDefaultPassword = sal_True; } if ( !bDefaultPassword ) { do { bAskAgain = sal_False; ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, aHandler ); if ( aPass.getLength() ) { if( aRMode == PasswordRequestMode_PASSWORD_CREATE ) { m_aMasterPasswd = aPass; vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd ); m_pStorageFile->setEncodedMP( EncodePasswords( getMasterPasswordName(), aMaster, m_aMasterPasswd ) ); } else { vector< ::rtl::OUString > aRM( DecodePasswords( getMasterPasswordName(), aEncodedMP, aPass ) ); if( !aRM.size() || !aPass.equals( aRM[0] ) ) { // Try the old encoding mOldPasswordEncoding = true; try { aRM = DecodePasswords( getMasterPasswordName(), aEncodedMP, aPass ); if (aRM.size() && aPass.equals(aRM[0])) { // Update all passwords to the new encoding m_aMasterPasswd = aPass; doChangeMasterPassword(aPass); } mOldPasswordEncoding = false; } catch (...) { mOldPasswordEncoding = false; throw; } } if( !aRM.size() || !aPass.equals( aRM[0] ) ) { bAskAgain = sal_True; aRMode = PasswordRequestMode_PASSWORD_REENTER; } else m_aMasterPasswd = aPass; } } } while( bAskAgain ); } } if ( !m_aMasterPasswd.getLength() ) throw NoMasterException( ::rtl::OUString::createFromAscii( "No master password!" ), Reference< XInterface >(), aRMode ); return m_aMasterPasswd; } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); ::rtl::OUString aUrl( aURL ); if( !m_aContainer.empty() ) { PassMap::iterator aIter = m_aContainer.find( aUrl ); if( aIter == m_aContainer.end() ) { sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) ); if( aInd > 0 && aUrl.getLength()-1 == aInd ) aUrl = aUrl.copy( 0, aUrl.getLength() - 1 ); else aUrl += ::rtl::OUString::createFromAscii( "/" ); aIter = m_aContainer.find( aUrl ); } if( aIter != m_aContainer.end() ) { for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) if( aNPIter->GetUserName().equals( aName ) ) { if( aNPIter->HasPasswords( PERSISTENT_RECORD ) && m_pStorageFile ) m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName ) // the iterator will not be used any more so it can be removed directly aIter->second.erase( aNPIter ); if( aIter->second.begin() == aIter->second.end() ) m_aContainer.erase( aIter ); return; } } } } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::removePersistent( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); ::rtl::OUString aUrl( aURL ); if( !m_aContainer.empty() ) { PassMap::iterator aIter = m_aContainer.find( aUrl ); if( aIter == m_aContainer.end() ) { sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) ); if( aInd > 0 && aUrl.getLength()-1 == aInd ) aUrl = aUrl.copy( 0, aUrl.getLength() - 1 ); else aUrl += ::rtl::OUString::createFromAscii( "/" ); aIter = m_aContainer.find( aUrl ); } if( aIter != m_aContainer.end() ) { for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) if( aNPIter->GetUserName().equals( aName ) ) { if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) { // TODO/LATER: should the password be converted to MemoryPassword? aNPIter->RemovePasswords( PERSISTENT_RECORD ); if ( m_pStorageFile ) m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName ) } if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) aIter->second.erase( aNPIter ); if( aIter->second.begin() == aIter->second.end() ) m_aContainer.erase( aIter ); return; } } } } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::removeAllPersistent() throw(RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); if( m_pStorageFile ) m_pStorageFile->clear(); for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); ) { for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ) { if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) { // TODO/LATER: should the password be converted to MemoryPassword? aNPIter->RemovePasswords( PERSISTENT_RECORD ); } if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) { list< NamePassRecord >::iterator aIterToDelete( aNPIter ); aNPIter++; aIter->second.erase( aIterToDelete ); } else aNPIter++; } if( aIter->second.begin() == aIter->second.end() ) { PassMap::iterator aIterToDelete( aIter ); aIter++; m_aContainer.erase( aIterToDelete ); } else aIter++; } } //------------------------------------------------------------------------- Sequence< UrlRecord > SAL_CALL PasswordContainer::getAllPersistent( const Reference< XInteractionHandler >& xHandler ) throw(RuntimeException) { Sequence< UrlRecord > aResult; ::osl::MutexGuard aGuard( mMutex ); for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ ) { Sequence< UserRecord > aUsers; for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) { sal_Int32 oldLen = aUsers.getLength(); aUsers.realloc( oldLen + 1 ); aUsers[ oldLen ] = UserRecord( aNPIter->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter->GetUserName(), aNPIter->GetPersPasswords(), GetMasterPassword( xHandler ) ) ) ); } if( aUsers.getLength() ) { sal_Int32 oldLen = aResult.getLength(); aResult.realloc( oldLen + 1 ); aResult[ oldLen ] = UrlRecord( aIter->first, aUsers ); } } return aResult; } //------------------------------------------------------------------------- sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) throw (uno::RuntimeException) { sal_Bool bResult = sal_False; ::rtl::OUString aEncodedMP; uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; ::osl::MutexGuard aGuard( mMutex ); // the method should fail if there is no master password if( m_pStorageFile && m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) ) { if ( !aEncodedMP.getLength() ) { // this is a default master password // no UI is necessary bResult = sal_True; } else { if ( !xTmpHandler.is() ) { uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); } if ( m_aMasterPasswd.getLength() ) { // there is a password, it should be just rechecked PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER; ::rtl::OUString aPass; do { aPass = RequestPasswordFromUser( aRMode, xTmpHandler ); bResult = ( aPass.getLength() && aPass.equals( m_aMasterPasswd ) ); aRMode = PasswordRequestMode_PASSWORD_REENTER; // further questions with error notification } while( !bResult && aPass.getLength() ); } else { try { // ask for the password, if user provide no correct password an exception will be thrown bResult = ( GetMasterPassword( xTmpHandler ).getLength() > 0 ); } catch( uno::Exception& ) {} } } } return bResult; } //------------------------------------------------------------------------- sal_Bool SAL_CALL PasswordContainer::changeMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) throw (uno::RuntimeException) { sal_Bool bResult = sal_False; uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; ::osl::MutexGuard aGuard( mMutex ); if ( m_pStorageFile && m_pStorageFile->useStorage() ) { if ( !xTmpHandler.is() ) { uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); } sal_Bool bCanChangePassword = sal_True; // if there is already a stored master password it should be entered by the user before the change happen ::rtl::OUString aEncodedMP; if( m_aMasterPasswd.getLength() || m_pStorageFile->getEncodedMP( aEncodedMP ) ) bCanChangePassword = authorizateWithMasterPassword( xTmpHandler ); if ( bCanChangePassword ) { // ask for the new password, but do not set it PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_CREATE; ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, xTmpHandler ); if ( aPass.getLength() ) { doChangeMasterPassword(aPass); bResult = sal_True; } } } return bResult; } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::removeMasterPassword() throw (uno::RuntimeException) { // remove all the stored passwords and the master password removeAllPersistent(); // Make sure we will not use the older encoding in the future mOldPasswordEncoding = false; ::osl::MutexGuard aGuard( mMutex ); if ( m_pStorageFile ) { m_aMasterPasswd = ::rtl::OUString(); m_pStorageFile->setEncodedMP( ::rtl::OUString() ); // let the master password be removed from configuration } } //------------------------------------------------------------------------- ::sal_Bool SAL_CALL PasswordContainer::hasMasterPassword( ) throw (::com::sun::star::uno::RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); if ( !m_pStorageFile ) throw uno::RuntimeException(); ::rtl::OUString aEncodedMP; return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) ); } //------------------------------------------------------------------------- ::sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( ::sal_Bool bAllow ) throw (::com::sun::star::uno::RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); if ( !m_pStorageFile ) throw uno::RuntimeException(); if ( !bAllow ) removeMasterPassword(); if ( m_pStorageFile->useStorage() == bAllow ) return bAllow; m_pStorageFile->setUseStorage( bAllow ); return !bAllow; } //------------------------------------------------------------------------- ::sal_Bool SAL_CALL PasswordContainer::isPersistentStoringAllowed() throw (::com::sun::star::uno::RuntimeException) { ::osl::MutexGuard aGuard( mMutex ); if ( !m_pStorageFile ) throw uno::RuntimeException(); return m_pStorageFile->useStorage(); } //------------------------------------------------------------------------- ::sal_Bool SAL_CALL PasswordContainer::useDefaultMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler ) throw ( uno::RuntimeException ) { sal_Bool bResult = sal_False; uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler; ::osl::MutexGuard aGuard( mMutex ); if ( m_pStorageFile && m_pStorageFile->useStorage() ) { if ( !xTmpHandler.is() ) { uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW ); xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW ); } sal_Bool bCanChangePassword = sal_True; // if there is already a stored nondefault master password it should be entered by the user before the change happen ::rtl::OUString aEncodedMP; if( m_pStorageFile->getEncodedMP( aEncodedMP ) && aEncodedMP.getLength() ) bCanChangePassword = authorizateWithMasterPassword( xTmpHandler ); if ( bCanChangePassword ) { // generate the default password ::rtl::OUString aPass = GetDefaultMasterPassword(); if ( aPass.getLength() ) { // get all the persistent entries if it is possible Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() ); // remove the master password and the entries persistence removeMasterPassword(); // store the empty string to flag the default master password m_aMasterPasswd = aPass; m_pStorageFile->setEncodedMP( ::rtl::OUString(), sal_True ); // store all the entries with the new password for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ ) for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ ) addPersistent( aPersistent[nURLInd].Url, aPersistent[nURLInd].UserList[nNameInd].UserName, aPersistent[nURLInd].UserList[nNameInd].Passwords, uno::Reference< task::XInteractionHandler >() ); bResult = sal_True; } } } return bResult; } //------------------------------------------------------------------------- ::sal_Bool SAL_CALL PasswordContainer::isDefaultMasterPasswordUsed() throw ( uno::RuntimeException ) { ::osl::MutexGuard aGuard( mMutex ); if ( !m_pStorageFile ) throw uno::RuntimeException(); ::rtl::OUString aEncodedMP; return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) && !aEncodedMP.getLength() ); } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent ) throw (uno::RuntimeException) { mUrlContainer.add( Url, MakePersistent ); } //------------------------------------------------------------------------- ::rtl::OUString SAL_CALL PasswordContainer::findUrl( const ::rtl::OUString& Url ) throw (uno::RuntimeException) { return mUrlContainer.find( Url ); } //------------------------------------------------------------------------- void SAL_CALL PasswordContainer::removeUrl( const ::rtl::OUString& Url ) throw (uno::RuntimeException) { mUrlContainer.remove( Url ); } //------------------------------------------------------------------------- uno::Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getUrls( ::sal_Bool OnlyPersistent ) throw (uno::RuntimeException) { return mUrlContainer.list( OnlyPersistent ); } //------------------------------------------------------------------------- void PasswordContainer::Notify() { ::osl::MutexGuard aGuard( mMutex ); PassMap::iterator aIter; // remove the cached persistent values in the memory for( aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ ) { for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ) { if( aNPIter->HasPasswords( PERSISTENT_RECORD ) ) { aNPIter->RemovePasswords( PERSISTENT_RECORD ); if ( m_pStorageFile ) m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName ) } if( !aNPIter->HasPasswords( MEMORY_RECORD ) ) { list< NamePassRecord >::iterator aIterToDelete( aNPIter ); aNPIter++; aIter->second.erase( aIterToDelete ); } else aNPIter++; } } PassMap addon; if( m_pStorageFile ) addon = m_pStorageFile->getInfo(); for( aIter = addon.begin(); aIter != addon.end(); aIter++ ) { PassMap::iterator aSearchIter = m_aContainer.find( aIter->first ); if( aSearchIter != m_aContainer.end() ) for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ ) UpdateVector( aSearchIter->first, aSearchIter->second, *aNPIter, sal_False ); else m_aContainer.insert( PairUrlRecord( aIter->first, aIter->second ) ); } } //------------------------------------------------------------------------- ::rtl::OUString SAL_CALL PasswordContainer::getImplementationName( ) throw(uno::RuntimeException) { return impl_getStaticImplementationName(); } //------------------------------------------------------------------------- sal_Bool SAL_CALL PasswordContainer::supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException) { if ( ServiceName.compareToAscii("com.sun.star.task.PasswordContainer") == 0 ) return sal_True; else return sal_False; } //------------------------------------------------------------------------- Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getSupportedServiceNames( ) throw(uno::RuntimeException) { return impl_getStaticSupportedServiceNames(); } //------------------------------------------------------------------------- Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::impl_getStaticSupportedServiceNames( ) throw(uno::RuntimeException) { Sequence< ::rtl::OUString > aRet(1); *aRet.getArray() = ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer"); return aRet; } //------------------------------------------------------------------------- ::rtl::OUString SAL_CALL PasswordContainer::impl_getStaticImplementationName() throw(uno::RuntimeException) { return ::rtl::OUString::createFromAscii("stardiv.svl.PasswordContainer"); } //------------------------------------------------------------------------- Reference< XInterface > SAL_CALL PasswordContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( RuntimeException ) { return Reference< XInterface >( *new PasswordContainer( xServiceManager ) ); } //------------------------------------------------------------------------- Reference< XSingleServiceFactory > SAL_CALL PasswordContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager ) throw(RuntimeException) { Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager, PasswordContainer::impl_getStaticImplementationName(), PasswordContainer::impl_createInstance, PasswordContainer::impl_getStaticSupportedServiceNames())); return xReturn ; } //------------------------------------------------------------------------- //------------------------------------------------------------------------- MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode ) { MasterPasswordRequest aRequest; aRequest.Classification = InteractionClassification_ERROR; aRequest.Mode = Mode; setRequest( makeAny( aRequest ) ); // Fill continuations... Sequence< RememberAuthentication > aRememberModes( 1 ); aRememberModes[ 0 ] = RememberAuthentication_NO; m_xAuthSupplier = new ::ucbhelper::InteractionSupplyAuthentication( this, sal_False, // bCanSetRealm sal_False, // bCanSetUserName sal_True, // bCanSetPassword sal_False, // bCanSetAccount aRememberModes, // rRememberPasswordModes RememberAuthentication_NO, // eDefaultRememberPasswordMode aRememberModes, // rRememberAccountModes RememberAuthentication_NO, // eDefaultRememberAccountMode sal_False, // bCanUseSystemCredentials sal_False // bDefaultUseSystemCredentials ); Sequence< Reference< XInteractionContinuation > > aContinuations( 3 ); aContinuations[ 0 ] = new ::ucbhelper::InteractionAbort( this ); aContinuations[ 1 ] = new ::ucbhelper::InteractionRetry( this ); aContinuations[ 2 ] = m_xAuthSupplier.get(); setContinuations( aContinuations ); } //------------------------------------------------------------------------- //------------------------------------------------------------------------- extern "C" { SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment ( const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */) { *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME; } SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory ( const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */) { void * pResult = 0; if (pServiceManager) { Reference< XSingleServiceFactory > xFactory; if (PasswordContainer::impl_getStaticImplementationName().compareToAscii (pImplementationName) == 0) { xFactory = PasswordContainer::impl_createFactory ( reinterpret_cast< XMultiServiceFactory* >(pServiceManager)); } if (xFactory.is()) { xFactory->acquire(); pResult = xFactory.get(); } } return pResult; } } // extern "C"