This repository has been archived on 2026-05-26. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
SimPas1/src/chkpass.cc
2026-01-21 04:47:40 +09:00

280 lines
8.5 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include "common.hh"
#include "chkpass.hh"
#include "../main.hh"
#include "showpass.hh"
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/fl_ask.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Button.H>
#include <FL/Fl_Text_Display.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Scrollbar.H>
#include <string>
#include <thread>
#include <algorithm>
Chkpass chk;
std::vector<std::string> foundRes;
std::vector<std::string> duppath;
std::vector<std::string> duppasswd;
struct InputData {
Fl_Radio_Button *all;
Fl_Radio_Button *len;
Fl_Radio_Button *chr;
Fl_Radio_Button *dup;
Fl_Window *dialog;
};
void Chkpass::lenPass(const std::string &path, const std::string &pass,
const std::string &lang) {
if (pass.length() > 0 && pass.length() < minimumlen) {
std::string res = "【E】";
res += (lang.compare(0, 2, "en") == 0 ?
"The password \"" + path + "\" is too short, minimum length should be " +
std::to_string(minimumlen) + " characters, recommended is " +
std::to_string(recommendlen) + " characters.":
"パスワード「" + path + "」は短すぎます。最短パスワードの長さは" +
std::to_string(minimumlen) + "文字ですが、勧めが" +
std::to_string(recommendlen) + "文字です。");
foundRes.push_back(res);
weaklencount++;
vulncount++;
} else if (pass.length() >= minimumlen && pass.length() < recommendlen) {
std::string res = "【W】";
res += (lang.compare(0, 2, "en") == 0 ?
"The password \"" + path + "\" is long enough, but for optimal security, " +
std::to_string(recommendlen) + " characters is recommended.\n" :
"パスワード「" + path + "」の長さは十分ですが、最強のセキュリティには" +
std::to_string(recommendlen) + "文字が勧めします。\n");
foundRes.push_back(res);
}
}
void Chkpass::charPass(const std::string &path, const std::string &pass,
const std::string &lang) {
bool isUpper = false;
bool isLower = false;
bool isDigit = false;
bool isSpecial = false;
for (char ch : pass) {
if (std::isupper(static_cast<unsigned char>(ch))) isUpper = true;
if (std::islower(static_cast<unsigned char>(ch))) isLower = true;
if (std::isdigit(static_cast<unsigned char>(ch))) isDigit = true;
if (std::find(spchar.begin(), spchar.end(), ch) != spchar.end()) isSpecial = true;
}
if (!isUpper || !isLower || !isDigit || !isSpecial) {
std::string res = "【E】";
res += (lang.compare(0, 2, "en") == 0 ?
"The password \"" + path + "\" is too weak! A strong password contains " +
"at least 1 uppercase, 1 lowercase, 1 digit, and 1 special character." :
"パスワード「" + path + "」は弱すぎます強いパスワードは最大1大文字、" +
"1小文字、1数字、及び1記号の文字が含みます。");
foundRes.push_back(res);
weakcharcount++;
vulncount++;
}
}
void Chkpass::dupPass(const std::string &path, const std::string &pass,
const std::string &lang) {
for (std::size_t k = 0; k < duppasswd.size(); k++) {
if (pass.compare(duppasswd[k]) == 0) {
std::string res = "【E】";
res += (lang.compare(0, 2, "en") == 0 ?
"The password \"" + path + "\" is the same as \"" + duppath[k] + "\". " +
"For security, please keep passwords unique!":
"パスワード「" + path + "」は「" + duppath[k] + "」と一致しています。" +
"セキュリティの為、各パスワードはユニークにする様にして下さい!");
foundRes.push_back(res);
duppasscount++;
vulncount++;
}
}
duppath.push_back(path);
duppasswd.push_back(pass);
}
bool Chkpass::exec() {
std::string lang = Common::getlang();
// パスワードをスキャンして
Showpass show;
for (const auto &dispath : dispaths) {
std::string fullpath = Common::getbasedir(true) + dispath + ".gpg";
std::string pass = show.exec(fullpath.c_str(), true);
if (pass.empty()) continue;
if (pass.rfind("otpauth://totp/", 0) == 0) continue;
if (isAll) {
lenPass(dispath, pass, lang);
charPass(dispath, pass, lang);
dupPass(dispath, pass, lang);
} else if (isLen) {
lenPass(dispath, pass, lang);
} else if (isChar) {
charPass(dispath, pass, lang);
} else if (isDup) {
dupPass(dispath, pass, lang);
}
}
return true;
}
void Chkpass::showRes() {
std::string lang = Common::getlang();
std::string res;
if (lang.compare(0, 2, "en") == 0) {
res = "Weak passwords:\n";
} else {
res = "不安定なパスワード:\n";
}
for (const auto &path : foundRes) {
res += path + "\n";
}
if (lang.compare(0, 2, "en") == 0) {
res += "Short password count: " + std::to_string(weaklencount) + "\n";
res += "Weak password count: " + std::to_string(weakcharcount) + "\n";
res += "Duplicate password count: " + std::to_string(duppasscount) + "\n";
res += "Total: " + std::to_string(duppath.size()) + "\n";
res += "It's advised to change any of the";
res += "weak passwords as soon as possible!";
} else {
res += "短いパスワード数: " + std::to_string(weaklencount) + "\n";
res += "弱いパスワード数: " + std::to_string(weakcharcount) + "\n";
res += "同じパスワード数: " + std::to_string(duppasscount) + "\n";
res += "合計: " + std::to_string(duppath.size()) + "\n";
res += "不安定なパスワードは出来るだけ早く変更する事をお勧めします!";
}
Fl_Window *win = new Fl_Window(500, 440, lang.compare(0, 2, "en") == 0 ?
"Results" : "結果");
Fl_Text_Display *display = new Fl_Text_Display(10, 10, 480, 380);
Fl_Text_Buffer *textbuf = new Fl_Text_Buffer();
textbuf->text(res.c_str());
display->buffer(textbuf);
display->scrollbar_width(15);
win->resizable(display);
Fl_Button *okBtn = new Fl_Button(210, 400, 80, 30, "OK");
okBtn->callback([](Fl_Widget *widget, void *win) {
(void)widget;
reinterpret_cast<Fl_Window*>(win)->hide();
}, win);
win->add(okBtn);
win->end();
win->show();
}
void Chkpass::chk_cb(Fl_Widget *, void *data) {
InputData *inputs = (InputData *)data;
std::string lang = Common::getlang();
if (inputs) {
isAll = inputs->all->value();
isLen = inputs->len->value();
isChar = inputs->chr->value();
isDup = inputs->dup->value();
}
Fl_Window *dialog = new Fl_Window(400, 50,
(lang.compare(0, 2, "en") == 0 ?
"Checking for weak password" : "不安的なパスワードの確認中"));
Fl_Box *box = new Fl_Box(10, 10, 380, 20,
(lang.compare(0, 2, "en") == 0 ?
"Checking, please wait for a while..." :
"確認中。暫くお待ち下さい・・・"));
dialog->add(box);
dialog->end();
dialog->set_modal();
dialog->show();
std::thread checker([dialog]() {
chk.exec();
Fl::lock();
dialog->hide();
chk.showRes();
Fl::unlock();
});
checker.detach();
}
void Chkpass::dialog_cb(Fl_Widget *w, void *) {
(void)w;
std::string lang = Common::getlang();
Fl_Window *dialog = new Fl_Window(390, 145,
(lang.compare(0, 2, "en") == 0 ?
"Check for weak password" : "不安的なパスワードの確認"));
Fl_Radio_Button *all = new Fl_Radio_Button(10, 10, 180, 30,
(lang.compare(0, 2, "en") == 0) ? "Everything" : "全部");
Fl_Radio_Button *len = new Fl_Radio_Button(10, 50, 180, 30,
(lang.compare(0, 2, "en") == 0) ? "Length" : "長さ");
Fl_Radio_Button *chr = new Fl_Radio_Button(200, 10, 180, 30,
(lang.compare(0, 2, "en") == 0) ? "Strength" : "強さ");
Fl_Radio_Button *dup = new Fl_Radio_Button(200, 50, 180, 30,
(lang.compare(0, 2, "en") == 0) ? "Duplicate" : "服数度");
dialog->add(all);
dialog->add(len);
dialog->add(chr);
dialog->add(dup);
InputData *inputs = new InputData();
inputs->all = all;
inputs->len = len;
inputs->chr = chr;
inputs->dup = dup;
inputs->dialog = dialog;
Fl_Button *okbtn = new Fl_Button(105, 100, 80, 30, "OK");
Fl_Button *cancelbtn = new Fl_Button(205, 100, 80, 30,
(lang.compare(0, 2, "en") == 0 ? "Cancel" : "キャンセル"));
okbtn->callback(static_ok_cb, inputs);
cancelbtn->callback(static_cancel_cb, dialog);
dialog->add(okbtn);
dialog->add(cancelbtn);
dialog->end();
dialog->set_modal();
dialog->show();
}
void Chkpass::static_ok_cb(Fl_Widget *w, void *data) {
(void)w;
InputData *inputs = (InputData *)data;
chk.chk_cb(nullptr, inputs);
}
void Chkpass::static_cancel_cb(Fl_Widget *w, void *data) {
((Chkpass *)data)->cancel_cb(w, data);
}