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