void PWSGridTable::SaveSettings(void) const { wxString colWidths, colShown; wxGrid* grid = GetView(); const int nCols = grid->GetNumberCols(); for(int idx = 0; idx < nCols; ++idx) { const int colID = grid->GetColAt(idx); #if wxCHECK_VERSION(2, 9, 1) if (!grid->IsColShown(colID)) continue; #endif colShown << GetColumnFieldType(colID) << wxT(','); colWidths << grid->GetColSize(colID) << wxT(','); } if (!colShown.IsEmpty()) colShown.RemoveLast(); if (!colWidths.IsEmpty()) colWidths.RemoveLast(); //write these, even if colWidth and colShown are empty PWSprefs::GetInstance()->SetPref(PWSprefs::ListColumns, tostringx(colShown)); PWSprefs::GetInstance()->SetPref(PWSprefs::ColumnWidths, tostringx(colWidths)); }
void EditShortcut::OnOkClick( wxCommandEvent& /* evt */ ) { if (Validate() && TransferDataFromWindow()) { bool modified = false; CItemData modified_item(*m_item); const wxString group = m_groupCtrl->GetValue(); if (group != m_item->GetGroup().c_str()) { modified = true; modified_item.SetGroup(tostringx(group)); } if (m_title != m_item->GetTitle().c_str()) { modified = true; modified_item.SetTitle(tostringx(m_title)); } if (m_user != m_item->GetUser().c_str()) { modified = true; modified_item.SetUser(tostringx(m_user)); } if (modified) { time_t t; time(&t); modified_item.SetRMTime(t); m_core.Execute(EditEntryCommand::Create(&m_core,*m_item, modified_item)); m_ui->GUIRefreshEntry(modified_item); } } EndModal(wxID_OK); }
void CSafeCombinationEntry::ProcessPhrase() { int status = m_core.CheckPasskey(tostringx(m_filename), m_password); wxString errmess; switch (status) { case PWScore::SUCCESS: m_core.SetReadOnly(m_readOnly); m_core.SetCurFile(tostringx(m_filename)); wxGetApp().recentDatabases().AddFileToHistory(m_filename); EndModal(wxID_OK); return; case PWScore::CANT_OPEN_FILE: { stringT str; LoadAString(str, IDSC_FILE_UNREADABLE); errmess = str.c_str(); } break; case PWScore::WRONG_PASSWORD: default: if (m_tries >= 2) { errmess = _("Three strikes - yer out!"); } else { m_tries++; errmess = _("Incorrect passkey, not a PasswordSafe database, or a corrupt database. (Backup database has same name as original, ending with '~')"); } break; } // switch (status) // here iff CheckPasskey failed. wxMessageDialog err(this, errmess, _("Error"), wxOK | wxICON_EXCLAMATION); err.ShowModal(); wxTextCtrl *txt = (wxTextCtrl *)FindWindow(ID_COMBINATION); txt->SetSelection(-1,-1); txt->SetFocus(); }
void CSafeCombinationEntry::OnNewDbClick( wxCommandEvent& /* evt */ ) { // 1. Get a filename from a file dialog box // 2. Get a password // 3. Set m_filespec && m_passkey to returned value! wxString newfile; wxString cs_msg, cs_title, cs_temp; wxString cf(wxT("pwsafe")); // reasonable default for first time user stringT v3FileName = PWSUtil::GetNewFileName(tostdstring(cf), wxT("psafe3")); stringT dir = PWSdirs::GetSafeDir(); while (1) { wxFileDialog fd(this, _("Please choose a name for the new database"), dir.c_str(), v3FileName.c_str(), _("Password Safe Databases (*.psafe3; *.dat)|*.psafe3;*.dat| All files (*.*; *)|*.*;*"), (wxFD_SAVE | wxFD_OVERWRITE_PROMPT| wxFD_CHANGE_DIR)); int rc = fd.ShowModal(); if (rc == wxID_OK) { wxFileName wxfn(fd.GetPath()); if (wxfn.GetExt().empty()) { wxfn.SetExt(DEFAULT_SUFFIX); } newfile = wxfn.GetFullPath(); break; } else return; } // 2. Get a password CSafeCombinationSetup pksetup(this); int rc = pksetup.ShowModal(); if (rc != wxID_OK) return; //User cancelled password entry // 3. Set m_filespec && m_passkey to returned value! m_core.SetCurFile(tostringx(newfile)); // Now lock the new file std::wstring locker(L""); // null init is important here m_core.LockFile(tostdstring(newfile), locker); m_core.SetReadOnly(false); // new file can't be read-only... m_core.NewFile(tostringx(pksetup.GetPassword())); if ((rc = m_core.WriteCurFile()) == PWSfile::SUCCESS) { wxGetApp().recentDatabases().AddFileToHistory(newfile); EndModal(wxID_OK); } else { wxMessageBox(wxString()<< newfile << wxT("\n\n") << _("Could not open file for writing!"), _("Write Error"), wxOK | wxICON_ERROR, this); } }
int ReadCore(PWScore& othercore, const wxString& file, const StringX& combination, bool showMsgbox /*= true*/, wxWindow* msgboxParent /*= NULL*/) { othercore.ClearData(); // Reading a new file changes the preferences! const StringX sxSavePrefString(PWSprefs::GetInstance()->Store()); const bool bDBPrefsChanged = PWSprefs::GetInstance()->IsDBprefsChanged(); StringX dbpath(tostringx(file)); int rc = othercore.ReadFile(dbpath, combination); // Reset database preferences - first to defaults then add saved changes! PWSprefs::GetInstance()->Load(sxSavePrefString); PWSprefs::GetInstance()->SetDBprefsChanged(bDBPrefsChanged); switch (rc) { case PWScore::SUCCESS: othercore.SetCurFile(tostringx(file)); break; case PWScore::CANT_OPEN_FILE: if (showMsgbox) wxMessageBox(wxString(file) << _("\n\nCould not open file for reading!"), _("File Read Error"), wxOK | wxICON_ERROR, msgboxParent ); break; case PWScore::BAD_DIGEST: if (showMsgbox && wxMessageBox(wxString(file) << _("\n\nFile corrupt or truncated!\nData may have been lost or modified.\nContinue anyway?"), _("File Read Error"), wxYES_NO | wxICON_QUESTION, msgboxParent) == wxYES) { rc = PWScore::SUCCESS; } break; #ifdef DEMO case PWScore::LIMIT_REACHED: if( showMsgbox) wxMessageBox(wxString::Format(_("This version of PasswordSafe does not support more than %d entries in a database.\nTo get an unlimited version for the U3 platform, please visit http://software.u3.com\nNote: Saving this database will result in the removal of unread entries!"), MAXDEMO), _("Trial Version Limitation"), wxOK | wxICON_WARNING, msgboxParent); break; #endif default: if (showMsgbox) wxMessageBox( wxString(file) << _("\n\nUnknown error"), _("File Read Error"), wxOK | wxICON_ERROR, msgboxParent); break; } return rc; }
bool CPasswordPolicy::Verify() { wxString mess; bool retval = true; int id = 0; // Check that options, as set, are valid. if (m_pwUseHex && (m_pwUseLowercase || m_pwUseUppercase || m_pwUseDigits || m_pwUseSymbols || m_pwUseEasyVision || m_pwMakePronounceable)) { mess = _("Hexadecimal is mutually exculsive to all other options."); retval = false; } else if (m_pwUseHex) { if (m_pwdefaultlength % 2 != 0) { mess = _("Hexadecimal passwords must have even length - each byte is two characters"); retval = false; } } else if (!m_pwUseLowercase && !m_pwUseUppercase && !m_pwUseDigits && !m_pwUseSymbols) { mess = _("At least one type of character (lowercase, uppercase, digits, symbols or hexadecimal) must be chosen"); retval = false; } if ((m_pwdefaultlength < 4) || (m_pwdefaultlength > 1024)) { mess = _("Password must be between 4 and 1024 characters"); id = ID_PWLENSB; retval = false; } if (!(m_pwUseHex || m_pwUseEasyVision || m_pwMakePronounceable) && (m_pwDigitMinLength + m_pwLowerMinLength + m_pwSymbolMinLength + m_pwUpperMinLength) > m_pwdefaultlength) { mess = _("Password length is less than sum of 'at least' constraints"); id = ID_PWLENSB; retval = false; } if ((m_pwUseHex || m_pwUseEasyVision || m_pwMakePronounceable)) m_pwDigitMinLength = m_pwLowerMinLength = m_pwSymbolMinLength = m_pwUpperMinLength = 1; if (m_polname.IsEmpty()) { mess = _("Policy name cannot be blank"); id = ID_POLICYNAME; retval = false; } else if ((m_polname != m_oldpolname && (m_MapPSWDPLC.find(tostringx(m_polname)) != m_MapPSWDPLC.end()))) { mess = _("Policy name is already in use"); id = ID_POLICYNAME; retval = false; } if (!retval) { wxMessageDialog md(this, mess, _("Policy Error"), wxOK | wxICON_ERROR); md.ShowModal(); if (id != 0) FindWindow(id)->SetFocus(); } return retval; }
void CompareDlg::OnCompare(wxCommandEvent& ) { if ( Validate() && TransferDataFromWindow()) { if (wxFileName(m_dbPanel->m_filepath).SameAs(towxstring(m_otherCore->GetCurFile())) || ReadCore(*m_otherCore, m_dbPanel->m_filepath, m_dbPanel->m_combination, true, this, true) == PWScore::SUCCESS) { m_otherCore->SetCurFile(tostringx(m_dbPanel->m_filepath)); m_otherCore->SetReadOnly(true); // TODO: must copy the selectionCriteria from advanced options pane. Or else // the search would always be conducted on default field criteria m_current->data.clear(); m_comparison->data.clear(); m_conflicts->data.clear(); m_identical->data.clear(); m_conflicts->pane->Collapse(); m_current->pane->Collapse(); m_comparison->pane->Collapse(); m_identical->pane->Collapse(); wxCommandEvent cmdEvent(EVT_START_COMPARISON, GetId()); GetEventHandler()->AddPendingEvent(cmdEvent); } } else { m_otherCore->SetCurFile(StringX()); } }
void PasswordSafeSearch::OnDoSearchT(Iter begin, Iter end, Accessor afn) { wxASSERT(m_toolbar); wxSearchCtrl* txtCtrl = wxDynamicCast(m_toolbar->FindControl(ID_FIND_EDITBOX), wxSearchCtrl); wxASSERT(txtCtrl); const wxString searchText = txtCtrl->GetLineText(0); if (searchText.IsEmpty()) return; if (m_criteria->IsDirty() || txtCtrl->IsModified() || m_searchPointer.IsEmpty()) { m_searchPointer.Clear(); if (!m_toolbar->GetToolState(ID_FIND_ADVANCED_OPTIONS)) FindMatches(tostringx(searchText), m_toolbar->GetToolState(ID_FIND_IGNORE_CASE), m_searchPointer, begin, end, afn); else FindMatches(tostringx(searchText), m_toolbar->GetToolState(ID_FIND_IGNORE_CASE), m_searchPointer, m_criteria->GetSelectedFields(), m_criteria->HasSubgroupRestriction(), m_criteria->SubgroupSearchText(), m_criteria->SubgroupObject(), m_criteria->SubgroupFunction(), m_criteria->CaseSensitive(), begin, end, afn); m_criteria->Clean(); txtCtrl->SetModified(false); m_searchPointer.InitIndex(); } else { ++m_searchPointer; } UpdateView(); // Replace the "Find" menu item under Edit menu by "Find Next" and "Find Previous" wxMenu* editMenu = 0; wxMenuItem* findItem = m_parentFrame->GetMenuBar()->FindItem(wxID_FIND, &editMenu); if (findItem && editMenu) { //Is there a way to do this without hard-coding the insert position? if (!m_parentFrame->GetMenuBar()->FindItem(ID_EDITMENU_FIND_NEXT) ) { editMenu->Insert(FIND_MENU_POSITION, ID_EDITMENU_FIND_NEXT, _("&Find next...\tF3"), wxT(""), wxITEM_NORMAL); } if (!m_parentFrame->GetMenuBar()->FindItem(ID_EDITMENU_FIND_PREVIOUS) ) { editMenu->Insert(FIND_MENU_POSITION+1, ID_EDITMENU_FIND_PREVIOUS, _("&Find previous...\tSHIFT+F3"), wxT(""), wxITEM_NORMAL); } } }
int ReadCore(PWScore& othercore, const wxString& file, const StringX& combination, bool showMsgbox /*= true*/, wxWindow* msgboxParent /*= NULL*/, bool setupCopy /*= false*/) { othercore.ClearData(); StringX dbpath(tostringx(file)); int rc = othercore.ReadFile(dbpath, combination); if (setupCopy) PWSprefs::GetInstance()->SetupCopyPrefs(); switch (rc) { case PWScore::SUCCESS: othercore.SetCurFile(tostringx(file)); break; case PWScore::CANT_OPEN_FILE: if (showMsgbox) wxMessageBox(wxString(file) << wxT("\n\n") << _("Could not open file for reading!"), _("File Read Error"), wxOK | wxICON_ERROR, msgboxParent ); break; case PWScore::BAD_DIGEST: if (showMsgbox && wxMessageBox(wxString(file) << wxT("\n\n") << _("File corrupt or truncated!\nData may have been lost or modified.\nContinue anyway?"), _("File Read Error"), wxYES_NO | wxICON_QUESTION, msgboxParent) == wxYES) { rc = PWScore::SUCCESS; } break; default: if (showMsgbox) wxMessageBox( wxString(file) << wxT("\n\n") << _("Unknown error"), _("File Read Error"), wxOK | wxICON_ERROR, msgboxParent); break; } return rc; }
void CSafeCombinationPrompt::ProcessPhrase() { if (m_core.CheckPasskey(tostringx(m_filename), m_password) != PWScore::SUCCESS) { wxString errmess; if (m_tries >= 2) { errmess = _("Three strikes - yer out!"); } else { m_tries++; errmess = _("Incorrect passkey, not a PasswordSafe database, or a corrupt database. (Backup database has same name as original, ending with '~')"); } wxMessageDialog err(this, errmess, _("Error"), wxOK | wxICON_EXCLAMATION); err.ShowModal(); wxTextCtrl *txt = dynamic_cast<wxTextCtrl *>(FindWindow(ID_PASSWORD)); txt->SetSelection(-1,-1); txt->SetFocus(); return; } // m_core.SetReadOnly(m_readOnly); m_core.SetCurFile(tostringx(m_filename)); EndModal(wxID_OK); }
void CSafeCombinationSetup::OnOkClick( wxCommandEvent& /* evt */ ) { if (Validate() && TransferDataFromWindow()) { if (m_password != m_verify) { wxMessageDialog err(this, _("The two entries do not match."), _("Error"), wxOK | wxICON_EXCLAMATION); err.ShowModal(); return; } if (m_password.empty()) { wxMessageDialog err(this, _("Please enter the key and verify it."), _("Error"), wxOK | wxICON_EXCLAMATION); err.ShowModal(); return; } // Vox populi vox dei - folks want the ability to use a weak // passphrase, best we can do is warn them... // If someone want to build a version that insists on proper // passphrases, then just define the preprocessor macro // PWS_FORCE_STRONG_PASSPHRASE in the build properties/Makefile // (also used in CPasskeyChangeDlg) #ifndef _DEBUG // for debug, we want no checks at all, to save time StringX errmess; if (!CPasswordCharPool::CheckPassword(tostringx(m_password), errmess)) { wxString cs_msg; cs_msg = _("Weak passphrase:"); cs_msg += wxT("\n\n"); cs_msg += errmess.c_str(); #ifndef PWS_FORCE_STRONG_PASSPHRASE cs_msg += wxT("\n"); cs_msg += _("Use it anyway?"); wxMessageDialog mb(this, cs_msg, _("Warning"), wxYES_NO | wxNO_DEFAULT | wxICON_HAND); int rc = mb.ShowModal(); if (rc == wxID_NO) return; #else cs_msg += wxT("\n"); cs_msg += _("Please try another"); wxMessageDialog mb(this, cs_msg, _("Error"), wxOK | wxICON_HAND); mb.ShowModal(); return; #endif // PWS_FORCE_STRONG_PASSPHRASE } #endif // _DEBUG EndModal(wxID_OK); } }
void CSafeCombinationSetup::OnYubibtnClick( wxCommandEvent& /* event */ ) { if (Validate() && TransferDataFromWindow()) { if (m_password != m_verify) { wxMessageDialog err(this, _("The two entries do not match."), _("Error"), wxOK | wxICON_EXCLAMATION); err.ShowModal(); return; } StringX response; bool oldYubiChallenge = ::wxGetKeyState(WXK_SHIFT); // for pre-0.94 databases if (PerformChallengeResponse(this, tostringx(m_password), response, oldYubiChallenge)) { m_password = response.c_str(); EndModal(wxID_OK); } } }
PWPolicy CManagePasswordPolicies::GetSelectedPolicy() const { /* If first row or no row selected, then fill in with the database default, otherwise use the name entry */ int row = GetSelectedRow(); if (row > 0) { const wxString policyname = m_PolicyNames->GetCellValue(row, 0); PSWDPolicyMapCIter iter = m_MapPSWDPLC.find(tostringx(policyname)); if (iter == m_MapPSWDPLC.end()) return m_st_default_pp; return iter->second; } else { return m_st_default_pp; } }
bool CPasswordPolicy::Verify() { wxString mess; bool retval = true; int id = 0; if (!m_pwUseLowercase && !m_pwUseUppercase && !m_pwUseDigits && !m_pwUseSymbols) { mess = _("At least one type of character (lowercase, uppercase, digits, or symbols) must be chosen"); retval = false; } if ((m_pwdefaultlength < 4) || (m_pwdefaultlength > 1024)) { mess = _("Password must be between 4 and 1024 characters"); id = ID_PWLENSB; retval = false; } if (m_polname.IsEmpty()) { mess = _("Policy name cannot be blank"); id = ID_POLICYNAME; retval = false; } else if ((m_polname != m_oldpolname && (m_MapPSWDPLC.find(tostringx(m_polname)) != m_MapPSWDPLC.end()))) { mess = _("Policy name is already in use"); id = ID_POLICYNAME; retval = false; } if (!retval) { wxMessageDialog md(this, mess, _("Policy Error"), wxOK | wxICON_ERROR); md.ShowModal(); if (id != 0) FindWindow(id)->SetFocus(); } return retval; }
bool DbSelectionPanel::DoValidation() { //the data has not been transferred from the window to our members yet, so get them from the controls if (wxWindow::Validate()) { wxFileName wxfn(m_filepicker->GetPath()); //Did the user enter a valid file path if (!wxfn.FileExists()) { wxMessageBox( _("File or path not found."), _("Error"), wxOK | wxICON_EXCLAMATION, this); return false; } //Did he enter the same file that's currently open? if (wxfn.SameAs(wxFileName(towxstring(m_core->GetCurFile())))) { // It is the same damn file wxMessageBox(_("That file is already open."), _("Error"), wxOK | wxICON_WARNING, this); return false; } StringX combination = m_sc->GetCombination(); //Does the combination match? if (m_core->CheckPasskey(tostringx(wxfn.GetFullPath()), combination) != PWScore::SUCCESS) { wxString errmess(_("Incorrect passkey, not a PasswordSafe database, or a corrupt database. (Backup database has same name as original, ending with '~')")); wxMessageBox(errmess, _("Error"), wxOK | wxICON_ERROR, this); SelectCombinationText(); return false; } return true; } else { return false; } }
void CManagePasswordPolicies::OnCopyPasswordClick( wxCommandEvent& ) { PWSclipboard::GetInstance()->SetData(tostringx(m_passwordCtrl->GetValue())); }
void CManagePasswordPolicies::UpdatePolicy(const wxString &polname, const PWPolicy &pol, CPP_FLAGS mode) { if (polname == _("Default Policy")) m_st_default_pp = pol; else m_MapPSWDPLC[tostringx(polname)] = pol; #ifdef NOTYET // Save changes for Undo/Redo PWPolicyChange st_change; st_change.flags = mode; st_change.name = policyname; st_change.st_pp_save = m_iSelectedItem != 0 ? m_mapIter->second : m_st_default_pp; switch (mode) { case CPP_ADD: break; case CPP_MODIFIED: break; case CPP_DELETE: break; default: ASSERT(0); } if (m_iSelectedItem != 0) { // Changed a named password policy PSWDPolicyMapIter iter_new = m_MapPSWDPLC.find(StringX(policyname.c_str())); if (iter_new == m_MapPSWDPLC.end()) ASSERT(0); st_change.st_pp_new = iter_new->second; } else { // Changed the database default policy st_change.st_pp_new = m_st_default_pp; } if (m_iundo_pos != (int)m_vchanges.size() - 1) { // We did have changes that could have been redone // But not anymore - delete all these to add new change on the end m_vchanges.resize(m_iundo_pos + 1); } // Add new change m_vchanges.push_back(st_change); // Update pointer to the one that is next to be undone m_iundo_pos++; // Update buttons appropriately FindWindow(wxID_UNDO)->Enable(true); FindWindow(wxID_REDO)->Enable(false); #else UNREFERENCED_PARAMETER(mode); #endif // Update lists UpdateNames(); int N = m_PolicyNames->GetNumberRows(); for (int row = 0; row < N; row++) if (m_PolicyNames->GetCellValue(row, 0) == polname) { m_PolicyNames->SelectRow(row); break; } UpdateDetails(); }
void PasswordSafeFrame::OnRestoreSafe(wxCommandEvent& /*evt*/) { if (SaveIfChanged() != PWScore::SUCCESS) return; const wxFileName currbackup(towxstring(PWSprefs::GetInstance()->GetPref(PWSprefs::CurrentBackup))); wxString dir; if (m_core.GetCurFile().empty()) dir = towxstring(PWSdirs::GetSafeDir()); else { wxFileName::SplitPath(towxstring(m_core.GetCurFile()), &dir, NULL, NULL); wxCHECK_RET(!dir.IsEmpty(), _("Could not parse current file path")); } //returns empty string if user cancels wxString wxbf = wxFileSelector(_("Please Choose a Backup to Restore:"), dir, currbackup.GetFullName(), wxT("bak"), _("Password Safe Backups (*.bak)|*.bak|Password Safe Intermediate Backups (*.ibak)|*.ibak||"), wxFD_OPEN|wxFD_FILE_MUST_EXIST, this); if (wxbf.empty()) return; #ifdef NOT_YET if (m_inExit) { // If U3ExitNow called while in CPWFileDialog, // PostQuitMessage makes us return here instead // of exiting the app. Try resignalling PostQuitMessage(0); return PWScore::USER_CANCEL; } #endif CSafeCombinationPrompt pwdprompt(this, m_core, wxbf); if (pwdprompt.ShowModal() == wxID_OK) { const StringX passkey = pwdprompt.GetPassword(); // unlock the file we're leaving if (!m_core.GetCurFile().empty()) { m_core.UnlockFile(m_core.GetCurFile().c_str()); } // Reset core and clear ALL associated data m_core.ReInit(); // clear the application data before restoring ClearAppData(); if (m_core.ReadFile(tostringx(wxbf), passkey, true, MAXTEXTCHARS) == PWScore::CANT_OPEN_FILE) { wxMessageBox(wxbf << wxT("\n\n") << _("Could not open file for reading!"), _("File Read Error"), wxOK | wxICON_ERROR, this); return /*PWScore::CANT_OPEN_FILE*/; } m_core.SetCurFile(wxEmptyString); // Force a Save As... m_bRestoredDBUnsaved = true; // So that the restored file will be saved SetTitle(_("Password Safe - <Untitled Restored Backup>")); #ifdef NOT_YET app.SetTooltipText(L"PasswordSafe"); #endif #ifdef NOT_YET ChangeOkUpdate(); #endif RefreshViews(); } }