2016-05-28 19:13:44 -04:00
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Name: wx/secretstore.h
|
|
|
|
// Purpose: wxSecretStore and related classes documentation
|
|
|
|
// Author: Vadim Zeitlin
|
|
|
|
// Copyright: (c) 2016 Vadim Zeitlin <vadim@wxwidgets.org>
|
|
|
|
// Licence: wxWindows licence
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
2021-01-09 19:21:45 -05:00
|
|
|
/**
|
|
|
|
Temporary string whose contents will be overwritten when it is destroyed.
|
|
|
|
|
|
|
|
Objects of this class must not be used polymorphically as it derives from
|
|
|
|
wxString which doesn't have a virtual destructor. Typically, they are used
|
|
|
|
as local variables, e.g.
|
|
|
|
@code
|
|
|
|
void TryToAuthenticate(const wxString& secretValue)
|
|
|
|
{
|
|
|
|
wxSecretString password(secretValue);
|
|
|
|
|
|
|
|
... use password as any wxString ...
|
|
|
|
|
|
|
|
// Here password memory is overwritten to prevent the password from
|
|
|
|
// remaining in memory.
|
|
|
|
}
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
@since 3.1.5
|
|
|
|
*/
|
|
|
|
class wxSecretString : public wxString
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
/// Default constructor creates an empty string.
|
|
|
|
wxSecretString();
|
|
|
|
|
|
|
|
/// Constructor from a plain string.
|
|
|
|
wxSecretString(const wxString& value);
|
|
|
|
|
|
|
|
/// Constructor from a secret value.
|
|
|
|
explicit wxSecretString(const wxSecretValue& value);
|
|
|
|
|
|
|
|
/// Destructor calls wxSecretValue::WipeString()
|
|
|
|
~wxSecretString();
|
|
|
|
};
|
|
|
|
|
2016-05-28 19:13:44 -04:00
|
|
|
/**
|
|
|
|
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.
|
2016-06-04 13:21:16 -04:00
|
|
|
|
|
|
|
Notice that at least under MSW the maximal size of the secret is
|
|
|
|
limited. The exact limit depends on the OS version and is e.g. 2560 for
|
|
|
|
Windows 7.
|
2016-05-28 19:13:44 -04:00
|
|
|
*/
|
|
|
|
wxSecretValue(size_t size, const void *data);
|
|
|
|
|
2016-06-04 13:19:15 -04:00
|
|
|
/**
|
|
|
|
Creates a secret value from the given string.
|
|
|
|
|
|
|
|
The @a secret argument may contain NUL bytes.
|
|
|
|
|
|
|
|
The secret value will stored serialized in UTF-8 encoding.
|
|
|
|
*/
|
2016-06-24 08:21:46 -04:00
|
|
|
explicit wxSecretValue(const wxString& secret);
|
2016-06-04 13:19:15 -04:00
|
|
|
|
2016-05-28 19:13:44 -04:00
|
|
|
/**
|
|
|
|
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.
|
2016-06-04 13:19:15 -04:00
|
|
|
|
|
|
|
@see GetAsString()
|
2016-05-28 19:13:44 -04:00
|
|
|
*/
|
|
|
|
const void *GetData() const;
|
|
|
|
|
2016-06-04 13:19:15 -04:00
|
|
|
/**
|
|
|
|
Get the secret data as a string.
|
|
|
|
|
|
|
|
This is a more convenient but less secure alternative to using
|
|
|
|
GetSize() and GetData(), as this function creates another copy of a
|
|
|
|
secret which won't be wiped when this object is destroyed and you will
|
|
|
|
need to call WipeString() to overwrite the content of the returned
|
|
|
|
string, as well all its copies, if any, manually to avoid the secret
|
|
|
|
being left in memory.
|
|
|
|
|
|
|
|
This function uses the specified @a conv object to convert binary
|
|
|
|
secret data to string form. As the secret data may have been created
|
|
|
|
by external programs not using wxWidgets API, it may be not a valid
|
|
|
|
UTF-8-encoded string, so by default ::wxConvWhateverWorks, which tries
|
|
|
|
to interpret it in any way not avoiding loss of data, is used. However
|
|
|
|
if the secrets are only saved by the program itself and are known to be
|
2019-10-20 05:52:26 -04:00
|
|
|
always encoded in UTF-8, it may be better to pass ::wxMBConvUTF8 as the
|
2016-06-04 13:19:15 -04:00
|
|
|
converter to use.
|
|
|
|
*/
|
|
|
|
wxString GetAsString(const wxMBConv& conv = wxConvWhateverWorks) const;
|
|
|
|
|
2016-05-28 19:13:44 -04:00
|
|
|
/**
|
|
|
|
Erase the given area of memory overwriting its presumably sensitive
|
|
|
|
content.
|
|
|
|
*/
|
|
|
|
static void Wipe(size_t size, void *data);
|
2016-06-04 13:19:15 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
Overwrite the contents of the given string.
|
2021-01-09 19:21:45 -05:00
|
|
|
|
|
|
|
@see wxSecretString
|
2016-06-04 13:19:15 -04:00
|
|
|
*/
|
|
|
|
static void WipeString(wxString& str);
|
2016-05-28 19:13:44 -04:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
A collection of secrets, sometimes called a key chain.
|
|
|
|
|
|
|
|
This class provides access to the secrets stored in the OS-provided
|
2020-07-04 16:08:24 -04:00
|
|
|
facility, e.g. credentials manager under MSW, keychain under macOS or
|
2016-05-28 19:13:44 -04:00
|
|
|
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
|
2020-07-04 16:08:24 -04:00
|
|
|
MinGW32 which doesn't provide the required @c wincred.h header) and macOS
|
2016-05-28 19:13:44 -04:00
|
|
|
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.
|
|
|
|
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
Example of storing credentials using this class:
|
|
|
|
@code
|
|
|
|
wxSecretStore store = wxSecretStore::GetDefault();
|
2020-02-10 12:23:59 -05:00
|
|
|
wxString errmsg;
|
|
|
|
if ( store.IsOk(&errmsg) )
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
{
|
|
|
|
if ( !store.Save("MyApp/MyService", username, password) )
|
|
|
|
wxLogWarning("Failed to save credentials to the system secret store.");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-02-10 12:23:59 -05:00
|
|
|
wxLogWarning("This system doesn't support storing passwords securely "
|
|
|
|
"(%s).", errmsg);
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
}
|
|
|
|
@endcode
|
|
|
|
|
|
|
|
And to load it back:
|
|
|
|
@code
|
|
|
|
wxSecretStore store = wxSecretStore::GetDefault();
|
|
|
|
if ( store.IsOk() )
|
|
|
|
{
|
|
|
|
wxString username;
|
|
|
|
wxSecretValue password;
|
|
|
|
if ( store.Load("MyApp/MyService", username, password) )
|
|
|
|
... use the password ...
|
|
|
|
}
|
|
|
|
@endcode
|
|
|
|
|
2016-05-28 19:13:44 -04:00
|
|
|
@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.
|
2020-02-10 12:27:38 -05:00
|
|
|
|
|
|
|
Note that this method may show a dialog to the user under some
|
|
|
|
platforms, so it can take an arbitrarily long time to return.
|
2016-05-28 19:13:44 -04:00
|
|
|
*/
|
|
|
|
static wxSecretStore GetDefault();
|
|
|
|
|
|
|
|
/**
|
2020-02-10 12:23:59 -05:00
|
|
|
Check if this object can actually be used.
|
|
|
|
|
|
|
|
@param errmsg If not @NULL, this parameter is filled with a
|
|
|
|
user-readable error message explaining why the secret store can't
|
|
|
|
be used (this argument is new since wxWidgets 3.1.4)
|
2016-05-28 19:13:44 -04:00
|
|
|
*/
|
2020-02-10 12:23:59 -05:00
|
|
|
bool IsOk(wxString* errmsg = NULL) const;
|
2016-05-28 19:13:44 -04:00
|
|
|
|
|
|
|
/**
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
Store a username/password combination.
|
2016-05-28 19:13:44 -04:00
|
|
|
|
|
|
|
The service name should be user readable and unique.
|
|
|
|
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
If a secret with the same service name already exists, it will be
|
|
|
|
overwritten with the new value. In particular, notice that it is not
|
|
|
|
currently allowed to store passwords for different usernames for the
|
|
|
|
same service, even if the underlying platform API supports this (as is
|
|
|
|
the case for macOS but not MSW).
|
2016-05-28 19:13:44 -04:00
|
|
|
|
|
|
|
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,
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
const wxString& username,
|
|
|
|
const wxSecretValue& password);
|
2016-05-28 19:13:44 -04:00
|
|
|
|
|
|
|
/**
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
Look up the username/password for the given service.
|
|
|
|
|
|
|
|
If no username/password is found for the given service, false is
|
|
|
|
returned.
|
2016-05-28 19:13:44 -04:00
|
|
|
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
Otherwise the function returns true and updates the provided @a username
|
|
|
|
and @a password arguments.
|
2016-05-28 19:13:44 -04:00
|
|
|
*/
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
bool Load(const wxString& service,
|
|
|
|
wxString& username,
|
|
|
|
wxSecretValue& password) const;
|
2016-05-28 19:13:44 -04:00
|
|
|
|
|
|
|
/**
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
Delete a previously stored username/password combination.
|
2016-05-28 19:13:44 -04:00
|
|
|
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
If anything was deleted, returns true. Otherwise returns false and
|
|
|
|
logs an error if any error other than not finding any matches occurred.
|
2016-05-28 19:13:44 -04:00
|
|
|
*/
|
Change wxSecretStore API to allow retrieving the username
The old API didn't make any sense for the most common case when both the
user name and password need to be stored, as it required providing the
user name as input, which couldn't work (but somehow this went
unnoticed for more than a year...).
Fix this by returning the username, and not only the password, from
Load() instead of taking it as parameter and removing this parameter
from Delete() as well.
Also improve the documentation, notably include a simple example of
using this class.
Notice that this is a backwards-incompatible change, but the old API was
really badly broken and didn't appear in 3.1.0 yet, so the breakage is
both unavoidable and, hopefully, shouldn't affect much code.
Nevertheless, a special wxHAS_SECRETSTORE_LOAD_USERNAME symbol is added
to allow testing for it if necessary.
2017-07-16 17:47:15 -04:00
|
|
|
bool Delete(const wxString& service);
|
2016-05-28 19:13:44 -04:00
|
|
|
};
|