#include "wpassgen.h"
#include "common/tools.h"
#include "fips181.h"
#include "enctain.h"
#include <wx/config.h>
#include <wx/textdlg.h>
#include <wx/tokenzr.h>
WPassGen::WPassGen(wxWindow* parent, bool _standalone, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long WXUNUSED(style))
: wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER|wxTHICK_FRAME),
standalone(_standalone)
{
{
#include "art/pwgen-16.h"
#include "art/pwgen-22.h"
#include "art/pwgen-32.h"
#include "art/pwgen-48.h"
wxIconBundle progicon;
progicon.AddIcon( wxIconFromMemory(pwgen_16_png) );
progicon.AddIcon( wxIconFromMemory(pwgen_22_png) );
progicon.AddIcon( wxIconFromMemory(pwgen_32_png) );
progicon.AddIcon( wxIconFromMemory(pwgen_48_png) );
SetIcons(progicon);
}
sizer2_staticbox = new wxStaticBox(this, -1, _("Generator Options"));
const wxString *choicePreset_choices = NULL;
choicePreset = new wxChoice(this, myID_PRESET, wxDefaultPosition, wxDefaultSize, 0, choicePreset_choices, 0);
buttonPresetAdd = new wxBitmapButton(this, myID_PRESET_ADD, wxNullBitmap);
buttonPresetRemove = new wxBitmapButton(this, myID_PRESET_REMOVE, wxNullBitmap);
const wxString *choiceType_choices = NULL;
choiceType = new wxChoice(this, myID_TYPE, wxDefaultPosition, wxDefaultSize, 0, choiceType_choices, 0);
checkboxSkipSimilarChar = new wxCheckBox(this, myID_SKIPSIMILARCHAR, _("Don't use 0/O and 1/l."));
checkboxSkipSwappedChar = new wxCheckBox(this, myID_SKIPSWAPPEDCHAR, _("Don't use z/y."));
textctrlExtraChar = new wxTextCtrl(this, myID_TEXT_EXTRACHAR, wxEmptyString);
spinctrlLength = new wxSpinCtrl(this, myID_LENGTH, wxT("12"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 6, 100);
textctrlStrength = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_READONLY);
spinctrlNumber = new wxSpinCtrl(this, myID_NUMBER, wxT("10"), wxDefaultPosition, wxDefaultSize, wxSP_ARROW_KEYS, 1, 1000);
checkboxEnumerate = new wxCheckBox(this, myID_ENUMERATE, _("Enumerate"));
buttonGenerate = new wxButton(this, myID_GENERATE, _("&Generate"));
listctrlPasslist = new wxListCtrl(this, myID_PASSLIST, wxDefaultPosition, wxDefaultSize, wxLC_LIST|wxSUNKEN_BORDER);
textctrlPasslist = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_MULTILINE|wxTE_READONLY);
buttonOK = new wxButton(this, wxID_OK, wxEmptyString);
buttonCancel = new wxButton(this, wxID_CANCEL, wxEmptyString);
buttonAbout = new wxButton(this, wxID_ABOUT, _("&About"));
buttonClose = new wxButton(this, wxID_CLOSE, wxEmptyString);
set_properties();
do_layout();
{
#include "art/gnome/list-add.h"
#include "art/gnome/list-remove.h"
buttonPresetAdd->SetBitmapLabel( wxBitmapFromMemory(gnome_list_add_png) );
buttonPresetRemove->SetBitmapLabel( wxBitmapFromMemory(gnome_list_remove_png) );
}
for (unsigned int pt = 0; pt <= PT_LAST; ++pt)
{
choiceType->Append( GetTypeName((pass_type)pt) );
}
ResetPresetChoice();
UpdateCheckboxes();
UpdateKeyStrength();
GenerateList();
buttonOK->Disable();
}
void WPassGen::set_properties()
{
SetTitle(_("CryptoTE Password Generator"));
SetSize(wxSize(502, 600));
choicePreset->SetToolTip(_("Default or saved password generation presets."));
buttonPresetAdd->SetToolTip(_("Save the current settings as a new preset."));
buttonPresetAdd->SetSize(buttonPresetAdd->GetBestSize());
buttonPresetRemove->SetToolTip(_("Remove current preset."));
buttonPresetRemove->SetSize(buttonPresetRemove->GetBestSize());
choiceType->SetToolTip(_("Select desired password components."));
checkboxSkipSimilarChar->SetToolTip(_("Does not use 0/O and 1/l, because these can hardly be distinguished in some fonts."));
checkboxSkipSwappedChar->SetToolTip(_("Does not include characters in password which are swapped on some keyboards."));
textctrlExtraChar->SetToolTip(_("Extra non-standard characters to include in the base random set."));
spinctrlLength->SetToolTip(_("Password length desired."));
textctrlStrength->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
textctrlStrength->SetToolTip(_("Theoretic number of keybits the entropy of the selected pass type generates."));
spinctrlNumber->SetToolTip(_("Number of passwords to generate."));
checkboxEnumerate->SetToolTip(_("Add serial enumeration to each password line."));
listctrlPasslist->SetFont(wxFont(10, wxMODERN, wxNORMAL, wxNORMAL, 0, wxT("")));
textctrlPasslist->SetFont(wxFont(10, wxMODERN, wxNORMAL, wxNORMAL, 0, wxT("")));
}
void WPassGen::do_layout()
{
wxBoxSizer* sizer1 = new wxBoxSizer(wxVERTICAL);
wxGridSizer* sizer7 = new wxGridSizer(1, 2, 0, 0);
wxGridSizer* sizer6 = new wxGridSizer(1, 2, 0, 0);
wxStaticBoxSizer* sizer2 = new wxStaticBoxSizer(sizer2_staticbox, wxVERTICAL);
wxFlexGridSizer* sizer3 = new wxFlexGridSizer(8, 2, 0, 0);
wxBoxSizer* sizer5 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer4 = new wxBoxSizer(wxHORIZONTAL);
wxStaticText* label1 = new wxStaticText(this, wxID_ANY, _("Preset:"));
sizer3->Add(label1, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer4->Add(choicePreset, 1, wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 6);
sizer4->Add(buttonPresetAdd, 0, wxLEFT, 6);
sizer4->Add(buttonPresetRemove, 0, wxLEFT, 6);
sizer3->Add(sizer4, 1, wxALL|wxEXPAND, 6);
wxStaticText* label2 = new wxStaticText(this, wxID_ANY, _("Type:"));
sizer3->Add(label2, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer3->Add(choiceType, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 6);
sizer3->Add(5, 5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer3->Add(checkboxSkipSimilarChar, 0, wxLEFT|wxRIGHT|wxBOTTOM, 6);
sizer3->Add(5, 5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer3->Add(checkboxSkipSwappedChar, 0, wxLEFT|wxRIGHT|wxBOTTOM, 6);
wxStaticText* label3 = new wxStaticText(this, wxID_ANY, _("Extra Characters:"));
sizer3->Add(label3, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer3->Add(textctrlExtraChar, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, 6);
wxStaticText* label4 = new wxStaticText(this, wxID_ANY, _("Length:"));
sizer3->Add(label4, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer3->Add(spinctrlLength, 0, wxLEFT|wxRIGHT|wxBOTTOM, 6);
wxStaticText* label5 = new wxStaticText(this, wxID_ANY, _("Theoretic Strength:"));
sizer3->Add(label5, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer3->Add(textctrlStrength, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND|wxALIGN_CENTER_VERTICAL, 6);
wxStaticText* label6 = new wxStaticText(this, wxID_ANY, _("Number of Passwords:"));
sizer3->Add(label6, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer5->Add(spinctrlNumber, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 6);
sizer5->Add(checkboxEnumerate, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxALIGN_CENTER_VERTICAL, 6);
sizer3->Add(sizer5, 1, wxEXPAND, 0);
sizer3->AddGrowableCol(1);
sizer2->Add(sizer3, 1, wxEXPAND, 0);
sizer2->Add(buttonGenerate, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 6);
sizer1->Add(sizer2, 0, wxALL|wxEXPAND, 8);
wxStaticLine* staticline1 = new wxStaticLine(this, wxID_ANY);
sizer1->Add(staticline1, 0, wxEXPAND, 0);
sizer1->Add(listctrlPasslist, 1, wxALL|wxEXPAND, 8);
sizer1->Add(textctrlPasslist, 1, wxALL|wxEXPAND, 8);
wxStaticLine* staticline2 = new wxStaticLine(this, wxID_ANY);
sizer1->Add(staticline2, 0, wxEXPAND, 0);
sizer6->Add(buttonOK, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer6->Add(buttonCancel, 0, wxALL|wxALIGN_CENTER_VERTICAL, 6);
sizer1->Add(sizer6, 0, wxEXPAND, 0);
sizer7->Add(buttonAbout, 0, wxALL|wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL, 6);
sizer7->Add(buttonClose, 0, wxALL|wxALIGN_CENTER_VERTICAL, 6);
sizer1->Add(sizer7, 0, wxEXPAND, 0);
SetSizer(sizer1);
Layout();
Centre();
if (standalone)
{
sizer1->Hide(listctrlPasslist);
sizer1->Hide(sizer6);
}
else
{
sizer5->Hide(checkboxEnumerate);
sizer1->Hide(textctrlPasslist);
sizer1->Hide(sizer7);
}
}
BEGIN_EVENT_TABLE(WPassGen, wxDialog)
EVT_CHOICE(myID_PRESET, WPassGen::OnChoicePreset)
EVT_BUTTON(myID_PRESET_ADD, WPassGen::OnButtonPresetAdd)
EVT_BUTTON(myID_PRESET_REMOVE, WPassGen::OnButtonPresetRemove)
EVT_CHOICE(myID_TYPE, WPassGen::OnChoiceType)
EVT_CHECKBOX(myID_SKIPSIMILARCHAR, WPassGen::OnCheckSkipSimilarChar)
EVT_CHECKBOX(myID_SKIPSWAPPEDCHAR, WPassGen::OnCheckSkipSwappedChar)
EVT_TEXT(myID_TEXT_EXTRACHAR, WPassGen::OnTextExtraCharChange)
EVT_SPINCTRL(myID_LENGTH, WPassGen::OnSpinLength)
EVT_SPINCTRL(myID_NUMBER, WPassGen::OnSpinNumber)
EVT_CHECKBOX(myID_ENUMERATE, WPassGen::OnCheckEnumerate)
EVT_BUTTON(myID_GENERATE, WPassGen::OnButtonGenerate)
EVT_LIST_ITEM_DESELECTED(myID_PASSLIST, WPassGen::OnPasslistSelected)
EVT_LIST_ITEM_SELECTED(myID_PASSLIST, WPassGen::OnPasslistSelected)
EVT_LIST_ITEM_ACTIVATED(myID_PASSLIST, WPassGen::OnPasslistActivated)
EVT_BUTTON(wxID_OK, WPassGen::OnButtonOK)
EVT_BUTTON(wxID_CANCEL, WPassGen::OnButtonCancel)
EVT_BUTTON(wxID_ABOUT, WPassGen::OnButtonAbout)
EVT_BUTTON(wxID_ANY, WPassGen::OnButtonClose)
EVT_CLOSE(WPassGen::OnClose)
END_EVENT_TABLE();
const std::vector<WPassGen::Preset>& WPassGen::GetDefaultPresets()
{
static std::vector<Preset> default_presets;
if (default_presets.empty())
{
default_presets.push_back(Preset(_("8 Char AlPhANuM"),
PT_ALPHANUMERIC, false, false, _T(""), 8));
default_presets.push_back(Preset(_("12 Char AlPhANuM"),
PT_ALPHANUMERIC, false, false, _T(""), 12));
default_presets.push_back(Preset(_("12 Char alpha"),
PT_ALPHALOWER, false, false, _T(""), 12));
default_presets.push_back(Preset(_("12 Letter Pronounceable"),
PT_PRONOUNCEABLE, false, false, _T(""), 12));
default_presets.push_back(Preset(_("16 Char AlPhANuM"),
PT_ALPHANUMERIC, false, false, _T(""), 16));
default_presets.push_back(Preset(_("16 Char alpha"),
PT_ALPHALOWER, false, false, _T(""), 16));
default_presets.push_back(Preset(_("16 Letter Pronounceable"),
PT_PRONOUNCEABLE, false, false, _T(""), 16));
default_presets.push_back(Preset(_("128 Keybits AlPhANuM"),
PT_ALPHANUMERIC, false, false, _T(""), 22));
default_presets.push_back(Preset(_("256 Keybits AlPhANuM"),
PT_ALPHANUMERIC, false, false, _T(""), 43));
default_presets.push_back(Preset(_("IP Port Number"),
PT_PORTNUMBER, false, false, _T(""), 5));
default_presets.push_back(Preset(_("64-bit WEP Key (40 keybits)"),
PT_HEXADECIMAL, false, false, _T(""), 10));
default_presets.push_back(Preset(_("128-bit WEP Key (104 keybits)"),
PT_HEXADECIMAL, false, false, _T(""), 26));
default_presets.push_back(Preset(_("256-bit WEP Key (232 keybits)"),
PT_HEXADECIMAL, false, false, _T(""), 58));
}
return default_presets;
}
void WPassGen::LoadDefaultSettings()
{
choicePreset->SetSelection(PT_ALPHANUMERIC);
choiceType->SetSelection(0);
checkboxSkipSimilarChar->SetValue(false);
checkboxSkipSwappedChar->SetValue(false);
textctrlExtraChar->SetValue(_T(""));
spinctrlLength->SetValue(12);
spinctrlNumber->SetValue(10);
checkboxEnumerate->SetValue(false);
presetlist = GetDefaultPresets();
ResetPresetChoice();
UpdateCheckboxes();
UpdateKeyStrength();
GenerateList();
buttonOK->Disable();
}
void WPassGen::LoadSettings(class wxConfigBase* cfg)
{
cfg->SetPath(_T("/pwgen"));
int preset, type, length, number;
bool skip_similar, skip_swapped, enumerate;
wxString extrachar;
cfg->Read(_T("preset"), &preset, PT_ALPHANUMERIC);
cfg->Read(_T("type"), &type, 0);
cfg->Read(_T("skip_similar"), &skip_similar, false);
cfg->Read(_T("skip_swapped"), &skip_swapped, false);
cfg->Read(_T("extrachar"), &extrachar);
cfg->Read(_T("length"), &length, 12);
cfg->Read(_T("number"), &number, 10);
cfg->Read(_T("enumerate"), &enumerate, false);
choicePreset->SetSelection(preset);
choiceType->SetSelection(type);
checkboxSkipSimilarChar->SetValue(skip_similar);
checkboxSkipSwappedChar->SetValue(skip_swapped);
textctrlExtraChar->SetValue(extrachar);
spinctrlLength->SetValue(length);
spinctrlNumber->SetValue(number);
checkboxEnumerate->SetValue(enumerate);
if (cfg->Exists(_T("/pwgen/presets")))
{
presetlist.clear();
cfg->SetPath(_T("/pwgen/presets"));
for (unsigned int pi = 0; cfg->HasGroup(wxString::Format(_T("%d"), pi)) ; ++pi)
{
cfg->SetPath( wxString::Format(_T("%d"), pi) );
Preset preset;
cfg->Read(_T("name"), &preset.name, _("<unknown>"));
cfg->Read(_T("type"), (int*)&preset.type, 0);
cfg->Read(_T("skip_similar"), &preset.skip_similar, false);
cfg->Read(_T("skip_swapped"), &preset.skip_swapped, false);
cfg->Read(_T("extrachar"), &preset.extrachar);
cfg->Read(_T("length"), &preset.length, 12);
presetlist.push_back(preset);
cfg->SetPath(_T(".."));
}
}
else
{
presetlist = GetDefaultPresets();
}
ResetPresetChoice();
UpdateCheckboxes();
UpdateKeyStrength();
GenerateList();
buttonOK->Disable();
}
void WPassGen::SaveSettings(class wxConfigBase* cfg)
{
cfg->SetPath(_T("/pwgen"));
cfg->Write(_T("preset"), choicePreset->GetSelection());
cfg->Write(_T("type"), choiceType->GetSelection());
cfg->Write(_T("skip_similar"), checkboxSkipSimilarChar->GetValue());
cfg->Write(_T("skip_swapped"), checkboxSkipSwappedChar->GetValue());
cfg->Write(_T("extrachar"), textctrlExtraChar->GetValue());
cfg->Write(_T("length"), spinctrlLength->GetValue());
cfg->Write(_T("number"), spinctrlNumber->GetValue());
cfg->Write(_T("enumerate"), checkboxEnumerate->GetValue());
cfg->DeleteGroup(_T("/pwgen/presets"));
if (presetlist != GetDefaultPresets())
{
cfg->SetPath(_T("/pwgen/presets"));
for (unsigned int pi = 0; pi < presetlist.size(); ++pi)
{
cfg->SetPath( wxString::Format(_T("%d"), pi) );
cfg->Write(_T("name"), presetlist[pi].name);
cfg->Write(_T("type"), presetlist[pi].type);
cfg->Write(_T("skip_similar"), presetlist[pi].skip_similar);
cfg->Write(_T("skip_swapped"), presetlist[pi].skip_swapped);
cfg->Write(_T("extrachar"), presetlist[pi].extrachar);
cfg->Write(_T("length"), presetlist[pi].length);
cfg->SetPath(_T(".."));
}
}
cfg->Flush();
}
void WPassGen::OnClose(wxCloseEvent& WXUNUSED(event))
{
if (IsModal())
{
EndModal(wxID_CANCEL);
}
else
{
wxConfigBase* cfg = wxConfigBase::Get();
SaveSettings(cfg);
Destroy();
}
}
void WPassGen::OnChoicePreset(wxCommandEvent& WXUNUSED(event))
{
int ni = choicePreset->GetSelection();
if (ni < 0 || (unsigned int)ni >= presetlist.size()) return;
const Preset& preset = presetlist[ni];
choiceType->SetSelection(preset.type);
checkboxSkipSimilarChar->SetValue(preset.skip_similar);
checkboxSkipSwappedChar->SetValue(preset.skip_swapped);
textctrlExtraChar->ChangeValue(preset.extrachar);
spinctrlLength->SetValue(preset.length);
UpdateCheckboxes();
UpdateKeyStrength();
}
void WPassGen::OnButtonPresetAdd(wxCommandEvent& WXUNUSED(event))
{
wxTextEntryDialog dlg(this, _("Enter a descriptive name for the new preset:"), _("Add New Password Preset"));
if (dlg.ShowModal() != wxID_OK) return;
Preset preset;
preset.name = dlg.GetValue();
preset.type = (pass_type)choiceType->GetSelection();
preset.skip_similar = checkboxSkipSimilarChar->GetValue();
preset.skip_swapped = checkboxSkipSwappedChar->GetValue();
preset.extrachar = textctrlExtraChar->GetValue();
preset.length = spinctrlLength->GetValue();
presetlist.push_back(preset);
ResetPresetChoice();
}
void WPassGen::OnButtonPresetRemove(wxCommandEvent& WXUNUSED(event))
{
int ni = choicePreset->GetSelection();
if (ni < 0 || (unsigned int)ni >= presetlist.size()) return;
presetlist.erase(presetlist.begin() + ni);
ResetPresetChoice();
}
void WPassGen::OnChoiceType(wxCommandEvent& WXUNUSED(event))
{
ResetPresetChoice();
UpdateCheckboxes();
UpdateKeyStrength();
}
void WPassGen::OnCheckSkipSimilarChar(wxCommandEvent& WXUNUSED(event))
{
ResetPresetChoice();
UpdateKeyStrength();
}
void WPassGen::OnCheckSkipSwappedChar(wxCommandEvent& WXUNUSED(event))
{
ResetPresetChoice();
UpdateKeyStrength();
}
void WPassGen::OnTextExtraCharChange(wxCommandEvent& WXUNUSED(event))
{
ResetPresetChoice();
UpdateKeyStrength();
}
void WPassGen::OnSpinLength(wxSpinEvent& WXUNUSED(event))
{
ResetPresetChoice();
UpdateKeyStrength();
}
void WPassGen::OnSpinNumber(wxSpinEvent& event)
{
pass_type passtype = (pass_type)choiceType->GetSelection();
bool skip_similar = checkboxSkipSimilarChar->GetValue();
bool skip_swapped = checkboxSkipSwappedChar->GetValue();
wxString extrachar = textctrlExtraChar->GetValue();
int passlen = spinctrlLength->GetValue();
bool enumerate = checkboxEnumerate->GetValue();
int passnumber = event.GetPosition();
Preset preset(_T(""), passtype, skip_similar, skip_swapped, extrachar, passlen);
if (standalone)
{
wxString oldtext = textctrlPasslist->GetValue();
wxStringTokenizer oldtexttoken(oldtext, _T("\n"));
wxString newtext;
for(int i = 0; i < passnumber; i++)
{
if (oldtexttoken.HasMoreTokens())
{
newtext += oldtexttoken.GetNextToken() + _T("\n");
}
else
{
if (enumerate)
newtext += wxString::Format(_T("%u "), i);
newtext += MakePassword(preset) + _T("\n");
}
}
textctrlPasslist->SetValue(newtext);
}
else
{
int oldcount = listctrlPasslist->GetItemCount();
for(int i = oldcount; i > passnumber; --i)
{
listctrlPasslist->DeleteItem(i-1);
}
for(int i = oldcount; i < passnumber; i++)
{
listctrlPasslist->InsertItem(i, MakePassword(preset) );
}
}
buttonOK->Disable();
}
void WPassGen::OnCheckEnumerate(wxCommandEvent& WXUNUSED(event))
{
}
void WPassGen::OnButtonGenerate(wxCommandEvent& WXUNUSED(event))
{
GenerateList();
}
void WPassGen::OnPasslistSelected(wxListEvent& WXUNUSED(event))
{
buttonOK->Enable( listctrlPasslist->GetSelectedItemCount() != 0 );
}
void WPassGen::OnPasslistActivated(wxListEvent& event)
{
OnButtonOK(event);
}
void WPassGen::OnButtonOK(wxCommandEvent& WXUNUSED(event))
{
if (!IsModal()) return;
EndModal(wxID_OK);
}
void WPassGen::OnButtonCancel(wxCommandEvent& WXUNUSED(event))
{
if (!IsModal()) return;
EndModal(wxID_CANCEL);
}
void WPassGen::OnButtonClose(wxCommandEvent& WXUNUSED(event))
{
Close();
}
void WPassGen::OnButtonAbout(wxCommandEvent& WXUNUSED(event))
{
PGWAbout dlg(this);
dlg.ShowModal();
}
void WPassGen::ResetPresetChoice()
{
choicePreset->Clear();
for(presetlist_type::const_iterator pi = presetlist.begin();
pi != presetlist.end(); ++pi)
{
int ni = choicePreset->Append(pi->name);
int passtype = choiceType->GetSelection();
bool skip_similar = checkboxSkipSimilarChar->GetValue();
bool skip_swapped = checkboxSkipSwappedChar->GetValue();
wxString extrachar = textctrlExtraChar->GetValue();
int length = spinctrlLength->GetValue();
if (pi->type == passtype &&
pi->skip_similar == skip_similar &&
pi->skip_swapped == skip_swapped &&
pi->extrachar == extrachar &&
pi->length == length)
{
choicePreset->SetSelection(ni);
}
}
}
void WPassGen::UpdateCheckboxes()
{
checkboxSkipSimilarChar->Enable( IsAllowedSimilar() );
checkboxSkipSwappedChar->Enable( IsAllowedSwapped() );
textctrlExtraChar->Enable( IsAllowedExtraChar() );
spinctrlLength->Enable( IsAllowedLength() );
}
void WPassGen::UpdateKeyStrength()
{
pass_type passtype = (pass_type)choiceType->GetSelection();
bool skip_similar = checkboxSkipSimilarChar->GetValue();
bool skip_swapped = checkboxSkipSwappedChar->GetValue();
wxString extrachar = textctrlExtraChar->GetValue();
int passlen = spinctrlLength->GetValue();
Preset preset(_T(""), passtype, skip_similar, skip_swapped, extrachar, passlen);
double keybits = GetTypeKeybits(preset);
if (IsAllowedLength()) keybits *= passlen;
wxString ss = wxString::Format(_("%.1f keybits"), keybits);
textctrlStrength->SetValue(ss);
}
void WPassGen::GenerateList()
{
pass_type passtype = (pass_type)choiceType->GetSelection();
bool skip_similar = checkboxSkipSimilarChar->GetValue();
bool skip_swapped = checkboxSkipSwappedChar->GetValue();
wxString extrachar = textctrlExtraChar->GetValue();
int passlen = spinctrlLength->GetValue();
bool enumerate = checkboxEnumerate->GetValue();
int passnumber = spinctrlNumber->GetValue();
Preset preset(_T(""), passtype, skip_similar, skip_swapped, extrachar, passlen);
if (standalone)
{
wxString text;
for(int i = 0; i < passnumber; i++)
{
if (enumerate)
text += wxString::Format(_T("%u "), i);
text += MakePassword(preset) + _T("\n");
}
textctrlPasslist->SetValue(text);
}
else
{
listctrlPasslist->DeleteAllItems();
for(int i = 0; i < passnumber; i++)
{
listctrlPasslist->InsertItem(i, MakePassword(preset) );
}
}
buttonOK->Disable();
}
wxArrayString WPassGen::GetSelectedPassword() const
{
wxArrayString arrstr;
long item = -1;
while( (item = listctrlPasslist->GetNextItem(item, wxLIST_NEXT_ALL, wxLIST_STATE_SELECTED)) >= 0 )
{
arrstr.Add( listctrlPasslist->GetItemText(item) );
}
return arrstr;
}
bool WPassGen::IsAllowedSimilar() const
{
pass_type passtype = (pass_type)choiceType->GetSelection();
switch(passtype)
{
case PT_PRONOUNCEABLE:
return false;
case PT_ALPHANUMERICSYMBOL:
case PT_ALPHANUMERIC:
return true;
case PT_ALPHA:
case PT_ALPHALOWER:
case PT_ALPHAUPPER:
return false;
case PT_HEXADECIMAL:
case PT_NUMERIC:
case PT_PORTNUMBER:
return false;
}
return false;
}
bool WPassGen::IsAllowedSwapped() const
{
pass_type passtype = (pass_type)choiceType->GetSelection();
switch(passtype)
{
case PT_PRONOUNCEABLE:
return false;
case PT_ALPHANUMERICSYMBOL:
case PT_ALPHANUMERIC:
return true;
case PT_ALPHA:
case PT_ALPHALOWER:
case PT_ALPHAUPPER:
return true;
case PT_HEXADECIMAL:
case PT_NUMERIC:
case PT_PORTNUMBER:
return false;
}
return false;
}
bool WPassGen::IsAllowedExtraChar() const
{
pass_type passtype = (pass_type)choiceType->GetSelection();
switch(passtype)
{
case PT_PRONOUNCEABLE:
return false;
case PT_ALPHANUMERICSYMBOL:
case PT_ALPHANUMERIC:
case PT_ALPHA:
case PT_ALPHALOWER:
case PT_ALPHAUPPER:
case PT_NUMERIC:
return true;
case PT_HEXADECIMAL:
case PT_PORTNUMBER:
return false;
}
return false;
}
bool WPassGen::IsAllowedLength() const
{
pass_type passtype = (pass_type)choiceType->GetSelection();
switch(passtype)
{
case PT_PRONOUNCEABLE:
case PT_ALPHANUMERICSYMBOL:
case PT_ALPHANUMERIC:
case PT_ALPHA:
case PT_ALPHALOWER:
case PT_ALPHAUPPER:
case PT_HEXADECIMAL:
case PT_NUMERIC:
return true;
case PT_PORTNUMBER:
return false;
}
return false;
}
const wxChar* WPassGen::GetTypeName(pass_type pt)
{
switch(pt)
{
case PT_ALPHANUMERICSYMBOL:
return _("Random Letters + Numbers + Symbols");
case PT_ALPHANUMERIC:
return _("Random Letters + Numbers");
case PT_ALPHA:
return _("Random Letters");
case PT_ALPHALOWER:
return _("Random Lower-case Letters");
case PT_PRONOUNCEABLE:
return _("Pronounceable Lower-case Letters");
case PT_ALPHAUPPER:
return _("Random Upper-case Letters");
case PT_HEXADECIMAL:
return _("Random Hexadecimal Number");
case PT_NUMERIC:
return _("Random Numbers");
case PT_PORTNUMBER:
return _("Random IP Port Number");
default:
return _("Unknown");
}
}
const wxChar* WPassGen::GetType0Letters(pass_type pt, bool skip_similar, bool skip_swapped)
{
switch(pt)
{
case PT_PRONOUNCEABLE:
assert(0);
return _T("");
case PT_ALPHANUMERICSYMBOL:
if (skip_similar && skip_swapped)
return _T("ABCDEFGHIJKLMNPQRSTUVWXabcdefghijkmnopqrstuvwx23456789!?\"#$%&*()[]{}<>,.;:+-=/_");
else if (skip_similar && !skip_swapped)
return _T("ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789!?\"#$%&*()[]{}<>,.;:+-=/_");
else if (!skip_similar && skip_swapped)
return _T("ABCDEFGHIJKLMNOPQRSTUVWXabcdefghijklmnopqrstuvwx0123456789!?\"#$%&*()[]{}<>,.;:+-=/_");
else
return _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!?\"#$%&*()[]{}<>,.;:+-=/_");
case PT_ALPHANUMERIC:
if (skip_similar && skip_swapped)
return _T("ABCDEFGHIJKLMNPQRSTUVWXabcdefghijkmnopqrstuvwx23456789");
else if (skip_similar && !skip_swapped)
return _T("ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz23456789");
else if (!skip_similar && skip_swapped)
return _T("ABCDEFGHIJKLMNOPQRSTUVWXabcdefghijklmnopqrstuvwx0123456789");
else
return _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789");
case PT_ALPHA:
if (skip_swapped)
return _T("ABCDEFGHIJKLMNOPQRSTUVWXabcdefghijklmnopqrstuvwx");
else
return _T("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
case PT_ALPHALOWER:
if (skip_swapped)
return _T("abcdefghijklmnopqrstuvwx");
else
return _T("abcdefghijklmnopqrstuvwxyz");
case PT_ALPHAUPPER:
if (skip_swapped)
return _T("ABCDEFGHIJKLMNOPQRSTUVWX");
else
return _T("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
case PT_HEXADECIMAL:
return _T("0123456789ABCDEF");
case PT_NUMERIC:
return _T("0123456789");
case PT_PORTNUMBER:
assert(0);
return _T("");
}
return _T("");
}
wxString WPassGen::GetType0LettersExtra(const Preset& preset)
{
switch(preset.type)
{
case PT_PRONOUNCEABLE:
assert(0);
return _T("");
case PT_ALPHANUMERICSYMBOL:
case PT_ALPHANUMERIC:
case PT_ALPHA:
case PT_ALPHALOWER:
case PT_ALPHAUPPER:
case PT_NUMERIC:
return wxString(GetType0Letters(preset.type, preset.skip_similar, preset.skip_swapped)) + preset.extrachar;
case PT_HEXADECIMAL:
return GetType0Letters(preset.type, preset.skip_similar, preset.skip_swapped);
case PT_PORTNUMBER:
assert(0);
return _T("");
}
return _T("");
}
float WPassGen::GetTypeKeybits(const Preset& preset)
{
switch(preset.type)
{
case PT_PRONOUNCEABLE:
return 4.05;
case PT_ALPHANUMERICSYMBOL:
case PT_ALPHANUMERIC:
case PT_ALPHA:
case PT_ALPHALOWER:
case PT_ALPHAUPPER:
case PT_HEXADECIMAL:
case PT_NUMERIC:
{
wxString letters = GetType0LettersExtra(preset);
for (unsigned int i = 0; i < letters.size(); ++i)
{
for(unsigned int j = i+1; j < letters.size(); ++j)
{
if (letters[i] == letters[j]) letters.Remove(j--, 1);
}
}
return log(letters.size()) / log(2);
}
case PT_PORTNUMBER:
return log(65536) / log(2);
}
return 0;
}
wxString WPassGen::MakePasswordType0(unsigned int len, const wxString& letters)
{
wxString s;
unsigned int lettlen = letters.size();
for(unsigned int i = 0; i < len; ++i)
{
s.Append( letters[ Enctain::RNG::random_uint() % lettlen ] );
}
return s;
}
wxString WPassGen::MakePassword(const Preset& preset)
{
switch(preset.type)
{
case PT_PRONOUNCEABLE:
{
FIPS181 fips181 (Enctain::RNG::random_uint);
std::string word, hyphenated_word;
fips181.randomword(word, hyphenated_word, preset.length, preset.length);
return wxString(word.data(), wxConvUTF8, word.size());
}
case PT_ALPHANUMERICSYMBOL:
case PT_ALPHANUMERIC:
case PT_ALPHA:
case PT_ALPHALOWER:
case PT_ALPHAUPPER:
case PT_HEXADECIMAL:
case PT_NUMERIC:
{
wxString letters = GetType0LettersExtra(preset);
return MakePasswordType0(preset.length, letters);
}
case PT_PORTNUMBER:
{
return wxString::Format(_T("%u"), Enctain::RNG::random_uint() % 65536);
}
}
return _T("");
}
PGWAbout::PGWAbout(wxWindow* parent, int id, const wxString& title, const wxPoint& pos, const wxSize& size, long WXUNUSED(style))
: wxDialog(parent, id, title, pos, size, wxDEFAULT_DIALOG_STYLE)
{
bitmapIcon = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap);
bitmapWeb = new wxStaticBitmap(this, wxID_ANY, wxNullBitmap);
hyperlink1 = new wxHyperlinkCtrl(this, wxID_ANY, _("Visit http://idlebox.net/2009/cryptote/"), _("http://idlebox.net/2009/cryptote/"), wxDefaultPosition, wxDefaultSize, wxNO_BORDER|wxHL_CONTEXTMENU|wxHL_ALIGN_LEFT);
buttonOK = new wxButton(this, wxID_OK, wxEmptyString);
set_properties();
do_layout();
#include "art/pwgen-48.h"
bitmapIcon->SetBitmap( wxBitmapFromMemory(pwgen_48_png) );
#include "art/web-16.h"
bitmapWeb->SetBitmap( wxBitmapFromMemory(web_16_png) );
Layout();
GetSizer()->Fit(this);
Centre();
}
void PGWAbout::set_properties()
{
SetTitle(_("About CryptoTE Password Generator"));
}
void PGWAbout::do_layout()
{
wxBoxSizer* sizer1 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sizer2 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer_3 = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sizer4 = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer* sizer5 = new wxBoxSizer(wxVERTICAL);
sizer2->Add(bitmapIcon, 0, wxALL, 8);
wxStaticText* label1 = new wxStaticText(this, wxID_ANY, _("CryptoTE\nPassword Generator"));
label1->SetFont(wxFont(18, wxDEFAULT, wxNORMAL, wxBOLD, 0, wxT("")));
sizer_3->Add(label1, 0, wxALL, 6);
wxStaticText* label2 = new wxStaticText(this, wxID_ANY, _("This is a stand-alone program containing only the\nrandom password generator found in CryptoTE\ntext editor component."));
sizer_3->Add(label2, 0, wxALL, 6);
wxStaticText* label3 = new wxStaticText(this, wxID_ANY, _("The random password generator can generate\npronounceable English passwords or general upper-\nand/or lowercase letter and digit combinations.\nIt also displays the theoretic strength in key bits of\nthe chosen generator settings."));
sizer_3->Add(label3, 0, wxALL, 6);
wxStaticText* label4 = new wxStaticText(this, wxID_ANY, _("Copyright 2009 Timo Bingmann\nReleased under the GNU General Public License v2"));
sizer_3->Add(label4, 0, wxALL, 6);
sizer4->Add(bitmapWeb, 0, wxALL|wxALIGN_CENTER_VERTICAL, 6);
sizer5->Add(hyperlink1, 1, wxEXPAND, 0);
wxStaticText* label5 = new wxStaticText(this, wxID_ANY, _("for updates and more."));
sizer5->Add(label5, 0, wxALL, 0);
sizer4->Add(sizer5, 1, wxEXPAND, 0);
sizer_3->Add(sizer4, 0, wxALL|wxEXPAND, 6);
sizer2->Add(sizer_3, 1, wxEXPAND, 0);
sizer1->Add(sizer2, 1, wxALL|wxEXPAND, 6);
sizer1->Add(buttonOK, 0, wxALL|wxALIGN_CENTER_HORIZONTAL|wxALIGN_CENTER_VERTICAL, 6);
SetSizer(sizer1);
sizer1->Fit(this);
Layout();
label1->SetLabel(wxString::Format(_("CryptoTE\nPassword Generator %s"), _(VERSION)));
}