1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 #ifndef INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX
28 #define INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX
29 
30 #include <list>
31 #include <vector>
32 #include <map>
33 #include <com/sun/star/task/XPasswordContainer.hpp>
34 #include <com/sun/star/task/XUrlContainer.hpp>
35 #include <com/sun/star/task/PasswordRequestMode.hpp>
36 #include <com/sun/star/lang/XServiceInfo.hpp>
37 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
38 #include <com/sun/star/lang/XEventListener.hpp>
39 #include <com/sun/star/lang/XComponent.hpp>
40 #include <com/sun/star/task/XMasterPasswordHandling2.hpp>
41 #include <cppuhelper/implbase5.hxx>
42 #include <cppuhelper/typeprovider.hxx>
43 #include <cppuhelper/queryinterface.hxx>
44 #include <cppuhelper/factory.hxx>
45 
46 #include <tools/stream.hxx>
47 #include <unotools/configitem.hxx>
48 #include <ucbhelper/interactionrequest.hxx>
49 
50 #include <rtl/ref.hxx>
51 #include <osl/mutex.hxx>
52 
53 #include "syscreds.hxx"
54 
55 #define MEMORY_RECORD         0
56 #define PERSISTENT_RECORD     1
57 
58 //----------------------------------------------------------------------------------
59 
60 class NamePassRecord
61 {
62     ::rtl::OUString                                     m_aName;
63 
64     // there are two lists of passwords, memory passwords and persistent passwords
65     sal_Bool                                              m_bHasMemPass;
66     ::std::vector< ::rtl::OUString >                      m_aMemPass;
67 
68     // persistent passwords are encrypted in one string
69     sal_Bool                                              m_bHasPersPass;
70     ::rtl::OUString                                       m_aPersPass;
71 
72     void InitArrays( sal_Bool bHasMemoryList, const ::std::vector< ::rtl::OUString >& aMemoryList,
73                      sal_Bool bHasPersistentList, const ::rtl::OUString& aPersistentList )
74     {
75         m_bHasMemPass = bHasMemoryList;
76         if ( bHasMemoryList )
77             m_aMemPass = aMemoryList;
78 
79         m_bHasPersPass = bHasPersistentList;
80         if ( bHasPersistentList )
81             m_aPersPass = aPersistentList;
82     }
83 
84 public:
85 
86     NamePassRecord( const ::rtl::OUString& aName )
87         : m_aName( aName )
88         , m_bHasMemPass( sal_False )
89         , m_bHasPersPass( sal_False )
90     {
91     }
92 
93     NamePassRecord( const ::rtl::OUString& aName, const ::std::vector< ::rtl::OUString >& aMemoryList )
94         : m_aName( aName )
95         , m_bHasMemPass( sal_True )
96         , m_aMemPass( aMemoryList )
97         , m_bHasPersPass( sal_False )
98     {
99     }
100 
101     NamePassRecord( const ::rtl::OUString& aName, const ::rtl::OUString& aPersistentList )
102         : m_aName( aName )
103         , m_bHasMemPass( sal_False )
104         , m_bHasPersPass( sal_True )
105         , m_aPersPass( aPersistentList )
106     {
107     }
108 
109     NamePassRecord( const ::rtl::OUString& aName,
110                     sal_Bool bHasMemoryList, const ::std::vector< ::rtl::OUString >& aMemoryList,
111                     sal_Bool bHasPersistentList, const ::rtl::OUString aPersistentList )
112         : m_aName( aName )
113         , m_bHasMemPass( bHasMemoryList )
114         , m_bHasPersPass( bHasPersistentList )
115     {
116         InitArrays( bHasMemoryList, aMemoryList, bHasPersistentList, aPersistentList );
117     }
118 
119     NamePassRecord( const NamePassRecord& aRecord )
120         : m_aName( aRecord.m_aName )
121         , m_bHasMemPass( sal_False )
122         , m_bHasPersPass( sal_False )
123     {
124         InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass, aRecord.m_bHasPersPass, aRecord.m_aPersPass );
125     }
126 
127     NamePassRecord& operator=( const NamePassRecord& aRecord )
128     {
129         m_aName = aRecord.m_aName;
130 
131         m_aMemPass.clear();
132         m_aPersPass = ::rtl::OUString();
133         InitArrays( aRecord.m_bHasMemPass, aRecord.m_aMemPass, aRecord.m_bHasPersPass, aRecord.m_aPersPass );
134 
135         return *this;
136     }
137 
138     ::rtl::OUString GetUserName() const
139     {
140         return m_aName;
141     }
142 
143     sal_Bool HasPasswords( sal_Int8 nStatus ) const
144     {
145         if ( nStatus == MEMORY_RECORD )
146             return m_bHasMemPass;
147         if ( nStatus == PERSISTENT_RECORD )
148             return m_bHasPersPass;
149 
150         return sal_False;
151     }
152 
153     ::std::vector< ::rtl::OUString > GetMemPasswords() const
154     {
155         if ( m_bHasMemPass )
156             return m_aMemPass;
157 
158         return ::std::vector< ::rtl::OUString >();
159     }
160 
161     ::rtl::OUString GetPersPasswords() const
162     {
163         if ( m_bHasPersPass )
164             return m_aPersPass;
165 
166         return ::rtl::OUString();
167     }
168 
169     void SetMemPasswords( const ::std::vector< ::rtl::OUString >& aMemList )
170     {
171         m_aMemPass = aMemList;
172         m_bHasMemPass = sal_True;
173     }
174 
175     void SetPersPasswords( const ::rtl::OUString& aPersList )
176     {
177         m_aPersPass = aPersList;
178         m_bHasPersPass = sal_True;
179     }
180 
181     void RemovePasswords( sal_Int8 nStatus )
182     {
183         if ( nStatus == MEMORY_RECORD )
184         {
185             m_bHasMemPass = sal_False;
186             m_aMemPass.clear();
187         }
188         else if ( nStatus == PERSISTENT_RECORD )
189         {
190             m_bHasPersPass = sal_False;
191             m_aPersPass = ::rtl::OUString();
192         }
193     }
194 
195 };
196 
197 //----------------------------------------------------------------------------------
198 
199 typedef ::std::pair< const ::rtl::OUString, ::std::list< NamePassRecord > > PairUrlRecord;
200 typedef ::std::map< ::rtl::OUString, ::std::list< NamePassRecord > > PassMap;
201 
202 //----------------------------------------------------------------------------------
203 
204 class PasswordContainer;
205 
206 class StorageItem : public ::utl::ConfigItem {
207     PasswordContainer*  mainCont;
208     sal_Bool            hasEncoded;
209     ::rtl::OUString        mEncoded;
210 public:
211     StorageItem( PasswordContainer* point, const ::rtl::OUString& path ) :
212         ConfigItem( path, CONFIG_MODE_IMMEDIATE_UPDATE ),
213         mainCont( point ),
214         hasEncoded( sal_False )
215     {
216         ::com::sun::star::uno::Sequence< ::rtl::OUString > aNode( 1 );
217         *aNode.getArray()  = path;
218         *aNode.getArray() += ::rtl::OUString::createFromAscii( "/Store" );
219         EnableNotification( aNode );
220     }
221 
222     PassMap getInfo();
223     void update( const ::rtl::OUString& url, const NamePassRecord& rec );
224     void remove( const ::rtl::OUString& url, const ::rtl::OUString& rec );
225     void clear();
226 
227     sal_Bool getEncodedMP( ::rtl::OUString& aResult );
228     void setEncodedMP( const ::rtl::OUString& aResult, sal_Bool bAcceptEnmpty = sal_False );
229     void setUseStorage( sal_Bool bUse );
230     sal_Bool useStorage();
231 
232     virtual void            Notify( const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPropertyNames );
233     virtual void            Commit();
234 };
235 
236 //----------------------------------------------------------------------------------
237 
238 enum PasswordState {
239     no_password,
240     entered,
241     cancelled
242 };
243 
244 class PasswordContainer : public ::cppu::WeakImplHelper5<
245         ::com::sun::star::task::XPasswordContainer,
246         ::com::sun::star::task::XMasterPasswordHandling2,
247         ::com::sun::star::task::XUrlContainer,
248         ::com::sun::star::lang::XServiceInfo,
249         ::com::sun::star::lang::XEventListener >
250 {
251 private:
252     PassMap      m_aContainer;
253     StorageItem* m_pStorageFile;
254     ::osl::Mutex mMutex;
255     ::rtl::OUString m_aMasterPasswd; // master password is set when the string is not empty
256     ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent > mComponent;
257     SysCredentialsConfig mUrlContainer;
258 
259     ::com::sun::star::uno::Sequence< ::com::sun::star::task::UserRecord > CopyToUserRecordSequence(
260                                         const ::std::list< NamePassRecord >& original,
261                                         const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
262                                                         throw(::com::sun::star::uno::RuntimeException);
263 
264     ::com::sun::star::task::UserRecord CopyToUserRecord(
265                                         const NamePassRecord& aRecord,
266                                         sal_Bool& io_bTryToDecode,
267                                         const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler );
268 
269     ::com::sun::star::uno::Sequence< ::com::sun::star::task::UserRecord > FindUsr(
270                                         const ::std::list< NamePassRecord >& userlist,
271                                         const ::rtl::OUString& name,
272                                         const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
273                                                         throw(::com::sun::star::uno::RuntimeException);
274 bool createUrlRecord(
275     const PassMap::iterator & rIter,
276     bool bName,
277     const ::rtl::OUString & aName,
278     const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler,
279     ::com::sun::star::task::UrlRecord & rRec  )
280         throw( ::com::sun::star::uno::RuntimeException );
281 
282 ::com::sun::star::task::UrlRecord find(
283     const ::rtl::OUString& aURL,
284     const ::rtl::OUString& aName,
285     bool bName, // only needed to support empty user names
286     const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& aHandler  ) throw(::com::sun::star::uno::RuntimeException);
287 
288     ::rtl::OUString GetDefaultMasterPassword();
289 
290     ::rtl::OUString RequestPasswordFromUser(
291                     ::com::sun::star::task::PasswordRequestMode aRMode,
292                     const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler );
293 
294     ::rtl::OUString GetMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
295                                                         throw(::com::sun::star::uno::RuntimeException);
296 
297     void UpdateVector( const ::rtl::OUString& url, ::std::list< NamePassRecord >& toUpdate, NamePassRecord& rec, sal_Bool writeFile )
298                                                         throw(::com::sun::star::uno::RuntimeException);
299 
300     void PrivateAdd( const ::rtl::OUString& aUrl,
301                               const ::rtl::OUString& aUserName,
302                               const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords,
303                               char  aMode,
304                               const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler )
305                                                         throw(::com::sun::star::uno::RuntimeException);
306 
307     ::std::vector< ::rtl::OUString > DecodePasswords( const ::rtl::OUString& aLine, const ::rtl::OUString& aMasterPassword )
308                                                         throw(::com::sun::star::uno::RuntimeException);
309 
310     ::rtl::OUString EncodePasswords( ::std::vector< ::rtl::OUString > lines, const ::rtl::OUString& aMasterPassword )
311                                                         throw(::com::sun::star::uno::RuntimeException);
312 
313 public:
314     PasswordContainer( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& );
315     ~PasswordContainer();
316 
317     virtual void SAL_CALL add( const ::rtl::OUString& aUrl,
318                                const ::rtl::OUString& aUserName,
319                                const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords,
320                                const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler  )
321                                                         throw(::com::sun::star::uno::RuntimeException);
322 
323     virtual void SAL_CALL addPersistent( const ::rtl::OUString& aUrl,
324                                             const ::rtl::OUString& aUserName,
325                                          const ::com::sun::star::uno::Sequence< ::rtl::OUString >& aPasswords,
326                                           const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler  )
327                                                         throw(::com::sun::star::uno::RuntimeException);
328 
329     virtual ::com::sun::star::task::UrlRecord SAL_CALL
330                             find( const ::rtl::OUString& aUrl,
331                                   const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler  )
332                                                         throw(::com::sun::star::uno::RuntimeException);
333 
334     virtual ::com::sun::star::task::UrlRecord SAL_CALL
335                             findForName( const ::rtl::OUString& aUrl,
336                                          const ::rtl::OUString& aUserName,
337                                             const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler  )
338                                                         throw(::com::sun::star::uno::RuntimeException);
339 
340     virtual void SAL_CALL remove( const ::rtl::OUString& aUrl,
341                                   const ::rtl::OUString& aUserName )
342                                                         throw(::com::sun::star::uno::RuntimeException);
343 
344     virtual void SAL_CALL removePersistent( const ::rtl::OUString& aUrl,
345                                             const ::rtl::OUString& aUserName )
346                                                         throw(::com::sun::star::uno::RuntimeException);
347 
348     virtual void SAL_CALL removeAllPersistent() throw(::com::sun::star::uno::RuntimeException);
349 
350     virtual ::com::sun::star::uno::Sequence< ::com::sun::star::task::UrlRecord > SAL_CALL
351                             getAllPersistent( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& Handler ) throw(::com::sun::star::uno::RuntimeException);
352 
353 
354     // provide factory
355     static ::rtl::OUString SAL_CALL        impl_getStaticImplementationName( ) throw(::com::sun::star::uno::RuntimeException);
356     static ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
357                     impl_getStaticSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
358     static ::com::sun::star::uno::Reference< ::com::sun::star::lang::XSingleServiceFactory > SAL_CALL
359                     impl_createFactory( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& ServiceManager ) throw(::com::sun::star::uno::RuntimeException);
360     static ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL
361                     impl_createInstance( const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& xServiceManager ) throw( ::com::sun::star::uno::RuntimeException );
362 
363     // XServiceInfo
364     virtual ::rtl::OUString    SAL_CALL    getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
365     virtual sal_Bool SAL_CALL            supportsService( const ::rtl::OUString& ServiceName ) throw(::com::sun::star::uno::RuntimeException);
366 
367     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL
368                                         getSupportedServiceNames(  ) throw(::com::sun::star::uno::RuntimeException);
369 
370     // XEventListener
371     virtual void SAL_CALL        disposing( const ::com::sun::star::lang::EventObject& Source )
372                                     throw(::com::sun::star::uno::RuntimeException);
373 
374     // XMasterPasswordHandling
375     virtual ::sal_Bool SAL_CALL authorizateWithMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler )
376         throw (::com::sun::star::uno::RuntimeException);
377     virtual ::sal_Bool SAL_CALL changeMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) throw (::com::sun::star::uno::RuntimeException);
378     virtual void SAL_CALL removeMasterPassword() throw (::com::sun::star::uno::RuntimeException);
379     virtual ::sal_Bool SAL_CALL hasMasterPassword(  ) throw (::com::sun::star::uno::RuntimeException);
380     virtual ::sal_Bool SAL_CALL allowPersistentStoring( ::sal_Bool bAllow ) throw (::com::sun::star::uno::RuntimeException);
381     virtual ::sal_Bool SAL_CALL isPersistentStoringAllowed(  ) throw (::com::sun::star::uno::RuntimeException);
382 
383     // XMasterPasswordHandling2
384     virtual ::sal_Bool SAL_CALL useDefaultMasterPassword( const ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionHandler >& xHandler ) throw (::com::sun::star::uno::RuntimeException);
385     virtual ::sal_Bool SAL_CALL isDefaultMasterPasswordUsed(  ) throw (::com::sun::star::uno::RuntimeException);
386 
387     // XUrlContainer
388     virtual void SAL_CALL addUrl( const ::rtl::OUString& Url, ::sal_Bool MakePersistent ) throw (::com::sun::star::uno::RuntimeException);
389     virtual ::rtl::OUString SAL_CALL findUrl( const ::rtl::OUString& Url ) throw (::com::sun::star::uno::RuntimeException);
390     virtual void SAL_CALL removeUrl( const ::rtl::OUString& Url ) throw (::com::sun::star::uno::RuntimeException);
391     virtual ::com::sun::star::uno::Sequence< ::rtl::OUString > SAL_CALL getUrls( ::sal_Bool OnlyPersistent ) throw (::com::sun::star::uno::RuntimeException);
392 
393     void            Notify();
394 };
395 
396 //----------------------------------------------------------------------------------
397 
398 class MasterPasswordRequest_Impl : public ucbhelper::InteractionRequest
399 {
400     ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > m_xAuthSupplier;
401 
402 public:
403     MasterPasswordRequest_Impl( ::com::sun::star::task::PasswordRequestMode Mode );
404 
405     const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > &
406     getAuthenticationSupplier() const { return m_xAuthSupplier; }
407 
408 };
409 
410 //----------------------------------------------------------------------------------
411 
412 class RW_SvMemoryStream : public SvMemoryStream {
413 public:
414     RW_SvMemoryStream( void* Buf, sal_uLong Size, StreamMode eMode ):
415             SvMemoryStream( Buf, Size, eMode){}
416 
417     RW_SvMemoryStream( sal_uLong InitSize=512, sal_uLong Resize=64 ):
418             SvMemoryStream( InitSize, Resize ){}
419 
420     sal_uLong getActualSize(){ return nEndOfData; }
421 };
422 
423 
424 
425 #endif // #ifndef INCLUDED_COMPHELPER_PASSWORDCONTAINER_HXX
426 
427