244 lines
6.1 KiB
C++
244 lines
6.1 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/common/secretstore.cpp
|
|
// Purpose: Common parts of wxSecretStore implementation.
|
|
// Author: Vadim Zeitlin
|
|
// Created: 2016-05-27
|
|
// Copyright: (c) 2016 Vadim Zeitlin <vadim@wxwidgets.org>
|
|
// Licence: wxWindows licence
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
// ============================================================================
|
|
// declarations
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// headers
|
|
// ----------------------------------------------------------------------------
|
|
|
|
// for compilers that support precompilation, includes "wx.h".
|
|
#include "wx/wxprec.h"
|
|
|
|
|
|
#if wxUSE_SECRETSTORE
|
|
|
|
#include "wx/secretstore.h"
|
|
|
|
#include "wx/log.h"
|
|
#include "wx/translation.h"
|
|
|
|
#include "wx/private/secretstore.h"
|
|
|
|
#include <string.h>
|
|
|
|
// ============================================================================
|
|
// wxSecretValue implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Memory management
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxSecretValue::wxSecretValue(const wxSecretValue& other)
|
|
: m_impl(other.m_impl)
|
|
{
|
|
if ( m_impl )
|
|
m_impl->IncRef();
|
|
}
|
|
|
|
wxSecretValue& wxSecretValue::operator=(const wxSecretValue& other)
|
|
{
|
|
// This code is written to be safe in case of self-assignment.
|
|
|
|
wxSecretValueImpl* const impl = other.m_impl;
|
|
if ( impl )
|
|
impl->IncRef();
|
|
|
|
if ( m_impl )
|
|
m_impl->DecRef();
|
|
|
|
m_impl = impl;
|
|
|
|
return *this;
|
|
}
|
|
|
|
wxSecretValue::~wxSecretValue()
|
|
{
|
|
if ( m_impl )
|
|
m_impl->DecRef();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Comparison
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool wxSecretValue::operator==(const wxSecretValue& other) const
|
|
{
|
|
// Two empty secrets are equal but no other secret is equal to the empty
|
|
// one (even the zero-length one).
|
|
if ( !m_impl )
|
|
return !other.m_impl;
|
|
|
|
wxSecretValueImpl* const impl = other.m_impl;
|
|
if ( !impl )
|
|
return false;
|
|
|
|
// Here both objects are not empty, so we can compare them.
|
|
return m_impl->GetSize() == impl->GetSize() &&
|
|
memcmp(m_impl->GetData(), impl->GetData(), m_impl->GetSize()) == 0;
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Methods forwarded to wxSecretValueImpl
|
|
// ----------------------------------------------------------------------------
|
|
|
|
size_t wxSecretValue::GetSize() const
|
|
{
|
|
return m_impl ? m_impl->GetSize() : (size_t)0;
|
|
}
|
|
|
|
const void *wxSecretValue::GetData() const
|
|
{
|
|
return m_impl ? m_impl->GetData() : NULL;
|
|
}
|
|
|
|
wxString wxSecretValue::GetAsString(const wxMBConv& conv) const
|
|
{
|
|
if ( !m_impl )
|
|
return wxString();
|
|
|
|
return wxString
|
|
(
|
|
static_cast<const char*>(m_impl->GetData()),
|
|
conv,
|
|
m_impl->GetSize()
|
|
);
|
|
}
|
|
|
|
#ifndef __WINDOWS__
|
|
|
|
/* static */
|
|
void wxSecretValue::Wipe(size_t size, void *data)
|
|
{
|
|
// memset_s() is not present under non-MSW systems anyhow and there doesn't
|
|
// seem to be any other way to portably ensure that the memory is really
|
|
// cleared, so just do it in this obvious way.
|
|
memset(data, 0, size);
|
|
}
|
|
|
|
#endif // __WINDOWS__
|
|
|
|
/* static */
|
|
void wxSecretValue::WipeString(wxString& str)
|
|
{
|
|
for ( wxString::iterator it = str.begin(); it != str.end(); ++it )
|
|
*it = '*';
|
|
}
|
|
|
|
// ============================================================================
|
|
// wxSecretStore implementation
|
|
// ============================================================================
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Memory management
|
|
// ----------------------------------------------------------------------------
|
|
|
|
wxSecretStore::wxSecretStore(const wxSecretStore& other)
|
|
: m_impl(other.m_impl)
|
|
{
|
|
if ( m_impl )
|
|
m_impl->IncRef();
|
|
}
|
|
|
|
wxSecretStore::~wxSecretStore()
|
|
{
|
|
if ( m_impl )
|
|
m_impl->DecRef();
|
|
}
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// Methods forwarded to wxSecretStoreImpl
|
|
// ----------------------------------------------------------------------------
|
|
|
|
bool
|
|
wxSecretStore::IsOk(wxString* errmsg) const
|
|
{
|
|
if ( !m_impl )
|
|
{
|
|
if ( errmsg )
|
|
*errmsg = _("Not available for this platform");
|
|
return false;
|
|
}
|
|
|
|
return m_impl->IsOk(errmsg);
|
|
}
|
|
|
|
bool
|
|
wxSecretStore::Save(const wxString& service,
|
|
const wxString& user,
|
|
const wxSecretValue& secret)
|
|
{
|
|
if ( !m_impl )
|
|
return false;
|
|
|
|
if ( !secret.m_impl )
|
|
return false;
|
|
|
|
wxString err;
|
|
if ( !m_impl->Save(service, user, *secret.m_impl, err) )
|
|
{
|
|
wxLogError(_("Saving password for \"%s\" failed: %s."),
|
|
service, err);
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
wxSecretStore::Load(const wxString& service,
|
|
wxString& user,
|
|
wxSecretValue& secret) const
|
|
{
|
|
if ( !m_impl )
|
|
return false;
|
|
|
|
wxString err;
|
|
wxSecretValueImpl* secretImpl = NULL;
|
|
if ( !m_impl->Load(service, &user, &secretImpl, err) )
|
|
{
|
|
if ( !err.empty() )
|
|
{
|
|
wxLogError(_("Reading password for \"%s\" failed: %s."),
|
|
service, err);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
secret = wxSecretValue(secretImpl);
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
wxSecretStore::Delete(const wxString& service)
|
|
{
|
|
if ( !m_impl )
|
|
return false;
|
|
|
|
wxString err;
|
|
if ( !m_impl->Delete(service, err) )
|
|
{
|
|
if ( !err.empty() )
|
|
{
|
|
wxLogError(_("Deleting password for \"%s\" failed: %s."),
|
|
service, err);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
#endif // wxUSE_SECRETSTORE
|