LCOV - code coverage report
Current view: top level - svl/source/passwordcontainer - passwordcontainer.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 391 670 58.4 %
Date: 2014-11-03 Functions: 42 63 66.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : 
      21             : #include "passwordcontainer.hxx"
      22             : 
      23             : #include <unotools/pathoptions.hxx>
      24             : #include <cppuhelper/factory.hxx>
      25             : #include <cppuhelper/supportsservice.hxx>
      26             : #include <comphelper/processfactory.hxx>
      27             : #include <comphelper/string.hxx>
      28             : #include <com/sun/star/registry/XSimpleRegistry.hpp>
      29             : #include <com/sun/star/beans/PropertyValue.hpp>
      30             : #include <com/sun/star/task/InteractionHandler.hpp>
      31             : #include <com/sun/star/task/MasterPasswordRequest.hpp>
      32             : #include <com/sun/star/task/NoMasterException.hpp>
      33             : 
      34             : #include <rtl/cipher.h>
      35             : #include <rtl/digest.h>
      36             : #include <rtl/byteseq.hxx>
      37             : 
      38             : using namespace std;
      39             : using namespace osl;
      40             : using namespace utl;
      41             : using namespace com::sun::star;
      42             : using namespace com::sun::star::uno;
      43             : using namespace com::sun::star::registry;
      44             : using namespace com::sun::star::lang;
      45             : using namespace com::sun::star::task;
      46             : using namespace com::sun::star::ucb;
      47             : 
      48             : 
      49         154 : static OUString createIndex( vector< OUString > lines )
      50             : {
      51         154 :     OString aResult;
      52             :     const sal_Char* pLine;
      53             : 
      54         408 :     for( unsigned int i = 0; i < lines.size(); i++ )
      55             :     {
      56         254 :         if( i )
      57         100 :             aResult += OString( "__" );
      58         254 :         OString line = OUStringToOString( lines[i], RTL_TEXTENCODING_UTF8 );
      59         254 :         pLine = line.getStr();
      60             : 
      61        4836 :         while( *pLine )
      62             :         {
      63        4328 :             if (comphelper::string::isalnumAscii(*pLine))
      64             :             {
      65        3528 :                 aResult += OString( *pLine );
      66             :             }
      67             :             else
      68             :             {
      69         800 :                 aResult += OString("_");
      70         800 :                 aResult += OString::number(  *pLine, 16 );
      71             :             }
      72             : 
      73        4328 :             pLine++;
      74             :         }
      75         254 :     }
      76             : 
      77         154 :     return OUString::createFromAscii( aResult.getStr() );
      78             : }
      79             : 
      80             : 
      81          40 : static vector< OUString > getInfoFromInd( const OUString& aInd )
      82             : {
      83          40 :     vector< OUString > aResult;
      84          40 :     bool aStart = true;
      85             : 
      86          80 :     OString line = OUStringToOString( aInd, RTL_TEXTENCODING_ASCII_US );
      87          40 :     const sal_Char* pLine = line.getStr();
      88          40 :     do
      89             :     {
      90          40 :         OUString newItem;
      91          40 :         if( !aStart )
      92           0 :             pLine += 2;
      93             :         else
      94          40 :             aStart = false;
      95             : 
      96         560 :         while( *pLine && !( pLine[0] == '_' && pLine[1] == '_' ))
      97         480 :             if( *pLine != '_' )
      98             :             {
      99         400 :                 newItem += OUString( (sal_Unicode) *pLine );
     100         400 :                 pLine++;
     101             :             }
     102             :             else
     103             :             {
     104          80 :                 OUString aNum;
     105         240 :                 for( int i = 1; i < 3; i++ )
     106             :                 {
     107         160 :                     if( !pLine[i]
     108         160 :                       ||  ( ( pLine[i] < '0' || pLine[i] > '9' )
     109          80 :                          && ( pLine[i] < 'a' || pLine[i] > 'f' )
     110           0 :                          && ( pLine[i] < 'A' || pLine[i] > 'F' ) ) )
     111             :                     {
     112             :                         OSL_FAIL( "Wrong index syntax!\n" );
     113           0 :                         return aResult;
     114             :                     }
     115             : 
     116         160 :                     aNum += OUString( (sal_Unicode) pLine[i] );
     117             :                 }
     118             : 
     119          80 :                 newItem += OUString( (sal_Unicode) aNum.toUInt32( 16 ) );
     120          80 :                 pLine += 3;
     121             :             }
     122             : 
     123          40 :         aResult.push_back( newItem );
     124          40 :     } while( pLine[0] == '_' && pLine[1] == '_' );
     125             : 
     126          40 :     if( *pLine )
     127             :         OSL_FAIL( "Wrong index syntax!\n" );
     128             : 
     129          40 :     return aResult;
     130             : }
     131             : 
     132             : 
     133           0 : static bool shorterUrl( OUString& aURL )
     134             : {
     135           0 :     sal_Int32 aInd = aURL.lastIndexOf( '/' );
     136           0 :     if( aInd > 0 && aURL.indexOf( "://" ) != aInd-2 )
     137             :     {
     138           0 :         aURL = aURL.copy( 0, aInd );
     139           0 :         return true;
     140             :     }
     141             : 
     142           0 :     return false;
     143             : }
     144             : 
     145             : 
     146          54 : static OUString getAsciiLine( const ::rtl::ByteSequence& buf )
     147             : {
     148          54 :     OUString aResult;
     149             : 
     150         108 :     ::rtl::ByteSequence outbuf( buf.getLength()*2+1 );
     151             : 
     152        1036 :     for( int ind = 0; ind < buf.getLength(); ind++ )
     153             :     {
     154         982 :         outbuf[ind*2]   = ( ((sal_uInt8)buf[ind]) >> 4 ) + 'a';
     155         982 :         outbuf[ind*2+1] = ( ((sal_uInt8)buf[ind]) & 0x0f ) + 'a';
     156             :     }
     157          54 :     outbuf[buf.getLength()*2] = '\0';
     158             : 
     159          54 :     aResult = OUString::createFromAscii( (sal_Char*)outbuf.getArray() );
     160             : 
     161         108 :     return aResult;
     162             : }
     163             : 
     164             : 
     165          40 : static ::rtl::ByteSequence getBufFromAsciiLine( const OUString& line )
     166             : {
     167             :     OSL_ENSURE( line.getLength() % 2 == 0, "Wrong syntax!\n" );
     168          40 :     OString tmpLine = OUStringToOString( line, RTL_TEXTENCODING_ASCII_US );
     169          40 :     ::rtl::ByteSequence aResult(line.getLength()/2);
     170             : 
     171         720 :     for( int ind = 0; ind < tmpLine.getLength()/2; ind++ )
     172             :     {
     173         680 :         aResult[ind] = ( (sal_uInt8)( tmpLine[ind*2] - 'a' ) << 4 ) | (sal_uInt8)( tmpLine[ind*2+1] - 'a' );
     174             :     }
     175             : 
     176          40 :     return aResult;
     177             : }
     178             : 
     179             : 
     180          80 : static Sequence< OUString > copyVectorToSequence( const vector< OUString >& original )
     181             : {
     182          80 :     Sequence< OUString > newOne ( original.size() );
     183         160 :     for( unsigned int i = 0; i < original.size() ; i++ )
     184          80 :         newOne[i] = original[i];
     185             : 
     186          80 :     return newOne;
     187             : }
     188             : 
     189          90 : static vector< OUString > copySequenceToVector( const Sequence< OUString >& original )
     190             : {
     191          90 :     vector< OUString > newOne ( original.getLength() );
     192         180 :     for( int i = 0; i < original.getLength() ; i++ )
     193          90 :         newOne[i] = original[i];
     194             : 
     195          90 :     return newOne;
     196             : }
     197             : 
     198             : 
     199           0 : PassMap StorageItem::getInfo()
     200             : {
     201           0 :     PassMap aResult;
     202             : 
     203           0 :     Sequence< OUString > aNodeNames     = ConfigItem::GetNodeNames( OUString("Store") );
     204           0 :     sal_Int32 aNodeCount = aNodeNames.getLength();
     205           0 :     Sequence< OUString > aPropNames( aNodeCount );
     206             :     sal_Int32 aNodeInd;
     207             : 
     208           0 :     for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
     209             :     {
     210           0 :         aPropNames[aNodeInd]  = "Store/Passwordstorage['" + aNodeNames[aNodeInd] + "']/Password";
     211             :     }
     212             : 
     213           0 :     Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aPropNames );
     214             : 
     215           0 :     if( aPropertyValues.getLength() != aNodeNames.getLength() )
     216             :     {
     217             :         OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
     218           0 :         return aResult;
     219             :     }
     220             : 
     221           0 :     for( aNodeInd = 0; aNodeInd < aNodeCount; ++aNodeInd )
     222             :     {
     223           0 :         vector< OUString > aUrlUsr = getInfoFromInd( aNodeNames[aNodeInd] );
     224             : 
     225           0 :         if( aUrlUsr.size() == 2 )
     226             :         {
     227           0 :             OUString aUrl  = aUrlUsr[0];
     228           0 :             OUString aName = aUrlUsr[1];
     229             : 
     230           0 :             OUString aEPasswd;
     231           0 :             aPropertyValues[aNodeInd] >>= aEPasswd;
     232             : 
     233           0 :             PassMap::iterator aIter = aResult.find( aUrl );
     234           0 :             if( aIter != aResult.end() )
     235           0 :                 aIter->second.push_back( NamePassRecord( aName, aEPasswd ) );
     236             :             else
     237             :             {
     238           0 :                 NamePassRecord aNewRecord( aName, aEPasswd );
     239           0 :                 list< NamePassRecord > listToAdd( 1, aNewRecord );
     240             : 
     241           0 :                 aResult.insert( PairUrlRecord( aUrl, listToAdd ) );
     242           0 :             }
     243             :         }
     244             :         else
     245             :             OSL_FAIL( "Wrong index sintax!\n" );
     246           0 :     }
     247             : 
     248           0 :     return aResult;
     249             : }
     250             : 
     251             : 
     252           8 : void StorageItem::setUseStorage( bool bUse )
     253             : {
     254           8 :     Sequence< OUString > sendNames(1);
     255          16 :     Sequence< uno::Any > sendVals(1);
     256             : 
     257           8 :     sendNames[0] = "UseStorage";
     258             : 
     259           8 :     sendVals[0] <<= bUse;
     260             : 
     261           8 :     ConfigItem::SetModified();
     262          16 :     ConfigItem::PutProperties( sendNames, sendVals );
     263           8 : }
     264             : 
     265             : 
     266         106 : bool StorageItem::useStorage()
     267             : {
     268         106 :     Sequence< OUString > aNodeNames( 1 );
     269         106 :     aNodeNames[0] = "UseStorage";
     270             : 
     271         212 :     Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
     272             : 
     273         106 :     if( aPropertyValues.getLength() != aNodeNames.getLength() )
     274             :     {
     275             :         OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
     276           0 :         return false;
     277             :     }
     278             : 
     279         106 :     bool aResult = false;
     280         106 :     aPropertyValues[0] >>= aResult;
     281             : 
     282         212 :     return aResult;
     283             : }
     284             : 
     285             : 
     286           4 : bool StorageItem::getEncodedMP( OUString& aResult )
     287             : {
     288           4 :     if( hasEncoded )
     289             :     {
     290           0 :         aResult = mEncoded;
     291           0 :         return true;
     292             :     }
     293             : 
     294           4 :     Sequence< OUString > aNodeNames( 2 );
     295           4 :     aNodeNames[0] = "HasMaster";
     296           4 :     aNodeNames[1] = "Master";
     297             : 
     298           8 :     Sequence< Any > aPropertyValues = ConfigItem::GetProperties( aNodeNames );
     299             : 
     300           4 :     if( aPropertyValues.getLength() != aNodeNames.getLength() )
     301             :     {
     302             :         OSL_ENSURE( aPropertyValues.getLength() == aNodeNames.getLength(), "Problems during reading\n" );
     303           0 :         return false;
     304             :     }
     305             : 
     306           4 :     aPropertyValues[0] >>= hasEncoded;
     307           4 :     aPropertyValues[1] >>= mEncoded;
     308             : 
     309           4 :     aResult = mEncoded;
     310             : 
     311           8 :     return hasEncoded;
     312             : }
     313             : 
     314             : 
     315           8 : void StorageItem::setEncodedMP( const OUString& aEncoded, bool bAcceptEmpty )
     316             : {
     317           8 :     Sequence< OUString > sendNames(2);
     318          16 :     Sequence< uno::Any > sendVals(2);
     319             : 
     320           8 :     sendNames[0] = "HasMaster";
     321           8 :     sendNames[1] = "Master";
     322             : 
     323           8 :     bool bHasMaster = ( !aEncoded.isEmpty() || bAcceptEmpty );
     324           8 :     sendVals[0] <<= bHasMaster;
     325           8 :     sendVals[1] <<= aEncoded;
     326             : 
     327           8 :     ConfigItem::SetModified();
     328           8 :     ConfigItem::PutProperties( sendNames, sendVals );
     329             : 
     330           8 :     hasEncoded = bHasMaster;
     331          16 :     mEncoded = aEncoded;
     332           8 : }
     333             : 
     334             : 
     335          50 : void StorageItem::remove( const OUString& aURL, const OUString& aName )
     336             : {
     337          50 :     vector < OUString > forIndex;
     338          50 :     forIndex.push_back( aURL );
     339          50 :     forIndex.push_back( aName );
     340             : 
     341         100 :     Sequence< OUString > sendSeq(1);
     342             : 
     343          50 :     sendSeq[0] = createIndex( forIndex );
     344             : 
     345         100 :     ConfigItem::ClearNodeElements( OUString("Store"), sendSeq );
     346          50 : }
     347             : 
     348             : 
     349           8 : void StorageItem::clear()
     350             : {
     351           8 :     ConfigItem::ClearNodeSet( OUString("Store") );
     352           8 : }
     353             : 
     354             : 
     355          50 : void StorageItem::update( const OUString& aURL, const NamePassRecord& aRecord )
     356             : {
     357          50 :     if ( !aRecord.HasPasswords( PERSISTENT_RECORD ) )
     358             :     {
     359             :         OSL_FAIL( "Unexpected storing of a record!" );
     360          50 :         return;
     361             :     }
     362             : 
     363          50 :     vector < OUString > forIndex;
     364          50 :     forIndex.push_back( aURL );
     365          50 :     forIndex.push_back( aRecord.GetUserName() );
     366             : 
     367         100 :     Sequence< beans::PropertyValue > sendSeq(1);
     368             : 
     369          50 :     sendSeq[0].Name  = "Store/Passwordstorage['" + createIndex( forIndex ) + "']/Password";
     370             : 
     371          50 :     sendSeq[0].Value <<= aRecord.GetPersPasswords();
     372             : 
     373          50 :     ConfigItem::SetModified();
     374         100 :     ConfigItem::SetSetProperties( OUString("Store"), sendSeq );
     375             : }
     376             : 
     377             : 
     378           0 : void StorageItem::Notify( const Sequence< OUString >& )
     379             : {
     380             :     // this feature still should not be used
     381           0 :     if( mainCont )
     382           0 :         mainCont->Notify();
     383           0 : }
     384             : 
     385             : 
     386           2 : void StorageItem::Commit()
     387             : {
     388             :     // Do nothing, we stored everything we want already
     389           2 : }
     390             : 
     391             : 
     392           4 : PasswordContainer::PasswordContainer( const Reference<XMultiServiceFactory>& xServiceFactory ):
     393           4 :     m_pStorageFile( NULL )
     394             : {
     395             :     // m_pStorageFile->Notify() can be called
     396           4 :     ::osl::MutexGuard aGuard( mMutex );
     397             : 
     398           4 :     mComponent = Reference< XComponent >( xServiceFactory, UNO_QUERY );
     399           4 :     mComponent->addEventListener( this );
     400             : 
     401           4 :     m_pStorageFile = new StorageItem( this, OUString("Office.Common/Passwords") );
     402           4 :     if( m_pStorageFile )
     403           4 :         if( m_pStorageFile->useStorage() )
     404           0 :             m_aContainer = m_pStorageFile->getInfo();
     405           4 : }
     406             : 
     407             : 
     408          12 : PasswordContainer::~PasswordContainer()
     409             : {
     410           4 :     ::osl::MutexGuard aGuard( mMutex );
     411             : 
     412           4 :     if( m_pStorageFile )
     413             :     {
     414           0 :         delete m_pStorageFile;
     415           0 :         m_pStorageFile = NULL;
     416             :     }
     417             : 
     418           4 :     if( mComponent.is() )
     419             :     {
     420           0 :         mComponent->removeEventListener(this);
     421           0 :         mComponent.clear();
     422           4 :     }
     423           8 : }
     424             : 
     425             : 
     426           4 : void SAL_CALL PasswordContainer::disposing( const EventObject& ) throw(RuntimeException, std::exception)
     427             : {
     428           4 :     ::osl::MutexGuard aGuard( mMutex );
     429             : 
     430           4 :     if( m_pStorageFile )
     431             :     {
     432           4 :         delete m_pStorageFile;
     433           4 :         m_pStorageFile = NULL;
     434             :     }
     435             : 
     436           4 :     if( mComponent.is() )
     437             :     {
     438             :         //mComponent->removeEventListener(this);
     439           4 :         mComponent.clear();
     440           4 :     }
     441           4 : }
     442             : 
     443             : 
     444          40 : vector< OUString > PasswordContainer::DecodePasswords( const OUString& aLine, const OUString& aMasterPasswd ) throw(RuntimeException)
     445             : {
     446          40 :     if( !aMasterPasswd.isEmpty() )
     447             :     {
     448          40 :         rtlCipher aDecoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
     449             :         OSL_ENSURE( aDecoder, "Can't create decoder\n" );
     450             : 
     451          40 :         if( aDecoder )
     452             :         {
     453             :             OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" );
     454             : 
     455             :             unsigned char code[RTL_DIGEST_LENGTH_MD5];
     456         680 :             for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
     457         640 :                 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toUInt32(16));
     458             : 
     459             :             rtlCipherError result = rtl_cipher_init (
     460             :                     aDecoder, rtl_Cipher_DirectionDecode,
     461          40 :                     code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
     462             : 
     463          40 :             if( result == rtl_Cipher_E_None )
     464             :             {
     465          40 :                 ::rtl::ByteSequence aSeq = getBufFromAsciiLine( aLine );
     466             : 
     467          80 :                 ::rtl::ByteSequence resSeq( aSeq.getLength() );
     468             : 
     469          80 :                 result = rtl_cipher_decode ( aDecoder, (sal_uInt8*)aSeq.getArray(), aSeq.getLength(),
     470         120 :                                                         (sal_uInt8*)resSeq.getArray(), resSeq.getLength() );
     471             : 
     472          80 :                 OUString aPasswd( ( sal_Char* )resSeq.getArray(), resSeq.getLength(), RTL_TEXTENCODING_UTF8 );
     473             : 
     474          40 :                 rtl_cipher_destroy (aDecoder);
     475             : 
     476         120 :                 return getInfoFromInd( aPasswd );
     477             :             }
     478             : 
     479           0 :             rtl_cipher_destroy (aDecoder);
     480             :         }
     481             :     }
     482             :     else
     483             :     {
     484             :         OSL_FAIL( "No master password provided!\n" );
     485             :         // throw special exception
     486             :     }
     487             : 
     488             :     // problems with decoding
     489             :     OSL_FAIL( "Problem with decoding\n" );
     490           0 :     throw RuntimeException("Can't decode!" );
     491             : }
     492             : 
     493             : 
     494             : 
     495          54 : OUString PasswordContainer::EncodePasswords( vector< OUString > lines, const OUString& aMasterPasswd ) throw(RuntimeException)
     496             : {
     497          54 :     if( !aMasterPasswd.isEmpty() )
     498             :     {
     499          54 :         OString aSeq = OUStringToOString( createIndex( lines ), RTL_TEXTENCODING_UTF8 );
     500             : 
     501          54 :         rtlCipher aEncoder = rtl_cipher_create (rtl_Cipher_AlgorithmBF, rtl_Cipher_ModeStream );
     502             :         OSL_ENSURE( aEncoder, "Can't create encoder\n" );
     503             : 
     504          54 :         if( aEncoder )
     505             :         {
     506             :             OSL_ENSURE( aMasterPasswd.getLength() == RTL_DIGEST_LENGTH_MD5 * 2, "Wrong master password format!\n" );
     507             : 
     508             :             unsigned char code[RTL_DIGEST_LENGTH_MD5];
     509         918 :             for( int ind = 0; ind < RTL_DIGEST_LENGTH_MD5; ind++ )
     510         864 :                 code[ ind ] = (char)(aMasterPasswd.copy( ind*2, 2 ).toUInt32(16));
     511             : 
     512             :             rtlCipherError result = rtl_cipher_init (
     513             :                     aEncoder, rtl_Cipher_DirectionEncode,
     514          54 :                     code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
     515             : 
     516          54 :             if( result == rtl_Cipher_E_None )
     517             :             {
     518          54 :                 ::rtl::ByteSequence resSeq(aSeq.getLength()+1);
     519             : 
     520         108 :                 result = rtl_cipher_encode ( aEncoder, (sal_uInt8*)aSeq.getStr(), aSeq.getLength()+1,
     521         162 :                                                         (sal_uInt8*)resSeq.getArray(), resSeq.getLength() );
     522             : 
     523             : /*
     524             :                 //test
     525             :                 rtlCipherError result = rtl_cipher_init (
     526             :                     aEncoder, rtl_Cipher_DirectionDecode,
     527             :                     code, RTL_DIGEST_LENGTH_MD5, NULL, 0 );
     528             : 
     529             : 
     530             :                 if( result == rtl_Cipher_E_None )
     531             :                 {
     532             :                     OUString testOU = getAsciiLine( resSeq );
     533             :                     ::rtl::ByteSequence aSeq1 = getBufFromAsciiLine( testOU );
     534             : 
     535             :                     ::rtl::ByteSequence resSeq1( aSeq1.getLength() );
     536             : 
     537             :                     if( resSeq.getLength() == aSeq1.getLength() )
     538             :                     {
     539             :                         for( int ind = 0; ind < aSeq1.getLength(); ind++ )
     540             :                             if( resSeq[ind] != aSeq1[ind] )
     541             :                                 testOU = "";
     542             :                     }
     543             : 
     544             :                     result = rtl_cipher_decode ( aEncoder, (sal_uInt8*)aSeq1.getArray(), aSeq1.getLength(),
     545             :                                                         (sal_uInt8*)resSeq1.getArray(), resSeq1.getLength() );
     546             : 
     547             :                     OUString aPasswd( ( sal_Char* )resSeq1.getArray(), resSeq1.getLength(), RTL_TEXTENCODING_UTF8 );
     548             :                 }
     549             : */
     550             : 
     551          54 :                 rtl_cipher_destroy (aEncoder);
     552             : 
     553          54 :                 if( result == rtl_Cipher_E_None )
     554         108 :                     return getAsciiLine( resSeq );
     555             : 
     556             :             }
     557             : 
     558           0 :             rtl_cipher_destroy (aEncoder);
     559           0 :         }
     560             :     }
     561             :     else
     562             :     {
     563             :         OSL_FAIL( "No master password provided!\n" );
     564             :         // throw special exception
     565             :     }
     566             : 
     567             :     // problems with encoding
     568             :     OSL_FAIL( "Problem with encoding\n" );
     569           0 :     throw RuntimeException("Can't encode!" );
     570             : }
     571             : 
     572             : 
     573          84 : void PasswordContainer::UpdateVector( const OUString& aURL, list< NamePassRecord >& toUpdate, NamePassRecord& aRecord, bool writeFile ) throw(RuntimeException)
     574             : {
     575         714 :     for( list< NamePassRecord >::iterator aNPIter = toUpdate.begin(); aNPIter != toUpdate.end(); ++aNPIter )
     576         630 :         if( aNPIter->GetUserName().equals( aRecord.GetUserName() ) )
     577             :         {
     578           0 :             if( aRecord.HasPasswords( MEMORY_RECORD ) )
     579           0 :                 aNPIter->SetMemPasswords( aRecord.GetMemPasswords() );
     580             : 
     581           0 :             if( aRecord.HasPasswords( PERSISTENT_RECORD ) )
     582             :             {
     583           0 :                 aNPIter->SetPersPasswords( aRecord.GetPersPasswords() );
     584             : 
     585           0 :                 if( writeFile )
     586             :                 {
     587             :                     // the password must be already encoded
     588           0 :                     m_pStorageFile->update( aURL, aRecord ); // change existing ( aURL, aName ) record in the configfile
     589             :                 }
     590             :             }
     591             : 
     592          84 :             return;
     593             :         }
     594             : 
     595             : 
     596          84 :     if( aRecord.HasPasswords( PERSISTENT_RECORD ) && writeFile )
     597             :     {
     598             :         // the password must be already encoded
     599          46 :         m_pStorageFile->update( aURL, aRecord ); // add new aName to the existing url
     600             :     }
     601             : 
     602          84 :     toUpdate.insert( toUpdate.begin(), aRecord );
     603             : }
     604             : 
     605             : 
     606          70 : UserRecord PasswordContainer::CopyToUserRecord( const NamePassRecord& aRecord, bool& io_bTryToDecode, const Reference< XInteractionHandler >& aHandler )
     607             : {
     608          70 :     ::std::vector< OUString > aPasswords;
     609          70 :     if( aRecord.HasPasswords( MEMORY_RECORD ) )
     610          40 :         aPasswords = aRecord.GetMemPasswords();
     611             : 
     612          70 :     if( io_bTryToDecode && aRecord.HasPasswords( PERSISTENT_RECORD ) )
     613             :     {
     614             :         try
     615             :         {
     616          30 :             ::std::vector< OUString > aDecodedPasswords = DecodePasswords( aRecord.GetPersPasswords(), GetMasterPassword( aHandler ) );
     617          30 :             aPasswords.insert( aPasswords.end(), aDecodedPasswords.begin(), aDecodedPasswords.end() );
     618             :         }
     619           0 :         catch( NoMasterException& )
     620             :         {
     621             :             // if master password could not be detected the entry will be just ignored
     622           0 :             io_bTryToDecode = false;
     623             :         }
     624             :     }
     625             : 
     626          70 :     return UserRecord( aRecord.GetUserName(), copyVectorToSequence( aPasswords ) );
     627             : }
     628             : 
     629             : 
     630          10 : Sequence< UserRecord > PasswordContainer::CopyToUserRecordSequence( const list< NamePassRecord >& original, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
     631             : {
     632          10 :     Sequence< UserRecord >     aResult( original.size() );
     633          10 :     sal_uInt32 nInd = 0;
     634          10 :     bool bTryToDecode = true;
     635             : 
     636         240 :     for( list< NamePassRecord >::const_iterator aNPIter = original.begin();
     637         160 :          aNPIter != original.end();
     638             :          ++aNPIter, ++nInd )
     639             :     {
     640          70 :         aResult[nInd] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler );
     641             :     }
     642             : 
     643          10 :     return aResult;
     644             : }
     645             : 
     646             : 
     647          40 : void SAL_CALL PasswordContainer::add( const OUString& Url, const OUString& UserName, const Sequence< OUString >& Passwords, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException, std::exception)
     648             : {
     649          40 :     ::osl::MutexGuard aGuard( mMutex );
     650             : 
     651          40 :     PrivateAdd( Url, UserName, Passwords, MEMORY_RECORD, aHandler );
     652          40 : }
     653             : 
     654             : 
     655          50 : void SAL_CALL PasswordContainer::addPersistent( const OUString& Url, const OUString& UserName, const Sequence< OUString >& Passwords, const Reference< XInteractionHandler >& aHandler  ) throw(RuntimeException, std::exception)
     656             : {
     657          50 :     ::osl::MutexGuard aGuard( mMutex );
     658             : 
     659          50 :     PrivateAdd( Url, UserName, Passwords, PERSISTENT_RECORD, aHandler );
     660          50 : }
     661             : 
     662             : 
     663          90 : void PasswordContainer::PrivateAdd( const OUString& Url, const OUString& UserName, const Sequence< OUString >& Passwords, char Mode, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
     664             : {
     665          90 :     NamePassRecord aRecord( UserName );
     666          96 :     ::std::vector< OUString > aStorePass = copySequenceToVector( Passwords );
     667             : 
     668          90 :     if( Mode == PERSISTENT_RECORD )
     669          50 :         aRecord.SetPersPasswords( EncodePasswords( aStorePass, GetMasterPassword( aHandler ) ) );
     670          40 :     else if( Mode == MEMORY_RECORD )
     671          40 :         aRecord.SetMemPasswords( aStorePass );
     672             :     else
     673             :     {
     674             :         OSL_FAIL( "Unexpected persistence status!" );
     675           0 :         return;
     676             :     }
     677             : 
     678          90 :     if( !m_aContainer.empty() )
     679             :     {
     680          84 :         PassMap::iterator aIter = m_aContainer.find( Url );
     681             : 
     682          84 :         if( aIter != m_aContainer.end() )
     683             :         {
     684          84 :             UpdateVector( aIter->first, aIter->second, aRecord, true );
     685          84 :             return;
     686             :         }
     687             :     }
     688             : 
     689          12 :     list< NamePassRecord > listToAdd( 1, aRecord );
     690           6 :     m_aContainer.insert( PairUrlRecord( Url, listToAdd ) );
     691             : 
     692           6 :     if( Mode == PERSISTENT_RECORD && m_pStorageFile && m_pStorageFile->useStorage() )
     693          10 :         m_pStorageFile->update( Url, aRecord );
     694             : 
     695             : }
     696             : 
     697             : 
     698             : 
     699          10 : UrlRecord SAL_CALL PasswordContainer::find( const OUString& aURL, const Reference< XInteractionHandler >& aHandler  ) throw(RuntimeException, std::exception)
     700             : {
     701          10 :     return find( aURL, OUString(), false, aHandler );
     702             : }
     703             : 
     704             : 
     705           0 : UrlRecord SAL_CALL PasswordContainer::findForName( const OUString& aURL, const OUString& aName, const Reference< XInteractionHandler >& aHandler  ) throw(RuntimeException, std::exception)
     706             : {
     707           0 :     return find( aURL, aName, true, aHandler );
     708             : }
     709             : 
     710             : 
     711           0 : Sequence< UserRecord > PasswordContainer::FindUsr( const list< NamePassRecord >& userlist, const OUString& aName, const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
     712             : {
     713           0 :     sal_uInt32 nInd = 0;
     714           0 :     for( list< NamePassRecord >::const_iterator aNPIter = userlist.begin();
     715           0 :          aNPIter != userlist.end();
     716             :          ++aNPIter, ++nInd )
     717             :     {
     718           0 :         if( aNPIter->GetUserName().equals( aName ) )
     719             :         {
     720           0 :             Sequence< UserRecord > aResult(1);
     721           0 :             bool bTryToDecode = true;
     722           0 :             aResult[0] = CopyToUserRecord( *aNPIter, bTryToDecode, aHandler );
     723             : 
     724           0 :             return aResult;
     725             :         }
     726             :     }
     727             : 
     728           0 :     return Sequence< UserRecord >();
     729             : }
     730             : 
     731             : 
     732          10 : bool PasswordContainer::createUrlRecord(
     733             :     const PassMap::iterator & rIter,
     734             :     bool bName,
     735             :     const OUString & aName,
     736             :     const Reference< XInteractionHandler >& aHandler,
     737             :     UrlRecord & rRec )
     738             :         throw( RuntimeException )
     739             : {
     740          10 :     if ( bName )
     741             :     {
     742             :         Sequence< UserRecord > aUsrRec
     743           0 :             = FindUsr( rIter->second, aName, aHandler );
     744           0 :         if( aUsrRec.getLength() )
     745             :         {
     746           0 :             rRec = UrlRecord( rIter->first, aUsrRec );
     747           0 :             return true;
     748           0 :         }
     749             :     }
     750             :     else
     751             :     {
     752          30 :         rRec = UrlRecord(
     753          10 :             rIter->first,
     754          20 :             CopyToUserRecordSequence( rIter->second, aHandler ) );
     755          10 :         return true;
     756             :     }
     757           0 :     return false;
     758             : }
     759             : 
     760             : 
     761          10 : UrlRecord PasswordContainer::find(
     762             :     const OUString& aURL,
     763             :     const OUString& aName,
     764             :     bool bName, // only needed to support empty user names
     765             :     const Reference< XInteractionHandler >& aHandler  ) throw(RuntimeException)
     766             : {
     767          10 :     ::osl::MutexGuard aGuard( mMutex );
     768             : 
     769          10 :     if( !m_aContainer.empty() && !aURL.isEmpty() )
     770             :     {
     771          10 :         OUString aUrl( aURL );
     772             : 
     773             :         // each iteration remove last '/...' section from the aUrl
     774             :         // while it's possible, up to the most left '://'
     775           0 :         do
     776             :         {
     777             :             // first look for <url>/somename and then look for <url>/somename/...
     778          10 :             PassMap::iterator aIter = m_aContainer.find( aUrl );
     779          10 :             if( aIter != m_aContainer.end() )
     780             :             {
     781          10 :                 UrlRecord aRec;
     782          10 :                 if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) )
     783          10 :                   return aRec;
     784             :             }
     785             :             else
     786             :             {
     787           0 :                 OUString tmpUrl( aUrl );
     788           0 :                 if ( !tmpUrl.endsWith("/") )
     789           0 :                     tmpUrl += "/";
     790             : 
     791           0 :                 aIter = m_aContainer.lower_bound( tmpUrl );
     792           0 :                 if( aIter != m_aContainer.end() && aIter->first.match( tmpUrl ) )
     793             :                 {
     794           0 :                     UrlRecord aRec;
     795           0 :                     if ( createUrlRecord( aIter, bName, aName, aHandler, aRec ) )
     796           0 :                       return aRec;
     797           0 :                 }
     798             :             }
     799             :         }
     800           0 :         while( shorterUrl( aUrl ) && !aUrl.isEmpty() );
     801             :     }
     802             : 
     803           0 :     return UrlRecord();
     804             : }
     805             : 
     806           0 : OUString PasswordContainer::GetDefaultMasterPassword()
     807             : {
     808           0 :     OUString aResult;
     809           0 :     for ( sal_Int32 nInd = 0; nInd < RTL_DIGEST_LENGTH_MD5; nInd++ )
     810           0 :         aResult += "aa";
     811             : 
     812           0 :     return aResult;
     813             : }
     814             : 
     815           4 : OUString PasswordContainer::RequestPasswordFromUser( PasswordRequestMode aRMode, const uno::Reference< task::XInteractionHandler >& xHandler )
     816             : {
     817             :     // empty string means that the call was cancelled or just failed
     818           4 :     OUString aResult;
     819             : 
     820           4 :     if ( xHandler.is() )
     821             :     {
     822           4 :         ::rtl::Reference< MasterPasswordRequest_Impl > xRequest = new MasterPasswordRequest_Impl( aRMode );
     823             : 
     824           4 :         xHandler->handle( xRequest.get() );
     825             : 
     826           8 :         ::rtl::Reference< ucbhelper::InteractionContinuation > xSelection = xRequest->getSelection();
     827             : 
     828           4 :         if ( xSelection.is() )
     829             :         {
     830           4 :             Reference< XInteractionAbort > xAbort( xSelection.get(), UNO_QUERY );
     831           4 :             if ( !xAbort.is() )
     832             :             {
     833             :                 const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & xSupp
     834           4 :                             = xRequest->getAuthenticationSupplier();
     835             : 
     836           4 :                 aResult = xSupp->getPassword();
     837           4 :             }
     838           4 :         }
     839             :     }
     840             : 
     841           4 :     return aResult;
     842             : }
     843             : 
     844             : 
     845          90 : OUString PasswordContainer::GetMasterPassword( const Reference< XInteractionHandler >& aHandler ) throw(RuntimeException)
     846             : {
     847          90 :     PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER;
     848          90 :     if( !m_pStorageFile || !m_pStorageFile->useStorage() )
     849           0 :         throw NoMasterException("Password storing is not active!", Reference< XInterface >(), aRMode );
     850             : 
     851          90 :     if( m_aMasterPasswd.isEmpty() && aHandler.is() )
     852             :     {
     853           4 :         OUString aEncodedMP;
     854           4 :         bool bAskAgain = false;
     855           4 :         bool bDefaultPassword = false;
     856             : 
     857           4 :         if( !m_pStorageFile->getEncodedMP( aEncodedMP ) )
     858           4 :             aRMode = PasswordRequestMode_PASSWORD_CREATE;
     859           0 :         else if ( aEncodedMP.isEmpty() )
     860             :         {
     861           0 :             m_aMasterPasswd = GetDefaultMasterPassword();
     862           0 :             bDefaultPassword = true;
     863             :         }
     864             : 
     865           4 :         if ( !bDefaultPassword )
     866             :         {
     867           4 :             do {
     868           4 :                 bAskAgain = false;
     869             : 
     870           4 :                 OUString aPass = RequestPasswordFromUser( aRMode, aHandler );
     871           4 :                 if ( !aPass.isEmpty() )
     872             :                 {
     873           4 :                     if( aRMode == PasswordRequestMode_PASSWORD_CREATE )
     874             :                     {
     875           4 :                         m_aMasterPasswd = aPass;
     876           4 :                         vector< OUString > aMaster( 1, m_aMasterPasswd );
     877             : 
     878           4 :                         m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) );
     879             :                     }
     880             :                     else
     881             :                     {
     882           0 :                         vector< OUString > aRM( DecodePasswords( aEncodedMP, aPass ) );
     883           0 :                         if( aRM.empty() || !aPass.equals( aRM[0] ) )
     884             :                         {
     885           0 :                             bAskAgain = true;
     886           0 :                             aRMode = PasswordRequestMode_PASSWORD_REENTER;
     887             :                         }
     888             :                         else
     889           0 :                             m_aMasterPasswd = aPass;
     890             :                     }
     891           4 :                 }
     892             : 
     893             :             } while( bAskAgain );
     894           4 :         }
     895             :     }
     896             : 
     897          90 :     if ( m_aMasterPasswd.isEmpty() )
     898           0 :         throw NoMasterException("No master password!", Reference< XInterface >(), aRMode );
     899             : 
     900          90 :     return m_aMasterPasswd;
     901             : }
     902             : 
     903             : 
     904          70 : void SAL_CALL PasswordContainer::remove( const OUString& aURL, const OUString& aName ) throw(RuntimeException, std::exception)
     905             : {
     906          70 :     ::osl::MutexGuard aGuard( mMutex );
     907             : 
     908          80 :     OUString aUrl( aURL );
     909          70 :     if( !m_aContainer.empty() )
     910             :     {
     911          60 :         PassMap::iterator aIter = m_aContainer.find( aUrl );
     912             : 
     913          60 :         if( aIter == m_aContainer.end() )
     914             :         {
     915           0 :             if( aUrl.endsWith("/") )
     916           0 :                 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 );
     917             :             else
     918           0 :                 aUrl += "/";
     919             : 
     920           0 :             aIter = m_aContainer.find( aUrl );
     921             :         }
     922             : 
     923          60 :         if( aIter != m_aContainer.end() )
     924             :         {
     925         440 :             for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ++aNPIter )
     926         440 :                 if( aNPIter->GetUserName().equals( aName ) )
     927             :                 {
     928          60 :                     if( aNPIter->HasPasswords( PERSISTENT_RECORD ) && m_pStorageFile )
     929          20 :                         m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName )
     930             : 
     931             :                     // the iterator will not be used any more so it can be removed directly
     932          60 :                     aIter->second.erase( aNPIter );
     933             : 
     934          60 :                     if( aIter->second.begin() == aIter->second.end() )
     935           4 :                         m_aContainer.erase( aIter );
     936             : 
     937         130 :                     return;
     938             :                 }
     939             :         }
     940          10 :     }
     941             : }
     942             : 
     943             : 
     944           0 : void SAL_CALL PasswordContainer::removePersistent( const OUString& aURL, const OUString& aName ) throw(RuntimeException, std::exception)
     945             : {
     946           0 :     ::osl::MutexGuard aGuard( mMutex );
     947             : 
     948           0 :     OUString aUrl( aURL );
     949           0 :     if( !m_aContainer.empty() )
     950             :     {
     951           0 :         PassMap::iterator aIter = m_aContainer.find( aUrl );
     952             : 
     953           0 :         if( aIter == m_aContainer.end() )
     954             :         {
     955           0 :             if( aUrl.endsWith("/") )
     956           0 :                 aUrl = aUrl.copy( 0, aUrl.getLength() - 1 );
     957             :             else
     958           0 :                 aUrl += "/";
     959             : 
     960           0 :             aIter = m_aContainer.find( aUrl );
     961             :         }
     962             : 
     963           0 :         if( aIter != m_aContainer.end() )
     964             :         {
     965           0 :             for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ++aNPIter )
     966           0 :                 if( aNPIter->GetUserName().equals( aName ) )
     967             :                 {
     968           0 :                     if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
     969             :                     {
     970             :                         // TODO/LATER: should the password be converted to MemoryPassword?
     971           0 :                         aNPIter->RemovePasswords( PERSISTENT_RECORD );
     972             : 
     973           0 :                         if ( m_pStorageFile )
     974           0 :                             m_pStorageFile->remove( aURL, aName ); // remove record ( aURL, aName )
     975             :                     }
     976             : 
     977           0 :                     if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
     978           0 :                         aIter->second.erase( aNPIter );
     979             : 
     980           0 :                     if( aIter->second.begin() == aIter->second.end() )
     981           0 :                         m_aContainer.erase( aIter );
     982             : 
     983           0 :                     return;
     984             :                 }
     985             :         }
     986           0 :     }
     987             : }
     988             : 
     989           8 : void SAL_CALL PasswordContainer::removeAllPersistent() throw(RuntimeException, std::exception)
     990             : {
     991           8 :     ::osl::MutexGuard aGuard( mMutex );
     992             : 
     993           8 :     if( m_pStorageFile )
     994           8 :         m_pStorageFile->clear();
     995             : 
     996          20 :     for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); )
     997             :     {
     998          48 :         for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); )
     999             :         {
    1000          40 :             if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
    1001             :             {
    1002             :                 // TODO/LATER: should the password be converted to MemoryPassword?
    1003          30 :                 aNPIter->RemovePasswords( PERSISTENT_RECORD );
    1004             : 
    1005          30 :                 if ( m_pStorageFile )
    1006          30 :                     m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName )
    1007             :             }
    1008             : 
    1009          40 :             if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
    1010             :             {
    1011          30 :                 list< NamePassRecord >::iterator aIterToDelete( aNPIter );
    1012          30 :                 ++aNPIter;
    1013          30 :                 aIter->second.erase( aIterToDelete );
    1014             :             }
    1015             :             else
    1016          10 :                 ++aNPIter;
    1017             :         }
    1018             : 
    1019           4 :         if( aIter->second.begin() == aIter->second.end() )
    1020             :         {
    1021           2 :             PassMap::iterator aIterToDelete( aIter );
    1022           2 :             ++aIter;
    1023           2 :             m_aContainer.erase( aIterToDelete );
    1024             :         }
    1025             :         else
    1026           2 :             ++aIter;
    1027           8 :     }
    1028           8 : }
    1029             : 
    1030           2 : Sequence< UrlRecord > SAL_CALL PasswordContainer::getAllPersistent( const Reference< XInteractionHandler >& xHandler ) throw(RuntimeException, std::exception)
    1031             : {
    1032           2 :     Sequence< UrlRecord > aResult;
    1033             : 
    1034           4 :     ::osl::MutexGuard aGuard( mMutex );
    1035           4 :     for( PassMap::iterator aIter = m_aContainer.begin(); aIter != m_aContainer.end(); ++aIter )
    1036             :     {
    1037           2 :         Sequence< UserRecord > aUsers;
    1038          12 :         for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ++aNPIter )
    1039          10 :             if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
    1040             :             {
    1041          10 :                 sal_Int32 oldLen = aUsers.getLength();
    1042          10 :                 aUsers.realloc( oldLen + 1 );
    1043          10 :                 aUsers[ oldLen ] = UserRecord( aNPIter->GetUserName(), copyVectorToSequence( DecodePasswords( aNPIter->GetPersPasswords(), GetMasterPassword( xHandler ) ) ) );
    1044             :             }
    1045             : 
    1046           2 :         if( aUsers.getLength() )
    1047             :         {
    1048           2 :             sal_Int32 oldLen = aResult.getLength();
    1049           2 :             aResult.realloc( oldLen + 1 );
    1050           2 :             aResult[ oldLen ] = UrlRecord( aIter->first, aUsers );
    1051             :         }
    1052           2 :     }
    1053             : 
    1054           4 :     return aResult;
    1055             : }
    1056             : 
    1057           0 : sal_Bool SAL_CALL PasswordContainer::authorizateWithMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
    1058             :     throw (uno::RuntimeException, std::exception)
    1059             : {
    1060           0 :     bool bResult = false;
    1061           0 :     OUString aEncodedMP;
    1062           0 :     uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
    1063           0 :     ::osl::MutexGuard aGuard( mMutex );
    1064             : 
    1065             :     // the method should fail if there is no master password
    1066           0 :     if( m_pStorageFile && m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) )
    1067             :     {
    1068           0 :         if ( aEncodedMP.isEmpty() )
    1069             :         {
    1070             :             // this is a default master password
    1071             :             // no UI is necessary
    1072           0 :             bResult = true;
    1073             :         }
    1074             :         else
    1075             :         {
    1076           0 :             if ( !xTmpHandler.is() )
    1077             :             {
    1078           0 :                 uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
    1079           0 :                 uno::Reference< uno::XComponentContext > xContext( comphelper::getComponentContext(xFactory) );
    1080           0 :                 xTmpHandler.set( InteractionHandler::createWithParent(xContext, 0), uno::UNO_QUERY_THROW );
    1081             :             }
    1082             : 
    1083           0 :             if ( !m_aMasterPasswd.isEmpty() )
    1084             :             {
    1085             :                 // there is a password, it should be just rechecked
    1086           0 :                 PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_ENTER;
    1087           0 :                 OUString aPass;
    1088             : 
    1089           0 :                 do {
    1090           0 :                     aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
    1091           0 :                     bResult = ( !aPass.isEmpty() && aPass.equals( m_aMasterPasswd ) );
    1092           0 :                     aRMode = PasswordRequestMode_PASSWORD_REENTER; // further questions with error notification
    1093           0 :                 } while( !bResult && !aPass.isEmpty() );
    1094             :             }
    1095             :             else
    1096             :             {
    1097             :                 try
    1098             :                 {
    1099             :                     // ask for the password, if user provide no correct password an exception will be thrown
    1100           0 :                     bResult = !GetMasterPassword( xTmpHandler ).isEmpty();
    1101             :                 }
    1102           0 :                 catch( uno::Exception& )
    1103             :                 {}
    1104             :             }
    1105             :         }
    1106             :     }
    1107             : 
    1108           0 :     return bResult;
    1109             : }
    1110             : 
    1111           0 : sal_Bool SAL_CALL PasswordContainer::changeMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
    1112             :     throw (uno::RuntimeException, std::exception)
    1113             : {
    1114           0 :     bool bResult = false;
    1115           0 :     uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
    1116           0 :     ::osl::MutexGuard aGuard( mMutex );
    1117             : 
    1118           0 :     if ( m_pStorageFile && m_pStorageFile->useStorage() )
    1119             :     {
    1120           0 :         if ( !xTmpHandler.is() )
    1121             :         {
    1122           0 :             uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
    1123           0 :             uno::Reference< uno::XComponentContext > xContext( comphelper::getComponentContext(xFactory) );
    1124           0 :             xTmpHandler.set( InteractionHandler::createWithParent(xContext, 0), uno::UNO_QUERY_THROW );
    1125             :         }
    1126             : 
    1127           0 :         bool bCanChangePassword = true;
    1128             :         // if there is already a stored master password it should be entered by the user before the change happen
    1129           0 :         OUString aEncodedMP;
    1130           0 :         if( !m_aMasterPasswd.isEmpty() || m_pStorageFile->getEncodedMP( aEncodedMP ) )
    1131           0 :             bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
    1132             : 
    1133           0 :         if ( bCanChangePassword )
    1134             :         {
    1135             :             // ask for the new password, but do not set it
    1136           0 :             PasswordRequestMode aRMode = PasswordRequestMode_PASSWORD_CREATE;
    1137           0 :             OUString aPass = RequestPasswordFromUser( aRMode, xTmpHandler );
    1138             : 
    1139           0 :             if ( !aPass.isEmpty() )
    1140             :             {
    1141             :                 // get all the persistent entries if it is possible
    1142           0 :                 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() );
    1143             : 
    1144             :                 // remove the master password and the entries persistence
    1145           0 :                 removeMasterPassword();
    1146             : 
    1147             :                 // store the new master password
    1148           0 :                 m_aMasterPasswd = aPass;
    1149           0 :                 vector< OUString > aMaster( 1, m_aMasterPasswd );
    1150           0 :                 m_pStorageFile->setEncodedMP( EncodePasswords( aMaster, m_aMasterPasswd ) );
    1151             : 
    1152             :                 // store all the entries with the new password
    1153           0 :                 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ )
    1154           0 :                     for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ )
    1155           0 :                         addPersistent( aPersistent[nURLInd].Url,
    1156           0 :                                        aPersistent[nURLInd].UserList[nNameInd].UserName,
    1157           0 :                                        aPersistent[nURLInd].UserList[nNameInd].Passwords,
    1158           0 :                                        uno::Reference< task::XInteractionHandler >() );
    1159             : 
    1160           0 :                 bResult = true;
    1161           0 :             }
    1162           0 :         }
    1163             :     }
    1164             : 
    1165           0 :     return bResult;
    1166             : }
    1167             : 
    1168           4 : void SAL_CALL PasswordContainer::removeMasterPassword()
    1169             :     throw (uno::RuntimeException, std::exception)
    1170             : {
    1171             :     // remove all the stored passwords and the master password
    1172           4 :     removeAllPersistent();
    1173             : 
    1174           4 :     ::osl::MutexGuard aGuard( mMutex );
    1175           4 :     if ( m_pStorageFile )
    1176             :     {
    1177           4 :         m_aMasterPasswd = "";
    1178           4 :         m_pStorageFile->setEncodedMP( OUString() ); // let the master password be removed from configuration
    1179           4 :     }
    1180           4 : }
    1181             : 
    1182           0 : sal_Bool SAL_CALL PasswordContainer::hasMasterPassword(  )
    1183             :     throw (::com::sun::star::uno::RuntimeException, std::exception)
    1184             : {
    1185           0 :     ::osl::MutexGuard aGuard( mMutex );
    1186             : 
    1187           0 :     if ( !m_pStorageFile )
    1188           0 :         throw uno::RuntimeException();
    1189             : 
    1190           0 :     OUString aEncodedMP;
    1191           0 :     return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) );
    1192             : }
    1193             : 
    1194           8 : sal_Bool SAL_CALL PasswordContainer::allowPersistentStoring( sal_Bool bAllow )
    1195             :     throw (::com::sun::star::uno::RuntimeException, std::exception)
    1196             : {
    1197           8 :     ::osl::MutexGuard aGuard( mMutex );
    1198             : 
    1199           8 :     if ( !m_pStorageFile )
    1200           0 :         throw uno::RuntimeException();
    1201             : 
    1202           8 :     if ( !bAllow )
    1203           4 :         removeMasterPassword();
    1204             : 
    1205           8 :     if (m_pStorageFile->useStorage() == static_cast<bool>(bAllow))
    1206           0 :         return bAllow;
    1207             : 
    1208           8 :     m_pStorageFile->setUseStorage( bAllow );
    1209           8 :     return !bAllow;
    1210             : }
    1211             : 
    1212           0 : sal_Bool SAL_CALL PasswordContainer::isPersistentStoringAllowed()
    1213             :     throw (::com::sun::star::uno::RuntimeException, std::exception)
    1214             : {
    1215           0 :     ::osl::MutexGuard aGuard( mMutex );
    1216             : 
    1217           0 :     if ( !m_pStorageFile )
    1218           0 :         throw uno::RuntimeException();
    1219             : 
    1220           0 :     return m_pStorageFile->useStorage();
    1221             : }
    1222             : 
    1223           0 : sal_Bool SAL_CALL PasswordContainer::useDefaultMasterPassword( const uno::Reference< task::XInteractionHandler >& xHandler )
    1224             :     throw ( uno::RuntimeException, std::exception )
    1225             : {
    1226           0 :     bool bResult = false;
    1227           0 :     uno::Reference< task::XInteractionHandler > xTmpHandler = xHandler;
    1228           0 :     ::osl::MutexGuard aGuard( mMutex );
    1229             : 
    1230           0 :     if ( m_pStorageFile && m_pStorageFile->useStorage() )
    1231             :     {
    1232           0 :         if ( !xTmpHandler.is() )
    1233             :         {
    1234           0 :             uno::Reference< lang::XMultiServiceFactory > xFactory( mComponent, uno::UNO_QUERY_THROW );
    1235           0 :             uno::Reference< uno::XComponentContext > xContext( comphelper::getComponentContext(xFactory) );
    1236           0 :             xTmpHandler.set( InteractionHandler::createWithParent(xContext, 0), uno::UNO_QUERY_THROW );
    1237             :         }
    1238             : 
    1239           0 :         bool bCanChangePassword = true;
    1240             :         // if there is already a stored nondefault master password it should be entered by the user before the change happen
    1241           0 :         OUString aEncodedMP;
    1242           0 :         if( m_pStorageFile->getEncodedMP( aEncodedMP ) && !aEncodedMP.isEmpty() )
    1243           0 :             bCanChangePassword = authorizateWithMasterPassword( xTmpHandler );
    1244             : 
    1245           0 :         if ( bCanChangePassword )
    1246             :         {
    1247             :             // generate the default password
    1248           0 :             OUString aPass = GetDefaultMasterPassword();
    1249           0 :             if ( !aPass.isEmpty() )
    1250             :             {
    1251             :                 // get all the persistent entries if it is possible
    1252           0 :                 Sequence< UrlRecord > aPersistent = getAllPersistent( uno::Reference< task::XInteractionHandler >() );
    1253             : 
    1254             :                 // remove the master password and the entries persistence
    1255           0 :                 removeMasterPassword();
    1256             : 
    1257             :                 // store the empty string to flag the default master password
    1258           0 :                 m_aMasterPasswd = aPass;
    1259           0 :                 m_pStorageFile->setEncodedMP( OUString(), true );
    1260             : 
    1261             :                 // store all the entries with the new password
    1262           0 :                 for ( int nURLInd = 0; nURLInd < aPersistent.getLength(); nURLInd++ )
    1263           0 :                     for ( int nNameInd = 0; nNameInd< aPersistent[nURLInd].UserList.getLength(); nNameInd++ )
    1264           0 :                         addPersistent( aPersistent[nURLInd].Url,
    1265           0 :                                        aPersistent[nURLInd].UserList[nNameInd].UserName,
    1266           0 :                                        aPersistent[nURLInd].UserList[nNameInd].Passwords,
    1267           0 :                                        uno::Reference< task::XInteractionHandler >() );
    1268             : 
    1269           0 :                 bResult = true;
    1270           0 :             }
    1271           0 :         }
    1272             :     }
    1273             : 
    1274           0 :     return bResult;
    1275             : 
    1276             : }
    1277             : 
    1278           0 : sal_Bool SAL_CALL PasswordContainer::isDefaultMasterPasswordUsed()
    1279             :     throw ( uno::RuntimeException, std::exception )
    1280             : {
    1281           0 :     ::osl::MutexGuard aGuard( mMutex );
    1282             : 
    1283           0 :     if ( !m_pStorageFile )
    1284           0 :         throw uno::RuntimeException();
    1285             : 
    1286           0 :     OUString aEncodedMP;
    1287           0 :     return ( m_pStorageFile->useStorage() && m_pStorageFile->getEncodedMP( aEncodedMP ) && aEncodedMP.isEmpty() );
    1288             : }
    1289             : 
    1290             : 
    1291           0 : void SAL_CALL PasswordContainer::addUrl( const OUString& Url, sal_Bool MakePersistent )
    1292             :     throw (uno::RuntimeException, std::exception)
    1293             : {
    1294           0 :     mUrlContainer.add( Url, MakePersistent );
    1295           0 : }
    1296             : 
    1297           0 : OUString SAL_CALL PasswordContainer::findUrl( const OUString& Url )
    1298             :     throw (uno::RuntimeException, std::exception)
    1299             : {
    1300           0 :     return mUrlContainer.find( Url );
    1301             : }
    1302             : 
    1303           0 : void SAL_CALL PasswordContainer::removeUrl( const OUString& Url )
    1304             :     throw (uno::RuntimeException, std::exception)
    1305             : {
    1306           0 :     mUrlContainer.remove( Url );
    1307           0 : }
    1308             : 
    1309           0 : uno::Sequence< OUString > SAL_CALL PasswordContainer::getUrls( sal_Bool OnlyPersistent )
    1310             :     throw (uno::RuntimeException, std::exception)
    1311             : {
    1312           0 :     return mUrlContainer.list( OnlyPersistent );
    1313             : }
    1314             : 
    1315             : 
    1316           0 : void PasswordContainer::Notify()
    1317             : {
    1318           0 :     ::osl::MutexGuard aGuard( mMutex );
    1319             : 
    1320           0 :     PassMap::iterator aIter;
    1321             : 
    1322             :     // remove the cached persistent values in the memory
    1323           0 :     for( aIter = m_aContainer.begin(); aIter != m_aContainer.end(); ++aIter )
    1324             :     {
    1325           0 :         for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); )
    1326             :         {
    1327           0 :             if( aNPIter->HasPasswords( PERSISTENT_RECORD ) )
    1328             :             {
    1329           0 :                 aNPIter->RemovePasswords( PERSISTENT_RECORD );
    1330             : 
    1331           0 :                 if ( m_pStorageFile )
    1332           0 :                     m_pStorageFile->remove( aIter->first, aNPIter->GetUserName() ); // remove record ( aURL, aName )
    1333             :             }
    1334             : 
    1335           0 :             if( !aNPIter->HasPasswords( MEMORY_RECORD ) )
    1336             :             {
    1337           0 :                 list< NamePassRecord >::iterator aIterToDelete( aNPIter );
    1338           0 :                 ++aNPIter;
    1339           0 :                 aIter->second.erase( aIterToDelete );
    1340             :             }
    1341             :             else
    1342           0 :                 ++aNPIter;
    1343             :         }
    1344             :     }
    1345             : 
    1346           0 :     PassMap addon;
    1347           0 :     if( m_pStorageFile )
    1348           0 :         addon = m_pStorageFile->getInfo();
    1349             : 
    1350           0 :     for( aIter = addon.begin(); aIter != addon.end(); ++aIter )
    1351             :     {
    1352           0 :         PassMap::iterator aSearchIter = m_aContainer.find( aIter->first );
    1353           0 :         if( aSearchIter != m_aContainer.end() )
    1354           0 :             for( list< NamePassRecord >::iterator aNPIter = aIter->second.begin(); aNPIter != aIter->second.end(); ++aNPIter )
    1355           0 :                 UpdateVector( aSearchIter->first, aSearchIter->second, *aNPIter, false );
    1356             :         else
    1357           0 :             m_aContainer.insert( PairUrlRecord( aIter->first, aIter->second ) );
    1358           0 :     }
    1359           0 : }
    1360             : 
    1361           0 : OUString SAL_CALL PasswordContainer::getImplementationName(  ) throw(uno::RuntimeException, std::exception)
    1362             : {
    1363           0 :     return impl_getStaticImplementationName();
    1364             : }
    1365             : 
    1366           0 : sal_Bool SAL_CALL PasswordContainer::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException, std::exception)
    1367             : {
    1368           0 :     return cppu::supportsService( this,  ServiceName );
    1369             : }
    1370             : 
    1371           0 : Sequence< OUString > SAL_CALL PasswordContainer::getSupportedServiceNames(  ) throw(uno::RuntimeException, std::exception)
    1372             : {
    1373           0 :     return impl_getStaticSupportedServiceNames();
    1374             : }
    1375             : 
    1376           4 : Sequence< OUString > SAL_CALL PasswordContainer::impl_getStaticSupportedServiceNames(  ) throw(uno::RuntimeException)
    1377             : {
    1378           4 :     Sequence< OUString > aRet(1);
    1379           4 :     aRet[0] = "com.sun.star.task.PasswordContainer";
    1380           4 :     return aRet;
    1381             : }
    1382             : 
    1383           8 : OUString SAL_CALL PasswordContainer::impl_getStaticImplementationName() throw(uno::RuntimeException)
    1384             : {
    1385           8 :     return OUString("stardiv.svl.PasswordContainer");
    1386             : }
    1387             : 
    1388             : 
    1389           4 : Reference< XInterface > SAL_CALL PasswordContainer::impl_createInstance( const Reference< XMultiServiceFactory >& xServiceManager ) throw( RuntimeException )
    1390             : {
    1391           4 :     return Reference< XInterface >( *new PasswordContainer( xServiceManager ) );
    1392             : }
    1393             : 
    1394             : 
    1395           4 : Reference< XSingleServiceFactory > SAL_CALL PasswordContainer::impl_createFactory( const Reference< XMultiServiceFactory >& ServiceManager ) throw(RuntimeException)
    1396             : {
    1397             :     Reference< XSingleServiceFactory > xReturn( ::cppu::createOneInstanceFactory( ServiceManager,
    1398             :                                                         PasswordContainer::impl_getStaticImplementationName(),
    1399             :                                                         PasswordContainer::impl_createInstance,
    1400           4 :                                                         PasswordContainer::impl_getStaticSupportedServiceNames()));
    1401           4 :     return xReturn ;
    1402             : 
    1403             : }
    1404             : 
    1405             : 
    1406           4 : MasterPasswordRequest_Impl::MasterPasswordRequest_Impl( PasswordRequestMode Mode )
    1407             : {
    1408           4 :     MasterPasswordRequest aRequest;
    1409             : 
    1410           4 :     aRequest.Classification = InteractionClassification_ERROR;
    1411           4 :     aRequest.Mode = Mode;
    1412             : 
    1413           4 :     setRequest( makeAny( aRequest ) );
    1414             : 
    1415             :     // Fill continuations...
    1416           8 :     Sequence< RememberAuthentication > aRememberModes( 1 );
    1417           4 :     aRememberModes[ 0 ] = RememberAuthentication_NO;
    1418             : 
    1419             :     m_xAuthSupplier
    1420           8 :         = new ::ucbhelper::InteractionSupplyAuthentication(
    1421             :                 this,
    1422             :                 false, // bCanSetRealm
    1423             :                 false,  // bCanSetUserName
    1424             :                 true,  // bCanSetPassword
    1425             :                 false, // bCanSetAccount
    1426             :                 aRememberModes, // rRememberPasswordModes
    1427             :                 RememberAuthentication_NO, // eDefaultRememberPasswordMode
    1428             :                 aRememberModes, // rRememberAccountModes
    1429             :                 RememberAuthentication_NO, // eDefaultRememberAccountMode
    1430             :                 false, // bCanUseSystemCredentials
    1431             :                 false  // bDefaultUseSystemCredentials
    1432           8 :             );
    1433             : 
    1434             :     Sequence<
    1435           8 :         Reference< XInteractionContinuation > > aContinuations( 3 );
    1436           4 :     aContinuations[ 0 ] = new ::ucbhelper::InteractionAbort( this );
    1437           4 :     aContinuations[ 1 ] = new ::ucbhelper::InteractionRetry( this );
    1438           4 :     aContinuations[ 2 ] = m_xAuthSupplier.get();
    1439             : 
    1440           8 :     setContinuations( aContinuations );
    1441           4 : }
    1442             : 
    1443             : 
    1444             : extern "C"
    1445             : {
    1446           4 : SAL_DLLPUBLIC_EXPORT void * SAL_CALL passwordcontainer_component_getFactory (
    1447             :     const sal_Char * pImplementationName,
    1448             :     SAL_UNUSED_PARAMETER void * pServiceManager,
    1449             :     SAL_UNUSED_PARAMETER void * /* pRegistryKey */)
    1450             : {
    1451           4 :     void * pResult = 0;
    1452           4 :     if (pServiceManager)
    1453             :     {
    1454           4 :         Reference< XSingleServiceFactory > xFactory;
    1455           4 :         if (PasswordContainer::impl_getStaticImplementationName().equalsAscii(pImplementationName))
    1456             :         {
    1457           8 :             xFactory = PasswordContainer::impl_createFactory (
    1458           4 :                 reinterpret_cast< XMultiServiceFactory* >(pServiceManager));
    1459             :         }
    1460           4 :         if (xFactory.is())
    1461             :         {
    1462           4 :             xFactory->acquire();
    1463           4 :             pResult = xFactory.get();
    1464           4 :         }
    1465             :     }
    1466           4 :     return pResult;
    1467             : }
    1468             : 
    1469             : } // extern "C"
    1470             : 
    1471             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10