summaryrefslogtreecommitdiff
path: root/svl/source/passwordcontainer
diff options
context:
space:
mode:
authorMathias Bauer <mba@openoffice.org>2009-10-08 12:20:11 +0200
committerMathias Bauer <mba@openoffice.org>2009-10-08 12:20:11 +0200
commite6b4345c7f4026cb9b3e8dee6ecc84b3531e1950 (patch)
tree35a66a82b052424c4664f1c4bb77b6ef71f654ba /svl/source/passwordcontainer
parentb429c6949ce70e47538f90f5c67979b9d0ec0333 (diff)
#i103496#: split svtools in two libs, depending on whether the code needs vcl or not
Diffstat (limited to 'svl/source/passwordcontainer')
-rw-r--r--svl/source/passwordcontainer/exports.map8
-rw-r--r--svl/source/passwordcontainer/makefile.mk66
-rw-r--r--svl/source/passwordcontainer/passwordcontainer.cxx1595
-rw-r--r--svl/source/passwordcontainer/syscreds.cxx298
-rw-r--r--svl/source/passwordcontainer/syscreds.hxx95
5 files changed, 2062 insertions, 0 deletions
diff --git a/svl/source/passwordcontainer/exports.map b/svl/source/passwordcontainer/exports.map
new file mode 100644
index 000000000000..f4ed78b9e970
--- /dev/null
+++ b/svl/source/passwordcontainer/exports.map
@@ -0,0 +1,8 @@
+UDK_3_0_0 {
+ global:
+ component_getImplementationEnvironment;
+ component_writeInfo;
+ component_getFactory;
+ local:
+ *;
+};
diff --git a/svl/source/passwordcontainer/makefile.mk b/svl/source/passwordcontainer/makefile.mk
new file mode 100644
index 000000000000..31e1336ad966
--- /dev/null
+++ b/svl/source/passwordcontainer/makefile.mk
@@ -0,0 +1,66 @@
+#*************************************************************************
+#
+# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+#
+# Copyright 2008 by Sun Microsystems, Inc.
+#
+# OpenOffice.org - a multi-platform office productivity suite
+#
+# $RCSfile: makefile.mk,v $
+#
+# $Revision: 1.6 $
+#
+# This file is part of OpenOffice.org.
+#
+# OpenOffice.org is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Lesser General Public License version 3
+# only, as published by the Free Software Foundation.
+#
+# OpenOffice.org is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Lesser General Public License version 3 for more details
+# (a copy is included in the LICENSE file that accompanied this code).
+#
+# You should have received a copy of the GNU Lesser General Public License
+# version 3 along with OpenOffice.org. If not, see
+# <http://www.openoffice.org/license.html>
+# for a copy of the LGPLv3 License.
+#
+#*************************************************************************
+
+PRJ=..$/..
+PRJNAME=svtools
+TARGET=passwordcontainer.uno
+LIBTARGET=NO
+ENABLE_EXCEPTIONS=TRUE
+
+# --- Settings ----------------------------------
+
+.INCLUDE : settings.mk
+DLLPRE=
+
+# --- Files -------------------------------------
+
+SLOFILES= \
+ $(SLO)$/passwordcontainer.obj\
+ $(SLO)$/syscreds.obj
+
+SHL1TARGET= $(TARGET)
+SHL1IMPLIB= i$(TARGET)
+SHL1OBJS= $(SLOFILES)
+SHL1STDLIBS=\
+ $(UNOTOOLSLIB) \
+ $(UCBHELPERLIB) \
+ $(CPPUHELPERLIB) \
+ $(CPPULIB) \
+ $(SALLIB)
+
+SHL1VERSIONMAP=exports.map
+SHL1DEF= $(MISC)$/$(SHL1TARGET).def
+DEF1NAME= $(SHL1TARGET)
+
+# --- Targets ----------------------------------
+
+.INCLUDE : target.mk
+
diff --git a/svl/source/passwordcontainer/passwordcontainer.cxx b/svl/source/passwordcontainer/passwordcontainer.cxx
new file mode 100644
index 000000000000..5f9ce207ff6b
--- /dev/null
+++ b/svl/source/passwordcontainer/passwordcontainer.cxx
@@ -0,0 +1,1595 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: passwordcontainer.cxx,v $
+ * $Revision: 1.17 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svtools.hxx"
+
+#include "passwordcontainer.hxx"
+
+#include <unotools/pathoptions.hxx>
+#include "cppuhelper/factory.hxx"
+#include <com/sun/star/registry/XSimpleRegistry.hpp>
+#include <com/sun/star/beans/PropertyValue.hpp>
+#include <com/sun/star/task/MasterPasswordRequest.hpp>
+#include <com/sun/star/task/NoMasterException.hpp>
+
+#include <rtl/cipher.h>
+#include <rtl/digest.h>
+#include <rtl/byteseq.hxx>
+
+#ifndef _TOOLS_INETSTRM_HXX
+// @@@ #include <inetstrm.hxx>
+#endif
+
+using namespace std;
+using namespace osl;
+using namespace utl;
+using namespace com::sun::star;
+using namespace com::sun::star::uno;
+using namespace com::sun::star::registry;
+using namespace com::sun::star::lang;
+using namespace com::sun::star::task;
+using namespace com::sun::star::ucb;
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+
+static ::rtl::OUString createIndex( vector< ::rtl::OUString > lines )
+{
+ ::rtl::OString aResult;
+ const sal_Char* pLine;
+
+ for( unsigned int i = 0; i < lines.size(); i++ )
+ {
+ if( i )
+ aResult += ::rtl::OString( "__" );
+ ::rtl::OString line = ::rtl::OUStringToOString( lines[i], RTL_TEXTENCODING_UTF8 );
+ pLine = line.getStr();
+
+ while( *pLine )
+ {
+ if( ( *pLine >= 'A' && *pLine <= 'Z' )
+ || ( *pLine >= 'a' && *pLine <= 'z' )
+ || ( *pLine >= '0' && *pLine <= '9' ) )
+ {
+ aResult += ::rtl::OString::valueOf( *pLine );
+ }
+ else
+ {
+ aResult += ::rtl::OString("_");
+ aResult += ::rtl::OString::valueOf( (sal_Int32) *pLine, 16 );
+ }
+
+ pLine++;
+ }
+ }
+
+ return ::rtl::OUString::createFromAscii( aResult.getStr() );
+}
+
+//-------------------------------------------------------------------------
+
+static vector< ::rtl::OUString > getInfoFromInd( ::rtl::OUString aInd )
+{
+ vector< ::rtl::OUString > aResult;
+ sal_Bool aStart = sal_True;
+
+ ::rtl::OString line = ::rtl::OUStringToOString( aInd, RTL_TEXTENCODING_ASCII_US );
+ const sal_Char* pLine = line.getStr();
+ do
+ {
+ ::rtl::OUString newItem;
+ if( !aStart )
+ pLine += 2;
+ else
+ aStart = sal_False;
+
+ while( *pLine && !( pLine[0] == '_' && pLine[1] == '_' ))
+ if( *pLine != '_' )
+ {
+ newItem += ::rtl::OUString::valueOf( (sal_Unicode) *pLine );
+ pLine++;
+ }
+ else
+ {
+ ::rtl::OUString aNum;
+ for( int i = 1; i < 3; i++ )
+ {
+ if( !pLine[i]
+ || ( ( pLine[i] < '0' || pLine[i] > '9' )
+ && ( pLine[i] < 'a' || pLine[i] > 'f' )
+ && ( pLine[i] < 'A' || pLine[i] > 'F' ) ) )
+ {
+ OSL_ENSURE( sal_False, "Wrong index syntax!\n" );
+ return aResult;
+ }
+
+ aNum += ::rtl::OUString::valueOf( (sal_Unicode) pLine[i] );
+ }
+
+ newItem += ::rtl::OUString::valueOf( (sal_Unicode) aNum.toInt32( 16 ) );
+ pLine += 3;
+ }
+
+ aResult.push_back( newItem );
+ } while( pLine[0] == '_' && pLine[1] == '_' );
+
+ if( *pLine )
+ OSL_ENSURE( sal_False, "Wrong index syntax!\n" );
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+
+static sal_Bool shorterUrl( ::rtl::OUString& aURL )
+{
+ sal_Int32 aInd = aURL.lastIndexOf( sal_Unicode( '/' ) );
+
+ if( aInd > 0 )
+ {
+ sal_Int32 aPrevInd = aURL.lastIndexOf( sal_Unicode( '/' ), aInd );
+ if ( aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) )
+ != aPrevInd - 2 ||
+ aInd != aURL.getLength() - 1 )
+ {
+ aURL = aURL.copy( 0, aInd );
+ return sal_True;
+ }
+ }
+
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+
+static ::rtl::OUString getAsciiLine( const ::rtl::ByteSequence& buf )
+{
+ ::rtl::OUString aResult;
+
+ ::rtl::ByteSequence outbuf( buf.getLength()*2+1 );
+
+ for( int ind = 0; ind < buf.getLength(); ind++ )
+ {
+ outbuf[ind*2] = ( ((sal_uInt8)buf[ind]) >> 4 ) + 'a';
+ outbuf[ind*2+1] = ( ((sal_uInt8)buf[ind]) & 0x0f ) + 'a';
+ }
+ outbuf[buf.getLength()*2] = '\0';
+
+ aResult = ::rtl::OUString::createFromAscii( (sal_Char*)outbuf.getArray() );
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+
+static ::rtl::ByteSequence getBufFromAsciiLine( ::rtl::OUString line )
+{
+ OSL_ENSURE( line.getLength() % 2 == 0, "Wrong syntax!\n" );
+ ::rtl::OString tmpLine = ::rtl::OUStringToOString( line, RTL_TEXTENCODING_ASCII_US );
+ ::rtl::ByteSequence aResult(line.getLength()/2);
+
+ for( int ind = 0; ind < tmpLine.getLength()/2; ind++ )
+ {
+ aResult[ind] = ( (sal_uInt8)( tmpLine.getStr()[ind*2] - 'a' ) << 4 ) | (sal_uInt8)( tmpLine.getStr()[ind*2+1] - 'a' );
+ }
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+
+static Sequence< ::rtl::OUString > copyVectorToSequence( const vector< ::rtl::OUString >& original )
+{
+ Sequence< ::rtl::OUString > newOne ( original.size() );
+ for( unsigned int i = 0; i < original.size() ; i++ )
+ newOne[i] = original[i];
+
+ return newOne;
+}
+
+static vector< ::rtl::OUString > copySequenceToVector( const Sequence< ::rtl::OUString >& original )
+{
+ vector< ::rtl::OUString > newOne ( original.getLength() );
+ for( int i = 0; i < original.getLength() ; i++ )
+ newOne[i] = original[i];
+
+ return newOne;
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+
+PassMap StorageItem::getInfo()
+{
+ PassMap aResult;
+
+ Sequence< ::rtl::OUString > aNodeNames = ConfigItem::GetNodeNames( ::rtl::OUString::createFromAscii("Store") );
+ sal_Int32 aNodeCount = aNodeNames.getLength();
+ Sequence< ::rtl::OUString > aPropNames( aNodeCount );
+ sal_Int32 aNodeInd;
+
+ for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
+ {
+ aPropNames[aNodeInd] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
+ aPropNames[aNodeInd] += aNodeNames[aNodeInd];
+ aPropNames[aNodeInd] += ::rtl::OUString::createFromAscii( "']/Password" );
+ }
+
+ Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aPropNames );
+
+ if( aPropertyValues.getLength() != aNodeNames.getLength() )
+ {
+ OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
+ return aResult;
+ }
+
+ for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
+ {
+ vector< ::rtl::OUString > aUrlUsr = getInfoFromInd( aNodeNames[aNodeInd] );
+
+ if( aUrlUsr.size() == 2 )
+ {
+ ::rtl::OUString aUrl = aUrlUsr[0];
+ ::rtl::OUString aName = aUrlUsr[1];
+
+ ::rtl::OUString aEPasswd;
+ aPropertyValues[aNodeInd] >>= aEPasswd;
+
+ PassMap::iterator aIter = aResult.find( aUrl );
+ if( aIter != aResult.end() )
+ aIter->second.push_back( NamePassRecord( aName, aEPasswd ) );
+ else
+ {
+ NamePassRecord aNewRecord( aName, aEPasswd );
+ list< NamePassRecord > listToAdd( 1, aNewRecord );
+
+ aResult.insert( PairUrlRecord( aUrl, listToAdd ) );
+ }
+ }
+ else
+ OSL_ENSURE( sal_False, "Wrong index sintax!\n" );
+ }
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+
+void StorageItem::setUseStorage( sal_Bool bUse )
+{
+ Sequence< ::rtl::OUString > sendNames(1);
+ Sequence< uno::Any > sendVals(1);
+
+ sendNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" );
+
+ sendVals[0] <<= bUse;
+
+ ConfigItem::SetModified();
+ ConfigItem::PutProperties( sendNames, sendVals );
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool StorageItem::useStorage()
+{
+ Sequence< ::rtl::OUString > aNodeNames( 1 );
+ aNodeNames[0] = ::rtl::OUString::createFromAscii( "UseStorage" );
+
+ Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
+
+ if( aPropertyValues.getLength() != aNodeNames.getLength() )
+ {
+ OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
+ return sal_False;
+ }
+
+ sal_Bool aResult = false;
+ aPropertyValues[0] >>= aResult;
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool StorageItem::getEncodedMP( ::rtl::OUString& aResult )
+{
+ if( hasEncoded )
+ {
+ aResult = mEncoded;
+ return sal_True;
+ }
+
+ Sequence< ::rtl::OUString > aNodeNames( 2 );
+ aNodeNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" );
+ aNodeNames[1] = ::rtl::OUString::createFromAscii( "Master" );
+
+ Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
+
+ if( aPropertyValues.getLength() != aNodeNames.getLength() )
+ {
+ OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
+ return sal_False;
+ }
+
+ aPropertyValues[0] >>= hasEncoded;
+ aPropertyValues[1] >>= mEncoded;
+
+ aResult = mEncoded;
+
+ return hasEncoded;
+}
+
+//-------------------------------------------------------------------------
+
+void StorageItem::setEncodedMP( const ::rtl::OUString& aEncoded, sal_Bool bAcceptEmpty )
+{
+ Sequence< ::rtl::OUString > sendNames(2);
+ Sequence< uno::Any > sendVals(2);
+
+ sendNames[0] = ::rtl::OUString::createFromAscii( "HasMaster" );
+ sendNames[1] = ::rtl::OUString::createFromAscii( "Master" );
+
+ sal_Bool bHasMaster = ( aEncoded.getLength() > 0 || bAcceptEmpty );
+ sendVals[0] <<= bHasMaster;
+ sendVals[1] <<= aEncoded;
+
+ ConfigItem::SetModified();
+ ConfigItem::PutProperties( sendNames, sendVals );
+
+ hasEncoded = bHasMaster;
+ mEncoded = aEncoded;
+}
+
+//-------------------------------------------------------------------------
+
+void StorageItem::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName )
+{
+ vector < ::rtl::OUString > forIndex;
+ forIndex.push_back( aURL );
+ forIndex.push_back( aName );
+
+ Sequence< ::rtl::OUString > sendSeq(1);
+
+ sendSeq[0] = createIndex( forIndex );
+ // sendSeq[0] = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
+ // sendSeq[0] += createIndex( forIndex );
+ // sendSeq[0] += ::rtl::OUString::createFromAscii( "']" );
+
+ ConfigItem::ClearNodeElements( ::rtl::OUString::createFromAscii( "Store" ), sendSeq );
+}
+
+//-------------------------------------------------------------------------
+
+void StorageItem::clear()
+{
+ Sequence< ::rtl::OUString > sendSeq(1);
+
+ ConfigItem::ClearNodeSet( ::rtl::OUString::createFromAscii( "Store" ) );
+}
+
+//-------------------------------------------------------------------------
+
+void StorageItem::update( const ::rtl::OUString& aURL, const NamePassRecord& aRecord )
+{
+ if ( !aRecord.HasPasswords( PERSISTENT_RECORD ) )
+ {
+ OSL_ASSERT( "Unexpected storing of a record!" );
+ return;
+ }
+
+ vector < ::rtl::OUString > forIndex;
+ forIndex.push_back( aURL );
+ forIndex.push_back( aRecord.GetUserName() );
+
+ Sequence< beans::PropertyValue > sendSeq(1);
+
+ sendSeq[0].Name = ::rtl::OUString::createFromAscii( "Store/Passwordstorage['" );
+ sendSeq[0].Name += createIndex( forIndex );
+ sendSeq[0].Name += ::rtl::OUString::createFromAscii( "']/Password" );
+
+ sendSeq[0].Value <<= aRecord.GetPersPasswords();
+
+ ConfigItem::SetModified();
+ ConfigItem::SetSetProperties( ::rtl::OUString::createFromAscii( "Store" ), sendSeq );
+}
+
+//-------------------------------------------------------------------------
+
+void StorageItem::Notify( const Sequence< ::rtl::OUString >& )
+{
+ // this feature still should not be used
+ if( mainCont )
+ mainCont->Notify();
+}
+
+//-------------------------------------------------------------------------
+
+void StorageItem::Commit()
+{
+ // Do nothing, we stored everything we want already
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+
+PasswordContainer::PasswordContainer( const Reference<XMultiServiceFactory>& xServiceFactory ):
+ m_pStorageFile( NULL )
+{
+ // m_pStorageFile->Notify() can be called
+ ::osl::MutexGuard aGuard( mMutex );
+
+ mComponent = Reference< XComponent >( xServiceFactory, UNO_QUERY );
+ mComponent->addEventListener( this );
+
+ m_pStorageFile = new StorageItem( this, ::rtl::OUString::createFromAscii( "Office.Common/Passwords" ) );
+ if( m_pStorageFile )
+ if( m_pStorageFile->useStorage() )
+ m_aContainer = m_pStorageFile->getInfo();
+}
+
+//-------------------------------------------------------------------------
+
+PasswordContainer::~PasswordContainer()
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if( m_pStorageFile )
+ {
+ delete m_pStorageFile;
+ m_pStorageFile = NULL;
+ }
+
+ if( mComponent.is() )
+ {
+ mComponent->removeEventListener(this);
+ mComponent = Reference< XComponent >();
+ }
+}
+
+//-------------------------------------------------------------------------
+
+void SAL_CALL PasswordContainer::disposing( const EventObject& ) throw(RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if( m_pStorageFile )
+ {
+ delete m_pStorageFile;
+ m_pStorageFile = NULL;
+ }
+
+ if( mComponent.is() )
+ {
+ //mComponent->removeEventListener(this);
+ mComponent = Reference< XComponent >();
+ }
+}
+
+//-------------------------------------------------------------------------
+
+vector< ::rtl::OUString > PasswordContainer::DecodePasswords( const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException)
+{
+ if( aMasterPasswd.getLength() )
+ {
+ rtlCipher aDecoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
+ OSL_ENSURE( aDecoder, "Can't create decoder\n" );
+
+ if( aDecoder )
+ {
+ OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" );
+
+ unsigned char code[RTL_DIGEST_LENGTH_MD5];
+ for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
+ code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16));
+
+ rtlCipherError result = rtl_cipher_init (
+ aDecoder, rtl_Cipher_DirectionDecode,
+ code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
+
+ if( result == rtl_Cipher_E_None )
+ {
+ ::rtl::ByteSequence aSeq = getBufFromAsciiLine( aLine );
+
+ ::rtl::ByteSequence resSeq( aSeq.getLength() );
+
+ result = rtl_cipher_decode ( aDecoder, (sal_uInt8*)aSeq.getArray(), aSeq.getLength(),
+ (sal_uInt8*)resSeq.getArray(), resSeq.getLength() );
+
+ ::rtl::OUString aPasswd( ( sal_Char* )resSeq.getArray(), resSeq.getLength(), RTL_TEXTENCODING_UTF8 );
+
+ rtl_cipher_destroy (aDecoder);
+
+ return getInfoFromInd( aPasswd );
+ }
+
+ rtl_cipher_destroy (aDecoder);
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "No master password provided!\n" );
+ // throw special exception
+ }
+
+ // problems with decoding
+ OSL_ENSURE( sal_False, "Problem with decoding\n" );
+ throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't decode!" ), Reference< XInterface >() );
+}
+
+
+//-------------------------------------------------------------------------
+
+::rtl::OUString PasswordContainer::EncodePasswords( vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPasswd ) throw(RuntimeException)
+{
+ if( aMasterPasswd.getLength() )
+ {
+ ::rtl::OString aSeq = ::rtl::OUStringToOString( createIndex( lines ), RTL_TEXTENCODING_UTF8 );
+
+ rtlCipher aEncoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
+ OSL_ENSURE( aEncoder, "Can't create encoder\n" );
+
+ if( aEncoder )
+ {
+ OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" );
+
+ unsigned char code[RTL_DIGEST_LENGTH_MD5];
+ for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
+ code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toInt32(16));
+
+ rtlCipherError result = rtl_cipher_init (
+ aEncoder, rtl_Cipher_DirectionEncode,
+ code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
+
+ if( result == rtl_Cipher_E_None )
+ {
+ ::rtl::ByteSequence resSeq(aSeq.getLength()+1);
+
+ result = rtl_cipher_encode ( aEncoder, (sal_uInt8*)aSeq.getStr(), aSeq.getLength()+1,
+ (sal_uInt8*)resSeq.getArray(), resSeq.getLength() );
+
+/*
+ //test
+ rtlCipherError result = rtl_cipher_init (
+ aEncoder, rtl_Cipher_DirectionDecode,
+ code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
+
+
+ if( result == rtl_Cipher_E_None )
+ {
+ ::rtl::OUString testOU = getAsciiLine( resSeq );
+ ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU );
+
+ ::rtl::ByteSequence resSeq1( aSeq1.getLength() );
+
+ if( resSeq.getLength() == aSeq1.getLength() )
+ {
+ for( int ind = 0; ind < aSeq1.getLength(); ind++ )
+ if( resSeq[ind] != aSeq1[ind] )
+ testOU = ::rtl::OUString();
+ }
+
+ result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(),
+ (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() );
+
+ ::rtl::OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 );
+ }
+*/
+
+ rtl_cipher_destroy (aEncoder);
+
+ if( result == rtl_Cipher_E_None )
+ return getAsciiLine( resSeq );
+
+ }
+
+ rtl_cipher_destroy (aEncoder);
+ }
+ }
+ else
+ {
+ OSL_ENSURE( sal_False, "No master password provided!\n" );
+ // throw special exception
+ }
+
+ // problems with encoding
+ OSL_ENSURE( sal_False, "Problem with encoding\n" );
+ throw RuntimeException( ::rtl::OUString::createFromAscii( "Can't encode!" ), Reference< XInterface >() );
+}
+
+//-------------------------------------------------------------------------
+
+void PasswordContainer::UpdateVector( const ::rtl::OUString& aURL, list< NamePassRecord >& toUpdate, NamePassRecord& aRecord, sal_Bool writeFile ) throw(RuntimeException)
+{
+ for( list< NamePassRecord >::iterator aNPIter = toUpdate.begin(); aNPIter != toUpdate.end(); aNPIter++ )
+ if( aNPIter->GetUserName().equals( aRecord.GetUserName() ) )
+ {
+ if( aRecord.HasPasswords( MEMORY_RECORD ) )
+ aNPIter->SetMemPasswords( aRecord.GetMemPasswords() );
+
+ if( aRecord.HasPasswords( PERSISTENT_RECORD ) )
+ {
+ aNPIter->SetPersPasswords( aRecord.GetPersPasswords() );
+
+ if( writeFile )
+ {
+ // the password must be already encoded
+ m_pStorageFile->update( aURL, aRecord ); // change existing ( aURL, aName ) record in the configfile
+ }
+ }
+
+ return;
+ }
+
+
+ if( aRecord.HasPasswords( PERSISTENT_RECORD ) && writeFile )
+ {
+ // the password must be already encoded
+ m_pStorageFile->update( aURL, aRecord ); // add new aName to the existing url
+ }
+
+ toUpdate.insert( toUpdate.begin(), aRecord );
+}
+
+//-------------------------------------------------------------------------
+
+UserRecord PasswordContainer::CopyToUserRecord( const NamePassRecord& aRecord, sal_Bool& io_bTryToDecode, const Reference< XInteractionHandler >& aHandler )
+{
+ ::std::vector< ::rtl::OUString > aPasswords;
+ if( aRecord.HasPasswords( MEMORY_RECORD ) )
+ aPasswords = aRecord.GetMemPasswords();
+
+ if( io_bTryToDecode && aRecord.HasPasswords( PERSISTENT_RECORD ) )
+ {
+ try
+ {
+ ::std::vector< ::rtl::OUString > aDecodedPasswords = DecodePasswords( aRecord.GetPersPasswords(), GetMasterPassword( aHandler ) );
+ aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), aDecodedPasswords.end() );
+ }
+ catch( NoMasterException& )
+ {
+ // if master password could not be detected the entry will be just ignored
+ io_bTryToDecode = sal_False;
+ }
+ }
+
+ return UserRecord( aRecord.GetUserName(), copyVectorToSequence( aPasswords ) );
+}
+
+//-------------------------------------------------------------------------
+
+Sequence< UserRecord > PasswordContainer::CopyToUserRecordSequence( const list< NamePassRecord >& original, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ Sequence< UserRecord > aResult( original.size() );
+ sal_uInt32 nInd = 0;
+ sal_Bool bTryToDecode = sal_True;
+
+ for( list< NamePassRecord >::const_iterator aNPIter = original.begin();
+ aNPIter != original.end();
+ aNPIter++, nInd++ )
+ {
+ aResult[nInd] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler );
+ }
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+
+void SAL_CALL PasswordContainer::add( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ PrivateAdd( Url, UserName, Passwords, MEMORY_RECORD, aHandler );
+}
+
+//-------------------------------------------------------------------------
+
+void SAL_CALL PasswordContainer::addPersistent( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler );
+}
+
+//-------------------------------------------------------------------------
+
+void PasswordContainer::PrivateAdd( const ::rtl::OUString& Url, const ::rtl::OUString& UserName, const Sequence< ::rtl::OUString >& Passwords, char Mode, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ NamePassRecord aRecord( UserName );
+ ::std::vector< ::rtl::OUString > aStorePass = copySequenceToVector( Passwords );
+
+ if( Mode == PERSISTENT_RECORD )
+ aRecord.SetPersPasswords( EncodePasswords( aStorePass, GetMasterPassword( aHandler ) ) );
+ else if( Mode == MEMORY_RECORD )
+ aRecord.SetMemPasswords( aStorePass );
+ else
+ {
+ OSL_ASSERT( "Unexpected persistence status!" );
+ return;
+ }
+
+ if( !m_aContainer.empty() )
+ {
+ PassMap::iterator aIter = m_aContainer.find( Url );
+
+ if( aIter != m_aContainer.end() )
+ {
+ UpdateVector( aIter->first, aIter->second, aRecord, sal_True );
+ return;
+ }
+ }
+
+ list< NamePassRecord > listToAdd( 1, aRecord );
+ m_aContainer.insert( PairUrlRecord( Url, listToAdd ) );
+
+ if( Mode == PERSISTENT_RECORD && m_pStorageFile && m_pStorageFile->useStorage() )
+ m_pStorageFile->update( Url, aRecord );
+
+}
+
+//-------------------------------------------------------------------------
+
+
+UrlRecord SAL_CALL PasswordContainer::find( const ::rtl::OUString& aURL, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ return find( aURL, rtl::OUString(), false, aHandler );
+}
+
+//-------------------------------------------------------------------------
+
+UrlRecord SAL_CALL PasswordContainer::findForName( const ::rtl::OUString& aURL, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ return find( aURL, aName, true, aHandler );
+}
+
+//-------------------------------------------------------------------------
+
+Sequence< UserRecord > PasswordContainer::FindUsr( const list< NamePassRecord >& userlist, const ::rtl::OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ sal_uInt32 nInd = 0;
+ for( list< NamePassRecord >::const_iterator aNPIter = userlist.begin();
+ aNPIter != userlist.end();
+ aNPIter++, nInd++ )
+ {
+ if( aNPIter->GetUserName().equals( aName ) )
+ {
+ Sequence< UserRecord > aResult(1);
+ sal_Bool bTryToDecode = sal_True;
+ aResult[0] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler );
+
+ return aResult;
+ }
+ }
+
+ return Sequence< UserRecord >();
+}
+
+//-------------------------------------------------------------------------
+
+bool PasswordContainer::createUrlRecord(
+ const PassMap::iterator & rIter,
+ bool bName,
+ const ::rtl::OUString & aName,
+ const Reference< XInteractionHandler >& aHandler,
+ UrlRecord & rRec )
+ throw( RuntimeException )
+{
+ if ( bName )
+ {
+ Sequence< UserRecord > aUsrRec
+ = FindUsr( rIter->second, aName, aHandler );
+ if( aUsrRec.getLength() )
+ {
+ rRec = UrlRecord( rIter->first, aUsrRec );
+ return true;
+ }
+ }
+ else
+ {
+ rRec = UrlRecord(
+ rIter->first,
+ CopyToUserRecordSequence( rIter->second, aHandler ) );
+ return true;
+ }
+ return false;
+}
+
+//-------------------------------------------------------------------------
+
+UrlRecord PasswordContainer::find(
+ const ::rtl::OUString& aURL,
+ const ::rtl::OUString& aName,
+ bool bName, // only needed to support empty user names
+ const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if( !m_aContainer.empty() && aURL.getLength() )
+ {
+ ::rtl::OUString aUrl( aURL );
+
+ // each iteration remove last '/...' section from the aUrl
+ // while it's possible, up to the most left '://'
+ do
+ {
+ // first look for <url>/somename and then look for <url>/somename/...
+ PassMap::iterator aIter = m_aContainer.find( aUrl );
+ if( aIter != m_aContainer.end() )
+ {
+ UrlRecord aRec;
+ if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) )
+ return aRec;
+ }
+ else
+ {
+ ::rtl::OUString tmpUrl( aUrl );
+ if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' )
+ tmpUrl += ::rtl::OUString::createFromAscii( "/" );
+
+ aIter = m_aContainer.lower_bound( tmpUrl );
+ if( aIter != m_aContainer.end() && aIter->first.match( tmpUrl ) )
+ {
+ UrlRecord aRec;
+ if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) )
+ return aRec;
+ }
+ }
+ }
+ while( shorterUrl( aUrl ) && aUrl.getLength() );
+ }
+
+ return UrlRecord();
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString PasswordContainer::GetDefaultMasterPassword()
+{
+ ::rtl::OUString aResult;
+ for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ )
+ aResult += ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "aa" ) );
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler )
+{
+ // empty string means that the call was cancelled or just failed
+ ::rtl::OUString aResult;
+
+ if ( xHandler.is() )
+ {
+ ::rtl::Reference< MasterPasswordRequest_Impl > xRequest = new MasterPasswordRequest_Impl( aRMode );
+
+ xHandler->handle( xRequest.get() );
+
+ ::rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection();
+
+ if ( xSelection.is() )
+ {
+ Reference< XInteractionAbort > xAbort( xSelection.get(), UNO_QUERY );
+ if ( !xAbort.is() )
+ {
+ const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp
+ = xRequest->getAuthenticationSupplier();
+
+ aResult = xSupp->getPassword();
+ }
+ }
+ }
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+
+::rtl::OUString PasswordContainer::GetMasterPassword( const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
+{
+ PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER;
+ if( !m_pStorageFile || !m_pStorageFile->useStorage() )
+ throw NoMasterException( ::rtl::OUString::createFromAscii( "Password storing is not active!" ), Reference< XInterface >(), aRMode );
+
+ if( !m_aMasterPasswd.getLength() && aHandler.is() )
+ {
+ ::rtl::OUString aEncodedMP;
+ sal_Bool bAskAgain = sal_False;
+ sal_Bool bDefaultPassword = sal_False;
+
+ if( !m_pStorageFile->getEncodedMP( aEncodedMP ) )
+ aRMode = PasswordRequestMode_PASSWORD_CREATE;
+ else if ( !aEncodedMP.getLength() )
+ {
+ m_aMasterPasswd = GetDefaultMasterPassword();
+ bDefaultPassword = sal_True;
+ }
+
+ if ( !bDefaultPassword )
+ {
+ do {
+ bAskAgain = sal_False;
+
+ ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, aHandler );
+ if ( aPass.getLength() )
+ {
+ if( aRMode == PasswordRequestMode_PASSWORD_CREATE )
+ {
+ m_aMasterPasswd = aPass;
+ vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd );
+
+ m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) );
+ }
+ else
+ {
+ vector< ::rtl::OUString > aRM( DecodePasswords( aEncodedMP, aPass ) );
+ if( !aRM.size() || !aPass.equals( aRM[0] ) )
+ {
+ bAskAgain = sal_True;
+ aRMode = PasswordRequestMode_PASSWORD_REENTER;
+ }
+ else
+ m_aMasterPasswd = aPass;
+ }
+ }
+
+ } while( bAskAgain );
+ }
+ }
+
+ if ( !m_aMasterPasswd.getLength() )
+ throw NoMasterException( ::rtl::OUString::createFromAscii( "No master password!" ), Reference< XInterface >(), aRMode );
+
+ return m_aMasterPasswd;
+}
+
+//-------------------------------------------------------------------------
+
+void SAL_CALL PasswordContainer::remove( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ ::rtl::OUString aUrl( aURL );
+ if( !m_aContainer.empty() )
+ {
+ PassMap::iterator aIter = m_aContainer.find( aUrl );
+
+ if( aIter == m_aContainer.end() )
+ {
+ sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) );
+ if( aInd > 0 && aUrl.getLength()-1 == aInd )
+ aUrl = aUrl.copy( 0, aUrl.getLength() - 1 );
+ else
+ aUrl += ::rtl::OUString::createFromAscii( "/" );
+
+ aIter = m_aContainer.find( aUrl );
+ }
+
+ if( aIter != m_aContainer.end() )
+ {
+ for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
+ if( aNPIter->GetUserName().equals( aName ) )
+ {
+ if( aNPIter->HasPasswords( PERSISTENT_RECORD ) && m_pStorageFile )
+ m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName )
+
+ // the iterator will not be used any more so it can be removed directly
+ aIter->second.erase( aNPIter );
+
+ if( aIter->second.begin() == aIter->second.end() )
+ m_aContainer.erase( aIter );
+
+ return;
+ }
+ }
+ }
+}
+
+//-------------------------------------------------------------------------
+
+void SAL_CALL PasswordContainer::removePersistent( const ::rtl::OUString& aURL, const ::rtl::OUString& aName ) throw(RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ ::rtl::OUString aUrl( aURL );
+ if( !m_aContainer.empty() )
+ {
+ PassMap::iterator aIter = m_aContainer.find( aUrl );
+
+ if( aIter == m_aContainer.end() )
+ {
+ sal_Int32 aInd = aUrl.lastIndexOf( sal_Unicode( '/' ) );
+ if( aInd > 0 && aUrl.getLength()-1 == aInd )
+ aUrl = aUrl.copy( 0, aUrl.getLength() - 1 );
+ else
+ aUrl += ::rtl::OUString::createFromAscii( "/" );
+
+ aIter = m_aContainer.find( aUrl );
+ }
+
+ if( aIter != m_aContainer.end() )
+ {
+ for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
+ if( aNPIter->GetUserName().equals( aName ) )
+ {
+ if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
+ {
+ // TODO/LATER: should the password be converted to MemoryPassword?
+ aNPIter->RemovePasswords( PERSISTENT_RECORD );
+
+ if ( m_pStorageFile )
+ m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName )
+ }
+
+ if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
+ aIter->second.erase( aNPIter );
+
+ if( aIter->second.begin() == aIter->second.end() )
+ m_aContainer.erase( aIter );
+
+ return;
+ }
+ }
+ }
+}
+//-------------------------------------------------------------------------
+
+void SAL_CALL PasswordContainer::removeAllPersistent() throw(RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if( m_pStorageFile )
+ m_pStorageFile->clear();
+
+ for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); )
+ {
+ for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); )
+ {
+ if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
+ {
+ // TODO/LATER: should the password be converted to MemoryPassword?
+ aNPIter->RemovePasswords( PERSISTENT_RECORD );
+
+ if ( m_pStorageFile )
+ m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName )
+ }
+
+ if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
+ {
+ list< NamePassRecord >::iterator aIterToDelete( aNPIter );
+ aNPIter++;
+ aIter->second.erase( aIterToDelete );
+ }
+ else
+ aNPIter++;
+ }
+
+ if( aIter->second.begin() == aIter->second.end() )
+ {
+ PassMap::iterator aIterToDelete( aIter );
+ aIter++;
+ m_aContainer.erase( aIterToDelete );
+ }
+ else
+ aIter++;
+ }
+}
+//-------------------------------------------------------------------------
+
+Sequence< UrlRecord > SAL_CALL PasswordContainer::getAllPersistent( const Reference< XInteractionHandler >& xHandler ) throw(RuntimeException)
+{
+ Sequence< UrlRecord > aResult;
+
+ ::osl::MutexGuard aGuard( mMutex );
+ for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ )
+ {
+ Sequence< UserRecord > aUsers;
+ for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
+ if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
+ {
+ sal_Int32 oldLen = aUsers.getLength();
+ aUsers.realloc( oldLen + 1 );
+ aUsers[ oldLen ] = UserRecord( aNPIter->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter->GetPersPasswords(), GetMasterPassword( xHandler ) ) ) );
+ }
+
+ if( aUsers.getLength() )
+ {
+ sal_Int32 oldLen = aResult.getLength();
+ aResult.realloc( oldLen + 1 );
+ aResult[ oldLen ] = UrlRecord( aIter->first, aUsers );
+ }
+ }
+
+ return aResult;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
+ throw (uno::RuntimeException)
+{
+ sal_Bool bResult = sal_False;
+ ::rtl::OUString aEncodedMP;
+ uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
+ ::osl::MutexGuard aGuard( mMutex );
+
+ // the method should fail if there is no master password
+ if( m_pStorageFile && m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) )
+ {
+ if ( !aEncodedMP.getLength() )
+ {
+ // this is a default master password
+ // no UI is necessary
+ bResult = sal_True;
+ }
+ else
+ {
+ if ( !xTmpHandler.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
+ xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
+ }
+
+ if ( m_aMasterPasswd.getLength() )
+ {
+ // there is a password, it should be just rechecked
+ PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER;
+ ::rtl::OUString aPass;
+
+ do {
+ aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
+ bResult = ( aPass.getLength() && aPass.equals( m_aMasterPasswd ) );
+ aRMode = PasswordRequestMode_PASSWORD_REENTER; // further questions with error notification
+ } while( !bResult && aPass.getLength() );
+ }
+ else
+ {
+ try
+ {
+ // ask for the password, if user provide no correct password an exception will be thrown
+ bResult = ( GetMasterPassword( xTmpHandler ).getLength() > 0 );
+ }
+ catch( uno::Exception& )
+ {}
+ }
+ }
+ }
+
+ return bResult;
+}
+
+//-------------------------------------------------------------------------
+sal_Bool SAL_CALL PasswordContainer::changeMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
+ throw (uno::RuntimeException)
+{
+ sal_Bool bResult = sal_False;
+ uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if ( m_pStorageFile && m_pStorageFile->useStorage() )
+ {
+ if ( !xTmpHandler.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
+ xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
+ }
+
+ sal_Bool bCanChangePassword = sal_True;
+ // if there is already a stored master password it should be entered by the user before the change happen
+ ::rtl::OUString aEncodedMP;
+ if( m_aMasterPasswd.getLength() || m_pStorageFile->getEncodedMP( aEncodedMP ) )
+ bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
+
+ if ( bCanChangePassword )
+ {
+ // ask for the new password, but do not set it
+ PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_CREATE;
+ ::rtl::OUString aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
+
+ if ( aPass.getLength() )
+ {
+ // get all the persistent entries if it is possible
+ Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() );
+
+ // remove the master password and the entries persistence
+ removeMasterPassword();
+
+ // store the new master password
+ m_aMasterPasswd = aPass;
+ vector< ::rtl::OUString > aMaster( 1, m_aMasterPasswd );
+ m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) );
+
+ // store all the entries with the new password
+ for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ )
+ for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ )
+ addPersistent( aPersistent[nURLInd].Url,
+ aPersistent[nURLInd].UserList[nNameInd].UserName,
+ aPersistent[nURLInd].UserList[nNameInd].Passwords,
+ uno::Reference< task::XInteractionHandler >() );
+
+ bResult = sal_True;
+ }
+ }
+ }
+
+ return bResult;
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL PasswordContainer::removeMasterPassword()
+ throw (uno::RuntimeException)
+{
+ // remove all the stored passwords and the master password
+ removeAllPersistent();
+
+ ::osl::MutexGuard aGuard( mMutex );
+ if ( m_pStorageFile )
+ {
+ m_aMasterPasswd = ::rtl::OUString();
+ m_pStorageFile->setEncodedMP( ::rtl::OUString() ); // let the master password be removed from configuration
+ }
+}
+
+//-------------------------------------------------------------------------
+::sal_Bool SAL_CALL PasswordContainer::hasMasterPassword( )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if ( !m_pStorageFile )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aEncodedMP;
+ return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) );
+}
+
+//-------------------------------------------------------------------------
+::sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( ::sal_Bool bAllow )
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if ( !m_pStorageFile )
+ throw uno::RuntimeException();
+
+ if ( !bAllow )
+ removeMasterPassword();
+
+ if ( m_pStorageFile->useStorage() == bAllow )
+ return bAllow;
+
+ m_pStorageFile->setUseStorage( bAllow );
+ return !bAllow;
+}
+
+//-------------------------------------------------------------------------
+::sal_Bool SAL_CALL PasswordContainer::isPersistentStoringAllowed()
+ throw (::com::sun::star::uno::RuntimeException)
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if ( !m_pStorageFile )
+ throw uno::RuntimeException();
+
+ return m_pStorageFile->useStorage();
+}
+
+//-------------------------------------------------------------------------
+::sal_Bool SAL_CALL PasswordContainer::useDefaultMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
+ throw ( uno::RuntimeException )
+{
+ sal_Bool bResult = sal_False;
+ uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if ( m_pStorageFile && m_pStorageFile->useStorage() )
+ {
+ if ( !xTmpHandler.is() )
+ {
+ uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
+ xTmpHandler.set( xFactory->createInstance( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.task.InteractionHandler" ) ) ), uno::UNO_QUERY_THROW );
+ }
+
+ sal_Bool bCanChangePassword = sal_True;
+ // if there is already a stored nondefault master password it should be entered by the user before the change happen
+ ::rtl::OUString aEncodedMP;
+ if( m_pStorageFile->getEncodedMP( aEncodedMP ) && aEncodedMP.getLength() )
+ bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
+
+ if ( bCanChangePassword )
+ {
+ // generate the default password
+ ::rtl::OUString aPass = GetDefaultMasterPassword();
+ if ( aPass.getLength() )
+ {
+ // get all the persistent entries if it is possible
+ Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() );
+
+ // remove the master password and the entries persistence
+ removeMasterPassword();
+
+ // store the empty string to flag the default master password
+ m_aMasterPasswd = aPass;
+ m_pStorageFile->setEncodedMP( ::rtl::OUString(), sal_True );
+
+ // store all the entries with the new password
+ for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ )
+ for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ )
+ addPersistent( aPersistent[nURLInd].Url,
+ aPersistent[nURLInd].UserList[nNameInd].UserName,
+ aPersistent[nURLInd].UserList[nNameInd].Passwords,
+ uno::Reference< task::XInteractionHandler >() );
+
+ bResult = sal_True;
+ }
+ }
+ }
+
+ return bResult;
+
+}
+
+//-------------------------------------------------------------------------
+::sal_Bool SAL_CALL PasswordContainer::isDefaultMasterPasswordUsed()
+ throw ( uno::RuntimeException )
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ if ( !m_pStorageFile )
+ throw uno::RuntimeException();
+
+ ::rtl::OUString aEncodedMP;
+ return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) && !aEncodedMP.getLength() );
+}
+
+
+//-------------------------------------------------------------------------
+void SAL_CALL PasswordContainer::addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent )
+ throw (uno::RuntimeException)
+{
+ mUrlContainer.add( Url, MakePersistent );
+}
+
+//-------------------------------------------------------------------------
+::rtl::OUString SAL_CALL PasswordContainer::findUrl( const ::rtl::OUString& Url )
+ throw (uno::RuntimeException)
+{
+ return mUrlContainer.find( Url );
+}
+
+//-------------------------------------------------------------------------
+void SAL_CALL PasswordContainer::removeUrl( const ::rtl::OUString& Url )
+ throw (uno::RuntimeException)
+{
+ mUrlContainer.remove( Url );
+}
+
+//-------------------------------------------------------------------------
+uno::Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getUrls( ::sal_Bool OnlyPersistent )
+ throw (uno::RuntimeException)
+{
+ return mUrlContainer.list( OnlyPersistent );
+}
+
+//-------------------------------------------------------------------------
+
+void PasswordContainer::Notify()
+{
+ ::osl::MutexGuard aGuard( mMutex );
+
+ PassMap::iterator aIter;
+
+ // remove the cached persistent values in the memory
+ for( aIter = m_aContainer.begin(); aIter != m_aContainer.end(); aIter++ )
+ {
+ for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); )
+ {
+ if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
+ {
+ aNPIter->RemovePasswords( PERSISTENT_RECORD );
+
+ if ( m_pStorageFile )
+ m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName )
+ }
+
+ if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
+ {
+ list< NamePassRecord >::iterator aIterToDelete( aNPIter );
+ aNPIter++;
+ aIter->second.erase( aIterToDelete );
+ }
+ else
+ aNPIter++;
+ }
+ }
+
+ PassMap addon;
+ if( m_pStorageFile )
+ addon = m_pStorageFile->getInfo();
+
+ for( aIter = addon.begin(); aIter != addon.end(); aIter++ )
+ {
+ PassMap::iterator aSearchIter = m_aContainer.find( aIter->first );
+ if( aSearchIter != m_aContainer.end() )
+ for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); aNPIter++ )
+ UpdateVector( aSearchIter->first, aSearchIter->second, *aNPIter, sal_False );
+ else
+ m_aContainer.insert( PairUrlRecord( aIter->first, aIter->second ) );
+ }
+}
+
+//-------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL PasswordContainer::getImplementationName( ) throw(uno::RuntimeException)
+{
+ return impl_getStaticImplementationName();
+}
+
+//-------------------------------------------------------------------------
+
+sal_Bool SAL_CALL PasswordContainer::supportsService( const ::rtl::OUString& ServiceName ) throw(uno::RuntimeException)
+{
+ if ( ServiceName.compareToAscii("com.sun.star.task.PasswordContainer") == 0 )
+ return sal_True;
+ else
+ return sal_False;
+}
+
+//-------------------------------------------------------------------------
+
+Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::getSupportedServiceNames( ) throw(uno::RuntimeException)
+{
+ return impl_getStaticSupportedServiceNames();
+}
+
+//-------------------------------------------------------------------------
+
+Sequence< ::rtl::OUString > SAL_CALL PasswordContainer::impl_getStaticSupportedServiceNames( ) throw(uno::RuntimeException)
+{
+ Sequence< ::rtl::OUString > aRet(1);
+ *aRet.getArray() = ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer");
+ return aRet;
+}
+
+//-------------------------------------------------------------------------
+
+::rtl::OUString SAL_CALL PasswordContainer::impl_getStaticImplementationName() throw(uno::RuntimeException)
+{
+ return ::rtl::OUString::createFromAscii("stardiv.svtools.PasswordContainer");
+}
+
+//-------------------------------------------------------------------------
+
+Reference< XInterface > SAL_CALL PasswordContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( RuntimeException )
+{
+ return Reference< XInterface >( *new PasswordContainer( xServiceManager ) );
+}
+
+//-------------------------------------------------------------------------
+
+Reference< XSingleServiceFactory > SAL_CALL PasswordContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager ) throw(RuntimeException)
+{
+ Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager,
+ PasswordContainer::impl_getStaticImplementationName(),
+ PasswordContainer::impl_createInstance,
+ PasswordContainer::impl_getStaticSupportedServiceNames()));
+ return xReturn ;
+
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+
+MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode )
+{
+ MasterPasswordRequest aRequest;
+
+ aRequest.Classification = InteractionClassification_ERROR;
+ aRequest.Mode = Mode;
+
+ setRequest( makeAny( aRequest ) );
+
+ // Fill continuations...
+ Sequence< RememberAuthentication > aRememberModes( 1 );
+ aRememberModes[ 0 ] = RememberAuthentication_NO;
+
+ m_xAuthSupplier
+ = new ::ucbhelper::InteractionSupplyAuthentication(
+ this,
+ sal_False, // bCanSetRealm
+ sal_False, // bCanSetUserName
+ sal_True, // bCanSetPassword
+ sal_False, // bCanSetAccount
+ aRememberModes, // rRememberPasswordModes
+ RememberAuthentication_NO, // eDefaultRememberPasswordMode
+ aRememberModes, // rRememberAccountModes
+ RememberAuthentication_NO, // eDefaultRememberAccountMode
+ sal_False, // bCanUseSystemCredentials
+ sal_False // bDefaultUseSystemCredentials
+ );
+
+ Sequence<
+ Reference< XInteractionContinuation > > aContinuations( 3 );
+ aContinuations[ 0 ] = new ::ucbhelper::InteractionAbort( this );
+ aContinuations[ 1 ] = new ::ucbhelper::InteractionRetry( this );
+ aContinuations[ 2 ] = m_xAuthSupplier.get();
+
+ setContinuations( aContinuations );
+}
+
+//-------------------------------------------------------------------------
+//-------------------------------------------------------------------------
+
+extern "C"
+{
+SAL_DLLPUBLIC_EXPORT void SAL_CALL component_getImplementationEnvironment (
+ const sal_Char ** ppEnvTypeName, uno_Environment ** /* ppEnv */)
+{
+ *ppEnvTypeName = CPPU_CURRENT_LANGUAGE_BINDING_NAME;
+}
+
+SAL_DLLPUBLIC_EXPORT sal_Bool SAL_CALL component_writeInfo (
+ void * /* pServiceManager */, void * pRegistryKey)
+{
+ if (pRegistryKey)
+ {
+ Reference< XRegistryKey > xRegistryKey (
+ reinterpret_cast< XRegistryKey* >( pRegistryKey ));
+ Reference< XRegistryKey > xNewKey;
+
+ xNewKey = xRegistryKey->createKey(
+ ::rtl::OUString::createFromAscii( "/stardiv.svtools.PasswordContainer/UNO/SERVICES" ));
+ xNewKey->createKey( ::rtl::OUString::createFromAscii("com.sun.star.task.PasswordContainer"));
+
+ return sal_True;
+ }
+ return sal_False;
+}
+
+SAL_DLLPUBLIC_EXPORT void * SAL_CALL component_getFactory (
+ const sal_Char * pImplementationName, void * pServiceManager, void * /* pRegistryKey */)
+{
+ void * pResult = 0;
+ if (pServiceManager)
+ {
+ Reference< XSingleServiceFactory > xFactory;
+ if (PasswordContainer::impl_getStaticImplementationName().compareToAscii (pImplementationName) == 0)
+ {
+ xFactory = PasswordContainer::impl_createFactory (
+ reinterpret_cast< XMultiServiceFactory* >(pServiceManager));
+ }
+ if (xFactory.is())
+ {
+ xFactory->acquire();
+ pResult = xFactory.get();
+ }
+ }
+ return pResult;
+}
+
+} // extern "C"
diff --git a/svl/source/passwordcontainer/syscreds.cxx b/svl/source/passwordcontainer/syscreds.cxx
new file mode 100644
index 000000000000..b8c223040e6d
--- /dev/null
+++ b/svl/source/passwordcontainer/syscreds.cxx
@@ -0,0 +1,298 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "syscreds.hxx"
+#include "com/sun/star/beans/PropertyValue.hpp"
+
+using namespace com::sun::star;
+
+SysCredentialsConfigItem::SysCredentialsConfigItem(
+ SysCredentialsConfig * pOwner )
+: utl::ConfigItem( rtl::OUString::createFromAscii( "Office.Common/Passwords" ),
+ CONFIG_MODE_IMMEDIATE_UPDATE ),
+ m_bInited( false ),
+ m_pOwner( pOwner )
+{
+ uno::Sequence< ::rtl::OUString > aNode( 1 );
+ aNode[ 0 ] = rtl::OUString::createFromAscii(
+ "Office.Common/Passwords/AuthenticateUsingSystemCredentials" );
+ EnableNotification( aNode );
+}
+
+//virtual
+void SysCredentialsConfigItem::Notify(
+ const uno::Sequence< rtl::OUString > & /*seqPropertyNames*/ )
+{
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_bInited = false;
+ // rebuild m_seqURLs
+ getSystemCredentialsURLs();
+ }
+ m_pOwner->persistentConfigChanged();
+}
+
+uno::Sequence< rtl::OUString >
+SysCredentialsConfigItem::getSystemCredentialsURLs()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_bInited )
+ {
+ // read config item
+ uno::Sequence< ::rtl::OUString > aPropNames( 1 );
+ aPropNames[ 0 ] = rtl::OUString::createFromAscii(
+ "AuthenticateUsingSystemCredentials" );
+ uno::Sequence< uno::Any > aAnyValues(
+ utl::ConfigItem::GetProperties( aPropNames ) );
+
+ OSL_ENSURE(
+ aAnyValues.getLength() == 1,
+ "SysCredentialsConfigItem::getSystemCredentialsURLs: "
+ "Error reading config item!" );
+
+ uno::Sequence< rtl::OUString > aValues;
+ if ( ( aAnyValues[ 0 ] >>= aValues ) ||
+ ( !aAnyValues[ 0 ].hasValue() ) )
+ {
+ m_seqURLs = aValues;
+ m_bInited = true;
+ }
+ }
+ return m_seqURLs;
+}
+
+void SysCredentialsConfigItem::setSystemCredentialsURLs(
+ const uno::Sequence< rtl::OUString > & seqURLList )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ // write config item.
+ uno::Sequence< rtl::OUString > aPropNames( 1 );
+ uno::Sequence< uno::Any > aPropValues( 1 );
+ aPropNames[ 0 ]
+ = ::rtl::OUString::createFromAscii(
+ "AuthenticateUsingSystemCredentials" );
+ aPropValues[ 0 ] <<= seqURLList;
+
+ utl::ConfigItem::SetModified();
+ utl::ConfigItem::PutProperties( aPropNames, aPropValues );
+
+ m_seqURLs = seqURLList;
+ m_bInited = true;
+}
+
+//============================================================================
+
+namespace
+{
+ // TODO: This code is actually copied from svtools/source/passwordcontainer.cxx
+ bool removeLastSegment( ::rtl::OUString & aURL )
+ {
+ sal_Int32 aInd = aURL.lastIndexOf( sal_Unicode( '/' ) );
+
+ if( aInd > 0 )
+ {
+ sal_Int32 aPrevInd = aURL.lastIndexOf( sal_Unicode( '/' ), aInd );
+ if ( aURL.indexOf( ::rtl::OUString::createFromAscii( "://" ) )
+ != aPrevInd - 2 ||
+ aInd != aURL.getLength() - 1 )
+ {
+ aURL = aURL.copy( 0, aInd );
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool findURL( StringSet const & rContainer, rtl::OUString const & aURL, rtl::OUString & aResult )
+ {
+ // TODO: This code is actually copied from svtools/source/passwordcontainer.cxx
+ if( !rContainer.empty() && aURL.getLength() )
+ {
+ ::rtl::OUString aUrl( aURL );
+
+ // each iteration remove last '/...' section from the aUrl
+ // while it's possible, up to the most left '://'
+ do
+ {
+ // first look for <url>/somename and then look for <url>/somename/...
+ StringSet::const_iterator aIter = rContainer.find( aUrl );
+ if( aIter != rContainer.end() )
+ {
+ aResult = *aIter;
+ return true;
+ }
+ else
+ {
+ ::rtl::OUString tmpUrl( aUrl );
+ if ( tmpUrl.getStr()[tmpUrl.getLength() - 1] != (sal_Unicode)'/' )
+ tmpUrl += ::rtl::OUString::createFromAscii( "/" );
+
+ aIter = rContainer.lower_bound( tmpUrl );
+ if( aIter != rContainer.end() && aIter->match( tmpUrl ) )
+ {
+ aResult = *aIter;
+ return true;
+ }
+ }
+ }
+ while( removeLastSegment( aUrl ) && aUrl.getLength() );
+ }
+ aResult = rtl::OUString();
+ return false;
+ }
+
+} // namespace
+
+SysCredentialsConfig::SysCredentialsConfig()
+: m_aConfigItem( this ),
+ m_bCfgInited( false )
+{
+}
+
+void SysCredentialsConfig::initCfg()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ if ( !m_bCfgInited )
+ {
+ uno::Sequence< rtl::OUString > aURLs(
+ m_aConfigItem.getSystemCredentialsURLs() );
+ for ( sal_Int32 n = 0; n < aURLs.getLength(); ++n )
+ m_aCfgContainer.insert( aURLs[ n ] );
+
+ m_bCfgInited = true;
+ }
+}
+
+void SysCredentialsConfig::writeCfg()
+{
+ osl::MutexGuard aGuard( m_aMutex );
+
+ OSL_ENSURE( m_bCfgInited, "SysCredentialsConfig::writeCfg : not initialized!" );
+
+ uno::Sequence< rtl::OUString > aURLs( m_aCfgContainer.size() );
+ StringSet::const_iterator it = m_aCfgContainer.begin();
+ const StringSet::const_iterator end = m_aCfgContainer.end();
+ sal_Int32 n = 0;
+
+ while ( it != end )
+ {
+ aURLs[ n ] = *it;
+ ++it;
+ ++n;
+ }
+
+ m_aConfigItem.setSystemCredentialsURLs( aURLs );
+}
+
+rtl::OUString SysCredentialsConfig::find( rtl::OUString const & aURL )
+{
+ osl::MutexGuard aGuard( m_aMutex );
+ rtl::OUString aResult;
+ if ( findURL( m_aMemContainer, aURL, aResult ) )
+ return aResult;
+
+ initCfg();
+ if ( findURL( m_aCfgContainer, aURL, aResult ) )
+ return aResult;
+
+ return rtl::OUString();
+}
+
+void SysCredentialsConfig::add( rtl::OUString const & rURL, bool bPersistent )
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+
+ if ( bPersistent )
+ {
+ m_aMemContainer.erase( rURL );
+
+ initCfg();
+ m_aCfgContainer.insert( rURL );
+ writeCfg();
+ }
+ else
+ {
+ initCfg();
+ if ( m_aCfgContainer.erase( rURL ) > 0 )
+ writeCfg();
+
+ m_aMemContainer.insert( rURL );
+ }
+}
+
+void SysCredentialsConfig::remove( rtl::OUString const & rURL )
+{
+ m_aMemContainer.erase( rURL );
+
+ initCfg();
+ if ( m_aCfgContainer.erase( rURL ) > 0 )
+ writeCfg();
+}
+
+uno::Sequence< rtl::OUString > SysCredentialsConfig::list( bool bOnlyPersistent )
+{
+ initCfg();
+ sal_Int32 nCount = m_aCfgContainer.size()
+ + ( bOnlyPersistent ? 0 : m_aMemContainer.size() );
+ uno::Sequence< rtl::OUString > aResult( nCount );
+
+ StringSet::const_iterator it = m_aCfgContainer.begin();
+ StringSet::const_iterator end = m_aCfgContainer.end();
+ sal_Int32 n = 0;
+
+ while ( it != end )
+ {
+ aResult[ n ] = *it;
+ ++it;
+ ++n;
+ }
+
+ if ( !bOnlyPersistent )
+ {
+ it = m_aMemContainer.begin();
+ end = m_aMemContainer.end();
+
+ while ( it != end )
+ {
+ aResult[ n ] = *it;
+ ++it;
+ ++n;
+ }
+ }
+ return aResult;
+}
+
+void SysCredentialsConfig::persistentConfigChanged()
+{
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_bCfgInited = false; // re-init on demand.
+}
diff --git a/svl/source/passwordcontainer/syscreds.hxx b/svl/source/passwordcontainer/syscreds.hxx
new file mode 100644
index 000000000000..b037e17c348e
--- /dev/null
+++ b/svl/source/passwordcontainer/syscreds.hxx
@@ -0,0 +1,95 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: $
+ * $Revision: $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#ifndef INCLUDED_SVTOOLS_SYSCREDS_HXX
+#define INCLUDED_SVTOOLS_SYSCREDS_HXX
+
+#include <set>
+#include <memory>
+#include "osl/mutex.hxx"
+#include "rtl/ustring.hxx"
+#include "com/sun/star/uno/Sequence.hxx"
+#include "unotools/configitem.hxx"
+
+class SysCredentialsConfig;
+
+class SysCredentialsConfigItem : public utl::ConfigItem
+{
+ public:
+ SysCredentialsConfigItem( SysCredentialsConfig * pOwner );
+ //virtual ~SysCredentialsConfigItem();
+
+ virtual void Notify(
+ const com::sun::star::uno::Sequence< rtl::OUString > &
+ seqPropertyNames );
+ //virtual void Commit();
+
+ com::sun::star::uno::Sequence< rtl::OUString >
+ getSystemCredentialsURLs();
+
+ void setSystemCredentialsURLs(
+ const com::sun::star::uno::Sequence< rtl::OUString > &
+ seqURLList );
+
+ //bool isSystemCredentialsURL( const rtl::OUString & rURL ) const;
+
+private:
+ ::osl::Mutex m_aMutex;
+ bool m_bInited;
+ com::sun::star::uno::Sequence< rtl::OUString > m_seqURLs;
+ SysCredentialsConfig * m_pOwner;
+};
+
+typedef std::set< rtl::OUString > StringSet;
+
+class SysCredentialsConfig
+{
+ public:
+ SysCredentialsConfig();
+
+ rtl::OUString find( rtl::OUString const & rURL );
+ void add( rtl::OUString const & rURL, bool bPersistent );
+ void remove( rtl::OUString const & rURL );
+ com::sun::star::uno::Sequence< rtl::OUString > list( bool bOnlyPersistent );
+
+ void persistentConfigChanged();
+
+ private:
+ void initCfg();
+ void writeCfg();
+
+ ::osl::Mutex m_aMutex;
+ StringSet m_aMemContainer;
+ StringSet m_aCfgContainer;
+ SysCredentialsConfigItem m_aConfigItem;
+ bool m_bCfgInited;
+};
+
+#endif // INCLUDED_SVTOOLS_SYSCREDS_HXX