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

Generated by: LCOV version 1.11