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( '/' ) );
158 sal_Int32 aPrevInd
= aURL
.lastIndexOf( sal_Unicode( '/' ), aInd
);
159 if ( aURL
.indexOf( ::rtl::OUString::createFromAscii( "://" ) )
161 aInd
!= aURL
.getLength() - 1 )
163 aURL
= aURL
.copy( 0, aInd
);
171 //-------------------------------------------------------------------------
173 static ::rtl::OUString
getAsciiLine( const ::rtl::ByteSequence
& buf
)
175 ::rtl::OUString aResult
;
177 ::rtl::ByteSequence
outbuf( buf
.getLength()*2+1 );
179 for( int ind
= 0; ind
< buf
.getLength(); ind
++ )
181 outbuf
[ind
*2] = ( ((sal_uInt8
)buf
[ind
]) >> 4 ) + 'a';
182 outbuf
[ind
*2+1] = ( ((sal_uInt8
)buf
[ind
]) & 0x0f ) + 'a';
184 outbuf
[buf
.getLength()*2] = '\0';
186 aResult
= ::rtl::OUString::createFromAscii( (sal_Char
*)outbuf
.getArray() );
191 //-------------------------------------------------------------------------
193 static ::rtl::ByteSequence
getBufFromAsciiLine( ::rtl::OUString line
)
195 OSL_ENSURE( line
.getLength() % 2 == 0, "Wrong syntax!\n" );
196 ::rtl::OString tmpLine
= ::rtl::OUStringToOString( line
, RTL_TEXTENCODING_ASCII_US
);
197 ::rtl::ByteSequence
aResult(line
.getLength()/2);
199 for( int ind
= 0; ind
< tmpLine
.getLength()/2; ind
++ )
201 aResult
[ind
] = ( (sal_uInt8
)( tmpLine
.getStr()[ind
*2] - 'a' ) << 4 ) | (sal_uInt8
)( tmpLine
.getStr()[ind
*2+1] - 'a' );
207 //-------------------------------------------------------------------------
209 static Sequence
< ::rtl::OUString
> copyVectorToSequence( const vector
< ::rtl::OUString
>& original
)
211 Sequence
< ::rtl::OUString
> newOne ( original
.size() );
212 for( unsigned int i
= 0; i
< original
.size() ; i
++ )
213 newOne
[i
] = original
[i
];
218 static vector
< ::rtl::OUString
> copySequenceToVector( const Sequence
< ::rtl::OUString
>& original
)
220 vector
< ::rtl::OUString
> newOne ( original
.getLength() );
221 for( int i
= 0; i
< original
.getLength() ; i
++ )
222 newOne
[i
] = original
[i
];
227 //-------------------------------------------------------------------------
228 //-------------------------------------------------------------------------
230 PassMap
StorageItem::getInfo()
234 Sequence
< ::rtl::OUString
> aNodeNames
= ConfigItem::GetNodeNames( ::rtl::OUString::createFromAscii("Store") );
235 sal_Int32 aNodeCount
= aNodeNames
.getLength();
236 Sequence
< ::rtl::OUString
> aPropNames( aNodeCount
);
239 for( aNodeInd
= 0; aNodeInd
< aNodeCount
; ++aNodeInd
)
241 aPropNames
[aNodeInd
] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
242 aPropNames
[aNodeInd
] += aNodeNames
[aNodeInd
];
243 aPropNames
[aNodeInd
] += ::rtl::OUString::createFromAscii( "']/Password" );
246 Sequence
< Any
> aPropertyValues
= ConfigItem::GetProperties( aPropNames
);
248 if( aPropertyValues
.getLength() != aNodeNames
.getLength() )
250 OSL_ENSURE( aPropertyValues
.getLength() == aNodeNames
.getLength(), "Problems during reading\n" );
254 for( aNodeInd
= 0; aNodeInd
< aNodeCount
; ++aNodeInd
)
256 vector
< ::rtl::OUString
> aUrlUsr
= getInfoFromInd( aNodeNames
[aNodeInd
] );
258 if( aUrlUsr
.size() == 2 )
260 ::rtl::OUString aUrl
= aUrlUsr
[0];
261 ::rtl::OUString aName
= aUrlUsr
[1];
263 ::rtl::OUString aEPasswd
;
264 aPropertyValues
[aNodeInd
] >>= aEPasswd
;
266 PassMap::iterator aIter
= aResult
.find( aUrl
);
267 if( aIter
!= aResult
.end() )
268 aIter
->second
.push_back( NamePassRecord( aName
, aEPasswd
) );
271 NamePassRecord
aNewRecord( aName
, aEPasswd
);
272 list
< NamePassRecord
> listToAdd( 1, aNewRecord
);
274 aResult
.insert( PairUrlRecord( aUrl
, listToAdd
) );
278 OSL_ENSURE( sal_False
, "Wrong index sintax!\n" );
284 //-------------------------------------------------------------------------
286 void StorageItem::setUseStorage( sal_Bool bUse
)
288 Sequence
< ::rtl::OUString
> sendNames(1);
289 Sequence
< uno::Any
> sendVals(1);
291 sendNames
[0] = ::rtl::OUString::createFromAscii( "UseStorage" );
293 sendVals
[0] <<= bUse
;
295 ConfigItem::SetModified();
296 ConfigItem::PutProperties( sendNames
, sendVals
);
299 //-------------------------------------------------------------------------
301 sal_Bool
StorageItem::useStorage()
303 Sequence
< ::rtl::OUString
> aNodeNames( 1 );
304 aNodeNames
[0] = ::rtl::OUString::createFromAscii( "UseStorage" );
306 Sequence
< Any
> aPropertyValues
= ConfigItem::GetProperties( aNodeNames
);
308 if( aPropertyValues
.getLength() != aNodeNames
.getLength() )
310 OSL_ENSURE( aPropertyValues
.getLength() == aNodeNames
.getLength(), "Problems during reading\n" );
314 sal_Bool aResult
= false;
315 aPropertyValues
[0] >>= aResult
;
320 //-------------------------------------------------------------------------
322 sal_Bool
StorageItem::getEncodedMP( ::rtl::OUString
& aResult
)
330 Sequence
< ::rtl::OUString
> aNodeNames( 2 );
331 aNodeNames
[0] = ::rtl::OUString::createFromAscii( "HasMaster" );
332 aNodeNames
[1] = ::rtl::OUString::createFromAscii( "Master" );
334 Sequence
< Any
> aPropertyValues
= ConfigItem::GetProperties( aNodeNames
);
336 if( aPropertyValues
.getLength() != aNodeNames
.getLength() )
338 OSL_ENSURE( aPropertyValues
.getLength() == aNodeNames
.getLength(), "Problems during reading\n" );
342 aPropertyValues
[0] >>= hasEncoded
;
343 aPropertyValues
[1] >>= mEncoded
;
350 //-------------------------------------------------------------------------
352 void StorageItem::setEncodedMP( const ::rtl::OUString
& aEncoded
, sal_Bool bAcceptEmpty
)
354 Sequence
< ::rtl::OUString
> sendNames(2);
355 Sequence
< uno::Any
> sendVals(2);
357 sendNames
[0] = ::rtl::OUString::createFromAscii( "HasMaster" );
358 sendNames
[1] = ::rtl::OUString::createFromAscii( "Master" );
360 sal_Bool bHasMaster
= ( aEncoded
.getLength() > 0 || bAcceptEmpty
);
361 sendVals
[0] <<= bHasMaster
;
362 sendVals
[1] <<= aEncoded
;
364 ConfigItem::SetModified();
365 ConfigItem::PutProperties( sendNames
, sendVals
);
367 hasEncoded
= bHasMaster
;
371 //-------------------------------------------------------------------------
373 void StorageItem::remove( const ::rtl::OUString
& aURL
, const ::rtl::OUString
& aName
)
375 vector
< ::rtl::OUString
> forIndex
;
376 forIndex
.push_back( aURL
);
377 forIndex
.push_back( aName
);
379 Sequence
< ::rtl::OUString
> sendSeq(1);
381 sendSeq
[0] = createIndex( forIndex
);
382 // sendSeq[0] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
383 // sendSeq[0] += createIndex( forIndex );
384 // sendSeq[0] += ::rtl::OUString::createFromAscii( "']" );
386 ConfigItem::ClearNodeElements( ::rtl::OUString::createFromAscii( "Store" ), sendSeq
);
389 //-------------------------------------------------------------------------
391 void StorageItem::clear()
393 Sequence
< ::rtl::OUString
> sendSeq(1);
395 ConfigItem::ClearNodeSet( ::rtl::OUString::createFromAscii( "Store" ) );
398 //-------------------------------------------------------------------------
400 void StorageItem::update( const ::rtl::OUString
& aURL
, const NamePassRecord
& aRecord
)
402 if ( !aRecord
.HasPasswords( PERSISTENT_RECORD
) )
404 OSL_ASSERT( "Unexpected storing of a record!" );
408 vector
< ::rtl::OUString
> forIndex
;
409 forIndex
.push_back( aURL
);
410 forIndex
.push_back( aRecord
.GetUserName() );
412 Sequence
< beans::PropertyValue
> sendSeq(1);
414 sendSeq
[0].Name
= ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
415 sendSeq
[0].Name
+= createIndex( forIndex
);
416 sendSeq
[0].Name
+= ::rtl::OUString::createFromAscii( "']/Password" );
418 sendSeq
[0].Value
<<= aRecord
.GetPersPasswords();
420 ConfigItem::SetModified();
421 ConfigItem::SetSetProperties( ::rtl::OUString::createFromAscii( "Store" ), sendSeq
);
424 //-------------------------------------------------------------------------
426 void StorageItem::Notify( const Sequence
< ::rtl::OUString
>& )
428 // this feature still should not be used
433 //-------------------------------------------------------------------------
435 void StorageItem::Commit()
437 // Do nothing, we stored everything we want already
440 //-------------------------------------------------------------------------
441 //-------------------------------------------------------------------------
443 PasswordContainer::PasswordContainer( const Reference
<XMultiServiceFactory
>& xServiceFactory
):
444 m_pStorageFile( NULL
)
446 // m_pStorageFile->Notify() can be called
447 ::osl::MutexGuard
aGuard( mMutex
);
449 mComponent
= Reference
< XComponent
>( xServiceFactory
, UNO_QUERY
);
450 mComponent
->addEventListener( this );
452 m_pStorageFile
= new StorageItem( this, ::rtl::OUString::createFromAscii( "Office.Common/Passwords" ) );
454 if( m_pStorageFile
->useStorage() )
455 m_aContainer
= m_pStorageFile
->getInfo();
458 //-------------------------------------------------------------------------
460 PasswordContainer::~PasswordContainer()
462 ::osl::MutexGuard
aGuard( mMutex
);
466 delete m_pStorageFile
;
467 m_pStorageFile
= NULL
;
470 if( mComponent
.is() )
472 mComponent
->removeEventListener(this);
473 mComponent
= Reference
< XComponent
>();
477 //-------------------------------------------------------------------------
479 void SAL_CALL
PasswordContainer::disposing( const EventObject
& ) throw(RuntimeException
)
481 ::osl::MutexGuard
aGuard( mMutex
);
485 delete m_pStorageFile
;
486 m_pStorageFile
= NULL
;
489 if( mComponent
.is() )
491 //mComponent->removeEventListener(this);
492 mComponent
= Reference
< XComponent
>();
496 //-------------------------------------------------------------------------
498 vector
< ::rtl::OUString
> PasswordContainer::DecodePasswords( const ::rtl::OUString
& aLine
, const ::rtl::OUString
& aMasterPasswd
) throw(RuntimeException
)
500 if( aMasterPasswd
.getLength() )
502 rtlCipher aDecoder
= rtl_cipher_create (rtl_Cipher_AlgorithmBF
, rtl_Cipher_ModeStream
);
503 OSL_ENSURE( aDecoder
, "Can't create decoder\n" );
507 OSL_ENSURE( aMasterPasswd
.getLength() == RTL_DIGEST_LENGTH_MD5
* 2, "Wrong master password format!\n" );
509 unsigned char code
[RTL_DIGEST_LENGTH_MD5
];
510 for( int ind
= 0; ind
< RTL_DIGEST_LENGTH_MD5
; ind
++ )
511 code
[ ind
] = (char)(aMasterPasswd
.copy( ind
*2, 2 ).toInt32(16));
513 rtlCipherError result
= rtl_cipher_init (
514 aDecoder
, rtl_Cipher_DirectionDecode
,
515 code
, RTL_DIGEST_LENGTH_MD5
, NULL
, 0 );
517 if( result
== rtl_Cipher_E_None
)
519 ::rtl::ByteSequence aSeq
= getBufFromAsciiLine( aLine
);
521 ::rtl::ByteSequence
resSeq( aSeq
.getLength() );
523 result
= rtl_cipher_decode ( aDecoder
, (sal_uInt8
*)aSeq
.getArray(), aSeq
.getLength(),
524 (sal_uInt8
*)resSeq
.getArray(), resSeq
.getLength() );
526 ::rtl::OUString
aPasswd( ( sal_Char
* )resSeq
.getArray(), resSeq
.getLength(), RTL_TEXTENCODING_UTF8
);
528 rtl_cipher_destroy (aDecoder
);
530 return getInfoFromInd( aPasswd
);
533 rtl_cipher_destroy (aDecoder
);
538 OSL_ENSURE( sal_False
, "No master password provided!\n" );
539 // throw special exception
542 // problems with decoding
543 OSL_ENSURE( sal_False
, "Problem with decoding\n" );
544 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't decode!" ), Reference
< XInterface
>() );
548 //-------------------------------------------------------------------------
550 ::rtl::OUString
PasswordContainer::EncodePasswords( vector
< ::rtl::OUString
> lines
, const ::rtl::OUString
& aMasterPasswd
) throw(RuntimeException
)
552 if( aMasterPasswd
.getLength() )
554 ::rtl::OString aSeq
= ::rtl::OUStringToOString( createIndex( lines
), RTL_TEXTENCODING_UTF8
);
556 rtlCipher aEncoder
= rtl_cipher_create (rtl_Cipher_AlgorithmBF
, rtl_Cipher_ModeStream
);
557 OSL_ENSURE( aEncoder
, "Can't create encoder\n" );
561 OSL_ENSURE( aMasterPasswd
.getLength() == RTL_DIGEST_LENGTH_MD5
* 2, "Wrong master password format!\n" );
563 unsigned char code
[RTL_DIGEST_LENGTH_MD5
];
564 for( int ind
= 0; ind
< RTL_DIGEST_LENGTH_MD5
; ind
++ )
565 code
[ ind
] = (char)(aMasterPasswd
.copy( ind
*2, 2 ).toInt32(16));
567 rtlCipherError result
= rtl_cipher_init (
568 aEncoder
, rtl_Cipher_DirectionEncode
,
569 code
, RTL_DIGEST_LENGTH_MD5
, NULL
, 0 );
571 if( result
== rtl_Cipher_E_None
)
573 ::rtl::ByteSequence
resSeq(aSeq
.getLength()+1);
575 result
= rtl_cipher_encode ( aEncoder
, (sal_uInt8
*)aSeq
.getStr(), aSeq
.getLength()+1,
576 (sal_uInt8
*)resSeq
.getArray(), resSeq
.getLength() );
580 rtlCipherError result = rtl_cipher_init (
581 aEncoder, rtl_Cipher_DirectionDecode,
582 code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
585 if( result == rtl_Cipher_E_None )
587 ::rtl::OUString testOU = getAsciiLine( resSeq );
588 ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU );
590 ::rtl::ByteSequence resSeq1( aSeq1.getLength() );
592 if( resSeq.getLength() == aSeq1.getLength() )
594 for( int ind = 0; ind < aSeq1.getLength(); ind++ )
595 if( resSeq[ind] != aSeq1[ind] )
596 testOU = ::rtl::OUString();
599 result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(),
600 (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() );
602 ::rtl::OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 );
606 rtl_cipher_destroy (aEncoder
);
608 if( result
== rtl_Cipher_E_None
)
609 return getAsciiLine( resSeq
);
613 rtl_cipher_destroy (aEncoder
);
618 OSL_ENSURE( sal_False
, "No master password provided!\n" );
619 // throw special exception
622 // problems with encoding
623 OSL_ENSURE( sal_False
, "Problem with encoding\n" );
624 throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't encode!" ), Reference
< XInterface
>() );
627 //-------------------------------------------------------------------------
629 void PasswordContainer::UpdateVector( const ::rtl::OUString
& aURL
, list
< NamePassRecord
>& toUpdate
, NamePassRecord
& aRecord
, sal_Bool writeFile
) throw(RuntimeException
)
631 for( list
< NamePassRecord
>::iterator aNPIter
= toUpdate
.begin(); aNPIter
!= toUpdate
.end(); aNPIter
++ )
632 if( aNPIter
->GetUserName().equals( aRecord
.GetUserName() ) )
634 if( aRecord
.HasPasswords( MEMORY_RECORD
) )
635 aNPIter
->SetMemPasswords( aRecord
.GetMemPasswords() );
637 if( aRecord
.HasPasswords( PERSISTENT_RECORD
) )
639 aNPIter
->SetPersPasswords( aRecord
.GetPersPasswords() );
643 // the password must be already encoded
644 m_pStorageFile
->update( aURL
, aRecord
); // change existing ( aURL, aName ) record in the configfile
652 if( aRecord
.HasPasswords( PERSISTENT_RECORD
) && writeFile
)
654 // the password must be already encoded
655 m_pStorageFile
->update( aURL
, aRecord
); // add new aName to the existing url
658 toUpdate
.insert( toUpdate
.begin(), aRecord
);
661 //-------------------------------------------------------------------------
663 UserRecord
PasswordContainer::CopyToUserRecord( const NamePassRecord
& aRecord
, sal_Bool
& io_bTryToDecode
, const Reference
< XInteractionHandler
>& aHandler
)
665 ::std::vector
< ::rtl::OUString
> aPasswords
;
666 if( aRecord
.HasPasswords( MEMORY_RECORD
) )
667 aPasswords
= aRecord
.GetMemPasswords();
669 if( io_bTryToDecode
&& aRecord
.HasPasswords( PERSISTENT_RECORD
) )
673 ::std::vector
< ::rtl::OUString
> aDecodedPasswords
= DecodePasswords( aRecord
.GetPersPasswords(), GetMasterPassword( aHandler
) );
674 aPasswords
.insert( aPasswords
.end(), aDecodedPasswords
.begin(), aDecodedPasswords
.end() );
676 catch( NoMasterException
& )
678 // if master password could not be detected the entry will be just ignored
679 io_bTryToDecode
= sal_False
;
683 return UserRecord( aRecord
.GetUserName(), copyVectorToSequence( aPasswords
) );
686 //-------------------------------------------------------------------------
688 Sequence
< UserRecord
> PasswordContainer::CopyToUserRecordSequence( const list
< NamePassRecord
>& original
, const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
690 Sequence
< UserRecord
> aResult( original
.size() );
692 sal_Bool bTryToDecode
= sal_True
;
694 for( list
< NamePassRecord
>::const_iterator aNPIter
= original
.begin();
695 aNPIter
!= original
.end();
698 aResult
[nInd
] = CopyToUserRecord( *aNPIter
, bTryToDecode
, aHandler
);
704 //-------------------------------------------------------------------------
706 void SAL_CALL
PasswordContainer::add( const ::rtl::OUString
& Url
, const ::rtl::OUString
& UserName
, const Sequence
< ::rtl::OUString
>& Passwords
, const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
708 ::osl::MutexGuard
aGuard( mMutex
);
710 PrivateAdd( Url
, UserName
, Passwords
, MEMORY_RECORD
, aHandler
);
713 //-------------------------------------------------------------------------
715 void SAL_CALL
PasswordContainer::addPersistent( const ::rtl::OUString
& Url
, const ::rtl::OUString
& UserName
, const Sequence
< ::rtl::OUString
>& Passwords
, const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
717 ::osl::MutexGuard
aGuard( mMutex
);
719 PrivateAdd( Url
, UserName
, Passwords
, PERSISTENT_RECORD
, aHandler
);
722 //-------------------------------------------------------------------------
724 void PasswordContainer::PrivateAdd( const ::rtl::OUString
& Url
, const ::rtl::OUString
& UserName
, const Sequence
< ::rtl::OUString
>& Passwords
, char Mode
, const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
726 NamePassRecord
aRecord( UserName
);
727 ::std::vector
< ::rtl::OUString
> aStorePass
= copySequenceToVector( Passwords
);
729 if( Mode
== PERSISTENT_RECORD
)
730 aRecord
.SetPersPasswords( EncodePasswords( aStorePass
, GetMasterPassword( aHandler
) ) );
731 else if( Mode
== MEMORY_RECORD
)
732 aRecord
.SetMemPasswords( aStorePass
);
735 OSL_ASSERT( "Unexpected persistence status!" );
739 if( !m_aContainer
.empty() )
741 PassMap::iterator aIter
= m_aContainer
.find( Url
);
743 if( aIter
!= m_aContainer
.end() )
745 UpdateVector( aIter
->first
, aIter
->second
, aRecord
, sal_True
);
750 list
< NamePassRecord
> listToAdd( 1, aRecord
);
751 m_aContainer
.insert( PairUrlRecord( Url
, listToAdd
) );
753 if( Mode
== PERSISTENT_RECORD
&& m_pStorageFile
&& m_pStorageFile
->useStorage() )
754 m_pStorageFile
->update( Url
, aRecord
);
758 //-------------------------------------------------------------------------
761 UrlRecord SAL_CALL
PasswordContainer::find( const ::rtl::OUString
& aURL
, const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
763 return find( aURL
, rtl::OUString(), false, aHandler
);
766 //-------------------------------------------------------------------------
768 UrlRecord SAL_CALL
PasswordContainer::findForName( const ::rtl::OUString
& aURL
, const ::rtl::OUString
& aName
, const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
770 return find( aURL
, aName
, true, aHandler
);
773 //-------------------------------------------------------------------------
775 Sequence
< UserRecord
> PasswordContainer::FindUsr( const list
< NamePassRecord
>& userlist
, const ::rtl::OUString
& aName
, const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
778 for( list
< NamePassRecord
>::const_iterator aNPIter
= userlist
.begin();
779 aNPIter
!= userlist
.end();
782 if( aNPIter
->GetUserName().equals( aName
) )
784 Sequence
< UserRecord
> aResult(1);
785 sal_Bool bTryToDecode
= sal_True
;
786 aResult
[0] = CopyToUserRecord( *aNPIter
, bTryToDecode
, aHandler
);
792 return Sequence
< UserRecord
>();
795 //-------------------------------------------------------------------------
797 bool PasswordContainer::createUrlRecord(
798 const PassMap::iterator
& rIter
,
800 const ::rtl::OUString
& aName
,
801 const Reference
< XInteractionHandler
>& aHandler
,
803 throw( RuntimeException
)
807 Sequence
< UserRecord
> aUsrRec
808 = FindUsr( rIter
->second
, aName
, aHandler
);
809 if( aUsrRec
.getLength() )
811 rRec
= UrlRecord( rIter
->first
, aUsrRec
);
819 CopyToUserRecordSequence( rIter
->second
, aHandler
) );
825 //-------------------------------------------------------------------------
827 UrlRecord
PasswordContainer::find(
828 const ::rtl::OUString
& aURL
,
829 const ::rtl::OUString
& aName
,
830 bool bName
, // only needed to support empty user names
831 const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
833 ::osl::MutexGuard
aGuard( mMutex
);
835 if( !m_aContainer
.empty() && aURL
.getLength() )
837 ::rtl::OUString
aUrl( aURL
);
839 // each iteration remove last '/...' section from the aUrl
840 // while it's possible, up to the most left '://'
843 // first look for <url>/somename and then look for <url>/somename/...
844 PassMap::iterator aIter
= m_aContainer
.find( aUrl
);
845 if( aIter
!= m_aContainer
.end() )
848 if ( createUrlRecord( aIter
, bName
, aName
, aHandler
, aRec
) )
853 ::rtl::OUString
tmpUrl( aUrl
);
854 if ( tmpUrl
.getStr()[tmpUrl
.getLength() - 1] != (sal_Unicode
)'/' )
855 tmpUrl
+= ::rtl::OUString::createFromAscii( "/" );
857 aIter
= m_aContainer
.lower_bound( tmpUrl
);
858 if( aIter
!= m_aContainer
.end() && aIter
->first
.match( tmpUrl
) )
861 if ( createUrlRecord( aIter
, bName
, aName
, aHandler
, aRec
) )
866 while( shorterUrl( aUrl
) && aUrl
.getLength() );
872 //-------------------------------------------------------------------------
873 ::rtl::OUString
PasswordContainer::GetDefaultMasterPassword()
875 ::rtl::OUString aResult
;
876 for ( sal_Int32 nInd
= 0; nInd
< RTL_DIGEST_LENGTH_MD5
; nInd
++ )
877 aResult
+= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "aa" ) );
882 //-------------------------------------------------------------------------
883 ::rtl::OUString
PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode
, const uno::Reference
< task::XInteractionHandler
>& xHandler
)
885 // empty string means that the call was cancelled or just failed
886 ::rtl::OUString aResult
;
890 ::rtl::Reference
< MasterPasswordRequest_Impl
> xRequest
= new MasterPasswordRequest_Impl( aRMode
);
892 xHandler
->handle( xRequest
.get() );
894 ::rtl::Reference
< ucbhelper::InteractionContinuation
> xSelection
= xRequest
->getSelection();
896 if ( xSelection
.is() )
898 Reference
< XInteractionAbort
> xAbort( xSelection
.get(), UNO_QUERY
);
901 const ::rtl::Reference
< ucbhelper::InteractionSupplyAuthentication
> & xSupp
902 = xRequest
->getAuthenticationSupplier();
904 aResult
= xSupp
->getPassword();
912 //-------------------------------------------------------------------------
914 ::rtl::OUString
PasswordContainer::GetMasterPassword( const Reference
< XInteractionHandler
>& aHandler
) throw(RuntimeException
)
916 PasswordRequestMode aRMode
= PasswordRequestMode_PASSWORD_ENTER
;
917 if( !m_pStorageFile
|| !m_pStorageFile
->useStorage() )
918 throw NoMasterException( ::rtl::OUString::createFromAscii( "Password storing is not active!" ), Reference
< XInterface
>(), aRMode
);
920 if( !m_aMasterPasswd
.getLength() && aHandler
.is() )
922 ::rtl::OUString aEncodedMP
;
923 sal_Bool bAskAgain
= sal_False
;
924 sal_Bool bDefaultPassword
= sal_False
;
926 if( !m_pStorageFile
->getEncodedMP( aEncodedMP
) )
927 aRMode
= PasswordRequestMode_PASSWORD_CREATE
;
928 else if ( !aEncodedMP
.getLength() )
930 m_aMasterPasswd
= GetDefaultMasterPassword();
931 bDefaultPassword
= sal_True
;
934 if ( !bDefaultPassword
)
937 bAskAgain
= sal_False
;
939 ::rtl::OUString aPass
= RequestPasswordFromUser( aRMode
, aHandler
);
940 if ( aPass
.getLength() )
942 if( aRMode
== PasswordRequestMode_PASSWORD_CREATE
)
944 m_aMasterPasswd
= aPass
;
945 vector
< ::rtl::OUString
> aMaster( 1, m_aMasterPasswd
);
947 m_pStorageFile
->setEncodedMP( EncodePasswords( aMaster
, m_aMasterPasswd
) );
951 vector
< ::rtl::OUString
> aRM( DecodePasswords( aEncodedMP
, aPass
) );
952 if( !aRM
.size() || !aPass
.equals( aRM
[0] ) )
954 bAskAgain
= sal_True
;
955 aRMode
= PasswordRequestMode_PASSWORD_REENTER
;
958 m_aMasterPasswd
= aPass
;
962 } while( bAskAgain
);
966 if ( !m_aMasterPasswd
.getLength() )
967 throw NoMasterException( ::rtl::OUString::createFromAscii( "No master password!" ), Reference
< XInterface
>(), aRMode
);
969 return m_aMasterPasswd
;
972 //-------------------------------------------------------------------------
974 void SAL_CALL
PasswordContainer::remove( const ::rtl::OUString
& aURL
, const ::rtl::OUString
& aName
) throw(RuntimeException
)
976 ::osl::MutexGuard
aGuard( mMutex
);
978 ::rtl::OUString
aUrl( aURL
);
979 if( !m_aContainer
.empty() )
981 PassMap::iterator aIter
= m_aContainer
.find( aUrl
);
983 if( aIter
== m_aContainer
.end() )
985 sal_Int32 aInd
= aUrl
.lastIndexOf( sal_Unicode( '/' ) );
986 if( aInd
> 0 && aUrl
.getLength()-1 == aInd
)
987 aUrl
= aUrl
.copy( 0, aUrl
.getLength() - 1 );
989 aUrl
+= ::rtl::OUString::createFromAscii( "/" );
991 aIter
= m_aContainer
.find( aUrl
);
994 if( aIter
!= m_aContainer
.end() )
996 for( list
< NamePassRecord
>::iterator aNPIter
= aIter
->second
.begin(); aNPIter
!= aIter
->second
.end(); aNPIter
++ )
997 if( aNPIter
->GetUserName().equals( aName
) )
999 if( aNPIter
->HasPasswords( PERSISTENT_RECORD
) && m_pStorageFile
)
1000 m_pStorageFile
->remove( aURL
, aName
); // remove record ( aURL, aName )
1002 // the iterator will not be used any more so it can be removed directly
1003 aIter
->second
.erase( aNPIter
);
1005 if( aIter
->second
.begin() == aIter
->second
.end() )
1006 m_aContainer
.erase( aIter
);
1014 //-------------------------------------------------------------------------
1016 void SAL_CALL
PasswordContainer::removePersistent( const ::rtl::OUString
& aURL
, const ::rtl::OUString
& aName
) throw(RuntimeException
)
1018 ::osl::MutexGuard
aGuard( mMutex
);
1020 ::rtl::OUString
aUrl( aURL
);
1021 if( !m_aContainer
.empty() )
1023 PassMap::iterator aIter
= m_aContainer
.find( aUrl
);
1025 if( aIter
== m_aContainer
.end() )
1027 sal_Int32 aInd
= aUrl
.lastIndexOf( sal_Unicode( '/' ) );
1028 if( aInd
> 0 && aUrl
.getLength()-1 == aInd
)
1029 aUrl
= aUrl
.copy( 0, aUrl
.getLength() - 1 );
1031 aUrl
+= ::rtl::OUString::createFromAscii( "/" );
1033 aIter
= m_aContainer
.find( aUrl
);
1036 if( aIter
!= m_aContainer
.end() )
1038 for( list
< NamePassRecord
>::iterator aNPIter
= aIter
->second
.begin(); aNPIter
!= aIter
->second
.end(); aNPIter
++ )
1039 if( aNPIter
->GetUserName().equals( aName
) )
1041 if( aNPIter
->HasPasswords( PERSISTENT_RECORD
) )
1043 // TODO/LATER: should the password be converted to MemoryPassword?
1044 aNPIter
->RemovePasswords( PERSISTENT_RECORD
);
1046 if ( m_pStorageFile
)
1047 m_pStorageFile
->remove( aURL
, aName
); // remove record ( aURL, aName )
1050 if( !aNPIter
->HasPasswords( MEMORY_RECORD
) )
1051 aIter
->second
.erase( aNPIter
);
1053 if( aIter
->second
.begin() == aIter
->second
.end() )
1054 m_aContainer
.erase( aIter
);
1061 //-------------------------------------------------------------------------
1063 void SAL_CALL
PasswordContainer::removeAllPersistent() throw(RuntimeException
)
1065 ::osl::MutexGuard
aGuard( mMutex
);
1067 if( m_pStorageFile
)
1068 m_pStorageFile
->clear();
1070 for( PassMap::iterator aIter
= m_aContainer
.begin(); aIter
!= m_aContainer
.end(); )
1072 for( list
< NamePassRecord
>::iterator aNPIter
= aIter
->second
.begin(); aNPIter
!= aIter
->second
.end(); )
1074 if( aNPIter
->HasPasswords( PERSISTENT_RECORD
) )
1076 // TODO/LATER: should the password be converted to MemoryPassword?
1077 aNPIter
->RemovePasswords( PERSISTENT_RECORD
);
1079 if ( m_pStorageFile
)
1080 m_pStorageFile
->remove( aIter
->first
, aNPIter
->GetUserName() ); // remove record ( aURL, aName )
1083 if( !aNPIter
->HasPasswords( MEMORY_RECORD
) )
1085 list
< NamePassRecord
>::iterator
aIterToDelete( aNPIter
);
1087 aIter
->second
.erase( aIterToDelete
);
1093 if( aIter
->second
.begin() == aIter
->second
.end() )
1095 PassMap::iterator
aIterToDelete( aIter
);
1097 m_aContainer
.erase( aIterToDelete
);
1103 //-------------------------------------------------------------------------
1105 Sequence
< UrlRecord
> SAL_CALL
PasswordContainer::getAllPersistent( const Reference
< XInteractionHandler
>& xHandler
) throw(RuntimeException
)
1107 Sequence
< UrlRecord
> aResult
;
1109 ::osl::MutexGuard
aGuard( mMutex
);
1110 for( PassMap::iterator aIter
= m_aContainer
.begin(); aIter
!= m_aContainer
.end(); aIter
++ )
1112 Sequence
< UserRecord
> aUsers
;
1113 for( list
< NamePassRecord
>::iterator aNPIter
= aIter
->second
.begin(); aNPIter
!= aIter
->second
.end(); aNPIter
++ )
1114 if( aNPIter
->HasPasswords( PERSISTENT_RECORD
) )
1116 sal_Int32 oldLen
= aUsers
.getLength();
1117 aUsers
.realloc( oldLen
+ 1 );
1118 aUsers
[ oldLen
] = UserRecord( aNPIter
->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter
->GetPersPasswords(), GetMasterPassword( xHandler
) ) ) );
1121 if( aUsers
.getLength() )
1123 sal_Int32 oldLen
= aResult
.getLength();
1124 aResult
.realloc( oldLen
+ 1 );
1125 aResult
[ oldLen
] = UrlRecord( aIter
->first
, aUsers
);
1132 //-------------------------------------------------------------------------
1133 sal_Bool SAL_CALL
PasswordContainer::authorizateWithMasterPassword( const uno::Reference
< task::XInteractionHandler
>& xHandler
)
1134 throw (uno::RuntimeException
)
1136 sal_Bool bResult
= sal_False
;
1137 ::rtl::OUString aEncodedMP
;
1138 uno::Reference
< task::XInteractionHandler
> xTmpHandler
= xHandler
;
1139 ::osl::MutexGuard
aGuard( mMutex
);
1141 // the method should fail if there is no master password
1142 if( m_pStorageFile
&& m_pStorageFile
->useStorage() && m_pStorageFile
->getEncodedMP( aEncodedMP
) )
1144 if ( !aEncodedMP
.getLength() )
1146 // this is a default master password
1147 // no UI is necessary
1152 if ( !xTmpHandler
.is() )
1154 uno::Reference
< lang::XMultiServiceFactory
> xFactory( mComponent
, uno::UNO_QUERY_THROW
);
1155 xTmpHandler
.set( xFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW
);
1158 if ( m_aMasterPasswd
.getLength() )
1160 // there is a password, it should be just rechecked
1161 PasswordRequestMode aRMode
= PasswordRequestMode_PASSWORD_ENTER
;
1162 ::rtl::OUString aPass
;
1165 aPass
= RequestPasswordFromUser( aRMode
, xTmpHandler
);
1166 bResult
= ( aPass
.getLength() && aPass
.equals( m_aMasterPasswd
) );
1167 aRMode
= PasswordRequestMode_PASSWORD_REENTER
; // further questions with error notification
1168 } while( !bResult
&& aPass
.getLength() );
1174 // ask for the password, if user provide no correct password an exception will be thrown
1175 bResult
= ( GetMasterPassword( xTmpHandler
).getLength() > 0 );
1177 catch( uno::Exception
& )
1186 //-------------------------------------------------------------------------
1187 sal_Bool SAL_CALL
PasswordContainer::changeMasterPassword( const uno::Reference
< task::XInteractionHandler
>& xHandler
)
1188 throw (uno::RuntimeException
)
1190 sal_Bool bResult
= sal_False
;
1191 uno::Reference
< task::XInteractionHandler
> xTmpHandler
= xHandler
;
1192 ::osl::MutexGuard
aGuard( mMutex
);
1194 if ( m_pStorageFile
&& m_pStorageFile
->useStorage() )
1196 if ( !xTmpHandler
.is() )
1198 uno::Reference
< lang::XMultiServiceFactory
> xFactory( mComponent
, uno::UNO_QUERY_THROW
);
1199 xTmpHandler
.set( xFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW
);
1202 sal_Bool bCanChangePassword
= sal_True
;
1203 // if there is already a stored master password it should be entered by the user before the change happen
1204 ::rtl::OUString aEncodedMP
;
1205 if( m_aMasterPasswd
.getLength() || m_pStorageFile
->getEncodedMP( aEncodedMP
) )
1206 bCanChangePassword
= authorizateWithMasterPassword( xTmpHandler
);
1208 if ( bCanChangePassword
)
1210 // ask for the new password, but do not set it
1211 PasswordRequestMode aRMode
= PasswordRequestMode_PASSWORD_CREATE
;
1212 ::rtl::OUString aPass
= RequestPasswordFromUser( aRMode
, xTmpHandler
);
1214 if ( aPass
.getLength() )
1216 // get all the persistent entries if it is possible
1217 Sequence
< UrlRecord
> aPersistent
= getAllPersistent( uno::Reference
< task::XInteractionHandler
>() );
1219 // remove the master password and the entries persistence
1220 removeMasterPassword();
1222 // store the new master password
1223 m_aMasterPasswd
= aPass
;
1224 vector
< ::rtl::OUString
> aMaster( 1, m_aMasterPasswd
);
1225 m_pStorageFile
->setEncodedMP( EncodePasswords( aMaster
, m_aMasterPasswd
) );
1227 // store all the entries with the new password
1228 for ( int nURLInd
= 0; nURLInd
< aPersistent
.getLength(); nURLInd
++ )
1229 for ( int nNameInd
= 0; nNameInd
< aPersistent
[nURLInd
].UserList
.getLength(); nNameInd
++ )
1230 addPersistent( aPersistent
[nURLInd
].Url
,
1231 aPersistent
[nURLInd
].UserList
[nNameInd
].UserName
,
1232 aPersistent
[nURLInd
].UserList
[nNameInd
].Passwords
,
1233 uno::Reference
< task::XInteractionHandler
>() );
1243 //-------------------------------------------------------------------------
1244 void SAL_CALL
PasswordContainer::removeMasterPassword()
1245 throw (uno::RuntimeException
)
1247 // remove all the stored passwords and the master password
1248 removeAllPersistent();
1250 ::osl::MutexGuard
aGuard( mMutex
);
1251 if ( m_pStorageFile
)
1253 m_aMasterPasswd
= ::rtl::OUString();
1254 m_pStorageFile
->setEncodedMP( ::rtl::OUString() ); // let the master password be removed from configuration
1258 //-------------------------------------------------------------------------
1259 ::sal_Bool SAL_CALL
PasswordContainer::hasMasterPassword( )
1260 throw (::com::sun::star::uno::RuntimeException
)
1262 ::osl::MutexGuard
aGuard( mMutex
);
1264 if ( !m_pStorageFile
)
1265 throw uno::RuntimeException();
1267 ::rtl::OUString aEncodedMP
;
1268 return ( m_pStorageFile
->useStorage() && m_pStorageFile
->getEncodedMP( aEncodedMP
) );
1271 //-------------------------------------------------------------------------
1272 ::sal_Bool SAL_CALL
PasswordContainer::allowPersistentStoring( ::sal_Bool bAllow
)
1273 throw (::com::sun::star::uno::RuntimeException
)
1275 ::osl::MutexGuard
aGuard( mMutex
);
1277 if ( !m_pStorageFile
)
1278 throw uno::RuntimeException();
1281 removeMasterPassword();
1283 if ( m_pStorageFile
->useStorage() == bAllow
)
1286 m_pStorageFile
->setUseStorage( bAllow
);
1290 //-------------------------------------------------------------------------
1291 ::sal_Bool SAL_CALL
PasswordContainer::isPersistentStoringAllowed()
1292 throw (::com::sun::star::uno::RuntimeException
)
1294 ::osl::MutexGuard
aGuard( mMutex
);
1296 if ( !m_pStorageFile
)
1297 throw uno::RuntimeException();
1299 return m_pStorageFile
->useStorage();
1302 //-------------------------------------------------------------------------
1303 ::sal_Bool SAL_CALL
PasswordContainer::useDefaultMasterPassword( const uno::Reference
< task::XInteractionHandler
>& xHandler
)
1304 throw ( uno::RuntimeException
)
1306 sal_Bool bResult
= sal_False
;
1307 uno::Reference
< task::XInteractionHandler
> xTmpHandler
= xHandler
;
1308 ::osl::MutexGuard
aGuard( mMutex
);
1310 if ( m_pStorageFile
&& m_pStorageFile
->useStorage() )
1312 if ( !xTmpHandler
.is() )
1314 uno::Reference
< lang::XMultiServiceFactory
> xFactory( mComponent
, uno::UNO_QUERY_THROW
);
1315 xTmpHandler
.set( xFactory
->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW
);
1318 sal_Bool bCanChangePassword
= sal_True
;
1319 // if there is already a stored nondefault master password it should be entered by the user before the change happen
1320 ::rtl::OUString aEncodedMP
;
1321 if( m_pStorageFile
->getEncodedMP( aEncodedMP
) && aEncodedMP
.getLength() )
1322 bCanChangePassword
= authorizateWithMasterPassword( xTmpHandler
);
1324 if ( bCanChangePassword
)
1326 // generate the default password
1327 ::rtl::OUString aPass
= GetDefaultMasterPassword();
1328 if ( aPass
.getLength() )
1330 // get all the persistent entries if it is possible
1331 Sequence
< UrlRecord
> aPersistent
= getAllPersistent( uno::Reference
< task::XInteractionHandler
>() );
1333 // remove the master password and the entries persistence
1334 removeMasterPassword();
1336 // store the empty string to flag the default master password
1337 m_aMasterPasswd
= aPass
;
1338 m_pStorageFile
->setEncodedMP( ::rtl::OUString(), sal_True
);
1340 // store all the entries with the new password
1341 for ( int nURLInd
= 0; nURLInd
< aPersistent
.getLength(); nURLInd
++ )
1342 for ( int nNameInd
= 0; nNameInd
< aPersistent
[nURLInd
].UserList
.getLength(); nNameInd
++ )
1343 addPersistent( aPersistent
[nURLInd
].Url
,
1344 aPersistent
[nURLInd
].UserList
[nNameInd
].UserName
,
1345 aPersistent
[nURLInd
].UserList
[nNameInd
].Passwords
,
1346 uno::Reference
< task::XInteractionHandler
>() );
1357 //-------------------------------------------------------------------------
1358 ::sal_Bool SAL_CALL
PasswordContainer::isDefaultMasterPasswordUsed()
1359 throw ( uno::RuntimeException
)
1361 ::osl::MutexGuard
aGuard( mMutex
);
1363 if ( !m_pStorageFile
)
1364 throw uno::RuntimeException();
1366 ::rtl::OUString aEncodedMP
;
1367 return ( m_pStorageFile
->useStorage() && m_pStorageFile
->getEncodedMP( aEncodedMP
) && !aEncodedMP
.getLength() );
1371 //-------------------------------------------------------------------------
1372 void SAL_CALL
PasswordContainer::addUrl( const ::rtl::OUString
& Url
, ::sal_Bool MakePersistent
)
1373 throw (uno::RuntimeException
)
1375 mUrlContainer
.add( Url
, MakePersistent
);
1378 //-------------------------------------------------------------------------
1379 ::rtl::OUString SAL_CALL
PasswordContainer::findUrl( const ::rtl::OUString
& Url
)
1380 throw (uno::RuntimeException
)
1382 return mUrlContainer
.find( Url
);
1385 //-------------------------------------------------------------------------
1386 void SAL_CALL
PasswordContainer::removeUrl( const ::rtl::OUString
& Url
)
1387 throw (uno::RuntimeException
)
1389 mUrlContainer
.remove( Url
);
1392 //-------------------------------------------------------------------------
1393 uno::Sequence
< ::rtl::OUString
> SAL_CALL
PasswordContainer::getUrls( ::sal_Bool OnlyPersistent
)
1394 throw (uno::RuntimeException
)
1396 return mUrlContainer
.list( OnlyPersistent
);
1399 //-------------------------------------------------------------------------
1401 void PasswordContainer::Notify()
1403 ::osl::MutexGuard
aGuard( mMutex
);
1405 PassMap::iterator aIter
;
1407 // remove the cached persistent values in the memory
1408 for( aIter
= m_aContainer
.begin(); aIter
!= m_aContainer
.end(); aIter
++ )
1410 for( list
< NamePassRecord
>::iterator aNPIter
= aIter
->second
.begin(); aNPIter
!= aIter
->second
.end(); )
1412 if( aNPIter
->HasPasswords( PERSISTENT_RECORD
) )
1414 aNPIter
->RemovePasswords( PERSISTENT_RECORD
);
1416 if ( m_pStorageFile
)
1417 m_pStorageFile
->remove( aIter
->first
, aNPIter
->GetUserName() ); // remove record ( aURL, aName )
1420 if( !aNPIter
->HasPasswords( MEMORY_RECORD
) )
1422 list
< NamePassRecord
>::iterator
aIterToDelete( aNPIter
);
1424 aIter
->second
.erase( aIterToDelete
);
1432 if( m_pStorageFile
)
1433 addon
= m_pStorageFile
->getInfo();
1435 for( aIter
= addon
.begin(); aIter
!= addon
.end(); aIter
++ )
1437 PassMap::iterator aSearchIter
= m_aContainer
.find( aIter
->first
);
1438 if( aSearchIter
!= m_aContainer
.end() )
1439 for( list
< NamePassRecord
>::iterator aNPIter
= aIter
->second
.begin(); aNPIter
!= aIter
->second
.end(); aNPIter
++ )
1440 UpdateVector( aSearchIter
->first
, aSearchIter
->second
, *aNPIter
, sal_False
);
1442 m_aContainer
.insert( PairUrlRecord( aIter
->first
, aIter
->second
) );
1446 //-------------------------------------------------------------------------
1448 ::rtl::OUString SAL_CALL
PasswordContainer::getImplementationName( ) throw(uno::RuntimeException
)
1450 return impl_getStaticImplementationName();
1453 //-------------------------------------------------------------------------
1455 sal_Bool SAL_CALL
PasswordContainer::supportsService( const ::rtl::OUString
& ServiceName
) throw(uno::RuntimeException
)
1457 if ( ServiceName
.compareToAscii("com.sun.star.task.PasswordContainer") == 0 )
1463 //-------------------------------------------------------------------------
1465 Sequence
< ::rtl::OUString
> SAL_CALL
PasswordContainer::getSupportedServiceNames( ) throw(uno::RuntimeException
)
1467 return impl_getStaticSupportedServiceNames();
1470 //-------------------------------------------------------------------------
1472 Sequence
< ::rtl::OUString
> SAL_CALL
PasswordContainer::impl_getStaticSupportedServiceNames( ) throw(uno::RuntimeException
)
1474 Sequence
< ::rtl::OUString
> aRet(1);
1475 *aRet
.getArray() = ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer");
1479 //-------------------------------------------------------------------------
1481 ::rtl::OUString SAL_CALL
PasswordContainer::impl_getStaticImplementationName() throw(uno::RuntimeException
)
1483 return ::rtl::OUString::createFromAscii("stardiv.svtools.PasswordContainer");
1486 //-------------------------------------------------------------------------
1488 Reference
< XInterface
> SAL_CALL
PasswordContainer::impl_createInstance( const Reference
< XMultiServiceFactory
>& xServiceManager
) throw( RuntimeException
)
1490 return Reference
< XInterface
>( *new PasswordContainer( xServiceManager
) );
1493 //-------------------------------------------------------------------------
1495 Reference
< XSingleServiceFactory
> SAL_CALL
PasswordContainer::impl_createFactory( const Reference
< XMultiServiceFactory
>& ServiceManager
) throw(RuntimeException
)
1497 Reference
< XSingleServiceFactory
> xReturn( ::cppu::createOneInstanceFactory( ServiceManager
,
1498 PasswordContainer::impl_getStaticImplementationName(),
1499 PasswordContainer::impl_createInstance
,
1500 PasswordContainer::impl_getStaticSupportedServiceNames()));
1505 //-------------------------------------------------------------------------
1506 //-------------------------------------------------------------------------
1508 MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode
)
1510 MasterPasswordRequest aRequest
;
1512 aRequest
.Classification
= InteractionClassification_ERROR
;
1513 aRequest
.Mode
= Mode
;
1515 setRequest( makeAny( aRequest
) );
1517 // Fill continuations...
1518 Sequence
< RememberAuthentication
> aRememberModes( 1 );
1519 aRememberModes
[ 0 ] = RememberAuthentication_NO
;
1522 = new ::ucbhelper::InteractionSupplyAuthentication(
1524 sal_False
, // bCanSetRealm
1525 sal_False
, // bCanSetUserName
1526 sal_True
, // bCanSetPassword
1527 sal_False
, // bCanSetAccount
1528 aRememberModes
, // rRememberPasswordModes
1529 RememberAuthentication_NO
, // eDefaultRememberPasswordMode
1530 aRememberModes
, // rRememberAccountModes
1531 RememberAuthentication_NO
, // eDefaultRememberAccountMode
1532 sal_False
, // bCanUseSystemCredentials
1533 sal_False
// bDefaultUseSystemCredentials
1537 Reference
< XInteractionContinuation
> > aContinuations( 3 );
1538 aContinuations
[ 0 ] = new ::ucbhelper::InteractionAbort( this );
1539 aContinuations
[ 1 ] = new ::ucbhelper::InteractionRetry( this );
1540 aContinuations
[ 2 ] = m_xAuthSupplier
.get();
1542 setContinuations( aContinuations
);
1545 //-------------------------------------------------------------------------
1546 //-------------------------------------------------------------------------
1550 SAL_DLLPUBLIC_EXPORT
void SAL_CALL
component_getImplementationEnvironment (
1551 const sal_Char
** ppEnvTypeName
, uno_Environment
** /* ppEnv */)
1553 *ppEnvTypeName
= CPPU_CURRENT_LANGUAGE_BINDING_NAME
;
1556 SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL
component_writeInfo (
1557 void * /* pServiceManager */, void * pRegistryKey
)
1561 Reference
< XRegistryKey
> xRegistryKey (
1562 reinterpret_cast< XRegistryKey
* >( pRegistryKey
));
1563 Reference
< XRegistryKey
> xNewKey
;
1565 xNewKey
= xRegistryKey
->createKey(
1566 ::rtl::OUString::createFromAscii( "/stardiv.svtools.PasswordContainer/UNO/SERVICES" ));
1567 xNewKey
->createKey( ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer"));
1574 SAL_DLLPUBLIC_EXPORT
void * SAL_CALL
component_getFactory (
1575 const sal_Char
* pImplementationName
, void * pServiceManager
, void * /* pRegistryKey */)
1578 if (pServiceManager
)
1580 Reference
< XSingleServiceFactory
> xFactory
;
1581 if (PasswordContainer::impl_getStaticImplementationName().compareToAscii (pImplementationName
) == 0)
1583 xFactory
= PasswordContainer::impl_createFactory (
1584 reinterpret_cast< XMultiServiceFactory
* >(pServiceManager
));
1588 xFactory
->acquire();
1589 pResult
= xFactory
.get();