1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: passwordcontainer.cxx,v $
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>
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
++ )
72 aResult
+= ::rtl::OString( "__" );
73 ::rtl::OString line
= ::rtl::OUStringToOString( lines
[i
], RTL_TEXTENCODING_UTF8
);
74 pLine
= line
.getStr();
78 if( ( *pLine
>= 'A' && *pLine
<= 'Z' )
79 || ( *pLine
>= 'a' && *pLine
<= 'z' )
80 || ( *pLine
>= '0' && *pLine
<= '9' ) )
82 aResult
+= ::rtl::OString::valueOf( *pLine
);
86 aResult
+= ::rtl::OString("_");
87 aResult
+= ::rtl::OString::valueOf( (sal_Int32
) *pLine
, 16 );
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
;
114 while( *pLine
&& !( pLine
[0] == '_' && pLine
[1] == '_' ))
117 newItem
+= ::rtl::OUString::valueOf( (sal_Unicode
) *pLine
);
122 ::rtl::OUString aNum
;
123 for( int i
= 1; i
< 3; 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" );
134 aNum
+= ::rtl::OUString::valueOf( (sal_Unicode
) pLine
[i
] );
137 newItem
+= ::rtl::OUString::valueOf( (sal_Unicode
) aNum
.toInt32( 16 ) );
141 aResult
.push_back( newItem
);
142 } while( pLine
[0] == '_' && pLine
[1] == '_' );
145 OSL_ENSURE( sal_False
, "Wrong index syntax!\n" );
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
);
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() );
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' );
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
];
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
];
220 //-------------------------------------------------------------------------
221 //-------------------------------------------------------------------------
223 PassMap
StorageItem::getInfo()
227 Sequence
< ::rtl::OUString
> aNodeNames
= ConfigItem::GetNodeNames( ::rtl::OUString::createFromAscii("Store") );
228 sal_Int32 aNodeCount
= aNodeNames
.getLength();
229 Sequence
< ::rtl::OUString
> aPropNames( aNodeCount
);
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" );
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
) );
264 NamePassRecord
aNewRecord( aName
, aEPasswd
);
265 list
< NamePassRecord
> listToAdd( 1, aNewRecord
);
267 aResult
.insert( PairUrlRecord( aUrl
, listToAdd
) );
271 OSL_ENSURE( sal_False
, "Wrong index sintax!\n" );
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" );
307 sal_Bool aResult
= false;
308 aPropertyValues
[0] >>= aResult
;
313 //-------------------------------------------------------------------------
315 sal_Bool
StorageItem::getEncodedMP( ::rtl::OUString
& aResult
)
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" );
335 aPropertyValues
[0] >>= hasEncoded
;
336 aPropertyValues
[1] >>= mEncoded
;
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
;
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!" );
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
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" ) );
447 if( m_pStorageFile
->useStorage() )
448 m_aContainer
= m_pStorageFile
->getInfo();
451 //-------------------------------------------------------------------------
453 PasswordContainer::~PasswordContainer()
455 ::osl::MutexGuard
aGuard( mMutex
);
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
);
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" );
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
);
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" );
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() );
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
);
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() );
636 // the password must be already encoded
637 m_pStorageFile
->update( aURL
, aRecord
); // change existing ( aURL, aName ) record in the configfile
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() );
685 sal_Bool bTryToDecode
= sal_True
;
687 for( list
< NamePassRecord
>::const_iterator aNPIter
= original
.begin();
688 aNPIter
!= original
.end();
691 aResult
[nInd
] = CopyToUserRecord( *aNPIter
, bTryToDecode
, aHandler
);
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
);
728 OSL_ASSERT( "Unexpected persistence status!" );
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
);
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
) );
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
) );
789 //-------------------------------------------------------------------------
791 Sequence
< UserRecord
> PasswordContainer::FindUsr( const list
< NamePassRecord
>& userlist
, const ::rtl::OUString
& aName
, const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
794 for( list
< NamePassRecord
>::const_iterator aNPIter
= userlist
.begin();
795 aNPIter
!= userlist
.end();
798 if( aNPIter
->GetUserName().equals( aName
) )
800 Sequence
< UserRecord
> aResult(1);
801 sal_Bool bTryToDecode
= sal_True
;
802 aResult
[0] = CopyToUserRecord( *aNPIter
, bTryToDecode
, aHandler
);
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
);
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
);
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" ) );
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
;
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
);
889 const ::rtl::Reference
< ucbhelper::InteractionSupplyAuthentication
> & xSupp
890 = xRequest
->getAuthenticationSupplier();
892 aResult
= xSupp
->getPassword();
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
)
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
) );
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
;
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 );
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
);
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 );
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
);
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
);
1075 aIter
->second
.erase( aIterToDelete
);
1081 if( aIter
->second
.begin() == aIter
->second
.end() )
1083 PassMap::iterator
aIterToDelete( aIter
);
1085 m_aContainer
.erase( aIterToDelete
);
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
);
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
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
;
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() );
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
& )
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
>() );
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();
1269 removeMasterPassword();
1271 if ( m_pStorageFile
->useStorage() == bAllow
)
1274 m_pStorageFile
->setUseStorage( 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
>() );
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
);
1383 aIter
->second
.erase( aIterToDelete
);
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
);
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 )
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");
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()));
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
;
1481 = new ::ucbhelper::InteractionSupplyAuthentication(
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
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 //-------------------------------------------------------------------------
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
)
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"));
1531 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
component_getFactory (
1532 const sal_Char
* pImplementationName
, void * pServiceManager
, void * /* pRegistryKey */)
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
));
1545 xFactory
->acquire();
1546 pResult
= xFactory
.get();