Now UI is working well enough to finally introduce secret management

First thing that is actually part of the final use case
This commit is contained in:
Cheng 2022-05-22 19:36:23 +10:00
parent 25ec24936f
commit e3ba96799c
No known key found for this signature in database
GPG Key ID: D51301E176B31828
8 changed files with 152 additions and 133 deletions

24
app.cpp
View File

@ -19,9 +19,9 @@ App::~App()
bool App::OnInit() bool App::OnInit()
{ if (wxApp::OnInit()) { { if (wxApp::OnInit()) {
SetVendorName(_T("rho")); /* This causes the non volatile config data to be stored under the rho on SetVendorName(wxT("rho")); /* This causes the non volatile config data to be stored under the rho on
windows.*/ windows.*/
SetAppName(_T("wallet")); /* This causes the non volatile config data to be stored under rho\wallet SetAppName(wxT("wallet")); /* This causes the non volatile config data to be stored under rho\wallet
We will generally place data in the database, and if additional executables need their own data We will generally place data in the database, and if additional executables need their own data
in the config, they will create their own subkey under Computer\HKEY_CURRENT_USER\Software\rho */ in the config, they will create their own subkey under Computer\HKEY_CURRENT_USER\Software\rho */
pConfig = std::unique_ptr<wxConfigBase>(wxConfigBase::Get()); pConfig = std::unique_ptr<wxConfigBase>(wxConfigBase::Get());
@ -91,7 +91,7 @@ bool App::OnExceptionInMainLoop()
error = wsz_program + _wx(sz_unknown_error); error = wsz_program + _wx(sz_unknown_error);
errorCode = 8; errorCode = 8;
} }
wxLogError(_T("%s"), error); wxLogError(wxT("%s"), error);
wxMessageDialog dlg(singletonFrame, error, wsz_error, wxICON_ERROR); wxMessageDialog dlg(singletonFrame, error, wsz_error, wxICON_ERROR);
dlg.SetId(myID_ERRORMESSAGE); dlg.SetId(myID_ERRORMESSAGE);
dlg.ShowModal(); dlg.ShowModal();
@ -103,7 +103,7 @@ void App::OnInitCmdLine(wxCmdLineParser& parser)
{ {
parser.SetDesc(g_cmdLineDesc); parser.SetDesc(g_cmdLineDesc);
// must refuse '/' as parameter starter or cannot use "/path" style paths // must refuse '/' as parameter starter or cannot use "/path" style paths
parser.SetSwitchChars(_T("-")); parser.SetSwitchChars(wxT("-"));
//Command line parameters //Command line parameters
parser.SetLogo(wsz_commandLineLogo); parser.SetLogo(wsz_commandLineLogo);
parser.AddUsageText(wsz_usageText); parser.AddUsageText(wsz_usageText);
@ -117,30 +117,30 @@ bool App::OnCmdLineParsed(wxCmdLineParser& parser)
{ {
case wxCMD_LINE_SWITCH: case wxCMD_LINE_SWITCH:
optionName = arg.GetShortName(); optionName = arg.GetShortName();
if (optionName == _T("t")) { if (optionName == wxT("t")) {
m_unit_test = !arg.IsNegated(); m_unit_test = !arg.IsNegated();
} }
else if (optionName == _T("l")) { else if (optionName == wxT("l")) {
m_display = !arg.IsNegated(); m_display = !arg.IsNegated();
} }
else if (optionName == _T("d")) { else if (optionName == wxT("d")) {
m_display |= m_display_in_front = !arg.IsNegated(); m_display |= m_display_in_front = !arg.IsNegated();
} }
else if (optionName == _T("f")) { else if (optionName == wxT("f")) {
m_log_focus_events = !arg.IsNegated(); m_log_focus_events = !arg.IsNegated();
if (m_log_focus_events) { if (m_log_focus_events) {
Bind( Bind(
wxEVT_IDLE, wxEVT_IDLE,
+[](wxIdleEvent& event) { //Since this function is only ever used once, never being unbound, using a lambda to avoid naming it. +[](wxIdleEvent& event) { //Since this function is only ever used once, never being unbound, using a lambda to avoid naming it.
static wxWindow* lastFocus = (wxWindow*)NULL; static wxWindow* lastFocus = (wxWindow*)NULL;
//wxLogMessage(_T("OnIdle")); //wxLogMessage(wxT("OnIdle"));
wxWindow* curFocus = ::wxWindow::FindFocus(); wxWindow* curFocus = ::wxWindow::FindFocus();
if (curFocus != lastFocus && curFocus) if (curFocus != lastFocus && curFocus)
{ {
lastFocus = curFocus; lastFocus = curFocus;
wxString name{ "" }; wxString name{ "" };
do { do {
name = wxString(_T("/")) + curFocus->GetClassInfo()->GetClassName() + _T(":") + curFocus->GetName() + name; name = wxString(wxT("/")) + curFocus->GetClassInfo()->GetClassName() + wxT(":") + curFocus->GetName() + name;
} while (curFocus = curFocus->GetParent()); } while (curFocus = curFocus->GetParent());
wxLogMessage(name); wxLogMessage(name);
} }
@ -149,11 +149,11 @@ bool App::OnCmdLineParsed(wxCmdLineParser& parser)
); );
} }
} }
else if (optionName == _T("q")) { else if (optionName == wxT("q")) {
m_quick_unit_test = !arg.IsNegated(); m_quick_unit_test = !arg.IsNegated();
m_complete_unit_test = m_complete_unit_test && !m_quick_unit_test; m_complete_unit_test = m_complete_unit_test && !m_quick_unit_test;
} }
else if (optionName == _T("c")) { else if (optionName == wxT("c")) {
m_complete_unit_test = !arg.IsNegated(); m_complete_unit_test = !arg.IsNegated();
m_quick_unit_test = m_quick_unit_test && !m_complete_unit_test; m_quick_unit_test = m_quick_unit_test && !m_complete_unit_test;
} }

View File

@ -1,12 +1,11 @@
#include "stdafx.h" #include "stdafx.h"
using ro::base58; using ro::base58;
display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) : display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) :
wxPanel(parent, myID_WALLET_UI, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, _T("Wallet")), wxPanel(parent, myID_WALLET_UI, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL, wxT("Wallet")),
m_db(nullptr), m_db(nullptr),
m_menuitem_close(this, &display_wallet::close_menu_event_handler),
m_menuitem_add_name(this, &display_wallet::add_name_event_handler) m_menuitem_add_name(this, &display_wallet::add_name_event_handler)
{ {
wxLogMessage(_T("Loading %s"), walletfile.GetFullPath()); wxLogMessage(wxT("Loading %s"), walletfile.GetFullPath());
if (!walletfile.IsOk() || !walletfile.HasName() || !walletfile.HasExt()) throw MyException("unexpected file name"); if (!walletfile.IsOk() || !walletfile.HasName() || !walletfile.HasExt()) throw MyException("unexpected file name");
if (!walletfile.FileExists())throw MyException( if (!walletfile.FileExists())throw MyException(
walletfile.GetFullPath().append(" does not exist.").ToUTF8() walletfile.GetFullPath().append(" does not exist.").ToUTF8()
@ -62,7 +61,6 @@ display_wallet::display_wallet(wxWindow* parent, wxFileName& walletfile) :
singletonFrame->m_LastUsedSqlite.Assign(walletfile); singletonFrame->m_LastUsedSqlite.Assign(walletfile);
wxMenu* menuFile{ singletonFrame->GetMenuBar()->GetMenu(0) }; wxMenu* menuFile{ singletonFrame->GetMenuBar()->GetMenu(0) };
m_menuitem_close.Insert(menuFile, 1, "close", "close wallet");
singletonFrame->GetMenuBar()->EnableTop(1, true); //enable edit menu. singletonFrame->GetMenuBar()->EnableTop(1, true); //enable edit menu.
wxMenu* menuEdit{ singletonFrame->GetMenuBar()->GetMenu(1) }; wxMenu* menuEdit{ singletonFrame->GetMenuBar()->GetMenu(1) };
m_menuitem_add_name.Insert(menuEdit, 0, "add name", "create new Zooko identity"); m_menuitem_add_name.Insert(menuEdit, 0, "add name", "create new Zooko identity");
@ -88,10 +86,14 @@ void display_wallet::add_name_event_handler(wxCommandEvent& event) {
wxOK | wxCANCEL); wxOK | wxCANCEL);
if (dialog.ShowModal() == wxID_OK) if (dialog.ShowModal() == wxID_OK)
{ {
wxMessageBox(dialog.GetValue(), "Got string", wxOK | wxICON_INFORMATION, this); std::string zookoNickname(dialog.GetValue().ToUTF8());
sql_insert_name insert_name(m_db);
auto zookoNickname_psz = zookoNickname.c_str();
insert_name(
zookoNickname_psz,
m_MasterSecret(zookoNickname_psz).timesBase()
);
} }
sql_insert_name insert_name(m_db);
insert_name(dialog.GetValue().ToUTF8(), m_MasterSecret(dialog.GetValue().ToUTF8()).timesBase());
} }

View File

@ -12,7 +12,6 @@ private:
wxBoxSizer* m_rSizer; wxBoxSizer* m_rSizer;
void close_menu_event_handler(wxCommandEvent&); void close_menu_event_handler(wxCommandEvent&);
void add_name_event_handler(wxCommandEvent&); void add_name_event_handler(wxCommandEvent&);
MenuLink m_menuitem_close;
MenuLink m_menuitem_add_name; MenuLink m_menuitem_add_name;
void OnClose(wxCloseEvent& event); void OnClose(wxCloseEvent& event);
}; };

139
frame.cpp
View File

@ -8,20 +8,20 @@ Frame* singletonFrame{nullptr};
void Frame::RestorePositionFromConfig(const wxSize& bestSize) { void Frame::RestorePositionFromConfig(const wxSize& bestSize) {
// SetPath() understands ".." but you should probably never use it. // SetPath() understands ".." but you should probably never use it.
singletonApp->pConfig->SetPath(_T("/MainFrame")); wxPoint scr{ wxSystemSettings::GetMetric(wxSYS_SCREEN_X), wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) }; singletonApp->pConfig->SetPath(wxT("/MainFrame")); wxPoint scr{ wxSystemSettings::GetMetric(wxSYS_SCREEN_X), wxSystemSettings::GetMetric(wxSYS_SCREEN_Y) };
// restore frame position and size // restore frame position and size
int x = singletonApp->pConfig->ReadLong(_T("x"), scr.x / 4); int x = singletonApp->pConfig->ReadLong(wxT("x"), scr.x / 4);
int y = singletonApp->pConfig->ReadLong(_T("y"), scr.y / 4); int y = singletonApp->pConfig->ReadLong(wxT("y"), scr.y / 4);
int w = singletonApp->pConfig->ReadLong(_T("w"), scr.x / 2); int w = singletonApp->pConfig->ReadLong(wxT("w"), scr.x / 2);
int h = singletonApp->pConfig->ReadLong(_T("h"), scr.y / 2); int h = singletonApp->pConfig->ReadLong(wxT("h"), scr.y / 2);
w = std::min(std::max(std::max(w, scr.x / 5), bestSize.GetWidth()), 8 * scr.x / 9); w = std::min(std::max(std::max(w, scr.x / 5), bestSize.GetWidth()), 8 * scr.x / 9);
h = std::min(std::max(std::max(h, scr.y / 9), bestSize.GetHeight()), 4 * scr.y / 5); h = std::min(std::max(std::max(h, scr.y / 9), bestSize.GetHeight()), 4 * scr.y / 5);
x = std::max(scr.x / 12, std::min(x, scr.x - w - scr.x / 12)); x = std::max(scr.x / 12, std::min(x, scr.x - w - scr.x / 12));
y = std::max(scr.y / 10, std::min(y, scr.y - h - scr.y / 10)); y = std::max(scr.y / 10, std::min(y, scr.y - h - scr.y / 10));
this->Move(x, y); this->Move(x, y);
this->Maximize(singletonApp->pConfig->ReadBool(_T("Maximized"), false)); this->Maximize(singletonApp->pConfig->ReadBool(wxT("Maximized"), false));
this->SetSize(w, h); this->SetSize(w, h);
singletonApp->pConfig->SetPath(_T("/")); singletonApp->pConfig->SetPath(wxT("/"));
if (singletonApp->m_display || m_pLogWindow != nullptr) { if (singletonApp->m_display || m_pLogWindow != nullptr) {
m_pLogWindow->GetFrame()->SetSize(w, h); m_pLogWindow->GetFrame()->SetSize(w, h);
if (singletonApp->m_display_in_front) { if (singletonApp->m_display_in_front) {
@ -40,22 +40,22 @@ void Frame::RestorePositionFromConfig(const wxSize& bestSize) {
void Frame::StorePositionToConfig() { void Frame::StorePositionToConfig() {
if (singletonApp->pConfig) { if (singletonApp->pConfig) {
singletonApp->pConfig->SetPath(_T("/MainFrame")); singletonApp->pConfig->SetPath(wxT("/MainFrame"));
if (this->IsMaximized()) { if (this->IsMaximized()) {
singletonApp->pConfig->Write(_T("Maximized"), true); singletonApp->pConfig->Write(wxT("Maximized"), true);
} }
else { else {
// save the frame position // save the frame position
int x, y, w, h; int x, y, w, h;
this->GetSize(&w, &h); this->GetSize(&w, &h);
this->GetPosition(&x, &y); this->GetPosition(&x, &y);
singletonApp->pConfig->Write(_T("x"), (long)x); singletonApp->pConfig->Write(wxT("x"), (long)x);
singletonApp->pConfig->Write(_T("y"), (long)y); singletonApp->pConfig->Write(wxT("y"), (long)y);
singletonApp->pConfig->Write(_T("w"), (long)w); singletonApp->pConfig->Write(wxT("w"), (long)w);
singletonApp->pConfig->Write(_T("h"), (long)h); singletonApp->pConfig->Write(wxT("h"), (long)h);
singletonApp->pConfig->Write(_T("Maximized"), false); singletonApp->pConfig->Write(wxT("Maximized"), false);
} }
singletonApp->pConfig->SetPath(_T("/")); singletonApp->pConfig->SetPath(wxT("/"));
} }
} }
@ -85,12 +85,12 @@ try {
m_pLogWindow->GetFrame()->SetName(sz_unit_test_log); m_pLogWindow->GetFrame()->SetName(sz_unit_test_log);
m_pLogWindow->GetFrame()->SetIcon(wxICON(AAArho)); m_pLogWindow->GetFrame()->SetIcon(wxICON(AAArho));
if (singletonApp->m_unit_test) { if (singletonApp->m_unit_test) {
wxLogMessage(_T("Command line specified %s unit test with%s exit on completion of unit test."), wxLogMessage(wxT("Command line specified %s unit test with%s exit on completion of unit test."),
singletonApp->m_complete_unit_test?_T("complete"): singletonApp->m_quick_unit_test?_T("quick"):_T(""), singletonApp->m_complete_unit_test?wxT("complete"): singletonApp->m_quick_unit_test?wxT("quick"):wxT(""),
singletonApp->m_display ? _T("out") : _T("")); singletonApp->m_display ? wxT("out") : wxT(""));
wxLogMessage(_T("If an error occurs during unit test, the program will return a non zero " wxLogMessage(wxT("If an error occurs during unit test, the program will return a non zero "
"error number on exit.")); "error number on exit."));
wxLogMessage(_T("")); wxLogMessage(wxT(""));
} }
}else { }else {
wxLog::EnableLogging(false); wxLog::EnableLogging(false);
@ -102,18 +102,18 @@ try {
&UnitTest &UnitTest
); );
if (singletonApp->m_log_focus_events) { if (singletonApp->m_log_focus_events) {
wxLogMessage(_T("Logging focus events")); wxLogMessage(wxT("Logging focus events"));
wxLogMessage(_T("")); wxLogMessage(wxT(""));
} }
if (singletonApp->m_params.empty()) { if (singletonApp->m_params.empty()) {
wxLogMessage(_T("No wallet specified. Attempting to open last used wallet")); wxLogMessage(wxT("No wallet specified. Attempting to open last used wallet"));
}else { }else {
wxString subcommands( _T("")); wxString subcommands( wxT(""));
for (auto& str : singletonApp->m_params) { for (auto& str : singletonApp->m_params) {
subcommands += str + _T(" "); subcommands += str + wxT(" ");
} }
wxLogMessage(_T("command argument%s %s"), singletonApp->m_params.size()==1?"":"s", subcommands); wxLogMessage(wxT("command argument%s %s"), singletonApp->m_params.size()==1?"":"s", subcommands);
wxLogMessage(_T("attempting to open %s"), singletonApp->m_params[0]); wxLogMessage(wxT("attempting to open %s"), singletonApp->m_params[0]);
} }
SetIcon(wxICON(AAArho)); //Does not appear to do anything. Maybe it does something in Unix. SetIcon(wxICON(AAArho)); //Does not appear to do anything. Maybe it does something in Unix.
//wxICON is a namestring on windows, and a symbol on Unix //wxICON is a namestring on windows, and a symbol on Unix
@ -128,12 +128,13 @@ try {
menuFile->Append(wxID_OPEN, menu_strings[0].tail[2][0], menu_strings[0].tail[2][1]); menuFile->Append(wxID_OPEN, menu_strings[0].tail[2][0], menu_strings[0].tail[2][1]);
menuFile->Bind(wxEVT_MENU, &Frame::OnFileOpen, this, wxID_OPEN); menuFile->Bind(wxEVT_MENU, &Frame::OnFileOpen, this, wxID_OPEN);
menuFile->Append(wxID_DELETE, menu_strings[0].tail[3][0], menu_strings[0].tail[3][1] + m_LastUsedSqlite.GetFullPath()); { auto _ = new wxMenuItem(menuFile, wxID_CLOSE);
wxLogMessage(m_LastUsedSqlite.GetFullPath()+" wallet path"); _->SetHelp(menu_strings[0].tail[3][1] + m_LastUsedSqlite.GetFullPath());
menuFile->Bind(wxEVT_MENU, &Frame::OnDelete, this, wxID_DELETE); menuFile->Append(myID_DELETECONFIG, menu_strings[0].tail[4][0], menu_strings[0].tail[4][1] + m_LastUsedSqlite.GetFullPath()); menuFile->Append(_);
menuFile->Bind(wxEVT_MENU, &Frame::OnMyCloseMPanel, this, wxID_CLOSE);
}
menuFile->Append(myID_DELETECONFIG, menu_strings[0].tail[4][0], menu_strings[0].tail[4][1] + m_LastUsedSqlite.GetFullPath());
menuFile->Bind(wxEVT_MENU, &Frame::OnDeleteConfiguration, this, myID_DELETECONFIG); menuFile->Bind(wxEVT_MENU, &Frame::OnDeleteConfiguration, this, myID_DELETECONFIG);
menuFile->Append(myID_MYEXIT,"my exit, testing destruction");
menuFile->Bind(wxEVT_MENU, &Frame::OnMyCloseMpanel, this, myID_MYEXIT);
menuFile->Append(wxID_EXIT); menuFile->Append(wxID_EXIT);
menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT); menuFile->Bind(wxEVT_MENU, &Frame::OnExit, this, wxID_EXIT);
@ -148,7 +149,7 @@ try {
CreateStatusBar(); CreateStatusBar();
menuBar->EnableTop(1, false); //disable edit menu. menuBar->EnableTop(1, false); //disable edit menu.
// child controls // child controls
m_LastUsedSqlite.Assign(singletonApp->pConfig->Read(_T("/Wallet/LastUsed"), _T(""))); m_LastUsedSqlite.Assign(singletonApp->pConfig->Read(wxT("/Wallet/LastUsed"), wxT("")));
if (!m_LastUsedSqlite.IsOk() || !m_LastUsedSqlite.HasName() || !m_LastUsedSqlite.HasExt()) { if (!m_LastUsedSqlite.IsOk() || !m_LastUsedSqlite.HasName() || !m_LastUsedSqlite.HasExt()) {
m_panel = new welcome_to_rhocoin(this); //Owner is "this", via the base class wxFrame. m_panel is a m_panel = new welcome_to_rhocoin(this); //Owner is "this", via the base class wxFrame. m_panel is a
// non owning pointer in the derived class that duplicates the owning pointer in the base class. // non owning pointer in the derived class that duplicates the owning pointer in the base class.
@ -169,11 +170,6 @@ try {
queue_error_message(e.what()); queue_error_message(e.what());
} }
} }
void Frame::OnMyCloseMpanel(wxCommandEvent& event) {
if (m_panel) {
m_panel->Close(true);
}
}
void Frame::OnExit(wxCommandEvent& event) { void Frame::OnExit(wxCommandEvent& event) {
if (m_panel) { if (m_panel) {
@ -187,7 +183,7 @@ void Frame::OnClose(wxCloseEvent& event) {
// This event gives you the opportunity to clean up anything that needs explicit cleanup, albeit if you have done your work right nothing should need explicit cleanup, // This event gives you the opportunity to clean up anything that needs explicit cleanup, albeit if you have done your work right nothing should need explicit cleanup,
// and to object to the closing in a "file not saved" type situation. // and to object to the closing in a "file not saved" type situation.
// https://docs.wxwidgets.org/trunk/classwx_close_event.html // https://docs.wxwidgets.org/trunk/classwx_close_event.html
if (sqlite3_shutdown())wxMessageBox(_T(R"|(Sqlite3 shutdown error)|"), wsz_error, wxICON_ERROR); if (sqlite3_shutdown())wxMessageBox(wxT(R"|(Sqlite3 shutdown error)|"), wsz_error, wxICON_ERROR);
DestroyChildren(); DestroyChildren();
Destroy(); //Default handler will destroy the window. This is our handler for the user calling close, replacing the default handler. Destroy(); //Default handler will destroy the window. This is our handler for the user calling close, replacing the default handler.
} }
@ -205,17 +201,17 @@ void Frame::OnDeleteConfiguration(wxCommandEvent&)
{ {
if (pConfig->DeleteAll()) if (pConfig->DeleteAll())
{ {
wxLogMessage(_T("Config file/registry key successfully deleted.")); wxLogMessage(wxT("Config file/registry key successfully deleted."));
wxConfigBase::DontCreateOnDemand(); wxConfigBase::DontCreateOnDemand();
pConfig.release(); pConfig.release();
} }
else else
{ {
wxLogError(_T("Deleting config file/registry key failed.")); wxLogError(wxT("Deleting config file/registry key failed."));
} }
} }
else { else {
wxLogError(_T("No config to delete!")); wxLogError(wxT("No config to delete!"));
return; return;
} }
} }
@ -271,6 +267,17 @@ COMMIT;)|");
} }
} }
class hide_panel {
wxPanel* oldpanel;
public:
hide_panel(wxPanel* v): oldpanel(v){
v->Hide();
}
~hide_panel() {
if (oldpanel == singletonFrame->m_panel) oldpanel->Show();
}
};
void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event)) void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event))
{ {
wxFileDialog dialog(this, wxFileDialog dialog(this,
@ -279,25 +286,27 @@ void Frame::OnSaveNew(wxCommandEvent& WXUNUSED(event))
sz_default_wallet_name, sz_default_wallet_name,
sz_wallet_files_title, sz_wallet_files_title,
wxFD_SAVE | wxFD_OVERWRITE_PROMPT); wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
dialog.SetFilterIndex(1); dialog.SetFilterIndex(1);
if (dialog.ShowModal() == wxID_OK) if (dialog.ShowModal() == wxID_OK)
{ {
wxLogMessage("%s, filter %d", wxLogMessage("%s, filter %d",
dialog.GetPath(), dialog.GetFilterIndex()); dialog.GetPath(), dialog.GetFilterIndex());
hide_panel hid(m_panel);
wxString wxStrWallet{ dialog.GetDirectory() + "/" + dialog.GetFilename() };
wxFileName wxFileWallet(wxStrWallet);
ristretto255::hash<256> WalletSecret{ wxStrWallet.ToUTF8() };
NewWallet(wxFileWallet, WalletSecret);
wxLogMessage("new wallet created: %s", wxStrWallet);
display_wallet* panel = new display_wallet(this, wxFileWallet);
if (m_panel)m_panel->Destroy();
m_panel = panel;
m_panel->Show();
} }
wxString wxStrWallet{ dialog.GetDirectory() + "/" + dialog.GetFilename() };
wxFileName wxFileWallet(wxStrWallet);
ristretto255::hash<256> WalletSecret{ wxStrWallet.ToUTF8() };
NewWallet(wxFileWallet, WalletSecret);
wxLogMessage("new wallet created: %s", wxStrWallet);
wxConfigBase::Get()->Write(_T("/Wallet/ LastUsed"), wxStrWallet);
} }
void Frame::OnFileOpen(wxCommandEvent&) { void Frame::OnFileOpen(wxCommandEvent&) {
wxString directory{ _T("") }; wxString directory{ wxT("") };
wxString file{ _T("") }; wxString file{ wxT("") };
if (m_LastUsedSqlite.IsOk()) { if (m_LastUsedSqlite.IsOk()) {
directory = m_LastUsedSqlite.GetPath(); directory = m_LastUsedSqlite.GetPath();
file = m_LastUsedSqlite.GetFullName(); file = m_LastUsedSqlite.GetFullName();
@ -318,7 +327,7 @@ void Frame::OnFileOpen(wxCommandEvent&) {
} }
void Frame::RecreateWalletFromExistingSecret(wxCommandEvent&) { void Frame::RecreateWalletFromExistingSecret(wxCommandEvent&) {
wxMessageBox(_T("new wallet existing secret event"), _T("")); wxMessageBox(wxT("new wallet existing secret event"), wxT(""));
auto standardpaths = wxStandardPaths::Get(); auto standardpaths = wxStandardPaths::Get();
wxFileDialog dialog(this, wxFileDialog dialog(this,
sz_new_wallet_existing_secret, sz_new_wallet_existing_secret,
@ -336,22 +345,24 @@ void Frame::RecreateWalletFromExistingSecret(wxCommandEvent&) {
} }
} }
void Frame::OnDelete(wxCommandEvent& WXUNUSED(event)) void Frame::OnMyCloseMPanel(wxCommandEvent& event) {
{ if (m_panel) {
singletonApp->pConfig->SetPath(_T("/Wallet")); if (!m_panel->Close(false)) throw MyException("Close cancelled");
wxFileName LastUsedSqlite(singletonApp->pConfig->Read(_T("LastUsed"), _T("")));
singletonApp->pConfig->DeleteEntry(_T("LastUsed"));
if (LastUsedSqlite.IsOk() && LastUsedSqlite.FileExists()) {
if (wxRemoveFile(LastUsedSqlite.GetFullPath()))wxLogMessage(_T("Deleting % s"), LastUsedSqlite.GetFullPath());
} }
LastUsedSqlite.Clear(); assert(m_panel == nullptr);
singletonApp->pConfig->SetPath(wxT("/Wallet"));
if (singletonApp->pConfig->Read(wxT("LastUsed"), wxT("")) == m_LastUsedSqlite.GetFullPath()) {
singletonApp->pConfig->DeleteEntry(wxT("LastUsed"));
m_LastUsedSqlite.Clear();
}
assert(m_panel == nullptr);
} }
void Frame::OnMenuOpen(wxMenuEvent& evt) { void Frame::OnMenuOpen(wxMenuEvent& evt) {
auto pMenu(evt.GetMenu()); auto pMenu(evt.GetMenu());
if (pMenu) { if (pMenu) {
auto label(pMenu->GetTitle()); auto label(pMenu->GetTitle());
wxLogMessage(_T("Open menu \"%s\""), label); wxLogMessage(wxT("Open menu \"%s\""), label);
} }
} }
@ -361,7 +372,7 @@ Frame::~Frame() {
wxConfigBase* pConfig = wxConfigBase::Get(); wxConfigBase* pConfig = wxConfigBase::Get();
if (pConfig == nullptr)return; if (pConfig == nullptr)return;
StorePositionToConfig(); StorePositionToConfig();
if (singletonApp->pConfig->Read(_T("/Wallet/LastUsed"), _T("")) != m_LastUsedSqlite.GetFullPath()) { if (singletonApp->pConfig->Read(wxT("/Wallet/LastUsed"), wxT("")) != m_LastUsedSqlite.GetFullPath()) {
pConfig->Write(_T("/Wallet/LastUsed"), m_LastUsedSqlite.GetFullPath()); pConfig->Write(wxT("/Wallet/LastUsed"), m_LastUsedSqlite.GetFullPath());
} }
} }

View File

@ -70,22 +70,19 @@ private:
void StorePositionToConfig(void); void StorePositionToConfig(void);
void RestorePositionFromConfig(const wxSize&); void RestorePositionFromConfig(const wxSize&);
void OnExit(wxCommandEvent&); void OnExit(wxCommandEvent&);
void OnClose(wxCloseEvent&);
void OnAbout(wxCommandEvent&); void OnAbout(wxCommandEvent&);
void OnDeleteConfiguration(wxCommandEvent&); void OnDeleteConfiguration(wxCommandEvent&);
void OnMyCloseMpanel(wxCommandEvent&); void OnMyCloseMPanel(wxCommandEvent&);
public: public:
void OnSaveNew(wxCommandEvent&); void OnSaveNew(wxCommandEvent&);
void NewWallet(wxFileName&, ristretto255::hash<256>&); void NewWallet(wxFileName&, ristretto255::hash<256>&);
void RecreateWalletFromExistingSecret(wxCommandEvent&); void RecreateWalletFromExistingSecret(wxCommandEvent&);
void OnFileOpen(wxCommandEvent&); void OnFileOpen(wxCommandEvent&);
void OnClose(wxCloseEvent& event);
private: private:
void OnMenuOpen(wxMenuEvent&); void OnMenuOpen(wxMenuEvent&);
public: public:
void OnDelete(wxCommandEvent&);
void OnFirstUse(wxCommandEvent&); void OnFirstUse(wxCommandEvent&);
public: public:

View File

@ -76,7 +76,7 @@ static const char * file_menu_strings[][2]{
{"&New wallet...", "New wallet file From new secret"}, {"&New wallet...", "New wallet file From new secret"},
{"Existing secret...","New Wallet File From the secret of an old wallet"}, {"Existing secret...","New Wallet File From the secret of an old wallet"},
{"&Open existing wallet file...",""}, {"&Open existing wallet file...",""},
{"&Delete Wallet File","Delete"}, {nullptr,"Close"},
{"&Reset defaults","Delete config file"}}; {"&Reset defaults","Delete config file"}};
const menu_string menu_strings_[]{ const menu_string menu_strings_[]{

View File

@ -72,6 +72,16 @@ namespace ro {
CompileSizedString() { CompileSizedString() {
*(this->rbegin()) = '0'; *(this->rbegin()) = '0';
} }
CompileSizedString(char *psz) {
auto tsz{ this->rbegin() };
*tsz = '0';
if (psz != nullptr) {
auto usz = tsz + strlen;
while (tsz < usz && *psz != '\0')
*tsz++ = *psz++;
*tsz = '\0';
}
}
operator char* () & { operator char* () & {
char* pc = &(static_cast<std::array<char, stringlen + 1>*>(this)->operator[](0)); char* pc = &(static_cast<std::array<char, stringlen + 1>*>(this)->operator[](0));
return pc; return pc;

View File

@ -41,16 +41,16 @@ protected:
virtual int Enter(wxDialog* dlg) wxOVERRIDE virtual int Enter(wxDialog* dlg) wxOVERRIDE
{ {
wxLogMessage( wxLogMessage(
_T("Showing %s:%s dialog"), wxT("Showing %s:%s dialog"),
dlg->GetClassInfo()->GetClassName(), dlg->GetClassInfo()->GetClassName(),
dlg->GetLabel() dlg->GetLabel()
); );
auto x = dlg->GetId(); auto x = dlg->GetId();
switch (x) { switch (x) {
case myID_ERRORMESSAGE: case myID_ERRORMESSAGE:
wxLogMessage(_T("\tError message modal dialog")); wxLogMessage(wxT("\tError message modal dialog"));
unit_test_action = next_action; unit_test_action = next_action;
wxLogMessage(_T("\tClosing dialog")); wxLogMessage(wxT("\tClosing dialog"));
return wxID_OK; return wxID_OK;
default: default:
return wxID_NONE; return wxID_NONE;
@ -82,7 +82,7 @@ static bool EndUnitTest() {
ILogMessage("Passed Unit Test"); ILogMessage("Passed Unit Test");
} }
else { else {
wxLogMessage(_T("\nFailed Unit Test\nunit test error %d\n%s"), wxLogMessage(wxT("\nFailed Unit Test\nunit test error %d\n%s"),
errorCode, _wx(szError.c_str()) errorCode, _wx(szError.c_str())
); );
} }
@ -251,12 +251,12 @@ static bool CheckForUtfEnvironment(void) {
ILogMessage("\tChecking for UTF locale."); ILogMessage("\tChecking for UTF locale.");
try { try {
bool utfEnvironment{ true }; bool utfEnvironment{ true };
wxString utfError{ _T("") }; wxString utfError{ wxT("") };
if constexpr (b_WINDOWS) { if constexpr (b_WINDOWS) {
auto ACP{ GetACP() }; auto ACP{ GetACP() };
utfEnvironment = utfEnvironment && (ACP == 65001); utfEnvironment = utfEnvironment && (ACP == 65001);
if (!utfEnvironment) { if (!utfEnvironment) {
utfError += wxString::Format(_T("current code page %d—should be 65001☹, "), ACP); utfError += wxString::Format(wxT("current code page %d—should be 65001☹, "), ACP);
} }
} }
auto FontEncoding{ wxLocale::GetSystemEncoding() }; auto FontEncoding{ wxLocale::GetSystemEncoding() };
@ -269,11 +269,11 @@ static bool CheckForUtfEnvironment(void) {
|| (FontEncoding == wxFONTENCODING_SYSTEM) || (FontEncoding == wxFONTENCODING_SYSTEM)
); );
if (!utfEnvironment) { if (!utfEnvironment) {
utfError = wxString::Format(_T("%swxFontEncoding %d—should be %d☹"), utfError = wxString::Format(wxT("%swxFontEncoding %d—should be %d☹"),
utfError, utfError,
FontEncoding, FontEncoding,
wxFONTENCODING_UTF8); wxFONTENCODING_UTF8);
wxLogMessage(_T("%s"), utfError); wxLogMessage(wxT("%s"), utfError);
} }
if (!utfEnvironment) { throw MyException(utfError); } if (!utfEnvironment) { throw MyException(utfError); }
} }
@ -367,19 +367,19 @@ static bool OpenWallet(void) {
wallet file.*/ wallet file.*/
ILogMessage("\tWallet file"); ILogMessage("\tWallet file");
assert(singletonApp->pConfig); assert(singletonApp->pConfig);
singletonApp->pConfig->SetPath(_T("/Wallet")); singletonApp->pConfig->SetPath(wxT("/Wallet"));
wxFileName LastUsedSqlite(singletonApp->pConfig->Read(_T("LastUsed"), _T(""))); wxFileName LastUsedSqlite(singletonApp->pConfig->Read(wxT("LastUsed"), wxT("")));
bool fWalletNameOk{ false }; bool fWalletNameOk{ false };
wxStandardPaths& StandardPaths(wxStandardPaths::Get()); wxStandardPaths& StandardPaths(wxStandardPaths::Get());
StandardPaths.UseAppInfo(3); StandardPaths.UseAppInfo(3);
wxFileName DefaultSqlite(StandardPaths.GetUserLocalDataDir(), "default.wallet"); wxFileName DefaultSqlite(StandardPaths.GetUserLocalDataDir(), "default.wallet");
wxLogMessage(_T("\t\tLastUsed=\"%s\""), LastUsedSqlite.GetFullPath()); wxLogMessage(wxT("\t\tLastUsed=\"%s\""), LastUsedSqlite.GetFullPath());
if (!LastUsedSqlite.IsOk() || !LastUsedSqlite.HasName() || !LastUsedSqlite.HasExt()) { if (!LastUsedSqlite.IsOk() || !LastUsedSqlite.HasName() || !LastUsedSqlite.HasExt()) {
wxLogMessage(_T("\t\tDefault=\"%s\""), DefaultSqlite.GetFullPath()); wxLogMessage(wxT("\t\tDefault=\"%s\""), DefaultSqlite.GetFullPath());
assert(DefaultSqlite.IsOk() && DefaultSqlite.HasName() && DefaultSqlite.HasExt()); assert(DefaultSqlite.IsOk() && DefaultSqlite.HasName() && DefaultSqlite.HasExt());
if (DefaultSqlite.FileExists()) { if (DefaultSqlite.FileExists()) {
LastUsedSqlite = DefaultSqlite; LastUsedSqlite = DefaultSqlite;
singletonApp->pConfig->Write(_T("LastUsed"), DefaultSqlite.GetFullPath()); singletonApp->pConfig->Write(wxT("LastUsed"), DefaultSqlite.GetFullPath());
fWalletNameOk = true; fWalletNameOk = true;
} }
} }
@ -408,7 +408,7 @@ static bool OpenWallet(void) {
} }
const char* name = read_name.name(); const char* name = read_name.name();
if(MasterSecret(name).timesBase()!=*pubkey)throw MyException(R"|(Public key of name fails to correspond)|"); if(MasterSecret(name).timesBase()!=*pubkey)throw MyException(R"|(Public key of name fails to correspond)|");
wxLogMessage(_T("\t\t\"%s\" has expected public key 0x%s"), name, (wxString)(bin2hex(*pubkey))); wxLogMessage(wxT("\t\t\"%s\" has expected public key 0x%s"), name, (wxString)(bin2hex(*pubkey)));
} }
} }
else { else {
@ -440,16 +440,16 @@ CREATE TABLE "Misc"(
); );
COMMIT;)|"); COMMIT;)|");
LastUsedSqlite = DefaultSqlite; LastUsedSqlite = DefaultSqlite;
singletonApp->pConfig->Write(_T("LastUsed"), DefaultSqlite.GetFullPath()); singletonApp->pConfig->Write(wxT("LastUsed"), DefaultSqlite.GetFullPath());
wxLogMessage(_T("\t\tConstructing default wallet %s"), DefaultSqlite.GetFullPath()); wxLogMessage(wxT("\t\tConstructing default wallet %s"), DefaultSqlite.GetFullPath());
// We now have a working wallet file with no valid data. Attempting to create a strong random secret, a name, and public and private keys for that name. // We now have a working wallet file with no valid data. Attempting to create a strong random secret, a name, and public and private keys for that name.
wxLogMessage(_T("\t\tGenerating random 128 bit wallet secret")); wxLogMessage(wxT("\t\tGenerating random 128 bit wallet secret"));
auto text_secret{ DeriveTextSecret(ristretto255::scalar::random(), 1) }; auto text_secret{ DeriveTextSecret(ristretto255::scalar::random(), 1) };
ro::msec start_time{ ro::msec_since_epoch() }; ro::msec start_time{ ro::msec_since_epoch() };
ristretto255::CMasterSecret MasterSecret(DeriveStrongSecret(&text_secret[0]) ); ristretto255::CMasterSecret MasterSecret(DeriveStrongSecret(&text_secret[0]) );
decltype(start_time) end_time{ ro::msec_since_epoch() }; decltype(start_time) end_time{ ro::msec_since_epoch() };
wxLogMessage(_T("\t\tStrong secret derivation took %d milliseconds"), (end_time - start_time).count()); wxLogMessage(wxT("\t\tStrong secret derivation took %d milliseconds"), (end_time - start_time).count());
sql_update_to_misc update_to_misc(db.get()); sql_update_to_misc update_to_misc(db.get());
update_to_misc(1, WALLET_FILE_IDENTIFIER); update_to_misc(1, WALLET_FILE_IDENTIFIER);
update_to_misc(2, WALLET_FILE_SCHEMA_VERSION_0_0); update_to_misc(2, WALLET_FILE_SCHEMA_VERSION_0_0);
@ -689,30 +689,30 @@ static bool TestShareSecretGenerationSpeed(void) {
szError = "Fail\tro:deserialize ro:deserialize on integers produced unexpected results."; szError = "Fail\tro:deserialize ro:deserialize on integers produced unexpected results.";
ILogError(szError.c_str()); ILogError(szError.c_str());
} }
wxLogMessage(_T("\tLibsodium constants\n\t\tsizeof(crypto_secretstream_xchacha20poly1305_state)=%d"), int(sizeof(crypto_secretstream_xchacha20poly1305_state))); wxLogMessage(wxT("\tLibsodium constants\n\t\tsizeof(crypto_secretstream_xchacha20poly1305_state)=%d"), int(sizeof(crypto_secretstream_xchacha20poly1305_state)));
wxLogMessage(_T("\t\tcrypto_generichash_KEYBYTES=%d"), crypto_generichash_KEYBYTES); wxLogMessage(wxT("\t\tcrypto_generichash_KEYBYTES=%d"), crypto_generichash_KEYBYTES);
wxLogMessage(_T("\t\tcrypto_secretstream_xchacha20poly1305_KEYBYTES=%d"), crypto_secretstream_xchacha20poly1305_KEYBYTES); wxLogMessage(wxT("\t\tcrypto_secretstream_xchacha20poly1305_KEYBYTES=%d"), crypto_secretstream_xchacha20poly1305_KEYBYTES);
wxLogMessage(_T("\t\tcrypto_secretstream_xchacha20poly1305_HEADERBYTES=%d"), crypto_secretstream_xchacha20poly1305_HEADERBYTES); wxLogMessage(wxT("\t\tcrypto_secretstream_xchacha20poly1305_HEADERBYTES=%d"), crypto_secretstream_xchacha20poly1305_HEADERBYTES);
wxLogMessage(_T("\t\tchecksum size == crypto_secretstream_xchacha20poly1305_ABYTES ==%d"), crypto_secretstream_xchacha20poly1305_ABYTES); wxLogMessage(wxT("\t\tchecksum size == crypto_secretstream_xchacha20poly1305_ABYTES ==%d"), crypto_secretstream_xchacha20poly1305_ABYTES);
wxLogMessage(_T("\t\tcrypto_pwhash_OPSLIMIT_MIN ==\t%08x"), crypto_pwhash_OPSLIMIT_MIN); wxLogMessage(wxT("\t\tcrypto_pwhash_OPSLIMIT_MIN ==\t%08x"), crypto_pwhash_OPSLIMIT_MIN);
wxLogMessage(_T("\t\tcrypto_pwhash_OPSLIMIT_MODERATE ==\t%08x"), crypto_pwhash_OPSLIMIT_MODERATE); wxLogMessage(wxT("\t\tcrypto_pwhash_OPSLIMIT_MODERATE ==\t%08x"), crypto_pwhash_OPSLIMIT_MODERATE);
wxLogMessage(_T("\t\tcrypto_pwhash_OPSLIMIT_SENSITIVE ==\t%08x"), crypto_pwhash_OPSLIMIT_SENSITIVE); wxLogMessage(wxT("\t\tcrypto_pwhash_OPSLIMIT_SENSITIVE ==\t%08x"), crypto_pwhash_OPSLIMIT_SENSITIVE);
wxLogMessage(_T("\t\tcrypto_pwhash_OPSLIMIT_MAX ==\t%08x"), crypto_pwhash_OPSLIMIT_MAX); wxLogMessage(wxT("\t\tcrypto_pwhash_OPSLIMIT_MAX ==\t%08x"), crypto_pwhash_OPSLIMIT_MAX);
wxLogMessage(_T("\t\tcrypto_pwhash_MEMLIMIT_MIN ==\t%08x"), crypto_pwhash_MEMLIMIT_MIN); wxLogMessage(wxT("\t\tcrypto_pwhash_MEMLIMIT_MIN ==\t%08x"), crypto_pwhash_MEMLIMIT_MIN);
wxLogMessage(_T("\t\tcrypto_pwhash_MEMLIMIT_MODERATE==%08x"), crypto_pwhash_MEMLIMIT_MODERATE); wxLogMessage(wxT("\t\tcrypto_pwhash_MEMLIMIT_MODERATE==%08x"), crypto_pwhash_MEMLIMIT_MODERATE);
wxLogMessage(_T("\t\tcrypto_pwhash_MEMLIMIT_SENSITIVE==\t%08x"), crypto_pwhash_MEMLIMIT_SENSITIVE); wxLogMessage(wxT("\t\tcrypto_pwhash_MEMLIMIT_SENSITIVE==\t%08x"), crypto_pwhash_MEMLIMIT_SENSITIVE);
wxLogMessage(_T("\t\tcrypto_auth_BYTES ==\t\t%08x"), crypto_auth_BYTES); wxLogMessage(wxT("\t\tcrypto_auth_BYTES ==\t\t%08x"), crypto_auth_BYTES);
wxLogMessage(_T("\t\tcrypto_stream_chacha20_NONCEBYTES\t%08x"), crypto_stream_chacha20_NONCEBYTES); wxLogMessage(wxT("\t\tcrypto_stream_chacha20_NONCEBYTES\t%08x"), crypto_stream_chacha20_NONCEBYTES);
wxLogMessage(_T("\t\tcrypto_stream_chacha20_KEYBYTES ==\t%08x"), crypto_stream_chacha20_KEYBYTES); wxLogMessage(wxT("\t\tcrypto_stream_chacha20_KEYBYTES ==\t%08x"), crypto_stream_chacha20_KEYBYTES);
wxLogMessage(_T("\t\tchacha20 is 2^(256+128) 512 bit pseudo random blocks")); wxLogMessage(wxT("\t\tchacha20 is 2^(256+128) 512 bit pseudo random blocks"));
wxLogMessage(_T("\t\tcrypto_stream_xchacha20_NONCEBYTES\t%08x"), crypto_stream_xchacha20_NONCEBYTES); wxLogMessage(wxT("\t\tcrypto_stream_xchacha20_NONCEBYTES\t%08x"), crypto_stream_xchacha20_NONCEBYTES);
wxLogMessage(_T("\t\tcrypto_stream_xchacha20_KEYBYTES ==\t%08x"), crypto_stream_chacha20_KEYBYTES); wxLogMessage(wxT("\t\tcrypto_stream_xchacha20_KEYBYTES ==\t%08x"), crypto_stream_chacha20_KEYBYTES);
wxLogMessage(_T("\t\txchacha20 is 2^512 512 bit pseudo random blocks")); wxLogMessage(wxT("\t\txchacha20 is 2^512 512 bit pseudo random blocks"));
wxLogMessage(_T("\t\tmin hash size is %d bits"), crypto_generichash_BYTES_MIN * 8); wxLogMessage(wxT("\t\tmin hash size is %d bits"), crypto_generichash_BYTES_MIN * 8);
wxLogMessage(_T("\t\tmax hash size is %d bits"), crypto_generichash_BYTES_MAX * 8); wxLogMessage(wxT("\t\tmax hash size is %d bits"), crypto_generichash_BYTES_MAX * 8);
wxLogMessage(_T("\t\tcrypto_shorthash_BYTES\t== %08x"), crypto_shorthash_BYTES); wxLogMessage(wxT("\t\tcrypto_shorthash_BYTES\t== %08x"), crypto_shorthash_BYTES);
wxLogMessage(_T("\t\tcrypto_shorthash_KEYBYTES\t== %08x"), crypto_shorthash_KEYBYTES); wxLogMessage(wxT("\t\tcrypto_shorthash_KEYBYTES\t== %08x"), crypto_shorthash_KEYBYTES);
wxLogMessage(_T("\t\tcrypto_auth_BYTES\t\t== %08x"), crypto_auth_BYTES); wxLogMessage(wxT("\t\tcrypto_auth_BYTES\t\t== %08x"), crypto_auth_BYTES);
} }
catch (const std::exception & e) { catch (const std::exception & e) {
errorCode = 15; errorCode = 15;
@ -820,7 +820,7 @@ static bool TestShareSecretGenerationSpeed(void) {
{ {
auto end_time{ std::chrono::high_resolution_clock::now() }; auto end_time{ std::chrono::high_resolution_clock::now() };
auto time_to_do_crypto{ std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time) }; auto time_to_do_crypto{ std::chrono::duration_cast<std::chrono::microseconds>(end_time - start_time) };
wxLogMessage(_T("\t\ttest of ristretto test vectors took %lld microseconds"), time_to_do_crypto.count()); wxLogMessage(wxT("\t\ttest of ristretto test vectors took %lld microseconds"), time_to_do_crypto.count());
ILogMessage("\tTesting generation of shared secrets."); ILogMessage("\tTesting generation of shared secrets.");
start_time = std::chrono::high_resolution_clock::now(); start_time = std::chrono::high_resolution_clock::now();
scalar sclrAnonSessionSecretKey{ scalar::random() }; scalar sclrAnonSessionSecretKey{ scalar::random() };