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:
186
interface/wx/secretstore.h
Normal file
186
interface/wx/secretstore.h
Normal file
@@ -0,0 +1,186 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: wx/secretstore.h
|
||||
// Purpose: wxSecretStore and related classes documentation
|
||||
// Author: Vadim Zeitlin
|
||||
// Copyright: (c) 2016 Vadim Zeitlin <vadim@wxwidgets.org>
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/**
|
||||
Represents the value of a secret in wxSecretStore.
|
||||
|
||||
Immutable value-like class which tries to ensure that the secret value will
|
||||
be removed once it's not needed any more.
|
||||
|
||||
@library{wxbase}
|
||||
@category{misc}
|
||||
|
||||
@since 3.1.1
|
||||
*/
|
||||
class wxSecretValue
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Creates an empty secret value (not the same as an empty password).
|
||||
*/
|
||||
wxSecretValue();
|
||||
|
||||
/**
|
||||
Creates a secret value from the given data.
|
||||
|
||||
The @a data argument may contain NUL bytes and doesn't need to be
|
||||
NUL-terminated.
|
||||
|
||||
Under MSW the secret size is effectively limited to 511 bytes and
|
||||
while constructing longer values will still succeed, saving it will
|
||||
fail with an error.
|
||||
*/
|
||||
wxSecretValue(size_t size, const void *data);
|
||||
|
||||
/**
|
||||
Creates a copy of an existing secret.
|
||||
*/
|
||||
wxSecretValue(const wxSecretValue& other);
|
||||
|
||||
/**
|
||||
Assigns another secret to this one.
|
||||
*/
|
||||
wxSecretValue& operator=(const wxSecretValue& other);
|
||||
|
||||
/**
|
||||
Wipes out the secret value from memory before destroying the object.
|
||||
|
||||
This method doesn't provide any real security guarantee, but it does
|
||||
reduce the likelihood that secret value is leaked if the program
|
||||
crashes and ends in a core or a minidump file, for example.
|
||||
|
||||
See Wipe() method if you need to overwrite another region of memory
|
||||
where the secret was copied to or from.
|
||||
*/
|
||||
~wxSecretValue();
|
||||
|
||||
/**
|
||||
Check if a secret is not empty.
|
||||
*/
|
||||
bool IsOk() const;
|
||||
|
||||
/**
|
||||
Compare with another secret for equality.
|
||||
*/
|
||||
bool operator==(const wxSecretValue& other) const;
|
||||
|
||||
/**
|
||||
Compare with another secret for inequality.
|
||||
*/
|
||||
bool operator!=(const wxSecretValue& other) const;
|
||||
|
||||
/**
|
||||
Get the size, in bytes, of the secret data.
|
||||
|
||||
May return 0.
|
||||
|
||||
@see GetData()
|
||||
*/
|
||||
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);
|
||||
};
|
||||
|
||||
/**
|
||||
A collection of secrets, sometimes called a key chain.
|
||||
|
||||
This class provides access to the secrets stored in the OS-provided
|
||||
facility, e.g. credentials manager under MSW, keychain under OS X or
|
||||
Freedesktop-compliant password storage mechanism such as GNOME keyring
|
||||
under Unix systems.
|
||||
|
||||
Currently only the access to the default keychain/ring is provided using
|
||||
GetDefault() method, support for other ones could be added in the future.
|
||||
After calling this method just call Save() to store a password entered by
|
||||
user and then call Load() to retrieve it during next program execution.
|
||||
See @ref page_samples_secretstore for an example of using this class.
|
||||
|
||||
The @c service parameter of the methods in this class should describe the
|
||||
purpose of the password and be unique to your program, e.g. it could be
|
||||
"MyCompany/MyProgram/SomeServer". Note that the server name must be
|
||||
included in the string to allow storing passwords for more than one server.
|
||||
|
||||
Notice that this class is always available under MSW (except when using
|
||||
MinGW32 which doesn't provide the required @c wincred.h header) and OS X
|
||||
but requires libsecret (see https://developer.gnome.org/libsecret/) under
|
||||
Unix and may not be compiled in if it wasn't found. You can check @c
|
||||
wxUSE_SECRETSTORE to test for this. Moreover, retrieving the default
|
||||
secret store may also fail under Unix during run-time if the desktop
|
||||
environment doesn't provide one, so don't forget to call IsOk() to check
|
||||
for this too.
|
||||
|
||||
@library{wxbase}
|
||||
@category{misc}
|
||||
|
||||
@since 3.1.1
|
||||
*/
|
||||
class wxSecretStore
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Returns the default secrets collection to use.
|
||||
|
||||
Call IsOk() on the returned object to check if this method succeeded.
|
||||
*/
|
||||
static wxSecretStore GetDefault();
|
||||
|
||||
/**
|
||||
Check if this object is valid.
|
||||
*/
|
||||
bool IsOk() const;
|
||||
|
||||
/**
|
||||
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 and
|
||||
can be retrieved by calling Load() later.
|
||||
*/
|
||||
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);
|
||||
};
|
Reference in New Issue
Block a user