Add wxSecretStore
Add a new class allowing to store passwords and other sensitive information using the OS-provided facilities. Add implementations for all the main platforms, documentation and a new sample (which contains an ad hoc unit test as the real unit test for this class would probably be a bad idea as it wouldn't run in non-interactive contexts and could show OS level dialog boxes if it did).
This commit is contained in:
@@ -433,6 +433,13 @@
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_FSVOLUME 1
|
||||
|
||||
// Use wxSecretStore class for storing passwords using OS-specific facilities.
|
||||
//
|
||||
// Default is 1
|
||||
//
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_SECRETSTORE 1
|
||||
|
||||
// Use wxStandardPaths class which allows to retrieve some standard locations
|
||||
// in the file system
|
||||
//
|
||||
|
@@ -277,6 +277,14 @@
|
||||
# endif
|
||||
#endif /* !defined(wxUSE_REGEX) */
|
||||
|
||||
#ifndef wxUSE_SECRETSTORE
|
||||
# ifdef wxABORT_ON_CONFIG_ERROR
|
||||
# error "wxUSE_SECRETSTORE must be defined, please read comment near the top of this file."
|
||||
# else
|
||||
# define wxUSE_SECRETSTORE 1
|
||||
# endif
|
||||
#endif /* !defined(wxUSE_SECRETSTORE) */
|
||||
|
||||
#ifndef wxUSE_STDPATHS
|
||||
# ifdef wxABORT_ON_CONFIG_ERROR
|
||||
# error "wxUSE_STDPATHS must be defined, please read comment near the top of this file."
|
||||
|
@@ -31,6 +31,12 @@ public:
|
||||
return &m_error;
|
||||
}
|
||||
|
||||
// Check if any error actually occurred.
|
||||
operator bool() const
|
||||
{
|
||||
return m_error != NULL;
|
||||
}
|
||||
|
||||
wxString GetMessage() const
|
||||
{
|
||||
return wxString::FromUTF8(m_error->message);
|
||||
|
@@ -434,6 +434,13 @@
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_FSVOLUME 1
|
||||
|
||||
// Use wxSecretStore class for storing passwords using OS-specific facilities.
|
||||
//
|
||||
// Default is 1
|
||||
//
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_SECRETSTORE 1
|
||||
|
||||
// Use wxStandardPaths class which allows to retrieve some standard locations
|
||||
// in the file system
|
||||
//
|
||||
|
@@ -434,6 +434,13 @@
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_FSVOLUME 1
|
||||
|
||||
// Use wxSecretStore class for storing passwords using OS-specific facilities.
|
||||
//
|
||||
// Default is 1
|
||||
//
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_SECRETSTORE 1
|
||||
|
||||
// Use wxStandardPaths class which allows to retrieve some standard locations
|
||||
// in the file system
|
||||
//
|
||||
|
@@ -177,6 +177,12 @@
|
||||
|
||||
#endif /* __GNUWIN32__ */
|
||||
|
||||
/* MinGW32 doesn't provide wincred.h defining the API needed by this */
|
||||
#ifdef __MINGW32_TOOLCHAIN__
|
||||
#undef wxUSE_SECRETSTORE
|
||||
#define wxUSE_SECRETSTORE 0
|
||||
#endif
|
||||
|
||||
#if !wxUSE_OWNER_DRAWN && !defined(__WXUNIVERSAL__)
|
||||
# undef wxUSE_CHECKLISTBOX
|
||||
# define wxUSE_CHECKLISTBOX 0
|
||||
|
@@ -434,6 +434,13 @@
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_FSVOLUME 1
|
||||
|
||||
// Use wxSecretStore class for storing passwords using OS-specific facilities.
|
||||
//
|
||||
// Default is 1
|
||||
//
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_SECRETSTORE 1
|
||||
|
||||
// Use wxStandardPaths class which allows to retrieve some standard locations
|
||||
// in the file system
|
||||
//
|
||||
|
@@ -435,6 +435,13 @@
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_FSVOLUME 1
|
||||
|
||||
// Use wxSecretStore class for storing passwords using OS-specific facilities.
|
||||
//
|
||||
// Default is 1
|
||||
//
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_SECRETSTORE 1
|
||||
|
||||
// Use wxStandardPaths class which allows to retrieve some standard locations
|
||||
// in the file system
|
||||
//
|
||||
|
93
include/wx/private/secretstore.h
Normal file
93
include/wx/private/secretstore.h
Normal file
@@ -0,0 +1,93 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/private/secretstore.h
|
||||
// Purpose: Classes used in wxSecretStore implementation only.
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2016-05-27
|
||||
// Copyright: (c) 2016 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_PRIVATE_SECRETSTORE_H_
|
||||
#define _WX_PRIVATE_SECRETSTORE_H_
|
||||
|
||||
#include "wx/object.h" // wxRefCounter
|
||||
|
||||
// Both of the implementation classes here are ref-counted so that the
|
||||
// corresponding public objects could be copied cheaply and, in the case of
|
||||
// wxSecretValue, also to avoid having the secret in more than one place in
|
||||
// memory at a time.
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Class holding wxSecretValue data
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This is a common base class for our own and libsecret-based implementations.
|
||||
class wxSecretValueImpl : public wxRefCounter
|
||||
{
|
||||
public:
|
||||
wxSecretValueImpl()
|
||||
{
|
||||
}
|
||||
|
||||
virtual size_t GetSize() const = 0;
|
||||
virtual const void *GetData() const = 0;
|
||||
};
|
||||
|
||||
// Trivial common implementation of wxSecretValueImpl used under MSW and OS X.
|
||||
#if defined(__WINDOWS__) || defined(__DARWIN__)
|
||||
|
||||
class wxSecretValueGenericImpl : public wxSecretValueImpl
|
||||
{
|
||||
public:
|
||||
wxSecretValueGenericImpl(size_t size, const void *data)
|
||||
: m_size(size),
|
||||
m_data(new char[size])
|
||||
{
|
||||
memcpy(m_data, data, size);
|
||||
}
|
||||
|
||||
virtual ~wxSecretValueGenericImpl()
|
||||
{
|
||||
if ( m_data )
|
||||
{
|
||||
wxSecretValue::Wipe(m_size, m_data);
|
||||
delete [] m_data;
|
||||
}
|
||||
}
|
||||
|
||||
virtual size_t GetSize() const wxOVERRIDE { return m_size; }
|
||||
virtual const void *GetData() const wxOVERRIDE { return m_data; }
|
||||
|
||||
private:
|
||||
const size_t m_size;
|
||||
char* const m_data;
|
||||
};
|
||||
|
||||
#endif // MSW or OSX
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Base class for wxSecretStore implementations
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// All its methods are similar to the methods of the public class except that
|
||||
// they work with the implementation rather than public objects and they all
|
||||
// take an extra "wxString&" output parameter which is filled with the low
|
||||
// level error message in case of an error. This message will be logged by
|
||||
// wxSecretStore itself, wxSecretStoreImpl methods shouldn't do any logging on
|
||||
// their own.
|
||||
class wxSecretStoreImpl : public wxRefCounter
|
||||
{
|
||||
public:
|
||||
virtual bool Save(const wxString& service,
|
||||
const wxString& user,
|
||||
const wxSecretValueImpl& secret,
|
||||
wxString& errmsg) = 0;
|
||||
virtual wxSecretValueImpl* Load(const wxString& service,
|
||||
const wxString& user,
|
||||
wxString& errmsg) const = 0;
|
||||
virtual bool Delete(const wxString& service,
|
||||
const wxString& user,
|
||||
wxString& errmsg) = 0;
|
||||
};
|
||||
|
||||
#endif // _WX_PRIVATE_SECRETSTORE_H_
|
141
include/wx/secretstore.h
Normal file
141
include/wx/secretstore.h
Normal file
@@ -0,0 +1,141 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/secretstore.h
|
||||
// Purpose: Storing and retrieving secrets using OS-provided facilities.
|
||||
// Author: Vadim Zeitlin
|
||||
// Created: 2016-05-27
|
||||
// Copyright: (c) 2016 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef _WX_SECRETSTORE_H_
|
||||
#define _WX_SECRETSTORE_H_
|
||||
|
||||
#include "wx/defs.h"
|
||||
|
||||
#if wxUSE_SECRETSTORE
|
||||
|
||||
class wxSecretStoreImpl;
|
||||
class wxSecretValueImpl;
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Represents a secret value, e.g. a password string.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
// This is an immutable value-like class which tries to ensure that the secret
|
||||
// value will be wiped out from memory once it's not needed any more.
|
||||
class WXDLLIMPEXP_BASE wxSecretValue
|
||||
{
|
||||
public:
|
||||
// Creates an empty secret value (not the same as an empty password).
|
||||
wxSecretValue() : m_impl(NULL) { }
|
||||
|
||||
// Creates a secret value from the given data.
|
||||
wxSecretValue(size_t size, const void *data);
|
||||
|
||||
wxSecretValue(const wxSecretValue& other);
|
||||
wxSecretValue& operator=(const wxSecretValue& other);
|
||||
|
||||
~wxSecretValue();
|
||||
|
||||
// Check if a secret is not empty.
|
||||
bool IsOk() const { return m_impl != NULL; }
|
||||
|
||||
// Compare with another secret.
|
||||
bool operator==(const wxSecretValue& other) const;
|
||||
bool operator!=(const wxSecretValue& other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
// Get the size, in bytes, of the secret data.
|
||||
size_t GetSize() const;
|
||||
|
||||
// Get read-only access to the secret data.
|
||||
//
|
||||
// Don't assume it is NUL-terminated, use GetSize() instead.
|
||||
const void *GetData() const;
|
||||
|
||||
// Erase the given area of memory overwriting its presumably sensitive
|
||||
// content.
|
||||
static void Wipe(size_t size, void *data);
|
||||
|
||||
private:
|
||||
// This ctor is only used by wxSecretStore and takes ownership of the
|
||||
// provided existing impl pointer.
|
||||
explicit wxSecretValue(wxSecretValueImpl* impl) : m_impl(impl) { }
|
||||
|
||||
wxSecretValueImpl* m_impl;
|
||||
|
||||
friend class wxSecretStore;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// A collection of secrets, sometimes called a key chain.
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
class WXDLLIMPEXP_BASE wxSecretStore
|
||||
{
|
||||
public:
|
||||
// Returns the default secrets collection to use.
|
||||
//
|
||||
// Currently this is the only way to create a secret store object. In the
|
||||
// future we could add more factory functions to e.g. create non-persistent
|
||||
// stores or allow creating stores corresponding to the native facilities
|
||||
// being used (e.g. specify schema name under Linux or a SecKeychainRef
|
||||
// under OS X).
|
||||
static wxSecretStore GetDefault();
|
||||
|
||||
// This class has no default ctor, use GetDefault() instead.
|
||||
|
||||
// But it can be copied, a copy refers to the same store as the original.
|
||||
wxSecretStore(const wxSecretStore& store);
|
||||
|
||||
// Dtor is not virtual, this class is not supposed to be derived from.
|
||||
~wxSecretStore();
|
||||
|
||||
|
||||
// Check if this object is valid.
|
||||
bool IsOk() const { return m_impl != NULL; }
|
||||
|
||||
|
||||
// Store a secret.
|
||||
//
|
||||
// The service name should be user readable and unique.
|
||||
//
|
||||
// If a secret with the same service name and user already exists, it will
|
||||
// be overwritten with the new value.
|
||||
//
|
||||
// Returns false after logging an error message if an error occurs,
|
||||
// otherwise returns true indicating that the secret has been stored.
|
||||
bool Save(const wxString& service,
|
||||
const wxString& user,
|
||||
const wxSecretValue& secret);
|
||||
|
||||
// Look up a secret.
|
||||
//
|
||||
// If no such secret is found, an empty value is returned, but no error is
|
||||
// logged (however an error may still be logged if some other error occurs).
|
||||
// If more than one secret matching the parameters exist, only one
|
||||
// arbitrarily chosen of them is returned (notice that it's impossible to
|
||||
// get into such situation using this API only).
|
||||
wxSecretValue Load(const wxString& service, const wxString& user) const;
|
||||
|
||||
// Delete a previously stored secret.
|
||||
//
|
||||
// If there is more than one matching secret, all of them are deleted.
|
||||
//
|
||||
// If any secrets were deleted, returns true. Otherwise returns false and
|
||||
// logs an error if any error other than not finding any matching secrets
|
||||
// occurred.
|
||||
bool Delete(const wxString& service, const wxString& user);
|
||||
|
||||
private:
|
||||
// Ctor takes ownership of the passed pointer.
|
||||
explicit wxSecretStore(wxSecretStoreImpl* impl) : m_impl(impl) { }
|
||||
|
||||
wxSecretStoreImpl* const m_impl;
|
||||
};
|
||||
|
||||
#endif // wxUSE_SECRETSTORE
|
||||
|
||||
#endif // _WX_SECRETSTORE_H_
|
@@ -430,6 +430,13 @@
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_FSVOLUME 1
|
||||
|
||||
// Use wxSecretStore class for storing passwords using OS-specific facilities.
|
||||
//
|
||||
// Default is 1
|
||||
//
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_SECRETSTORE 1
|
||||
|
||||
// Use wxStandardPaths class which allows to retrieve some standard locations
|
||||
// in the file system
|
||||
//
|
||||
|
@@ -433,6 +433,13 @@
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_FSVOLUME 1
|
||||
|
||||
// Use wxSecretStore class for storing passwords using OS-specific facilities.
|
||||
//
|
||||
// Default is 1
|
||||
//
|
||||
// Recommended setting: 1 (but may be safely disabled if you don't use it)
|
||||
#define wxUSE_SECRETSTORE 1
|
||||
|
||||
// Use wxStandardPaths class which allows to retrieve some standard locations
|
||||
// in the file system
|
||||
//
|
||||
|
Reference in New Issue
Block a user