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