LibreOffice Module svl (master) 1
passwordcontainer.hxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_SVL_SOURCE_PASSWORDCONTAINER_PASSWORDCONTAINER_HXX
20#define INCLUDED_SVL_SOURCE_PASSWORDCONTAINER_PASSWORDCONTAINER_HXX
21
22#include <utility>
23#include <vector>
24#include <map>
25#include <mutex>
26#include <optional>
27#include <com/sun/star/task/XPasswordContainer2.hpp>
28#include <com/sun/star/task/PasswordRequestMode.hpp>
29#include <com/sun/star/lang/XServiceInfo.hpp>
30#include <com/sun/star/lang/XEventListener.hpp>
31#include <com/sun/star/lang/XComponent.hpp>
32#include <com/sun/star/uno/XComponentContext.hpp>
34
37
38#include <rtl/random.h>
39#include <rtl/ref.hxx>
40#include <osl/mutex.hxx>
41
42#include "syscreds.hxx"
43
44#define MEMORY_RECORD 0
45#define PERSISTENT_RECORD 1
46
47
49{
50 OUString m_aName;
51
52 // there are two lists of passwords, memory passwords and persistent passwords
54 ::std::vector< OUString > m_aMemoryPasswords;
55
56 // persistent passwords are encrypted in one string
60
61 void InitArrays( bool bHasMemoryList, ::std::vector< OUString >&& aMemoryList,
62 bool bHasPersistentList, const OUString& aPersistentList, const OUString& aPersistentIV )
63 {
64 m_bHasMemoryPasswords = bHasMemoryList;
65 if ( bHasMemoryList )
66 m_aMemoryPasswords = aMemoryList;
67
68 m_bHasPersistentPassword = bHasPersistentList;
69 if ( bHasPersistentList )
70 {
71 m_aPersistentPassword = aPersistentList;
72 m_aPersistentIV = aPersistentIV;
73 }
74 }
75
76public:
77
78 NamePasswordRecord( OUString aName )
79 : m_aName(std::move( aName ))
80 , m_bHasMemoryPasswords( false )
82 {
83 }
84
85 NamePasswordRecord( OUString aName, OUString aPersistentList, OUString aPersistentIV )
86 : m_aName(std::move( aName ))
87 , m_bHasMemoryPasswords( false )
89 , m_aPersistentPassword(std::move( aPersistentList ))
90 , m_aPersistentIV(std::move( aPersistentIV ))
91 {
92 }
93
95 : m_aName( aRecord.m_aName )
96 , m_bHasMemoryPasswords( false )
98 {
99 InitArrays( aRecord.m_bHasMemoryPasswords, std::vector(aRecord.m_aMemoryPasswords),
101 }
102
104 {
105 if (this != &aRecord)
106 {
107 m_aName = aRecord.m_aName;
108
109 m_aMemoryPasswords.clear();
110 m_aPersistentPassword.clear();
111 m_aPersistentIV.clear();
112 InitArrays( aRecord.m_bHasMemoryPasswords, std::vector(aRecord.m_aMemoryPasswords),
114 }
115 return *this;
116 }
117
118 const OUString& GetUserName() const
119 {
120 return m_aName;
121 }
122
123 bool HasPasswords( sal_Int8 nStatus ) const
124 {
125 if ( nStatus == MEMORY_RECORD )
127 if ( nStatus == PERSISTENT_RECORD )
129
130 return false;
131 }
132
133 ::std::vector< OUString > GetMemoryPasswords() const
134 {
136 return m_aMemoryPasswords;
137
138 return ::std::vector< OUString >();
139 }
140
141 OUString GetPersistentPasswords() const
142 {
145
146 return OUString();
147 }
148
149 OUString GetPersistentIV() const
150 {
152 return m_aPersistentIV;
153
154 return OUString();
155 }
156
157 void SetMemoryPasswords( ::std::vector< OUString >&& aMemList )
158 {
159 m_aMemoryPasswords = std::move(aMemList);
161 }
162
163 void SetPersistentPasswords( const OUString& aPersList, const OUString& aPersIV )
164 {
165 m_aPersistentPassword = aPersList;
166 m_aPersistentIV = aPersIV;
168 }
169
170 void RemovePasswords( sal_Int8 nStatus )
171 {
172 if ( nStatus == MEMORY_RECORD )
173 {
174 m_bHasMemoryPasswords = false;
175 m_aMemoryPasswords.clear();
176 }
177 else if ( nStatus == PERSISTENT_RECORD )
178 {
180 m_aPersistentPassword.clear();
181 m_aPersistentIV.clear();
182 }
183 }
184
185};
186
187
188typedef ::std::pair< const OUString, ::std::vector< NamePasswordRecord > > PairUrlRecord;
189typedef ::std::map< OUString, ::std::vector< NamePasswordRecord > > PasswordMap;
190
191// org.openoffice.Office.Common/Passwords/StorageVersion bump if details of
192// how password details are saved changes. Enables migration from previous
193// schemes.
194constexpr sal_Int32 nCurrentStorageVersion = 1;
195
197
199 : public ::utl::ConfigItem
200{
201private:
204 OUString mEncoded;
205 OUString mEncodedIV;
206
207 virtual void ImplCommit() override;
208
209public:
210 StorageItem( PasswordContainer* point, const OUString& path ) :
212 mainCont( point ),
213 hasEncoded( false )
214 {
215 css::uno::Sequence< OUString > aNode { path + "/Store" };
216 EnableNotification( aNode );
217 }
218
220 void update( const OUString& url, const NamePasswordRecord& rec );
221 void remove( const OUString& url, const OUString& rec );
222 void clear();
223
224 sal_Int32 getStorageVersion();
225
226 bool getEncodedMasterPassword( OUString& aResult, OUString& aResultIV );
227 void setEncodedMasterPassword( const OUString& aResult, const OUString& aResultIV, bool bAcceptEmpty = false );
228 void setUseStorage( bool bUse );
229 bool useStorage();
230
231 virtual void Notify( const css::uno::Sequence< OUString >& aPropertyNames ) override;
232};
233
234
235class PasswordContainer : public ::cppu::WeakImplHelper<
236 css::task::XPasswordContainer2,
237 css::lang::XServiceInfo,
238 css::lang::XEventListener >
239{
240private:
242 std::optional<StorageItem> m_xStorageFile;
243 std::mutex mMutex;
244 OUString m_aMasterPassword; // master password is set when the string is not empty
245 css::uno::Reference< css::lang::XComponent > mComponent;
247
249 {
250 private:
252 public:
253 RandomPool() : m_aRandomPool(rtl_random_createPool())
254 {
255 }
257 {
258 return m_aRandomPool;
259 }
261 {
262 // Clean up random pool memory
263 rtl_random_destroyPool(m_aRandomPool);
264 }
265 };
266
268
269 OUString createIV();
270
272 css::uno::Sequence< css::task::UserRecord > CopyToUserRecordSequence(
273 const ::std::vector< NamePasswordRecord >& original,
274 const css::uno::Reference< css::task::XInteractionHandler >& Handler );
275
276 css::task::UserRecord CopyToUserRecord(
277 const NamePasswordRecord& aRecord,
278 bool& io_bTryToDecode,
279 const css::uno::Reference< css::task::XInteractionHandler >& aHandler );
280
282 css::uno::Sequence< css::task::UserRecord > FindUsr(
283 const ::std::vector< NamePasswordRecord >& userlist,
284 std::u16string_view name,
285 const css::uno::Reference< css::task::XInteractionHandler >& Handler );
287 bool createUrlRecord(
288 const PasswordMap::iterator & rIter,
289 bool bName,
290 std::u16string_view aName,
291 const css::uno::Reference< css::task::XInteractionHandler >& aHandler,
292 css::task::UrlRecord & rRec );
293
295 css::task::UrlRecord find(
296 const OUString& aURL,
297 std::u16string_view aName,
298 bool bName, // only needed to support empty user names
299 const css::uno::Reference< css::task::XInteractionHandler >& aHandler );
300
301 static OUString GetDefaultMasterPassword();
302
303 static OUString RequestPasswordFromUser(
304 css::task::PasswordRequestMode aRMode,
305 const css::uno::Reference< css::task::XInteractionHandler >& xHandler );
306
308 OUString const & GetMasterPassword( const css::uno::Reference< css::task::XInteractionHandler >& Handler );
309
311 void UpdateVector( const OUString& url, ::std::vector< NamePasswordRecord >& toUpdate, NamePasswordRecord const & rec, bool writeFile );
312
314 void PrivateAdd( const OUString& aUrl,
315 const OUString& aUserName,
316 const css::uno::Sequence< OUString >& aPasswords,
317 char aMode,
318 const css::uno::Reference< css::task::XInteractionHandler >& Handler );
319
321 static ::std::vector< OUString > DecodePasswords( std::u16string_view aLine, std::u16string_view aIV, std::u16string_view aMasterPassword, css::task::PasswordRequestMode mode );
322
324 static OUString EncodePasswords(const std::vector< OUString >& lines, std::u16string_view aIV, std::u16string_view aMasterPassword );
325
326public:
327 PasswordContainer( const css::uno::Reference< css::uno::XComponentContext >& );
328 virtual ~PasswordContainer() override;
329
330 virtual void SAL_CALL add( const OUString& aUrl,
331 const OUString& aUserName,
332 const css::uno::Sequence< OUString >& aPasswords,
333 const css::uno::Reference< css::task::XInteractionHandler >& Handler ) override;
334
335 virtual void SAL_CALL addPersistent( const OUString& aUrl,
336 const OUString& aUserName,
337 const css::uno::Sequence< OUString >& aPasswords,
338 const css::uno::Reference< css::task::XInteractionHandler >& Handler ) override;
339
340 virtual css::task::UrlRecord SAL_CALL
341 find( const OUString& aUrl,
342 const css::uno::Reference< css::task::XInteractionHandler >& Handler ) override;
343
344 virtual css::task::UrlRecord SAL_CALL
345 findForName( const OUString& aUrl,
346 const OUString& aUserName,
347 const css::uno::Reference< css::task::XInteractionHandler >& Handler ) override;
348
349 virtual void SAL_CALL remove( const OUString& aUrl,
350 const OUString& aUserName ) override;
351
352 virtual void SAL_CALL removePersistent( const OUString& aUrl,
353 const OUString& aUserName ) override;
354
355 virtual void SAL_CALL removeAllPersistent() override;
356
357 virtual css::uno::Sequence< css::task::UrlRecord > SAL_CALL
358 getAllPersistent( const css::uno::Reference< css::task::XInteractionHandler >& Handler ) override;
359
360 // XServiceInfo
361 virtual OUString SAL_CALL getImplementationName( ) override;
362 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
363
364 virtual css::uno::Sequence< OUString > SAL_CALL
365 getSupportedServiceNames( ) override;
366
367 // XEventListener
368 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
369
370 // XMasterPasswordHandling
371 virtual sal_Bool SAL_CALL authorizateWithMasterPassword( const css::uno::Reference< css::task::XInteractionHandler >& xHandler ) override;
372 virtual sal_Bool SAL_CALL changeMasterPassword( const css::uno::Reference< css::task::XInteractionHandler >& xHandler ) override;
373 virtual void SAL_CALL removeMasterPassword() override;
374 virtual sal_Bool SAL_CALL hasMasterPassword( ) override;
375 virtual sal_Bool SAL_CALL allowPersistentStoring( sal_Bool bAllow ) override;
376 virtual sal_Bool SAL_CALL isPersistentStoringAllowed( ) override;
377
378 // XMasterPasswordHandling2
379 virtual sal_Bool SAL_CALL useDefaultMasterPassword( const css::uno::Reference< css::task::XInteractionHandler >& xHandler ) override;
380 virtual sal_Bool SAL_CALL isDefaultMasterPasswordUsed( ) override;
381
382 // XUrlContainer
383 virtual void SAL_CALL addUrl( const OUString& Url, sal_Bool MakePersistent ) override;
384 virtual OUString SAL_CALL findUrl( const OUString& Url ) override;
385 virtual void SAL_CALL removeUrl( const OUString& Url ) override;
386 virtual css::uno::Sequence< OUString > SAL_CALL getUrls( sal_Bool OnlyPersistent ) override;
387
388 void Notify();
389private:
390 void removeAllPersistent(std::unique_lock<std::mutex>& rGuard);
391 void removeMasterPassword(std::unique_lock<std::mutex>& rGuard);
392};
393
394
396{
398
399public:
400 MasterPasswordRequest_Impl( css::task::PasswordRequestMode Mode );
401
402 const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > &
404
405};
406
407
408#endif
409
410/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
void * rtlRandomPool
const ::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > & getAuthenticationSupplier() const
MasterPasswordRequest_Impl(css::task::PasswordRequestMode Mode)
::rtl::Reference< ucbhelper::InteractionSupplyAuthentication > m_xAuthSupplier
::std::vector< OUString > GetMemoryPasswords() const
bool HasPasswords(sal_Int8 nStatus) const
void InitArrays(bool bHasMemoryList, ::std::vector< OUString > &&aMemoryList, bool bHasPersistentList, const OUString &aPersistentList, const OUString &aPersistentIV)
void RemovePasswords(sal_Int8 nStatus)
OUString GetPersistentPasswords() const
::std::vector< OUString > m_aMemoryPasswords
NamePasswordRecord(OUString aName, OUString aPersistentList, OUString aPersistentIV)
NamePasswordRecord & operator=(const NamePasswordRecord &aRecord)
NamePasswordRecord(OUString aName)
void SetMemoryPasswords(::std::vector< OUString > &&aMemList)
void SetPersistentPasswords(const OUString &aPersList, const OUString &aPersIV)
OUString GetPersistentIV() const
const OUString & GetUserName() const
NamePasswordRecord(const NamePasswordRecord &aRecord)
SysCredentialsConfig mUrlContainer
css::uno::Sequence< css::task::UserRecord > CopyToUserRecordSequence(const ::std::vector< NamePasswordRecord > &original, const css::uno::Reference< css::task::XInteractionHandler > &Handler)
virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
void PrivateAdd(const OUString &aUrl, const OUString &aUserName, const css::uno::Sequence< OUString > &aPasswords, char aMode, const css::uno::Reference< css::task::XInteractionHandler > &Handler)
static OUString GetDefaultMasterPassword()
static OUString RequestPasswordFromUser(css::task::PasswordRequestMode aRMode, const css::uno::Reference< css::task::XInteractionHandler > &xHandler)
virtual sal_Bool SAL_CALL supportsService(const OUString &ServiceName) override
void UpdateVector(const OUString &url, ::std::vector< NamePasswordRecord > &toUpdate, NamePasswordRecord const &rec, bool writeFile)
std::optional< StorageItem > m_xStorageFile
bool createUrlRecord(const PasswordMap::iterator &rIter, bool bName, std::u16string_view aName, const css::uno::Reference< css::task::XInteractionHandler > &aHandler, css::task::UrlRecord &rRec)
virtual void SAL_CALL removeUrl(const OUString &Url) override
virtual void SAL_CALL removeMasterPassword() override
virtual sal_Bool SAL_CALL useDefaultMasterPassword(const css::uno::Reference< css::task::XInteractionHandler > &xHandler) override
virtual css::uno::Sequence< OUString > SAL_CALL getUrls(sal_Bool OnlyPersistent) override
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
css::uno::Reference< css::lang::XComponent > mComponent
static ::std::vector< OUString > DecodePasswords(std::u16string_view aLine, std::u16string_view aIV, std::u16string_view aMasterPassword, css::task::PasswordRequestMode mode)
virtual sal_Bool SAL_CALL isDefaultMasterPasswordUsed() override
virtual css::task::UrlRecord SAL_CALL find(const OUString &aUrl, const css::uno::Reference< css::task::XInteractionHandler > &Handler) override
virtual OUString SAL_CALL findUrl(const OUString &Url) override
virtual void SAL_CALL removePersistent(const OUString &aUrl, const OUString &aUserName) override
virtual void SAL_CALL remove(const OUString &aUrl, const OUString &aUserName) override
PasswordContainer(const css::uno::Reference< css::uno::XComponentContext > &)
virtual sal_Bool SAL_CALL changeMasterPassword(const css::uno::Reference< css::task::XInteractionHandler > &xHandler) override
css::task::UserRecord CopyToUserRecord(const NamePasswordRecord &aRecord, bool &io_bTryToDecode, const css::uno::Reference< css::task::XInteractionHandler > &aHandler)
virtual void SAL_CALL removeAllPersistent() override
virtual void SAL_CALL addPersistent(const OUString &aUrl, const OUString &aUserName, const css::uno::Sequence< OUString > &aPasswords, const css::uno::Reference< css::task::XInteractionHandler > &Handler) override
virtual ~PasswordContainer() override
virtual OUString SAL_CALL getImplementationName() override
virtual void SAL_CALL addUrl(const OUString &Url, sal_Bool MakePersistent) override
css::task::UrlRecord find(const OUString &aURL, std::u16string_view aName, bool bName, const css::uno::Reference< css::task::XInteractionHandler > &aHandler)
virtual sal_Bool SAL_CALL isPersistentStoringAllowed() override
OUString const & GetMasterPassword(const css::uno::Reference< css::task::XInteractionHandler > &Handler)
static OUString EncodePasswords(const std::vector< OUString > &lines, std::u16string_view aIV, std::u16string_view aMasterPassword)
virtual void SAL_CALL add(const OUString &aUrl, const OUString &aUserName, const css::uno::Sequence< OUString > &aPasswords, const css::uno::Reference< css::task::XInteractionHandler > &Handler) override
virtual sal_Bool SAL_CALL allowPersistentStoring(sal_Bool bAllow) override
virtual sal_Bool SAL_CALL hasMasterPassword() override
css::uno::Sequence< css::task::UserRecord > FindUsr(const ::std::vector< NamePasswordRecord > &userlist, std::u16string_view name, const css::uno::Reference< css::task::XInteractionHandler > &Handler)
virtual sal_Bool SAL_CALL authorizateWithMasterPassword(const css::uno::Reference< css::task::XInteractionHandler > &xHandler) override
virtual css::uno::Sequence< css::task::UrlRecord > SAL_CALL getAllPersistent(const css::uno::Reference< css::task::XInteractionHandler > &Handler) override
virtual css::task::UrlRecord SAL_CALL findForName(const OUString &aUrl, const OUString &aUserName, const css::uno::Reference< css::task::XInteractionHandler > &Handler) override
void setEncodedMasterPassword(const OUString &aResult, const OUString &aResultIV, bool bAcceptEmpty=false)
void remove(const OUString &url, const OUString &rec)
bool getEncodedMasterPassword(OUString &aResult, OUString &aResultIV)
void update(const OUString &url, const NamePasswordRecord &rec)
virtual void Notify(const css::uno::Sequence< OUString > &aPropertyNames) override
virtual void ImplCommit() override
PasswordContainer * mainCont
PasswordMap getInfo()
void setUseStorage(bool bUse)
StorageItem(PasswordContainer *point, const OUString &path)
sal_Int32 getStorageVersion()
bool EnableNotification(const css::uno::Sequence< OUString > &rNames, bool bEnableInternalNotification=false)
ConfigItem(ConfigItem const &)=default
ConfigItemMode
OUString aName
def point()
NONE
Mode
#define MEMORY_RECORD
constexpr sal_Int32 nCurrentStorageVersion
::std::pair< const OUString, ::std::vector< NamePasswordRecord > > PairUrlRecord
#define PERSISTENT_RECORD
::std::map< OUString, ::std::vector< NamePasswordRecord > > PasswordMap
unsigned char sal_Bool
signed char sal_Int8