update dev300-m58
[ooovba.git] / svtools / source / passwordcontainer / passwordcontainer.cxx
blob3656d0b83fe4f1e2e51447a0571c14725d9cbc61
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( '/' ) );
155 if( aInd > 0 && aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) ) != aInd-2 )
157 aURL = aURL.copy( 0, aInd );
158 return sal_True;
161 return sal_False;
164 //-------------------------------------------------------------------------
166 static ::rtl::OUString getAsciiLine( const ::rtl::ByteSequence& buf )
168 ::rtl::OUString aResult;
170 ::rtl::ByteSequence outbuf( buf.getLength()*2+1 );
172 for( int ind = 0; ind < buf.getLength(); ind++ )
174 outbuf[ind*2] = ( ((sal_uInt8)buf[ind]) >> 4 ) + 'a';
175 outbuf[ind*2+1] = ( ((sal_uInt8)buf[ind]) & 0x0f ) + 'a';
177 outbuf[buf.getLength()*2] = '\0';
179 aResult = ::rtl::OUString::createFromAscii( (sal_Char*)outbuf.getArray() );
181 return aResult;
184 //-------------------------------------------------------------------------
186 static ::rtl::ByteSequence getBufFromAsciiLine( ::rtl::OUString line )
188 OSL_ENSURE( line.getLength() % 2 == 0, "Wrong syntax!\n" );
189 ::rtl::OString tmpLine = ::rtl::OUStringToOString( line, RTL_TEXTENCODING_ASCII_US );
190 ::rtl::ByteSequence aResult(line.getLength()/2);
192 for( int ind = 0; ind < tmpLine.getLength()/2; ind++ )
194 aResult[ind] = ( (sal_uInt8)( tmpLine.getStr()[ind*2] - 'a' ) << 4 ) | (sal_uInt8)( tmpLine.getStr()[ind*2+1] - 'a' );
197 return aResult;
200 //-------------------------------------------------------------------------
202 static Sequence< ::rtl::OUString > copyVectorToSequence( const vector< ::rtl::OUString >& original )
204 Sequence< ::rtl::OUString > newOne ( original.size() );
205 for( unsigned int i = 0; i < original.size() ; i++ )
206 newOne[i] = original[i];
208 return newOne;
211 static vector< ::rtl::OUString > copySequenceToVector( const Sequence< ::rtl::OUString >& original )
213 vector< ::rtl::OUString > newOne ( original.getLength() );
214 for( int i = 0; i < original.getLength() ; i++ )
215 newOne[i] = original[i];
217 return newOne;
220 //-------------------------------------------------------------------------
221 //-------------------------------------------------------------------------
223 PassMap StorageItem::getInfo()
225 PassMap aResult;
227 Sequence< ::rtl::OUString > aNodeNames = ConfigItem::GetNodeNames( ::rtl::OUString::createFromAscii("Store") );
228 sal_Int32 aNodeCount = aNodeNames.getLength();
229 Sequence< ::rtl::OUString > aPropNames( aNodeCount );
230 sal_Int32 aNodeInd;
232 for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
234 aPropNames[aNodeInd] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
235 aPropNames[aNodeInd] += aNodeNames[aNodeInd];
236 aPropNames[aNodeInd] += ::rtl::OUString::createFromAscii( "']/Password" );
239 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aPropNames );
241 if( aPropertyValues.getLength() != aNodeNames.getLength() )
243 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
244 return aResult;
247 for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
249 vector< ::rtl::OUString > aUrlUsr = getInfoFromInd( aNodeNames[aNodeInd] );
251 if( aUrlUsr.size() == 2 )
253 ::rtl::OUString aUrl = aUrlUsr[0];
254 ::rtl::OUString aName = aUrlUsr[1];
256 ::rtl::OUString aEPasswd;
257 aPropertyValues[aNodeInd] >>= aEPasswd;
259 PassMap::iterator aIter = aResult.find( aUrl );
260 if( aIter != aResult.end() )
261 aIter->second.push_back( NamePassRecord( aName, aEPasswd ) );
262 else
264 NamePassRecord aNewRecord( aName, aEPasswd );
265 list< NamePassRecord > listToAdd( 1, aNewRecord );
267 aResult.insert( PairUrlRecord( aUrl, listToAdd ) );
270 else
271 OSL_ENSURE( sal_False, "Wrong index sintax!\n" );
274 return aResult;
277 //-------------------------------------------------------------------------
279 void StorageItem::setUseStorage( sal_Bool bUse )
281 Sequence< ::rtl::OUString > sendNames(1);
282 Sequence< uno::Any > sendVals(1);
284 sendNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" );
286 sendVals[0] <<= bUse;
288 ConfigItem::SetModified();
289 ConfigItem::PutProperties( sendNames, sendVals );
292 //-------------------------------------------------------------------------
294 sal_Bool StorageItem::useStorage()
296 Sequence< ::rtl::OUString > aNodeNames( 1 );
297 aNodeNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" );
299 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
301 if( aPropertyValues.getLength() != aNodeNames.getLength() )
303 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
304 return sal_False;
307 sal_Bool aResult = false;
308 aPropertyValues[0] >>= aResult;
310 return aResult;
313 //-------------------------------------------------------------------------
315 sal_Bool StorageItem::getEncodedMP( ::rtl::OUString& aResult )
317 if( hasEncoded )
319 aResult = mEncoded;
320 return sal_True;
323 Sequence< ::rtl::OUString > aNodeNames( 2 );
324 aNodeNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" );
325 aNodeNames[1] = ::rtl::OUString::createFromAscii( "Master" );
327 Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
329 if( aPropertyValues.getLength() != aNodeNames.getLength() )
331 OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
332 return sal_False;
335 aPropertyValues[0] >>= hasEncoded;
336 aPropertyValues[1] >>= mEncoded;
338 aResult = mEncoded;
340 return hasEncoded;
343 //-------------------------------------------------------------------------
345 void StorageItem::setEncodedMP( const ::rtl::OUString& aEncoded, sal_Bool bAcceptEmpty )
347 Sequence< ::rtl::OUString > sendNames(2);
348 Sequence< uno::Any > sendVals(2);
350 sendNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" );
351 sendNames[1] = ::rtl::OUString::createFromAscii( "Master" );
353 sal_Bool bHasMaster = ( aEncoded.getLength() > 0 || bAcceptEmpty );
354 sendVals[0] <<= bHasMaster;
355 sendVals[1] <<= aEncoded;
357 ConfigItem::SetModified();
358 ConfigItem::PutProperties( sendNames, sendVals );
360 hasEncoded = bHasMaster;
361 mEncoded = aEncoded;
364 //-------------------------------------------------------------------------
366 void StorageItem::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName )
368 vector < ::rtl::OUString > forIndex;
369 forIndex.push_back( aURL );
370 forIndex.push_back( aName );
372 Sequence< ::rtl::OUString > sendSeq(1);
374 sendSeq[0] = createIndex( forIndex );
375 // sendSeq[0] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
376 // sendSeq[0] += createIndex( forIndex );
377 // sendSeq[0] += ::rtl::OUString::createFromAscii( "']" );
379 ConfigItem::ClearNodeElements( ::rtl::OUString::createFromAscii( "Store" ), sendSeq );
382 //-------------------------------------------------------------------------
384 void StorageItem::clear()
386 Sequence< ::rtl::OUString > sendSeq(1);
388 ConfigItem::ClearNodeSet( ::rtl::OUString::createFromAscii( "Store" ) );
391 //-------------------------------------------------------------------------
393 void StorageItem::update( const ::rtl::OUString& aURL, const NamePassRecord& aRecord )
395 if ( !aRecord.HasPasswords( PERSISTENT_RECORD ) )
397 OSL_ASSERT( "Unexpected storing of a record!" );
398 return;
401 vector < ::rtl::OUString > forIndex;
402 forIndex.push_back( aURL );
403 forIndex.push_back( aRecord.GetUserName() );
405 Sequence< beans::PropertyValue > sendSeq(1);
407 sendSeq[0].Name = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
408 sendSeq[0].Name += createIndex( forIndex );
409 sendSeq[0].Name += ::rtl::OUString::createFromAscii( "']/Password" );
411 sendSeq[0].Value <<= aRecord.GetPersPasswords();
413 ConfigItem::SetModified();
414 ConfigItem::SetSetProperties( ::rtl::OUString::createFromAscii( "Store" ), sendSeq );
417 //-------------------------------------------------------------------------
419 void StorageItem::Notify( const Sequence< ::rtl::OUString >& )
421 // this feature still should not be used
422 if( mainCont )
423 mainCont->Notify();
426 //-------------------------------------------------------------------------
428 void StorageItem::Commit()
430 // Do nothing, we stored everything we want already
433 //-------------------------------------------------------------------------
434 //-------------------------------------------------------------------------
436 PasswordContainer::PasswordContainer( const Reference<XMultiServiceFactory>& xServiceFactory ):
437 m_pStorageFile( NULL )
439 // m_pStorageFile->Notify() can be called
440 ::osl::MutexGuard aGuard( mMutex );
442 mComponent = Reference< XComponent >( xServiceFactory, UNO_QUERY );
443 mComponent->addEventListener( this );
445 m_pStorageFile = new StorageItem( this, ::rtl::OUString::createFromAscii( "Office.Common/Passwords" ) );
446 if( m_pStorageFile )
447 if( m_pStorageFile->useStorage() )
448 m_aContainer = m_pStorageFile->getInfo();
451 //-------------------------------------------------------------------------
453 PasswordContainer::~PasswordContainer()
455 ::osl::MutexGuard aGuard( mMutex );
457 if( m_pStorageFile )
459 delete m_pStorageFile;
460 m_pStorageFile = NULL;
463 if( mComponent.is() )
465 mComponent->removeEventListener(this);
466 mComponent = Reference< XComponent >();
470 //-------------------------------------------------------------------------
472 void SAL_CALL PasswordContainer::disposing( const EventObject& ) throw(RuntimeException)
474 ::osl::MutexGuard aGuard( mMutex );
476 if( m_pStorageFile )
478 delete m_pStorageFile;
479 m_pStorageFile = NULL;
482 if( mComponent.is() )
484 //mComponent->removeEventListener(this);
485 mComponent = Reference< XComponent >();
489 //-------------------------------------------------------------------------
491 vector< ::rtl::OUString > PasswordContainer::DecodePasswords( const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException)
493 if( aMasterPasswd.getLength() )
495 rtlCipher aDecoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
496 OSL_ENSURE( aDecoder, "Can't create decoder\n" );
498 if( aDecoder )
500 OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" );
502 unsigned char code[RTL_DIGEST_LENGTH_MD5];
503 for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
504 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16));
506 rtlCipherError result = rtl_cipher_init (
507 aDecoder, rtl_Cipher_DirectionDecode,
508 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
510 if( result == rtl_Cipher_E_None )
512 ::rtl::ByteSequence aSeq = getBufFromAsciiLine( aLine );
514 ::rtl::ByteSequence resSeq( aSeq.getLength() );
516 result = rtl_cipher_decode ( aDecoder, (sal_uInt8*)aSeq.getArray(), aSeq.getLength(),
517 (sal_uInt8*)resSeq.getArray(), resSeq.getLength() );
519 ::rtl::OUString aPasswd( ( sal_Char* )resSeq.getArray(), resSeq.getLength(), RTL_TEXTENCODING_UTF8 );
521 rtl_cipher_destroy (aDecoder);
523 return getInfoFromInd( aPasswd );
526 rtl_cipher_destroy (aDecoder);
529 else
531 OSL_ENSURE( sal_False, "No master password provided!\n" );
532 // throw special exception
535 // problems with decoding
536 OSL_ENSURE( sal_False, "Problem with decoding\n" );
537 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't decode!" ), Reference< XInterface >() );
541 //-------------------------------------------------------------------------
543 ::rtl::OUString PasswordContainer::EncodePasswords( vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException)
545 if( aMasterPasswd.getLength() )
547 ::rtl::OString aSeq = ::rtl::OUStringToOString( createIndex( lines ), RTL_TEXTENCODING_UTF8 );
549 rtlCipher aEncoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
550 OSL_ENSURE( aEncoder, "Can't create encoder\n" );
552 if( aEncoder )
554 OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" );
556 unsigned char code[RTL_DIGEST_LENGTH_MD5];
557 for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
558 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16));
560 rtlCipherError result = rtl_cipher_init (
561 aEncoder, rtl_Cipher_DirectionEncode,
562 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
564 if( result == rtl_Cipher_E_None )
566 ::rtl::ByteSequence resSeq(aSeq.getLength()+1);
568 result = rtl_cipher_encode ( aEncoder, (sal_uInt8*)aSeq.getStr(), aSeq.getLength()+1,
569 (sal_uInt8*)resSeq.getArray(), resSeq.getLength() );
572 //test
573 rtlCipherError result = rtl_cipher_init (
574 aEncoder, rtl_Cipher_DirectionDecode,
575 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
578 if( result == rtl_Cipher_E_None )
580 ::rtl::OUString testOU = getAsciiLine( resSeq );
581 ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU );
583 ::rtl::ByteSequence resSeq1( aSeq1.getLength() );
585 if( resSeq.getLength() == aSeq1.getLength() )
587 for( int ind = 0; ind < aSeq1.getLength(); ind++ )
588 if( resSeq[ind] != aSeq1[ind] )
589 testOU = ::rtl::OUString();
592 result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(),
593 (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() );
595 ::rtl::OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 );
599 rtl_cipher_destroy (aEncoder);
601 if( result == rtl_Cipher_E_None )
602 return getAsciiLine( resSeq );
606 rtl_cipher_destroy (aEncoder);
609 else
611 OSL_ENSURE( sal_False, "No master password provided!\n" );
612 // throw special exception
615 // problems with encoding
616 OSL_ENSURE( sal_False, "Problem with encoding\n" );
617 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't encode!" ), Reference< XInterface >() );
620 //-------------------------------------------------------------------------
622 void PasswordContainer::UpdateVector( const ::rtl::OUString& aURL, list< NamePassRecord >& toUpdate, NamePassRecord& aRecord, sal_Bool writeFile ) throw(RuntimeException)
624 for( list< NamePassRecord >::iterator aNPIter = toUpdate.begin(); aNPIter != toUpdate.end(); aNPIter++ )
625 if( aNPIter->GetUserName().equals( aRecord.GetUserName() ) )
627 if( aRecord.HasPasswords( MEMORY_RECORD ) )
628 aNPIter->SetMemPasswords( aRecord.GetMemPasswords() );
630 if( aRecord.HasPasswords( PERSISTENT_RECORD ) )
632 aNPIter->SetPersPasswords( aRecord.GetPersPasswords() );
634 if( writeFile )
636 // the password must be already encoded
637 m_pStorageFile->update( aURL, aRecord ); // change existing ( aURL, aName ) record in the configfile
641 return;
645 if( aRecord.HasPasswords( PERSISTENT_RECORD ) && writeFile )
647 // the password must be already encoded
648 m_pStorageFile->update( aURL, aRecord ); // add new aName to the existing url
651 toUpdate.insert( toUpdate.begin(), aRecord );
654 //-------------------------------------------------------------------------
656 UserRecord PasswordContainer::CopyToUserRecord( const NamePassRecord& aRecord, sal_Bool& io_bTryToDecode, const Reference< XInteractionHandler >& aHandler )
658 ::std::vector< ::rtl::OUString > aPasswords;
659 if( aRecord.HasPasswords( MEMORY_RECORD ) )
660 aPasswords = aRecord.GetMemPasswords();
662 if( io_bTryToDecode && aRecord.HasPasswords( PERSISTENT_RECORD ) )
666 ::std::vector< ::rtl::OUString > aDecodedPasswords = DecodePasswords( aRecord.GetPersPasswords(), GetMasterPassword( aHandler ) );
667 aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), aDecodedPasswords.end() );
669 catch( NoMasterException& )
671 // if master password could not be detected the entry will be just ignored
672 io_bTryToDecode = sal_False;
676 return UserRecord( aRecord.GetUserName(), copyVectorToSequence( aPasswords ) );
679 //-------------------------------------------------------------------------
681 Sequence< UserRecord > PasswordContainer::CopyToUserRecordSequence( const list< NamePassRecord >& original, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
683 Sequence< UserRecord > aResult( original.size() );
684 sal_uInt32 nInd = 0;
685 sal_Bool bTryToDecode = sal_True;
687 for( list< NamePassRecord >::const_iterator aNPIter = original.begin();
688 aNPIter != original.end();
689 aNPIter++, nInd++ )
691 aResult[nInd] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler );
694 return aResult;
697 //-------------------------------------------------------------------------
699 void SAL_CALL PasswordContainer::add( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
701 ::osl::MutexGuard aGuard( mMutex );
703 PrivateAdd( Url, UserName, Passwords, MEMORY_RECORD, aHandler );
706 //-------------------------------------------------------------------------
708 void SAL_CALL PasswordContainer::addPersistent( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
710 ::osl::MutexGuard aGuard( mMutex );
712 PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler );
715 //-------------------------------------------------------------------------
717 void PasswordContainer::PrivateAdd( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, char Mode, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
719 NamePassRecord aRecord( UserName );
720 ::std::vector< ::rtl::OUString > aStorePass = copySequenceToVector( Passwords );
722 if( Mode == PERSISTENT_RECORD )
723 aRecord.SetPersPasswords( EncodePasswords( aStorePass, GetMasterPassword( aHandler ) ) );
724 else if( Mode == MEMORY_RECORD )
725 aRecord.SetMemPasswords( aStorePass );
726 else
728 OSL_ASSERT( "Unexpected persistence status!" );
729 return;
732 if( !m_aContainer.empty() )
734 PassMap::iterator aIter = m_aContainer.find( Url );
736 if( aIter != m_aContainer.end() )
738 UpdateVector( aIter->first, aIter->second, aRecord, sal_True );
739 return;
743 list< NamePassRecord > listToAdd( 1, aRecord );
744 m_aContainer.insert( PairUrlRecord( Url, listToAdd ) );
746 if( Mode == PERSISTENT_RECORD && m_pStorageFile && m_pStorageFile->useStorage() )
747 m_pStorageFile->update( Url, aRecord );
751 //-------------------------------------------------------------------------
754 UrlRecord SAL_CALL PasswordContainer::find( const ::rtl::OUString& aURL, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
756 ::osl::MutexGuard aGuard( mMutex );
758 if( !m_aContainer.empty() )
760 ::rtl::OUString aUrl( aURL );
761 PassMap::iterator aIter = m_aContainer.find( aUrl );
763 if( aIter != m_aContainer.end() )
764 return UrlRecord( aIter->first, CopyToUserRecordSequence( aIter->second, aHandler ) );
766 // each iteration remove last '/...' section from the aUrl
767 // while it's possible, up to the most left '://'
768 while( shorterUrl( aUrl ) )
770 // first look for <url>/somename and then look for <url>/somename/...
771 aIter = m_aContainer.find( aUrl );
772 if( aIter != m_aContainer.end() )
773 return UrlRecord( aIter->first, CopyToUserRecordSequence( aIter->second, aHandler ) );
774 else
776 ::rtl::OUString tmpUrl( aUrl );
777 tmpUrl += ::rtl::OUString::createFromAscii( "/" );
779 aIter = m_aContainer.lower_bound( aUrl );
780 if( aIter != m_aContainer.end() )
781 return UrlRecord( aIter->first, CopyToUserRecordSequence( aIter->second, aHandler ) );
786 return UrlRecord();
789 //-------------------------------------------------------------------------
791 Sequence< UserRecord > PasswordContainer::FindUsr( const list< NamePassRecord >& userlist, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
793 sal_uInt32 nInd = 0;
794 for( list< NamePassRecord >::const_iterator aNPIter = userlist.begin();
795 aNPIter != userlist.end();
796 aNPIter++, nInd++ )
798 if( aNPIter->GetUserName().equals( aName ) )
800 Sequence< UserRecord > aResult(1);
801 sal_Bool bTryToDecode = sal_True;
802 aResult[0] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler );
804 return aResult;
808 return Sequence< UserRecord >();
811 //-------------------------------------------------------------------------
813 UrlRecord SAL_CALL PasswordContainer::findForName( const ::rtl::OUString& aURL, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
816 ::osl::MutexGuard aGuard( mMutex );
817 if( !m_aContainer.empty() )
819 ::rtl::OUString aUrl( aURL );
820 PassMap::iterator aIter = m_aContainer.find( aUrl );
822 if( aIter != m_aContainer.end() )
824 Sequence< UserRecord > aUsrRec = FindUsr( aIter->second, aName, aHandler );
825 if( aUsrRec.getLength() )
826 return UrlRecord( aIter->first, aUsrRec );
829 // each iteration remove last '/...' section from the aUrl
830 // while it's possible, up to the most left '://'
831 while( shorterUrl( aUrl ) )
833 // first look for <url>/somename and then look for <url>/somename/...
834 aIter = m_aContainer.find( aUrl );
835 if( aIter != m_aContainer.end() )
837 Sequence< UserRecord > aUsrRec = FindUsr( aIter->second, aName, aHandler );
838 if( aUsrRec.getLength() )
839 return UrlRecord( aIter->first, aUsrRec );
841 else
843 ::rtl::OUString tmpUrl( aUrl );
844 tmpUrl += ::rtl::OUString::createFromAscii( "/" );
846 aIter = m_aContainer.lower_bound( aUrl );
847 if( aIter != m_aContainer.end() )
849 Sequence< UserRecord > aUsrRec = FindUsr( aIter->second, aName, aHandler );
850 if( aUsrRec.getLength() )
851 return UrlRecord( aIter->first, aUsrRec );
857 return UrlRecord();
860 //-------------------------------------------------------------------------
861 ::rtl::OUString PasswordContainer::GetDefaultMasterPassword()
863 ::rtl::OUString aResult;
864 for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ )
865 aResult += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "aa" ) );
867 return aResult;
870 //-------------------------------------------------------------------------
871 ::rtl::OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler )
873 // empty string means that the call was cancelled or just failed
874 ::rtl::OUString aResult;
876 if ( xHandler.is() )
878 ::rtl::Reference< MasterPasswordRequest_Impl > xRequest = new MasterPasswordRequest_Impl( aRMode );
880 xHandler->handle( xRequest.get() );
882 ::rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection();
884 if ( xSelection.is() )
886 Reference< XInteractionAbort > xAbort( xSelection.get(), UNO_QUERY );
887 if ( !xAbort.is() )
889 const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp
890 = xRequest->getAuthenticationSupplier();
892 aResult = xSupp->getPassword();
897 return aResult;
900 //-------------------------------------------------------------------------
902 ::rtl::OUString PasswordContainer::GetMasterPassword( const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
904 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER;
905 if( !m_pStorageFile || !m_pStorageFile->useStorage() )
906 throw NoMasterException( ::rtl::OUString::createFromAscii( "Password storing is not active!" ), Reference< XInterface >(), aRMode );
908 if( !m_aMasterPasswd.getLength() && aHandler.is() )
910 ::rtl::OUString aEncodedMP;
911 sal_Bool bAskAgain = sal_False;
912 sal_Bool bDefaultPassword = sal_False;
914 if( !m_pStorageFile->getEncodedMP( aEncodedMP ) )
915 aRMode = PasswordRequestMode_PASSWORD_CREATE;
916 else if ( !aEncodedMP.getLength() )
918 m_aMasterPasswd = GetDefaultMasterPassword();
919 bDefaultPassword = sal_True;
922 if ( !bDefaultPassword )
924 do {
925 bAskAgain = sal_False;
927 ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, aHandler );
928 if ( aPass.getLength() )
930 if( aRMode == PasswordRequestMode_PASSWORD_CREATE )
932 m_aMasterPasswd = aPass;
933 vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd );
935 m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) );
937 else
939 vector< ::rtl::OUString > aRM( DecodePasswords( aEncodedMP, aPass ) );
940 if( !aRM.size() || !aPass.equals( aRM[0] ) )
942 bAskAgain = sal_True;
943 aRMode = PasswordRequestMode_PASSWORD_REENTER;
945 else
946 m_aMasterPasswd = aPass;
950 } while( bAskAgain );
954 if ( !m_aMasterPasswd.getLength() )
955 throw NoMasterException( ::rtl::OUString::createFromAscii( "No master password!" ), Reference< XInterface >(), aRMode );
957 return m_aMasterPasswd;
960 //-------------------------------------------------------------------------
962 void SAL_CALL PasswordContainer::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException)
964 ::osl::MutexGuard aGuard( mMutex );
966 ::rtl::OUString aUrl( aURL );
967 if( !m_aContainer.empty() )
969 PassMap::iterator aIter = m_aContainer.find( aUrl );
971 if( aIter == m_aContainer.end() )
973 sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) );
974 if( aInd > 0 && aUrl.getLength()-1 == aInd )
975 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 );
976 else
977 aUrl += ::rtl::OUString::createFromAscii( "/" );
979 aIter = m_aContainer.find( aUrl );
982 if( aIter != m_aContainer.end() )
984 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
985 if( aNPIter->GetUserName().equals( aName ) )
987 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) && m_pStorageFile )
988 m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName )
990 // the iterator will not be used any more so it can be removed directly
991 aIter->second.erase( aNPIter );
993 if( aIter->second.begin() == aIter->second.end() )
994 m_aContainer.erase( aIter );
996 return;
1002 //-------------------------------------------------------------------------
1004 void SAL_CALL PasswordContainer::removePersistent( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException)
1006 ::osl::MutexGuard aGuard( mMutex );
1008 ::rtl::OUString aUrl( aURL );
1009 if( !m_aContainer.empty() )
1011 PassMap::iterator aIter = m_aContainer.find( aUrl );
1013 if( aIter == m_aContainer.end() )
1015 sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) );
1016 if( aInd > 0 && aUrl.getLength()-1 == aInd )
1017 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 );
1018 else
1019 aUrl += ::rtl::OUString::createFromAscii( "/" );
1021 aIter = m_aContainer.find( aUrl );
1024 if( aIter != m_aContainer.end() )
1026 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
1027 if( aNPIter->GetUserName().equals( aName ) )
1029 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
1031 // TODO/LATER: should the password be converted to MemoryPassword?
1032 aNPIter->RemovePasswords( PERSISTENT_RECORD );
1034 if ( m_pStorageFile )
1035 m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName )
1038 if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
1039 aIter->second.erase( aNPIter );
1041 if( aIter->second.begin() == aIter->second.end() )
1042 m_aContainer.erase( aIter );
1044 return;
1049 //-------------------------------------------------------------------------
1051 void SAL_CALL PasswordContainer::removeAllPersistent() throw(RuntimeException)
1053 ::osl::MutexGuard aGuard( mMutex );
1055 if( m_pStorageFile )
1056 m_pStorageFile->clear();
1058 for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); )
1060 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); )
1062 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
1064 // TODO/LATER: should the password be converted to MemoryPassword?
1065 aNPIter->RemovePasswords( PERSISTENT_RECORD );
1067 if ( m_pStorageFile )
1068 m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName )
1071 if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
1073 list< NamePassRecord >::iterator aIterToDelete( aNPIter );
1074 aNPIter++;
1075 aIter->second.erase( aIterToDelete );
1077 else
1078 aNPIter++;
1081 if( aIter->second.begin() == aIter->second.end() )
1083 PassMap::iterator aIterToDelete( aIter );
1084 aIter++;
1085 m_aContainer.erase( aIterToDelete );
1087 else
1088 aIter++;
1091 //-------------------------------------------------------------------------
1093 Sequence< UrlRecord > SAL_CALL PasswordContainer::getAllPersistent( const Reference< XInteractionHandler >& xHandler ) throw(RuntimeException)
1095 Sequence< UrlRecord > aResult;
1097 ::osl::MutexGuard aGuard( mMutex );
1098 for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ )
1100 Sequence< UserRecord > aUsers;
1101 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
1102 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
1104 sal_Int32 oldLen = aUsers.getLength();
1105 aUsers.realloc( oldLen + 1 );
1106 aUsers[ oldLen ] = UserRecord( aNPIter->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter->GetPersPasswords(), GetMasterPassword( xHandler ) ) ) );
1109 if( aUsers.getLength() )
1111 sal_Int32 oldLen = aResult.getLength();
1112 aResult.realloc( oldLen + 1 );
1113 aResult[ oldLen ] = UrlRecord( aIter->first, aUsers );
1117 return aResult;
1120 //-------------------------------------------------------------------------
1121 sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
1122 throw (uno::RuntimeException)
1124 sal_Bool bResult = sal_False;
1125 ::rtl::OUString aEncodedMP;
1126 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
1127 ::osl::MutexGuard aGuard( mMutex );
1129 // the method should fail if there is no master password
1130 if( m_pStorageFile && m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) )
1132 if ( !aEncodedMP.getLength() )
1134 // this is a default master password
1135 // no UI is necessary
1136 bResult = sal_True;
1138 else
1140 if ( !xTmpHandler.is() )
1142 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
1143 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
1146 if ( m_aMasterPasswd.getLength() )
1148 // there is a password, it should be just rechecked
1149 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER;
1150 ::rtl::OUString aPass;
1152 do {
1153 aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
1154 bResult = ( aPass.getLength() && aPass.equals( m_aMasterPasswd ) );
1155 aRMode = PasswordRequestMode_PASSWORD_REENTER; // further questions with error notification
1156 } while( !bResult && aPass.getLength() );
1158 else
1162 // ask for the password, if user provide no correct password an exception will be thrown
1163 bResult = ( GetMasterPassword( xTmpHandler ).getLength() > 0 );
1165 catch( uno::Exception& )
1171 return bResult;
1174 //-------------------------------------------------------------------------
1175 sal_Bool SAL_CALL PasswordContainer::changeMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
1176 throw (uno::RuntimeException)
1178 sal_Bool bResult = sal_False;
1179 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
1180 ::osl::MutexGuard aGuard( mMutex );
1182 if ( m_pStorageFile && m_pStorageFile->useStorage() )
1184 if ( !xTmpHandler.is() )
1186 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
1187 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
1190 sal_Bool bCanChangePassword = sal_True;
1191 // if there is already a stored master password it should be entered by the user before the change happen
1192 ::rtl::OUString aEncodedMP;
1193 if( m_aMasterPasswd.getLength() || m_pStorageFile->getEncodedMP( aEncodedMP ) )
1194 bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
1196 if ( bCanChangePassword )
1198 // ask for the new password, but do not set it
1199 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_CREATE;
1200 ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
1202 if ( aPass.getLength() )
1204 // get all the persistent entries if it is possible
1205 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() );
1207 // remove the master password and the entries persistence
1208 removeMasterPassword();
1210 // store the new master password
1211 m_aMasterPasswd = aPass;
1212 vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd );
1213 m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) );
1215 // store all the entries with the new password
1216 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ )
1217 for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ )
1218 addPersistent( aPersistent[nURLInd].Url,
1219 aPersistent[nURLInd].UserList[nNameInd].UserName,
1220 aPersistent[nURLInd].UserList[nNameInd].Passwords,
1221 uno::Reference< task::XInteractionHandler >() );
1223 bResult = sal_True;
1228 return bResult;
1231 //-------------------------------------------------------------------------
1232 void SAL_CALL PasswordContainer::removeMasterPassword()
1233 throw (uno::RuntimeException)
1235 // remove all the stored passwords and the master password
1236 removeAllPersistent();
1238 ::osl::MutexGuard aGuard( mMutex );
1239 if ( m_pStorageFile )
1241 m_aMasterPasswd = ::rtl::OUString();
1242 m_pStorageFile->setEncodedMP( ::rtl::OUString() ); // let the master password be removed from configuration
1246 //-------------------------------------------------------------------------
1247 ::sal_Bool SAL_CALL PasswordContainer::hasMasterPassword( )
1248 throw (::com::sun::star::uno::RuntimeException)
1250 ::osl::MutexGuard aGuard( mMutex );
1252 if ( !m_pStorageFile )
1253 throw uno::RuntimeException();
1255 ::rtl::OUString aEncodedMP;
1256 return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) );
1259 //-------------------------------------------------------------------------
1260 ::sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( ::sal_Bool bAllow )
1261 throw (::com::sun::star::uno::RuntimeException)
1263 ::osl::MutexGuard aGuard( mMutex );
1265 if ( !m_pStorageFile )
1266 throw uno::RuntimeException();
1268 if ( !bAllow )
1269 removeMasterPassword();
1271 if ( m_pStorageFile->useStorage() == bAllow )
1272 return bAllow;
1274 m_pStorageFile->setUseStorage( bAllow );
1275 return !bAllow;
1278 //-------------------------------------------------------------------------
1279 ::sal_Bool SAL_CALL PasswordContainer::isPersistentStoringAllowed()
1280 throw (::com::sun::star::uno::RuntimeException)
1282 ::osl::MutexGuard aGuard( mMutex );
1284 if ( !m_pStorageFile )
1285 throw uno::RuntimeException();
1287 return m_pStorageFile->useStorage();
1290 //-------------------------------------------------------------------------
1291 ::sal_Bool SAL_CALL PasswordContainer::useDefaultMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
1292 throw ( uno::RuntimeException )
1294 sal_Bool bResult = sal_False;
1295 uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
1296 ::osl::MutexGuard aGuard( mMutex );
1298 if ( m_pStorageFile && m_pStorageFile->useStorage() )
1300 if ( !xTmpHandler.is() )
1302 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
1303 xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
1306 sal_Bool bCanChangePassword = sal_True;
1307 // if there is already a stored nondefault master password it should be entered by the user before the change happen
1308 ::rtl::OUString aEncodedMP;
1309 if( m_pStorageFile->getEncodedMP( aEncodedMP ) && aEncodedMP.getLength() )
1310 bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
1312 if ( bCanChangePassword )
1314 // generate the default password
1315 ::rtl::OUString aPass = GetDefaultMasterPassword();
1316 if ( aPass.getLength() )
1318 // get all the persistent entries if it is possible
1319 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() );
1321 // remove the master password and the entries persistence
1322 removeMasterPassword();
1324 // store the empty string to flag the default master password
1325 m_aMasterPasswd = aPass;
1326 m_pStorageFile->setEncodedMP( ::rtl::OUString(), sal_True );
1328 // store all the entries with the new password
1329 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ )
1330 for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ )
1331 addPersistent( aPersistent[nURLInd].Url,
1332 aPersistent[nURLInd].UserList[nNameInd].UserName,
1333 aPersistent[nURLInd].UserList[nNameInd].Passwords,
1334 uno::Reference< task::XInteractionHandler >() );
1336 bResult = sal_True;
1341 return bResult;
1345 //-------------------------------------------------------------------------
1346 ::sal_Bool SAL_CALL PasswordContainer::isDefaultMasterPasswordUsed()
1347 throw ( uno::RuntimeException )
1349 ::osl::MutexGuard aGuard( mMutex );
1351 if ( !m_pStorageFile )
1352 throw uno::RuntimeException();
1354 ::rtl::OUString aEncodedMP;
1355 return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) && !aEncodedMP.getLength() );
1358 //-------------------------------------------------------------------------
1360 void PasswordContainer::Notify()
1362 ::osl::MutexGuard aGuard( mMutex );
1364 PassMap::iterator aIter;
1366 // remove the cached persistent values in the memory
1367 for( aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ )
1369 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); )
1371 if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
1373 aNPIter->RemovePasswords( PERSISTENT_RECORD );
1375 if ( m_pStorageFile )
1376 m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName )
1379 if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
1381 list< NamePassRecord >::iterator aIterToDelete( aNPIter );
1382 aNPIter++;
1383 aIter->second.erase( aIterToDelete );
1385 else
1386 aNPIter++;
1390 PassMap addon;
1391 if( m_pStorageFile )
1392 addon = m_pStorageFile->getInfo();
1394 for( aIter = addon.begin(); aIter != addon.end(); aIter++ )
1396 PassMap::iterator aSearchIter = m_aContainer.find( aIter->first );
1397 if( aSearchIter != m_aContainer.end() )
1398 for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
1399 UpdateVector( aSearchIter->first, aSearchIter->second, *aNPIter, sal_False );
1400 else
1401 m_aContainer.insert( PairUrlRecord( aIter->first, aIter->second ) );
1405 //-------------------------------------------------------------------------
1407 ::rtl::OUString SAL_CALL PasswordContainer::getImplementationName( ) throw(uno::RuntimeException)
1409 return impl_getStaticImplementationName();
1412 //-------------------------------------------------------------------------
1414 sal_Bool SAL_CALL PasswordContainer::supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException)
1416 if ( ServiceName.compareToAscii("com.sun.star.task.PasswordContainer") == 0 )
1417 return sal_True;
1418 else
1419 return sal_False;
1422 //-------------------------------------------------------------------------
1424 Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getSupportedServiceNames( ) throw(uno::RuntimeException)
1426 return impl_getStaticSupportedServiceNames();
1429 //-------------------------------------------------------------------------
1431 Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::impl_getStaticSupportedServiceNames( ) throw(uno::RuntimeException)
1433 Sequence< ::rtl::OUString > aRet(1);
1434 *aRet.getArray() = ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer");
1435 return aRet;
1438 //-------------------------------------------------------------------------
1440 ::rtl::OUString SAL_CALL PasswordContainer::impl_getStaticImplementationName() throw(uno::RuntimeException)
1442 return ::rtl::OUString::createFromAscii("stardiv.svtools.PasswordContainer");
1445 //-------------------------------------------------------------------------
1447 Reference< XInterface > SAL_CALL PasswordContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( RuntimeException )
1449 return Reference< XInterface >( *new PasswordContainer( xServiceManager ) );
1452 //-------------------------------------------------------------------------
1454 Reference< XSingleServiceFactory > SAL_CALL PasswordContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager ) throw(RuntimeException)
1456 Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager,
1457 PasswordContainer::impl_getStaticImplementationName(),
1458 PasswordContainer::impl_createInstance,
1459 PasswordContainer::impl_getStaticSupportedServiceNames()));
1460 return xReturn ;
1464 //-------------------------------------------------------------------------
1465 //-------------------------------------------------------------------------
1467 MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode )
1469 MasterPasswordRequest aRequest;
1471 aRequest.Classification = InteractionClassification_ERROR;
1472 aRequest.Mode = Mode;
1474 setRequest( makeAny( aRequest ) );
1476 // Fill continuations...
1477 Sequence< RememberAuthentication > aRememberModes( 1 );
1478 aRememberModes[ 0 ] = RememberAuthentication_NO;
1480 m_xAuthSupplier
1481 = new ::ucbhelper::InteractionSupplyAuthentication(
1482 this,
1483 sal_False, // bCanSetRealm
1484 sal_False, // bCanSetUserName
1485 sal_True, // bCanSetPassword
1486 sal_False, // bCanSetAccount
1487 aRememberModes, // rRememberPasswordModes
1488 RememberAuthentication_NO, // eDefaultRememberPasswordMode
1489 aRememberModes, // rRememberAccountModes
1490 RememberAuthentication_NO // eDefaultRememberAccountMode
1493 Sequence<
1494 Reference< XInteractionContinuation > > aContinuations( 3 );
1495 aContinuations[ 0 ] = new ::ucbhelper::InteractionAbort( this );
1496 aContinuations[ 1 ] = new ::ucbhelper::InteractionRetry( this );
1497 aContinuations[ 2 ] = m_xAuthSupplier.get();
1499 setContinuations( aContinuations );
1502 //-------------------------------------------------------------------------
1503 //-------------------------------------------------------------------------
1505 extern "C"
1507 SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment (
1508 const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */)
1510 *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
1513 SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo (
1514 void * /* pServiceManager */, void * pRegistryKey)
1516 if (pRegistryKey)
1518 Reference< XRegistryKey > xRegistryKey (
1519 reinterpret_cast< XRegistryKey* >( pRegistryKey ));
1520 Reference< XRegistryKey > xNewKey;
1522 xNewKey = xRegistryKey->createKey(
1523 ::rtl::OUString::createFromAscii( "/stardiv.svtools.PasswordContainer/UNO/SERVICES" ));
1524 xNewKey->createKey( ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer"));
1526 return sal_True;
1528 return sal_False;
1531 SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory (
1532 const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */)
1534 void * pResult = 0;
1535 if (pServiceManager)
1537 Reference< XSingleServiceFactory > xFactory;
1538 if (PasswordContainer::impl_getStaticImplementationName().compareToAscii (pImplementationName) == 0)
1540 xFactory = PasswordContainer::impl_createFactory (
1541 reinterpret_cast< XMultiServiceFactory* >(pServiceManager));
1543 if (xFactory.is())
1545 xFactory->acquire();
1546 pResult = xFactory.get();
1549 return pResult;
1552 } // extern "C"