1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
19 #ifndef INCLUDED_SVL_SOURCE_PASSWORDCONTAINER_PASSWORDCONTAINER_HXX
20 #define INCLUDED_SVL_SOURCE_PASSWORDCONTAINER_PASSWORDCONTAINER_HXX
25 #include <com/sun/star/task/XPasswordContainer2.hpp>
26 #include <com/sun/star/task/PasswordRequestMode.hpp>
27 #include <com/sun/star/lang/XServiceInfo.hpp>
28 #include <com/sun/star/lang/XEventListener.hpp>
29 #include <com/sun/star/lang/XComponent.hpp>
30 #include <com/sun/star/uno/XComponentContext.hpp>
31 #include <cppuhelper/implbase.hxx>
33 #include <unotools/configitem.hxx>
34 #include <ucbhelper/interactionrequest.hxx>
36 #include <rtl/random.h>
37 #include <rtl/ref.hxx>
38 #include <osl/mutex.hxx>
40 #include "syscreds.hxx"
42 #define MEMORY_RECORD 0
43 #define PERSISTENT_RECORD 1
46 class NamePasswordRecord
50 // there are two lists of passwords, memory passwords and persistent passwords
51 bool m_bHasMemoryPasswords
;
52 ::std::vector
< OUString
> m_aMemoryPasswords
;
54 // persistent passwords are encrypted in one string
55 bool m_bHasPersistentPassword
;
56 OUString m_aPersistentPassword
;
57 OUString m_aPersistentIV
;
59 void InitArrays( bool bHasMemoryList
, ::std::vector
< OUString
>&& aMemoryList
,
60 bool bHasPersistentList
, const OUString
& aPersistentList
, const OUString
& aPersistentIV
)
62 m_bHasMemoryPasswords
= bHasMemoryList
;
64 m_aMemoryPasswords
= aMemoryList
;
66 m_bHasPersistentPassword
= bHasPersistentList
;
67 if ( bHasPersistentList
)
69 m_aPersistentPassword
= aPersistentList
;
70 m_aPersistentIV
= aPersistentIV
;
76 NamePasswordRecord( const OUString
& aName
)
78 , m_bHasMemoryPasswords( false )
79 , m_bHasPersistentPassword( false )
83 NamePasswordRecord( const OUString
& aName
, const OUString
& aPersistentList
, const OUString
& aPersistentIV
)
85 , m_bHasMemoryPasswords( false )
86 , m_bHasPersistentPassword( true )
87 , m_aPersistentPassword( aPersistentList
)
88 , m_aPersistentIV( aPersistentIV
)
92 NamePasswordRecord( const NamePasswordRecord
& aRecord
)
93 : m_aName( aRecord
.m_aName
)
94 , m_bHasMemoryPasswords( false )
95 , m_bHasPersistentPassword( false )
97 InitArrays( aRecord
.m_bHasMemoryPasswords
, std::vector(aRecord
.m_aMemoryPasswords
),
98 aRecord
.m_bHasPersistentPassword
, aRecord
.m_aPersistentPassword
, aRecord
.m_aPersistentIV
);
101 NamePasswordRecord
& operator=( const NamePasswordRecord
& aRecord
)
103 if (this != &aRecord
)
105 m_aName
= aRecord
.m_aName
;
107 m_aMemoryPasswords
.clear();
108 m_aPersistentPassword
.clear();
109 m_aPersistentIV
.clear();
110 InitArrays( aRecord
.m_bHasMemoryPasswords
, std::vector(aRecord
.m_aMemoryPasswords
),
111 aRecord
.m_bHasPersistentPassword
, aRecord
.m_aPersistentPassword
, aRecord
.m_aPersistentIV
);
116 const OUString
& GetUserName() const
121 bool HasPasswords( sal_Int8 nStatus
) const
123 if ( nStatus
== MEMORY_RECORD
)
124 return m_bHasMemoryPasswords
;
125 if ( nStatus
== PERSISTENT_RECORD
)
126 return m_bHasPersistentPassword
;
131 ::std::vector
< OUString
> GetMemoryPasswords() const
133 if ( m_bHasMemoryPasswords
)
134 return m_aMemoryPasswords
;
136 return ::std::vector
< OUString
>();
139 OUString
GetPersistentPasswords() const
141 if ( m_bHasPersistentPassword
)
142 return m_aPersistentPassword
;
147 OUString
GetPersistentIV() const
149 if ( m_bHasPersistentPassword
)
150 return m_aPersistentIV
;
155 void SetMemoryPasswords( ::std::vector
< OUString
>&& aMemList
)
157 m_aMemoryPasswords
= std::move(aMemList
);
158 m_bHasMemoryPasswords
= true;
161 void SetPersistentPasswords( const OUString
& aPersList
, const OUString
& aPersIV
)
163 m_aPersistentPassword
= aPersList
;
164 m_aPersistentIV
= aPersIV
;
165 m_bHasPersistentPassword
= true;
168 void RemovePasswords( sal_Int8 nStatus
)
170 if ( nStatus
== MEMORY_RECORD
)
172 m_bHasMemoryPasswords
= false;
173 m_aMemoryPasswords
.clear();
175 else if ( nStatus
== PERSISTENT_RECORD
)
177 m_bHasPersistentPassword
= false;
178 m_aPersistentPassword
.clear();
179 m_aPersistentIV
.clear();
186 typedef ::std::pair
< const OUString
, ::std::vector
< NamePasswordRecord
> > PairUrlRecord
;
187 typedef ::std::map
< OUString
, ::std::vector
< NamePasswordRecord
> > PasswordMap
;
189 // org.openoffice.Office.Common/Passwords/StorageVersion bump if details of
190 // how password details are saved changes. Enables migration from previous
192 constexpr sal_Int32 nCurrentStorageVersion
= 1;
194 class PasswordContainer
;
197 : public ::utl::ConfigItem
200 PasswordContainer
* mainCont
;
205 virtual void ImplCommit() override
;
208 StorageItem( PasswordContainer
* point
, const OUString
& path
) :
209 ConfigItem( path
, ConfigItemMode::NONE
),
213 css::uno::Sequence
< OUString
> aNode
{ path
+ "/Store" };
214 EnableNotification( aNode
);
217 PasswordMap
getInfo();
218 void update( const OUString
& url
, const NamePasswordRecord
& rec
);
219 void remove( const OUString
& url
, const OUString
& rec
);
222 sal_Int32
getStorageVersion();
224 bool getEncodedMasterPassword( OUString
& aResult
, OUString
& aResultIV
);
225 void setEncodedMasterPassword( const OUString
& aResult
, const OUString
& aResultIV
, bool bAcceptEmpty
= false );
226 void setUseStorage( bool bUse
);
229 virtual void Notify( const css::uno::Sequence
< OUString
>& aPropertyNames
) override
;
233 class PasswordContainer
: public ::cppu::WeakImplHelper
<
234 css::task::XPasswordContainer2
,
235 css::lang::XServiceInfo
,
236 css::lang::XEventListener
>
239 PasswordMap m_aContainer
;
240 std::optional
<StorageItem
> m_xStorageFile
;
242 OUString m_aMasterPassword
; // master password is set when the string is not empty
243 css::uno::Reference
< css::lang::XComponent
> mComponent
;
244 SysCredentialsConfig mUrlContainer
;
249 rtlRandomPool m_aRandomPool
;
251 RandomPool() : m_aRandomPool(rtl_random_createPool())
256 return m_aRandomPool
;
260 // Clean up random pool memory
261 rtl_random_destroyPool(m_aRandomPool
);
265 RandomPool mRandomPool
;
269 /// @throws css::uno::RuntimeException
270 css::uno::Sequence
< css::task::UserRecord
> CopyToUserRecordSequence(
271 const ::std::vector
< NamePasswordRecord
>& original
,
272 const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
);
274 css::task::UserRecord
CopyToUserRecord(
275 const NamePasswordRecord
& aRecord
,
276 bool& io_bTryToDecode
,
277 const css::uno::Reference
< css::task::XInteractionHandler
>& aHandler
);
279 /// @throws css::uno::RuntimeException
280 css::uno::Sequence
< css::task::UserRecord
> FindUsr(
281 const ::std::vector
< NamePasswordRecord
>& userlist
,
282 std::u16string_view name
,
283 const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
);
284 /// @throws css::uno::RuntimeException
285 bool createUrlRecord(
286 const PasswordMap::iterator
& rIter
,
288 std::u16string_view aName
,
289 const css::uno::Reference
< css::task::XInteractionHandler
>& aHandler
,
290 css::task::UrlRecord
& rRec
);
292 /// @throws css::uno::RuntimeException
293 css::task::UrlRecord
find(
294 const OUString
& aURL
,
295 std::u16string_view aName
,
296 bool bName
, // only needed to support empty user names
297 const css::uno::Reference
< css::task::XInteractionHandler
>& aHandler
);
299 static OUString
GetDefaultMasterPassword();
301 static OUString
RequestPasswordFromUser(
302 css::task::PasswordRequestMode aRMode
,
303 const css::uno::Reference
< css::task::XInteractionHandler
>& xHandler
);
305 /// @throws css::uno::RuntimeException
306 OUString
const & GetMasterPassword( const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
);
308 /// @throws css::uno::RuntimeException
309 void UpdateVector( const OUString
& url
, ::std::vector
< NamePasswordRecord
>& toUpdate
, NamePasswordRecord
const & rec
, bool writeFile
);
311 /// @throws css::uno::RuntimeException
312 void PrivateAdd( const OUString
& aUrl
,
313 const OUString
& aUserName
,
314 const css::uno::Sequence
< OUString
>& aPasswords
,
316 const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
);
318 /// @throws css::uno::RuntimeException
319 static ::std::vector
< OUString
> DecodePasswords( const OUString
& aLine
, const OUString
& aIV
, const OUString
& aMasterPassword
, css::task::PasswordRequestMode mode
);
321 /// @throws css::uno::RuntimeException
322 static OUString
EncodePasswords(const std::vector
< OUString
>& lines
, const OUString
& aIV
, const OUString
& aMasterPassword
);
325 PasswordContainer( const css::uno::Reference
< css::uno::XComponentContext
>& );
326 virtual ~PasswordContainer() override
;
328 virtual void SAL_CALL
add( const OUString
& aUrl
,
329 const OUString
& aUserName
,
330 const css::uno::Sequence
< OUString
>& aPasswords
,
331 const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
) override
;
333 virtual void SAL_CALL
addPersistent( const OUString
& aUrl
,
334 const OUString
& aUserName
,
335 const css::uno::Sequence
< OUString
>& aPasswords
,
336 const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
) override
;
338 virtual css::task::UrlRecord SAL_CALL
339 find( const OUString
& aUrl
,
340 const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
) override
;
342 virtual css::task::UrlRecord SAL_CALL
343 findForName( const OUString
& aUrl
,
344 const OUString
& aUserName
,
345 const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
) override
;
347 virtual void SAL_CALL
remove( const OUString
& aUrl
,
348 const OUString
& aUserName
) override
;
350 virtual void SAL_CALL
removePersistent( const OUString
& aUrl
,
351 const OUString
& aUserName
) override
;
353 virtual void SAL_CALL
removeAllPersistent() override
;
355 virtual css::uno::Sequence
< css::task::UrlRecord
> SAL_CALL
356 getAllPersistent( const css::uno::Reference
< css::task::XInteractionHandler
>& Handler
) override
;
359 virtual OUString SAL_CALL
getImplementationName( ) override
;
360 virtual sal_Bool SAL_CALL
supportsService( const OUString
& ServiceName
) override
;
362 virtual css::uno::Sequence
< OUString
> SAL_CALL
363 getSupportedServiceNames( ) override
;
366 virtual void SAL_CALL
disposing( const css::lang::EventObject
& Source
) override
;
368 // XMasterPasswordHandling
369 virtual sal_Bool SAL_CALL
authorizateWithMasterPassword( const css::uno::Reference
< css::task::XInteractionHandler
>& xHandler
) override
;
370 virtual sal_Bool SAL_CALL
changeMasterPassword( const css::uno::Reference
< css::task::XInteractionHandler
>& xHandler
) override
;
371 virtual void SAL_CALL
removeMasterPassword() override
;
372 virtual sal_Bool SAL_CALL
hasMasterPassword( ) override
;
373 virtual sal_Bool SAL_CALL
allowPersistentStoring( sal_Bool bAllow
) override
;
374 virtual sal_Bool SAL_CALL
isPersistentStoringAllowed( ) override
;
376 // XMasterPasswordHandling2
377 virtual sal_Bool SAL_CALL
useDefaultMasterPassword( const css::uno::Reference
< css::task::XInteractionHandler
>& xHandler
) override
;
378 virtual sal_Bool SAL_CALL
isDefaultMasterPasswordUsed( ) override
;
381 virtual void SAL_CALL
addUrl( const OUString
& Url
, sal_Bool MakePersistent
) override
;
382 virtual OUString SAL_CALL
findUrl( const OUString
& Url
) override
;
383 virtual void SAL_CALL
removeUrl( const OUString
& Url
) override
;
384 virtual css::uno::Sequence
< OUString
> SAL_CALL
getUrls( sal_Bool OnlyPersistent
) override
;
390 class MasterPasswordRequest_Impl
: public ucbhelper::InteractionRequest
392 ::rtl::Reference
< ucbhelper::InteractionSupplyAuthentication
> m_xAuthSupplier
;
395 MasterPasswordRequest_Impl( css::task::PasswordRequestMode Mode
);
397 const ::rtl::Reference
< ucbhelper::InteractionSupplyAuthentication
> &
398 getAuthenticationSupplier() const { return m_xAuthSupplier
; }
405 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */