#include "src/addpass.hh" #include "src/delpass.hh" #include "src/editpass.hh" #include "src/genpass.hh" #include "src/initpass.hh" #include "src/showpass.hh" #include "src/vulnpass.hh" #include "src/chkpass.hh" #include "src/common.hh" #include "main.hh" #undef Status #undef None #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include Fl_Select_Browser *browser = nullptr; Fl_Text_Display *textview = nullptr; Fl_Text_Buffer *textbuf = nullptr; Fl_Input *searchfield = nullptr; Fl_Check_Button *hidechk = nullptr; Fl_Button *showbtn = nullptr; Addpass a; Chkpass c; Delpass d; Editpass e; Genpass g; Initpass i; Showpass s; Vulnpass v; const char *sofname = "simpas"; const char *intname = "SimPas"; const char *version = "1.1.1"; const char *basedof = "sp-1.5.1"; std::vector fullpaths; std::vector dispaths; std::vector filterpaths; int browseId; bool isPassHidden = true; std::string realpass = ""; void browse(std::string &path, bool isNew) { std::string cont = s.exec(path.c_str(), false); realpass = cont; if (isNew) browseId = browser->size(); browser->value(browseId); if (!cont.empty()) { if (isPassHidden) { std::string lang = Common::getlang(); if (lang.compare(0, 2, "en") == 0) { textbuf->text("(Hidden, please click the \"show\" button to reveal)"); } else { textbuf->text("(非表示、「表示」ボタンをクリックして確認して下さい)"); } showbtn->activate(); showbtn->label((Common::getlang().compare(0, 2, "en") == 0) ? "Show password" : "パスワードの表示"); } else { textbuf->text(cont.c_str()); showbtn->label((Common::getlang().compare(0, 2, "en") == 0) ? "Hide password" : "パスワードを隠す"); showbtn->activate();} Editpass::setFile(path); Delpass::setFile(path); d.btn->activate(); e.btn->activate(); } } void hide_cb(Fl_Widget *w, void *) { isPassHidden = ((Fl_Check_Button *)w)->value(); int idx = browser->value(); if (isPassHidden && idx > 0) { showbtn->activate(); showbtn->label((Common::getlang().compare(0, 2, "en") == 0) ? "Show password" : "パスワードの表示"); } else { showbtn->deactivate(); showbtn->label((Common::getlang().compare(0, 2, "en") == 0) ? "Hide password" : "パスワードを隠す"); } showbtn->label((Common::getlang().compare(0, 2, "en") == 0) ? "Show password" : "パスワードの表示"); if (idx > 0) { std::string path = filterpaths[idx - 1]; browse(path, false); } } void clearpaths(bool isReset, std::string &path) { fullpaths.clear(); dispaths.clear(); if (isReset) { std::string mockpath = ""; Editpass::setFile(mockpath); Delpass::setFile(mockpath); d.btn->deactivate(); e.btn->deactivate(); } } void updatelist() { browser->clear(); filterpaths.clear(); std::string searchtxt = searchfield->value(); for (size_t i = 0; i < dispaths.size(); ++i) { if (dispaths[i].find(searchtxt) != std::string::npos) { browser->add(dispaths[i].c_str()); filterpaths.push_back(fullpaths[i]); } } textbuf->text(""); } void search_cb(Fl_Widget *, void *) { std::string mockpath = ""; Editpass::setFile(mockpath); Delpass::setFile(mockpath); d.btn->deactivate(); e.btn->deactivate(); updatelist(); } void copy_cb(Fl_Widget *, void *) { if (!realpass.empty()) { Fl::copy(realpass.c_str(), realpass.length(), 1, Fl::clipboard_plain_text); } else { Fl::copy("", 0, 1, Fl::clipboard_plain_text); } } void browser_cb(Fl_Widget *w, void *) { (void)w; int idx = browser->value(); if (idx == 0) return; browseId = idx; std::string path = filterpaths[idx - 1]; browse(path, false); } void show_cb(Fl_Widget *, void *) { int idx = browser->value(); if (idx == 0) return; std::string path = filterpaths[idx - 1]; if (isPassHidden) { std::string cont = s.exec(path.c_str(), false); realpass = cont; textbuf->text(cont.c_str()); std::string lang = Common::getlang(); if (lang.compare(0, 2, "en") == 0) { showbtn->label("Hide password"); } else { showbtn->label("パスワードを隠す"); } isPassHidden = false; } else { std::string lang = Common::getlang(); if (lang.compare(0, 2, "en") == 0) { textbuf->text("(Hidden, please click the \"show\" button to reveal)"); showbtn->label("Show password"); } else { textbuf->text("(非表示、「表示」ボタンをクリックして確認して下さい)"); showbtn->label("パスワードの表示"); } isPassHidden = true; } } void scandir(const std::string &dpath, const std::string &rpath, std::vector &fpaths) { DIR *dir = opendir(dpath.c_str()); if (!dir) return; struct dirent *entry; while ((entry = readdir(dir)) != nullptr) { std::string name = entry->d_name; if (name == "." || name == ".." || name == ".gpg-id") continue; std::string fpath = std::string(dpath) + "/" + name; struct stat s; if (stat(fpath.c_str(), &s) != 0) { closedir(dir); return; } if (S_ISDIR(s.st_mode)) { scandir(fpath, rpath, fpaths); } else if (name.find(".gpg") != std::string::npos) { std::string rel = fpath.substr(rpath.size() + 1); fpaths.push_back(rel); fullpaths.push_back(fpath); std::string disname = rel.substr(0, rel.rfind(".gpg")); dispaths.push_back(disname); } } closedir(dir); } void init_cb(Fl_Widget *w, void *data) { i.exec(i.gpgid->value()); i.btn->deactivate(); ((Initpass *)data)->cancel_cb(w, data); } void init_dialog_cb(Fl_Widget *w, void *) { (void)w; std::string lang = Common::getlang(); Fl_Window *dialog = new Fl_Window(450, 120, (lang.compare(0, 2, "en") == 0 ? "Initialize password" : "パスワードの初期設定")); i.gpgid = new Fl_Input(90, 20, 300, 30, (lang.compare(0, 2, "en") == 0 ? "GPG secret key:" : "gpg秘密鍵:")); dialog->add(i.gpgid); Fl_Button *startbtn = new Fl_Button(185, 70, 80, 30, (lang.compare(0, 2, "en") == 0 ? "Start" : "開始")); startbtn->callback(init_cb, dialog); dialog->add(startbtn); dialog->end(); dialog->set_modal(); dialog->show(); } void set_dark_theme() { Fl::background(35, 32, 35); Fl::background2(68, 59, 68); Fl::foreground(252, 252, 252); } int main(int argc, char **argv) { std::string lang = Common::getlang(); std::string windowtit = std::string(intname) + " " + version; Fl_Window *window = new Fl_Window(790, 740, windowtit.c_str()); set_dark_theme(); #if defined(__linux) const char *iconPath = "/usr/share/icons/076/512x512/simpas.png"; #else const char *iconPath = "/usr/local/share/icons/076/512x512/simpas.png"; #endif Fl_PNG_Image *icon = new Fl_PNG_Image(iconPath); window->icon(icon); searchfield = new Fl_Input( (lang.compare(0, 2, "en") == 0 ? 70 : 50), 10, (lang.compare(0, 2, "en") == 0 ? 710 : 730), 30, (lang.compare(0, 2, "en") == 0 ? "Search:" : "検索:")); searchfield->callback(search_cb); browser = new Fl_Select_Browser(10, 50, 380, 500); textview = new Fl_Text_Display(400, 50, 380, 500); textbuf = new Fl_Text_Buffer(); textview->buffer(textbuf); browser->callback(browser_cb); Fl_Button *copybtn = new Fl_Button(400, 600, 150, 30, (lang.compare(0, 2, "en") == 0 ? "Copy password" : "パスワードのコピー")); copybtn->callback(copy_cb); a.btn = new Fl_Button(10, 560, 150, 30, (lang.compare(0, 2, "en") == 0 ? "Add password" : "パスワードの追加")); a.btn->callback(a.dialog_cb); d.btn = new Fl_Button(10, 600, 150, 30, (lang.compare(0, 2, "en") == 0 ? "Delete password" : "パスワードの削除")); d.btn->deactivate(); d.btn->callback(d.dialog_cb); e.btn = new Fl_Button(400, 560, 150, 30, (lang.compare(0, 2, "en") == 0 ? "Edit password" : "パスワードの編集")); e.btn->deactivate(); e.btn->callback(e.dialog_cb); hidechk = new Fl_Check_Button(560, 560, 150, 30, (lang.compare(0, 2, "en") == 0 ? "Hide password" : "パスワードを隠す")); hidechk->set(); hidechk->callback(hide_cb); showbtn = new Fl_Button(560, 600, 150, 30, (lang.compare(0, 2, "en") == 0 ? "Show password" : "パスワードの表示")); showbtn->deactivate(); showbtn->callback(show_cb); g.btn = new Fl_Button(10, 640, 150, 30, (lang.compare(0, 2, "en") == 0 ? "Generate password" : "パスワードの作成")); g.btn->callback(g.dialog_cb); i.btn = new Fl_Button(10, 680, 150, 30, (lang.compare(0, 2, "en") == 0 ? "Initialize password" : "パスワードの初期設定")); v.btn = new Fl_Button(170, 560, 200, 30, (lang.compare(0, 2, "en") == 0 ? "Check for breach" : "漏洩されたかの確認")); v.btn->callback(v.dialog_cb); c.btn = new Fl_Button(170, 600, 200, 30, (lang.compare(0, 2, "en") == 0 ? "Check for unsafe passwords" : "不安定的なパスワードの確認")); c.btn->callback(c.dialog_cb); std::string gpgidpath = Common::getbasedir(true) + ".gpg-id"; struct stat buf; if (stat(gpgidpath.c_str(), &buf) == 0) { i.btn->deactivate(); } i.btn->callback(init_dialog_cb); std::string bothver = windowtit + " (" + std::string(basedof) + ")"; Fl_Box *versionlabel = new Fl_Box(FL_NO_BOX, 620, 700, 160, 30, bothver.c_str()); versionlabel->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE); std::vector fpaths; std::string rdir = Common::getbasedir(false); scandir(rdir, rdir, fpaths); updatelist(); window->end(); window->show(argc, argv); return Fl::run(); }