Update ooo320-m1
[ooovba.git] / svtools / source / passwordcontainer / passwordcontainer.cxx
blobebf68c9039cc1787cce39466a652baa56a4fe149
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: passwordcontainer.cxx,v $
10 * $Revision: 1.17 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #include "passwordcontainer.hxx"
36 #include <svtools/pathoptions.hxx>
37 #include "cppuhelper/factory.hxx"
38 #include <com/sun/star/registry/XSimpleRegistry.hpp>
39 #include <com/sun/star/beans/PropertyValue.hpp>
40 #include <com/sun/star/task/MasterPasswordRequest.hpp>
41 #include <com/sun/star/task/NoMasterException.hpp>
43 #include <rtl/cipher.h>
44 #include <rtl/digest.h>
45 #include <rtl/byteseq.hxx>
47 #ifndef _TOOLS_INETSTRM_HXX
48 // @@@ #include <inetstrm.hxx>
49 #endif
51 using namespace std;
52 using namespace osl;
53 using namespace utl;
54 using namespace com::sun::star;
55 using namespace com::sun::star::uno;
56 using namespace com::sun::star::registry;
57 using namespace com::sun::star::lang;
58 using namespace com::sun::star::task;
59 using namespace com::sun::star::ucb;
61 //-------------------------------------------------------------------------
62 //-------------------------------------------------------------------------
64 static ::rtl::OUString createIndex( vector< ::rtl::OUString > lines )
66 ::rtl::OString aResult;
67 const sal_Char* pLine;
69 for( unsigned int i = 0; i < lines.size(); i++ )
71 if( i )
72 aResult += ::rtl::OString( "__" );
73 ::rtl::OString line = ::rtl::OUStringToOString( lines[i], RTL_TEXTENCODING_UTF8 );
74 pLine = line.getStr();
76 while( *pLine )
78 if( ( *pLine >= 'A' && *pLine <= 'Z' )
79 || ( *pLine >= 'a' && *pLine <= 'z' )
80 || ( *pLine >= '0' && *pLine <= '9' ) )
82 aResult += ::rtl::OString::valueOf( *pLine );
84 else
86 aResult += ::rtl::OString("_");
87 aResult += ::rtl::OString::valueOf( (sal_Int32) *pLine, 16 );
90 pLine++;
94 return ::rtl::OUString::createFromAscii( aResult.getStr() );
97 //-------------------------------------------------------------------------
99 static vector< ::rtl::OUString > getInfoFromInd( ::rtl::OUString aInd )
101 vector< ::rtl::OUString > aResult;
102 sal_Bool aStart = sal_True;
104 ::rtl::OString line = ::rtl::OUStringToOString( aInd, RTL_TEXTENCODING_ASCII_US );
105 const sal_Char* pLine = line.getStr();
108 ::rtl::OUString newItem;
109 if( !aStart )
110 pLine += 2;
111 else
112 aStart = sal_False;
114 while( *pLine && !( pLine[0] == '_' && pLine[1] == '_' ))
115 if( *pLine != '_' )
117 newItem += ::rtl::OUString::valueOf( (sal_Unicode) *pLine );
118 pLine++;
120 else
122 ::rtl::OUString aNum;
123 for( int i = 1; i < 3; i++ )
125 if( !pLine[i]
126 || ( ( pLine[i] < '0' || pLine[i] > '9' )
127 && ( pLine[i] < 'a' || pLine[i] > 'f' )
128 && ( pLine[i] < 'A' || pLine[i] > 'F' ) ) )
130 OSL_ENSURE( sal_False, "Wrong index syntax!\n" );
131 return aResult;
134 aNum += ::rtl::OUString::valueOf( (sal_Unicode) pLine[i] );
137 newItem += ::rtl::OUString::valueOf( (sal_Unicode) aNum.toInt32( 16 ) );
138 pLine += 3;
141 aResult.push_back( newItem );
142 } while( pLine[0] == '_' && pLine[1] == '_' );
144 if( *pLine )
145 OSL_ENSURE( sal_False, "Wrong index syntax!\n" );
147 return aResult;
150 //-------------------------------------------------------------------------
152 static sal_Bool shorterUrl( ::rtl::OUString& aURL )
154 sal_Int32 aInd = aURL.lastIndexOf( sal_Unicode( '/' ) );
156 if( aInd > 0 )
158 sal_Int32 aPrevInd = aURL.lastIndexOf( sal_Unicode( '/' ), aInd );
159 if ( aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) )
160 != aPrevInd - 2 ||
161 aInd != aURL.getLength() - 1 )
163 aURL = aURL.copy( 0, aInd );
164 return sal_True;
168 return sal_False;
171 //-------------------------------------------------------------------------
173 static ::rtl::OUString getAsciiLine( const ::rtl::ByteSequence& buf )
175 ::rtl::OUString aResult;
177 ::rtl::ByteSequence outbuf( buf.getLength()*2+1 );
179 for( int ind = 0; ind < buf.getLength(); ind++ )
181 outbuf[ind*2] = ( ((sal_uInt8)buf[ind]) >> 4 ) + 'a';
182 outbuf[ind*2+1] = ( ((sal_uInt8)buf[ind]) & 0x0f ) + 'a';
184 outbuf[buf.getLength()*2] = '\0';
186 aResult = ::rtl::OUString::createFromAscii( (sal_Char*)outbuf.getArray() );
188 return aResult;
191 //-------------------------------------------------------------------------
193 static ::rtl::ByteSequence getBufFromAsciiLine( ::rtl::OUString line )
195 OSL_ENSURE( line.getLength() % 2 == 0, "Wrong syntax!\n" );
196 ::rtl::OString tmpLine = ::rtl::OUStringToOString( line, RTL_TEXTENCODING_ASCII_US );
197 ::rtl::ByteSequence aResult(line.getLength()/2);
199 for( int ind = 0; ind < tmpLine.getLength()/2; ind++ )
201 aResult[ind] = ( (sal_uInt8)( tmpLine.getStr()[ind*2] - 'a' ) << 4 ) | (sal_uInt8)( tmpLine.getStr()[ind*2+1] - 'a' );
204 return aResult;
207 //-------------------------------------------------------------------------
209 static Sequence< ::rtl::OUString > copyVectorToSequence( const vector< ::rtl::OUString >& original )
211 Sequence< ::rtl::OUString > newOne ( original.size() );
212 for( unsigned int i = 0; i < original.size() ; i++ )
213 newOne[i] = original[i];
215 return newOne;
218 static vector< ::rtl::OUString > copySequenceToVector( const Sequence< ::rtl::OUString >& original )
220 vector< ::rtl::OUString > newOne ( original.getLength() );
221 for( int i = 0; i < original.getLength() ; i++ )
222 newOne[i] = original[i];
224 return newOne;
227 //-------------------------------------------------------------------------
228 //-------------------------------------------------------------------------
230 PassMap StorageItem::getInfo()
232 PassMap aResult;
234 Sequence< ::rtl::OUString > aNodeNames = ConfigItem::GetNodeNames( ::rtl::OUString::createFromAscii("Store") );
235 sal_Int32 aNodeCount = aNodeNames.getLength();
236 Sequence< ::rtl::OUString > aPropNames( aNodeCount );
237 sal_Int32 aNodeInd;
239 for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
241 aPropNames[aNodeInd] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
242 aPropNames[aNodeInd] += aNodeNames[aNodeInd];
243 aPropNames[aNodeInd] += ::rtl::OUString::createFromAscii( "']/Password" );
246 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aPropNames );
248 if( aPropertyValues.getLength() != aNodeNames.getLength() )
250 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
251 return aResult;
254 for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
256 vector< ::rtl::OUString > aUrlUsr = getInfoFromInd( aNodeNames[aNodeInd] );
258 if( aUrlUsr.size() == 2 )
260 ::rtl::OUString aUrl = aUrlUsr[0];
261 ::rtl::OUString aName = aUrlUsr[1];
263 ::rtl::OUString aEPasswd;
264 aPropertyValues[aNodeInd] >>= aEPasswd;
266 PassMap::iterator aIter = aResult.find( aUrl );
267 if( aIter != aResult.end() )
268 aIter->second.push_back( NamePassRecord( aName, aEPasswd ) );
269 else
271 NamePassRecord aNewRecord( aName, aEPasswd );
272 list< NamePassRecord > listToAdd( 1, aNewRecord );
274 aResult.insert( PairUrlRecord( aUrl, listToAdd ) );
277 else
278 OSL_ENSURE( sal_False, "Wrong index sintax!\n" );
281 return aResult;
284 //-------------------------------------------------------------------------
286 void StorageItem::setUseStorage( sal_Bool bUse )
288 Sequence< ::rtl::OUString > sendNames(1);
289 Sequence< uno::Any > sendVals(1);
291 sendNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" );
293 sendVals[0] <<= bUse;
295 ConfigItem::SetModified();
296 ConfigItem::PutProperties( sendNames, sendVals );
299 //-------------------------------------------------------------------------
301 sal_Bool StorageItem::useStorage()
303 Sequence< ::rtl::OUString > aNodeNames( 1 );
304 aNodeNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" );
306 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
308 if( aPropertyValues.getLength() != aNodeNames.getLength() )
310 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
311 return sal_False;
314 sal_Bool aResult = false;
315 aPropertyValues[0] >>= aResult;
317 return aResult;
320 //-------------------------------------------------------------------------
322 sal_Bool StorageItem::getEncodedMP( ::rtl::OUString& aResult )
324 if( hasEncoded )
326 aResult = mEncoded;
327 return sal_True;
330 Sequence< ::rtl::OUString > aNodeNames( 2 );
331 aNodeNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" );
332 aNodeNames[1] = ::rtl::OUString::createFromAscii( "Master" );
334 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
336 if( aPropertyValues.getLength() != aNodeNames.getLength() )
338 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
339 return sal_False;
342 aPropertyValues[0] >>= hasEncoded;
343 aPropertyValues[1] >>= mEncoded;
345 aResult = mEncoded;
347 return hasEncoded;
350 //-------------------------------------------------------------------------
352 void StorageItem::setEncodedMP( const ::rtl::OUString& aEncoded, sal_Bool bAcceptEmpty )
354 Sequence< ::rtl::OUString > sendNames(2);
355 Sequence< uno::Any > sendVals(2);
357 sendNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" );
358 sendNames[1] = ::rtl::OUString::createFromAscii( "Master" );
360 sal_Bool bHasMaster = ( aEncoded.getLength() > 0 || bAcceptEmpty );
361 sendVals[0] <<= bHasMaster;
362 sendVals[1] <<= aEncoded;
364 ConfigItem::SetModified();
365 ConfigItem::PutProperties( sendNames, sendVals );
367 hasEncoded = bHasMaster;
368 mEncoded = aEncoded;
371 //-------------------------------------------------------------------------
373 void StorageItem::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName )
375 vector < ::rtl::OUString > forIndex;
376 forIndex.push_back( aURL );
377 forIndex.push_back( aName );
379 Sequence< ::rtl::OUString > sendSeq(1);
381 sendSeq[0] = createIndex( forIndex );
382 // sendSeq[0] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
383 // sendSeq[0] += createIndex( forIndex );
384 // sendSeq[0] += ::rtl::OUString::createFromAscii( "']" );
386 ConfigItem::ClearNodeElements( ::rtl::OUString::createFromAscii( "Store" ), sendSeq );
389 //-------------------------------------------------------------------------
391 void StorageItem::clear()
393 Sequence< ::rtl::OUString > sendSeq(1);
395 ConfigItem::ClearNodeSet( ::rtl::OUString::createFromAscii( "Store" ) );
398 //-------------------------------------------------------------------------
400 void StorageItem::update( const ::rtl::OUString& aURL, const NamePassRecord& aRecord )
402 if ( !aRecord.HasPasswords( PERSISTENT_RECORD ) )
404 OSL_ASSERT( "Unexpected storing of a record!" );
405 return;
408 vector < ::rtl::OUString > forIndex;
409 forIndex.push_back( aURL );
410 forIndex.push_back( aRecord.GetUserName() );
412 Sequence< beans::PropertyValue > sendSeq(1);
414 sendSeq[0].Name = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
415 sendSeq[0].Name += createIndex( forIndex );
416 sendSeq[0].Name += ::rtl::OUString::createFromAscii( "']/Password" );
418 sendSeq[0].Value <<= aRecord.GetPersPasswords();
420 ConfigItem::SetModified();
421 ConfigItem::SetSetProperties( ::rtl::OUString::createFromAscii( "Store" ), sendSeq );
424 //-------------------------------------------------------------------------
426 void StorageItem::Notify( const Sequence< ::rtl::OUString >& )
428 // this feature still should not be used
429 if( mainCont )
430 mainCont->Notify();
433 //-------------------------------------------------------------------------
435 void StorageItem::Commit()
437 // Do nothing, we stored everything we want already
440 //-------------------------------------------------------------------------
441 //-------------------------------------------------------------------------
443 PasswordContainer::PasswordContainer( const Reference<XMultiServiceFactory>& xServiceFactory ):
444 m_pStorageFile( NULL )
446 // m_pStorageFile->Notify() can be called
447 ::osl::MutexGuard aGuard( mMutex );
449 mComponent = Reference< XComponent >( xServiceFactory, UNO_QUERY );
450 mComponent->addEventListener( this );
452 m_pStorageFile = new StorageItem( this, ::rtl::OUString::createFromAscii( "Office.Common/Passwords" ) );
453 if( m_pStorageFile )
454 if( m_pStorageFile->useStorage() )
455 m_aContainer = m_pStorageFile->getInfo();
458 //-------------------------------------------------------------------------
460 PasswordContainer::~PasswordContainer()
462 ::osl::MutexGuard aGuard( mMutex );
464 if( m_pStorageFile )
466 delete m_pStorageFile;
467 m_pStorageFile = NULL;
470 if( mComponent.is() )
472 mComponent->removeEventListener(this);
473 mComponent = Reference< XComponent >();
477 //-------------------------------------------------------------------------
479 void SAL_CALL PasswordContainer::disposing( const EventObject& ) throw(RuntimeException)
481 ::osl::MutexGuard aGuard( mMutex );
483 if( m_pStorageFile )
485 delete m_pStorageFile;
486 m_pStorageFile = NULL;
489 if( mComponent.is() )
491 //mComponent->removeEventListener(this);
492 mComponent = Reference< XComponent >();
496 //-------------------------------------------------------------------------
498 vector< ::rtl::OUString > PasswordContainer::DecodePasswords( const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException)
500 if( aMasterPasswd.getLength() )
502 rtlCipher aDecoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
503 OSL_ENSURE( aDecoder, "Can't create decoder\n" );
505 if( aDecoder )
507 OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" );
509 unsigned char code[RTL_DIGEST_LENGTH_MD5];
510 for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
511 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16));
513 rtlCipherError result = rtl_cipher_init (
514 aDecoder, rtl_Cipher_DirectionDecode,
515 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
517 if( result == rtl_Cipher_E_None )
519 ::rtl::ByteSequence aSeq = getBufFromAsciiLine( aLine );
521 ::rtl::ByteSequence resSeq( aSeq.getLength() );
523 result = rtl_cipher_decode ( aDecoder, (sal_uInt8*)aSeq.getArray(), aSeq.getLength(),
524 (sal_uInt8*)resSeq.getArray(), resSeq.getLength() );
526 ::rtl::OUString aPasswd( ( sal_Char* )resSeq.getArray(), resSeq.getLength(), RTL_TEXTENCODING_UTF8 );
528 rtl_cipher_destroy (aDecoder);
530 return getInfoFromInd( aPasswd );
533 rtl_cipher_destroy (aDecoder);
536 else
538 OSL_ENSURE( sal_False, "No master password provided!\n" );
539 // throw special exception
542 // problems with decoding
543 OSL_ENSURE( sal_False, "Problem with decoding\n" );
544 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't decode!" ), Reference< XInterface >() );
548 //-------------------------------------------------------------------------
550 ::rtl::OUString PasswordContainer::EncodePasswords( vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException)
552 if( aMasterPasswd.getLength() )
554 ::rtl::OString aSeq = ::rtl::OUStringToOString( createIndex( lines ), RTL_TEXTENCODING_UTF8 );
556 rtlCipher aEncoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
557 OSL_ENSURE( aEncoder, "Can't create encoder\n" );
559 if( aEncoder )
561 OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" );
563 unsigned char code[RTL_DIGEST_LENGTH_MD5];
564 for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
565 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16));
567 rtlCipherError result = rtl_cipher_init (
568 aEncoder, rtl_Cipher_DirectionEncode,
569 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
571 if( result == rtl_Cipher_E_None )
573 ::rtl::ByteSequence resSeq(aSeq.getLength()+1);
575 result = rtl_cipher_encode ( aEncoder, (sal_uInt8*)aSeq.getStr(), aSeq.getLength()+1,
576 (sal_uInt8*)resSeq.getArray(), resSeq.getLength() );
579 //test
580 rtlCipherError result = rtl_cipher_init (
581 aEncoder, rtl_Cipher_DirectionDecode,
582 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
585 if( result == rtl_Cipher_E_None )
587 ::rtl::OUString testOU = getAsciiLine( resSeq );
588 ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU );
590 ::rtl::ByteSequence resSeq1( aSeq1.getLength() );
592 if( resSeq.getLength() == aSeq1.getLength() )
594 for( int ind = 0; ind < aSeq1.getLength(); ind++ )
595 if( resSeq[ind] != aSeq1[ind] )
596 testOU = ::rtl::OUString();
599 result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(),
600 (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() );
602 ::rtl::OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 );
606 rtl_cipher_destroy (aEncoder);
608 if( result == rtl_Cipher_E_None )
609 return getAsciiLine( resSeq );
613 rtl_cipher_destroy (aEncoder);
616 else
618 OSL_ENSURE( sal_False, "No master password provided!\n" );
619 // throw special exception
622 // problems with encoding
623 OSL_ENSURE( sal_False, "Problem with encoding\n" );
624 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't encode!" ), Reference< XInterface >() );
627 //-------------------------------------------------------------------------
629 void PasswordContainer::UpdateVector( const ::rtl::OUString& aURL, list< NamePassRecord >& toUpdate, NamePassRecord& aRecord, sal_Bool writeFile ) throw(RuntimeException)
631 for( list< NamePassRecord >::iterator aNPIter = toUpdate.begin(); aNPIter != toUpdate.end(); aNPIter++ )
632 if( aNPIter->GetUserName().equals( aRecord.GetUserName() ) )
634 if( aRecord.HasPasswords( MEMORY_RECORD ) )
635 aNPIter->SetMemPasswords( aRecord.GetMemPasswords() );
637 if( aRecord.HasPasswords( PERSISTENT_RECORD ) )
639 aNPIter->SetPersPasswords( aRecord.GetPersPasswords() );
641 if( writeFile )
643 // the password must be already encoded
644 m_pStorageFile->update( aURL, aRecord ); // change existing ( aURL, aName ) record in the configfile
648 return;
652 if( aRecord.HasPasswords( PERSISTENT_RECORD ) && writeFile )
654 // the password must be already encoded
655 m_pStorageFile->update( aURL, aRecord ); // add new aName to the existing url
658 toUpdate.insert( toUpdate.begin(), aRecord );
661 //-------------------------------------------------------------------------
663 UserRecord PasswordContainer::CopyToUserRecord( const NamePassRecord& aRecord, sal_Bool& io_bTryToDecode, const Reference< XInteractionHandler >& aHandler )
665 ::std::vector< ::rtl::OUString > aPasswords;
666 if( aRecord.HasPasswords( MEMORY_RECORD ) )
667 aPasswords = aRecord.GetMemPasswords();
669 if( io_bTryToDecode && aRecord.HasPasswords( PERSISTENT_RECORD ) )
673 ::std::vector< ::rtl::OUString > aDecodedPasswords = DecodePasswords( aRecord.GetPersPasswords(), GetMasterPassword( aHandler ) );
674 aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), aDecodedPasswords.end() );
676 catch( NoMasterException& )
678 // if master password could not be detected the entry will be just ignored
679 io_bTryToDecode = sal_False;
683 return UserRecord( aRecord.GetUserName(), copyVectorToSequence( aPasswords ) );
686 //-------------------------------------------------------------------------
688 Sequence< UserRecord > PasswordContainer::CopyToUserRecordSequence( const list< NamePassRecord >& original, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
690 Sequence< UserRecord > aResult( original.size() );
691 sal_uInt32 nInd = 0;
692 sal_Bool bTryToDecode = sal_True;
694 for( list< NamePassRecord >::const_iterator aNPIter = original.begin();
695 aNPIter != original.end();
696 aNPIter++, nInd++ )
698 aResult[nInd] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler );
701 return aResult;
704 //-------------------------------------------------------------------------
706 void SAL_CALL PasswordContainer::add( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
708 ::osl::MutexGuard aGuard( mMutex );
710 PrivateAdd( Url, UserName, Passwords, MEMORY_RECORD, aHandler );
713 //-------------------------------------------------------------------------
715 void SAL_CALL PasswordContainer::addPersistent( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
717 ::osl::MutexGuard aGuard( mMutex );
719 PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler );
722 //-------------------------------------------------------------------------
724 void PasswordContainer::PrivateAdd( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, char Mode, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
726 NamePassRecord aRecord( UserName );
727 ::std::vector< ::rtl::OUString > aStorePass = copySequenceToVector( Passwords );
729 if( Mode == PERSISTENT_RECORD )
730 aRecord.SetPersPasswords( EncodePasswords( aStorePass, GetMasterPassword( aHandler ) ) );
731 else if( Mode == MEMORY_RECORD )
732 aRecord.SetMemPasswords( aStorePass );
733 else
735 OSL_ASSERT( "Unexpected persistence status!" );
736 return;
739 if( !m_aContainer.empty() )
741 PassMap::iterator aIter = m_aContainer.find( Url );
743 if( aIter != m_aContainer.end() )
745 UpdateVector( aIter->first, aIter->second, aRecord, sal_True );
746 return;
750 list< NamePassRecord > listToAdd( 1, aRecord );
751 m_aContainer.insert( PairUrlRecord( Url, listToAdd ) );
753 if( Mode == PERSISTENT_RECORD && m_pStorageFile && m_pStorageFile->useStorage() )
754 m_pStorageFile->update( Url, aRecord );
758 //-------------------------------------------------------------------------
761 UrlRecord SAL_CALL PasswordContainer::find( const ::rtl::OUString& aURL, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
763 return find( aURL, rtl::OUString(), false, aHandler );
766 //-------------------------------------------------------------------------
768 UrlRecord SAL_CALL PasswordContainer::findForName( const ::rtl::OUString& aURL, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
770 return find( aURL, aName, true, aHandler );
773 //-------------------------------------------------------------------------
775 Sequence< UserRecord > PasswordContainer::FindUsr( const list< NamePassRecord >& userlist, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
777 sal_uInt32 nInd = 0;
778 for( list< NamePassRecord >::const_iterator aNPIter = userlist.begin();
779 aNPIter != userlist.end();
780 aNPIter++, nInd++ )
782 if( aNPIter->GetUserName().equals( aName ) )
784 Sequence< UserRecord > aResult(1);
785 sal_Bool bTryToDecode = sal_True;
786 aResult[0] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler );
788 return aResult;
792 return Sequence< UserRecord >();
795 //-------------------------------------------------------------------------
797 bool PasswordContainer::createUrlRecord(
798 const PassMap::iterator & rIter,
799 bool bName,
800 const ::rtl::OUString & aName,
801 const Reference< XInteractionHandler >& aHandler,
802 UrlRecord & rRec )
803 throw( RuntimeException )
805 if ( bName )
807 Sequence< UserRecord > aUsrRec
808 = FindUsr( rIter->second, aName, aHandler );
809 if( aUsrRec.getLength() )
811 rRec = UrlRecord( rIter->first, aUsrRec );
812 return true;
815 else
817 rRec = UrlRecord(
818 rIter->first,
819 CopyToUserRecordSequence( rIter->second, aHandler ) );
820 return true;
822 return false;
825 //-------------------------------------------------------------------------
827 UrlRecord PasswordContainer::find(
828 const ::rtl::OUString& aURL,
829 const ::rtl::OUString& aName,
830 bool bName, // only needed to support empty user names
831 const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
833 ::osl::MutexGuard aGuard( mMutex );
835 if( !m_aContainer.empty() && aURL.getLength() )
837 ::rtl::OUString aUrl( aURL );
839 // each iteration remove last '/...' section from the aUrl
840 // while it's possible, up to the most left '://'
843 // first look for <url>/somename and then look for <url>/somename/...
844 PassMap::iterator aIter = m_aContainer.find( aUrl );
845 if( aIter != m_aContainer.end() )
847 UrlRecord aRec;
848 if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) )
849 return aRec;
851 else
853 ::rtl::OUString tmpUrl( aUrl );
854 if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' )
855 tmpUrl += ::rtl::OUString::createFromAscii( "/" );
857 aIter = m_aContainer.lower_bound( tmpUrl );
858 if( aIter != m_aContainer.end() && aIter->first.match( tmpUrl ) )
860 UrlRecord aRec;
861 if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) )
862 return aRec;
866 while( shorterUrl( aUrl ) && aUrl.getLength() );
869 return UrlRecord();
872 //-------------------------------------------------------------------------
873 ::rtl::OUString PasswordContainer::GetDefaultMasterPassword()
875 ::rtl::OUString aResult;
876 for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ )
877 aResult += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "aa" ) );
879 return aResult;
882 //-------------------------------------------------------------------------
883 ::rtl::OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler )
885 // empty string means that the call was cancelled or just failed
886 ::rtl::OUString aResult;
888 if ( xHandler.is() )
890 ::rtl::Reference< MasterPasswordRequest_Impl > xRequest = new MasterPasswordRequest_Impl( aRMode );
892 xHandler->handle( xRequest.get() );
894 ::rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection();
896 if ( xSelection.is() )
898 Reference< XInteractionAbort > xAbort( xSelection.get(), UNO_QUERY );
899 if ( !xAbort.is() )
901 const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp
902 = xRequest->getAuthenticationSupplier();
904 aResult = xSupp->getPassword();
909 return aResult;
912 //-------------------------------------------------------------------------
914 ::rtl::OUString PasswordContainer::GetMasterPassword( const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
916 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER;
917 if( !m_pStorageFile || !m_pStorageFile->useStorage() )
918 throw NoMasterException( ::rtl::OUString::createFromAscii( "Password storing is not active!" ), Reference< XInterface >(), aRMode );
920 if( !m_aMasterPasswd.getLength() && aHandler.is() )
922 ::rtl::OUString aEncodedMP;
923 sal_Bool bAskAgain = sal_False;
924 sal_Bool bDefaultPassword = sal_False;
926 if( !m_pStorageFile->getEncodedMP( aEncodedMP ) )
927 aRMode = PasswordRequestMode_PASSWORD_CREATE;
928 else if ( !aEncodedMP.getLength() )
930 m_aMasterPasswd = GetDefaultMasterPassword();
931 bDefaultPassword = sal_True;
934 if ( !bDefaultPassword )
936 do {
937 bAskAgain = sal_False;
939 ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, aHandler );
940 if ( aPass.getLength() )
942 if( aRMode == PasswordRequestMode_PASSWORD_CREATE )
944 m_aMasterPasswd = aPass;
945 vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd );
947 m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) );
949 else
951 vector< ::rtl::OUString > aRM( DecodePasswords( aEncodedMP, aPass ) );
952 if( !aRM.size() || !aPass.equals( aRM[0] ) )
954 bAskAgain = sal_True;
955 aRMode = PasswordRequestMode_PASSWORD_REENTER;
957 else
958 m_aMasterPasswd = aPass;
962 } while( bAskAgain );
966 if ( !m_aMasterPasswd.getLength() )
967 throw NoMasterException( ::rtl::OUString::createFromAscii( "No master password!" ), Reference< XInterface >(), aRMode );
969 return m_aMasterPasswd;
972 //-------------------------------------------------------------------------
974 void SAL_CALL PasswordContainer::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException)
976 ::osl::MutexGuard aGuard( mMutex );
978 ::rtl::OUString aUrl( aURL );
979 if( !m_aContainer.empty() )
981 PassMap::iterator aIter = m_aContainer.find( aUrl );
983 if( aIter == m_aContainer.end() )
985 sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) );
986 if( aInd > 0 && aUrl.getLength()-1 == aInd )
987 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 );
988 else
989 aUrl += ::rtl::OUString::createFromAscii( "/" );
991 aIter = m_aContainer.find( aUrl );
994 if( aIter != m_aContainer.end() )
996 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
997 if( aNPIter->GetUserName().equals( aName ) )
999 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) && m_pStorageFile )
1000 m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName )
1002 // the iterator will not be used any more so it can be removed directly
1003 aIter->second.erase( aNPIter );
1005 if( aIter->second.begin() == aIter->second.end() )
1006 m_aContainer.erase( aIter );
1008 return;
1014 //-------------------------------------------------------------------------
1016 void SAL_CALL PasswordContainer::removePersistent( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException)
1018 ::osl::MutexGuard aGuard( mMutex );
1020 ::rtl::OUString aUrl( aURL );
1021 if( !m_aContainer.empty() )
1023 PassMap::iterator aIter = m_aContainer.find( aUrl );
1025 if( aIter == m_aContainer.end() )
1027 sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) );
1028 if( aInd > 0 && aUrl.getLength()-1 == aInd )
1029 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 );
1030 else
1031 aUrl += ::rtl::OUString::createFromAscii( "/" );
1033 aIter = m_aContainer.find( aUrl );
1036 if( aIter != m_aContainer.end() )
1038 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
1039 if( aNPIter->GetUserName().equals( aName ) )
1041 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
1043 // TODO/LATER: should the password be converted to MemoryPassword?
1044 aNPIter->RemovePasswords( PERSISTENT_RECORD );
1046 if ( m_pStorageFile )
1047 m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName )
1050 if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
1051 aIter->second.erase( aNPIter );
1053 if( aIter->second.begin() == aIter->second.end() )
1054 m_aContainer.erase( aIter );
1056 return;
1061 //-------------------------------------------------------------------------
1063 void SAL_CALL PasswordContainer::removeAllPersistent() throw(RuntimeException)
1065 ::osl::MutexGuard aGuard( mMutex );
1067 if( m_pStorageFile )
1068 m_pStorageFile->clear();
1070 for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); )
1072 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); )
1074 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
1076 // TODO/LATER: should the password be converted to MemoryPassword?
1077 aNPIter->RemovePasswords( PERSISTENT_RECORD );
1079 if ( m_pStorageFile )
1080 m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName )
1083 if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
1085 list< NamePassRecord >::iterator aIterToDelete( aNPIter );
1086 aNPIter++;
1087 aIter->second.erase( aIterToDelete );
1089 else
1090 aNPIter++;
1093 if( aIter->second.begin() == aIter->second.end() )
1095 PassMap::iterator aIterToDelete( aIter );
1096 aIter++;
1097 m_aContainer.erase( aIterToDelete );
1099 else
1100 aIter++;
1103 //-------------------------------------------------------------------------
1105 Sequence< UrlRecord > SAL_CALL PasswordContainer::getAllPersistent( const Reference< XInteractionHandler >& xHandler ) throw(RuntimeException)
1107 Sequence< UrlRecord > aResult;
1109 ::osl::MutexGuard aGuard( mMutex );
1110 for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ )
1112 Sequence< UserRecord > aUsers;
1113 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
1114 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
1116 sal_Int32 oldLen = aUsers.getLength();
1117 aUsers.realloc( oldLen + 1 );
1118 aUsers[ oldLen ] = UserRecord( aNPIter->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter->GetPersPasswords(), GetMasterPassword( xHandler ) ) ) );
1121 if( aUsers.getLength() )
1123 sal_Int32 oldLen = aResult.getLength();
1124 aResult.realloc( oldLen + 1 );
1125 aResult[ oldLen ] = UrlRecord( aIter->first, aUsers );
1129 return aResult;
1132 //-------------------------------------------------------------------------
1133 sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
1134 throw (uno::RuntimeException)
1136 sal_Bool bResult = sal_False;
1137 ::rtl::OUString aEncodedMP;
1138 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
1139 ::osl::MutexGuard aGuard( mMutex );
1141 // the method should fail if there is no master password
1142 if( m_pStorageFile && m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) )
1144 if ( !aEncodedMP.getLength() )
1146 // this is a default master password
1147 // no UI is necessary
1148 bResult = sal_True;
1150 else
1152 if ( !xTmpHandler.is() )
1154 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
1155 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
1158 if ( m_aMasterPasswd.getLength() )
1160 // there is a password, it should be just rechecked
1161 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER;
1162 ::rtl::OUString aPass;
1164 do {
1165 aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
1166 bResult = ( aPass.getLength() && aPass.equals( m_aMasterPasswd ) );
1167 aRMode = PasswordRequestMode_PASSWORD_REENTER; // further questions with error notification
1168 } while( !bResult && aPass.getLength() );
1170 else
1174 // ask for the password, if user provide no correct password an exception will be thrown
1175 bResult = ( GetMasterPassword( xTmpHandler ).getLength() > 0 );
1177 catch( uno::Exception& )
1183 return bResult;
1186 //-------------------------------------------------------------------------
1187 sal_Bool SAL_CALL PasswordContainer::changeMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
1188 throw (uno::RuntimeException)
1190 sal_Bool bResult = sal_False;
1191 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
1192 ::osl::MutexGuard aGuard( mMutex );
1194 if ( m_pStorageFile && m_pStorageFile->useStorage() )
1196 if ( !xTmpHandler.is() )
1198 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
1199 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
1202 sal_Bool bCanChangePassword = sal_True;
1203 // if there is already a stored master password it should be entered by the user before the change happen
1204 ::rtl::OUString aEncodedMP;
1205 if( m_aMasterPasswd.getLength() || m_pStorageFile->getEncodedMP( aEncodedMP ) )
1206 bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
1208 if ( bCanChangePassword )
1210 // ask for the new password, but do not set it
1211 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_CREATE;
1212 ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
1214 if ( aPass.getLength() )
1216 // get all the persistent entries if it is possible
1217 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() );
1219 // remove the master password and the entries persistence
1220 removeMasterPassword();
1222 // store the new master password
1223 m_aMasterPasswd = aPass;
1224 vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd );
1225 m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) );
1227 // store all the entries with the new password
1228 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ )
1229 for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ )
1230 addPersistent( aPersistent[nURLInd].Url,
1231 aPersistent[nURLInd].UserList[nNameInd].UserName,
1232 aPersistent[nURLInd].UserList[nNameInd].Passwords,
1233 uno::Reference< task::XInteractionHandler >() );
1235 bResult = sal_True;
1240 return bResult;
1243 //-------------------------------------------------------------------------
1244 void SAL_CALL PasswordContainer::removeMasterPassword()
1245 throw (uno::RuntimeException)
1247 // remove all the stored passwords and the master password
1248 removeAllPersistent();
1250 ::osl::MutexGuard aGuard( mMutex );
1251 if ( m_pStorageFile )
1253 m_aMasterPasswd = ::rtl::OUString();
1254 m_pStorageFile->setEncodedMP( ::rtl::OUString() ); // let the master password be removed from configuration
1258 //-------------------------------------------------------------------------
1259 ::sal_Bool SAL_CALL PasswordContainer::hasMasterPassword( )
1260 throw (::com::sun::star::uno::RuntimeException)
1262 ::osl::MutexGuard aGuard( mMutex );
1264 if ( !m_pStorageFile )
1265 throw uno::RuntimeException();
1267 ::rtl::OUString aEncodedMP;
1268 return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) );
1271 //-------------------------------------------------------------------------
1272 ::sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( ::sal_Bool bAllow )
1273 throw (::com::sun::star::uno::RuntimeException)
1275 ::osl::MutexGuard aGuard( mMutex );
1277 if ( !m_pStorageFile )
1278 throw uno::RuntimeException();
1280 if ( !bAllow )
1281 removeMasterPassword();
1283 if ( m_pStorageFile->useStorage() == bAllow )
1284 return bAllow;
1286 m_pStorageFile->setUseStorage( bAllow );
1287 return !bAllow;
1290 //-------------------------------------------------------------------------
1291 ::sal_Bool SAL_CALL PasswordContainer::isPersistentStoringAllowed()
1292 throw (::com::sun::star::uno::RuntimeException)
1294 ::osl::MutexGuard aGuard( mMutex );
1296 if ( !m_pStorageFile )
1297 throw uno::RuntimeException();
1299 return m_pStorageFile->useStorage();
1302 //-------------------------------------------------------------------------
1303 ::sal_Bool SAL_CALL PasswordContainer::useDefaultMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
1304 throw ( uno::RuntimeException )
1306 sal_Bool bResult = sal_False;
1307 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
1308 ::osl::MutexGuard aGuard( mMutex );
1310 if ( m_pStorageFile && m_pStorageFile->useStorage() )
1312 if ( !xTmpHandler.is() )
1314 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
1315 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
1318 sal_Bool bCanChangePassword = sal_True;
1319 // if there is already a stored nondefault master password it should be entered by the user before the change happen
1320 ::rtl::OUString aEncodedMP;
1321 if( m_pStorageFile->getEncodedMP( aEncodedMP ) && aEncodedMP.getLength() )
1322 bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
1324 if ( bCanChangePassword )
1326 // generate the default password
1327 ::rtl::OUString aPass = GetDefaultMasterPassword();
1328 if ( aPass.getLength() )
1330 // get all the persistent entries if it is possible
1331 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() );
1333 // remove the master password and the entries persistence
1334 removeMasterPassword();
1336 // store the empty string to flag the default master password
1337 m_aMasterPasswd = aPass;
1338 m_pStorageFile->setEncodedMP( ::rtl::OUString(), sal_True );
1340 // store all the entries with the new password
1341 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ )
1342 for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ )
1343 addPersistent( aPersistent[nURLInd].Url,
1344 aPersistent[nURLInd].UserList[nNameInd].UserName,
1345 aPersistent[nURLInd].UserList[nNameInd].Passwords,
1346 uno::Reference< task::XInteractionHandler >() );
1348 bResult = sal_True;
1353 return bResult;
1357 //-------------------------------------------------------------------------
1358 ::sal_Bool SAL_CALL PasswordContainer::isDefaultMasterPasswordUsed()
1359 throw ( uno::RuntimeException )
1361 ::osl::MutexGuard aGuard( mMutex );
1363 if ( !m_pStorageFile )
1364 throw uno::RuntimeException();
1366 ::rtl::OUString aEncodedMP;
1367 return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) && !aEncodedMP.getLength() );
1371 //-------------------------------------------------------------------------
1372 void SAL_CALL PasswordContainer::addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent )
1373 throw (uno::RuntimeException)
1375 mUrlContainer.add( Url, MakePersistent );
1378 //-------------------------------------------------------------------------
1379 ::rtl::OUString SAL_CALL PasswordContainer::findUrl( const ::rtl::OUString& Url )
1380 throw (uno::RuntimeException)
1382 return mUrlContainer.find( Url );
1385 //-------------------------------------------------------------------------
1386 void SAL_CALL PasswordContainer::removeUrl( const ::rtl::OUString& Url )
1387 throw (uno::RuntimeException)
1389 mUrlContainer.remove( Url );
1392 //-------------------------------------------------------------------------
1393 uno::Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getUrls( ::sal_Bool OnlyPersistent )
1394 throw (uno::RuntimeException)
1396 return mUrlContainer.list( OnlyPersistent );
1399 //-------------------------------------------------------------------------
1401 void PasswordContainer::Notify()
1403 ::osl::MutexGuard aGuard( mMutex );
1405 PassMap::iterator aIter;
1407 // remove the cached persistent values in the memory
1408 for( aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ )
1410 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); )
1412 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
1414 aNPIter->RemovePasswords( PERSISTENT_RECORD );
1416 if ( m_pStorageFile )
1417 m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName )
1420 if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
1422 list< NamePassRecord >::iterator aIterToDelete( aNPIter );
1423 aNPIter++;
1424 aIter->second.erase( aIterToDelete );
1426 else
1427 aNPIter++;
1431 PassMap addon;
1432 if( m_pStorageFile )
1433 addon = m_pStorageFile->getInfo();
1435 for( aIter = addon.begin(); aIter != addon.end(); aIter++ )
1437 PassMap::iterator aSearchIter = m_aContainer.find( aIter->first );
1438 if( aSearchIter != m_aContainer.end() )
1439 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
1440 UpdateVector( aSearchIter->first, aSearchIter->second, *aNPIter, sal_False );
1441 else
1442 m_aContainer.insert( PairUrlRecord( aIter->first, aIter->second ) );
1446 //-------------------------------------------------------------------------
1448 ::rtl::OUString SAL_CALL PasswordContainer::getImplementationName( ) throw(uno::RuntimeException)
1450 return impl_getStaticImplementationName();
1453 //-------------------------------------------------------------------------
1455 sal_Bool SAL_CALL PasswordContainer::supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException)
1457 if ( ServiceName.compareToAscii("com.sun.star.task.PasswordContainer") == 0 )
1458 return sal_True;
1459 else
1460 return sal_False;
1463 //-------------------------------------------------------------------------
1465 Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getSupportedServiceNames( ) throw(uno::RuntimeException)
1467 return impl_getStaticSupportedServiceNames();
1470 //-------------------------------------------------------------------------
1472 Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::impl_getStaticSupportedServiceNames( ) throw(uno::RuntimeException)
1474 Sequence< ::rtl::OUString > aRet(1);
1475 *aRet.getArray() = ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer");
1476 return aRet;
1479 //-------------------------------------------------------------------------
1481 ::rtl::OUString SAL_CALL PasswordContainer::impl_getStaticImplementationName() throw(uno::RuntimeException)
1483 return ::rtl::OUString::createFromAscii("stardiv.svtools.PasswordContainer");
1486 //-------------------------------------------------------------------------
1488 Reference< XInterface > SAL_CALL PasswordContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( RuntimeException )
1490 return Reference< XInterface >( *new PasswordContainer( xServiceManager ) );
1493 //-------------------------------------------------------------------------
1495 Reference< XSingleServiceFactory > SAL_CALL PasswordContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager ) throw(RuntimeException)
1497 Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager,
1498 PasswordContainer::impl_getStaticImplementationName(),
1499 PasswordContainer::impl_createInstance,
1500 PasswordContainer::impl_getStaticSupportedServiceNames()));
1501 return xReturn ;
1505 //-------------------------------------------------------------------------
1506 //-------------------------------------------------------------------------
1508 MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode )
1510 MasterPasswordRequest aRequest;
1512 aRequest.Classification = InteractionClassification_ERROR;
1513 aRequest.Mode = Mode;
1515 setRequest( makeAny( aRequest ) );
1517 // Fill continuations...
1518 Sequence< RememberAuthentication > aRememberModes( 1 );
1519 aRememberModes[ 0 ] = RememberAuthentication_NO;
1521 m_xAuthSupplier
1522 = new ::ucbhelper::InteractionSupplyAuthentication(
1523 this,
1524 sal_False, // bCanSetRealm
1525 sal_False, // bCanSetUserName
1526 sal_True, // bCanSetPassword
1527 sal_False, // bCanSetAccount
1528 aRememberModes, // rRememberPasswordModes
1529 RememberAuthentication_NO, // eDefaultRememberPasswordMode
1530 aRememberModes, // rRememberAccountModes
1531 RememberAuthentication_NO, // eDefaultRememberAccountMode
1532 sal_False, // bCanUseSystemCredentials
1533 sal_False // bDefaultUseSystemCredentials
1536 Sequence<
1537 Reference< XInteractionContinuation > > aContinuations( 3 );
1538 aContinuations[ 0 ] = new ::ucbhelper::InteractionAbort( this );
1539 aContinuations[ 1 ] = new ::ucbhelper::InteractionRetry( this );
1540 aContinuations[ 2 ] = m_xAuthSupplier.get();
1542 setContinuations( aContinuations );
1545 //-------------------------------------------------------------------------
1546 //-------------------------------------------------------------------------
1548 extern "C"
1550 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment (
1551 const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */)
1553 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
1556 SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo (
1557 void * /* pServiceManager */, void * pRegistryKey)
1559 if (pRegistryKey)
1561 Reference< XRegistryKey > xRegistryKey (
1562 reinterpret_cast< XRegistryKey* >( pRegistryKey ));
1563 Reference< XRegistryKey > xNewKey;
1565 xNewKey = xRegistryKey->createKey(
1566 ::rtl::OUString::createFromAscii( "/stardiv.svtools.PasswordContainer/UNO/SERVICES" ));
1567 xNewKey->createKey( ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer"));
1569 return sal_True;
1571 return sal_False;
1574 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory (
1575 const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */)
1577 void * pResult = 0;
1578 if (pServiceManager)
1580 Reference< XSingleServiceFactory > xFactory;
1581 if (PasswordContainer::impl_getStaticImplementationName().compareToAscii (pImplementationName) == 0)
1583 xFactory = PasswordContainer::impl_createFactory (
1584 reinterpret_cast< XMultiServiceFactory* >(pServiceManager));
1586 if (xFactory.is())
1588 xFactory->acquire();
1589 pResult = xFactory.get();
1592 return pResult;
1595 } // extern "C"