diff options
Diffstat (limited to 'debian/pinentry-tqt/pinentry-tqt-1.2.1/fltk/pinwindow.cxx')
-rw-r--r-- | debian/pinentry-tqt/pinentry-tqt-1.2.1/fltk/pinwindow.cxx | 251 |
1 files changed, 251 insertions, 0 deletions
diff --git a/debian/pinentry-tqt/pinentry-tqt-1.2.1/fltk/pinwindow.cxx b/debian/pinentry-tqt/pinentry-tqt-1.2.1/fltk/pinwindow.cxx new file mode 100644 index 00000000..c187dd5e --- /dev/null +++ b/debian/pinentry-tqt/pinentry-tqt-1.2.1/fltk/pinwindow.cxx @@ -0,0 +1,251 @@ +/* + pinwindow.cxx - PinWindow is a simple fltk dialog for entring password + with timeout. if needed description (long text), error message, qualitybar + and etc should used PassWindow. + + Copyright (C) 2016 Anatoly madRat L. Berenblit + + Written by Anatoly madRat L. Berenblit <madrat-@users.noreply.github.com>. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <FL/Fl.H> +#include <FL/Fl_Window.H> +#include <FL/Fl_Box.H> +#include <FL/Fl_Input.H> +#include <FL/Fl_Button.H> +#include <FL/Fl_Secret_Input.H> +#include <FL/Fl_Return_Button.H> +#include <FL/Fl_Pixmap.H> + +#include "memory.h" + +#include "encrypt.xpm" +#include "icon.xpm" + +#include "pinwindow.h" + +const char *PinWindow::TITLE = "Password"; +const char *PinWindow::BUTTON_OK = "OK"; +const char *PinWindow::BUTTON_CANCEL = "Cancel"; +const char *PinWindow::PROMPT = "Passphrase:"; + +static const char *timeout_format = "%s(%d)"; + +static Fl_Pixmap encrypt(encrypt_xpm); +static Fl_Pixmap icon(icon_xpm); + +PinWindow::PinWindow() : window_(NULL) + ,message_(NULL) ,input_(NULL) ,ok_(NULL) ,cancel_(NULL) + ,cancel_name_(BUTTON_CANCEL) + ,passwd_(NULL) ,timeout_(0) +{ +} + +PinWindow::~PinWindow() +{ + wipe(); + release(); + delete window_; +} + +void PinWindow::release() +{ + if (NULL != passwd_) + { + memset(passwd_, 0, strlen(passwd_)); + secmem_free(passwd_); + } + passwd_ = NULL; +} + +void PinWindow::title(const char *name) +{ + set_label(window_, name, TITLE); +} + +void PinWindow::ok(const char* name) +{ + set_label(ok_, name, BUTTON_OK); +} + +void PinWindow::cancel(const char* label) +{ + if (NULL != label && 0 != *label) + cancel_name_ = label; + else + cancel_name_ = BUTTON_CANCEL; + + update_cancel_label(); +} + +void PinWindow::prompt(const char *name) +{ + set_label(message_, name, PROMPT); +} + +void PinWindow::timeout(unsigned int time) +{ + if (timeout_ == time) + return; + + // A xor B ~ A != B + if ( (time>0) != (timeout_>0)) + { + //enable or disable + if (time>0) + Fl::add_timeout(1.0, timeout_cb, this); + else + Fl::remove_timeout(timeout_cb, this); + } + + timeout_=time; + update_cancel_label(); + --timeout_; +} + +void PinWindow::showModal() +{ + if (NULL != window_) + { + window_->show(); + Fl::run(); + } + Fl::check(); +} + +void PinWindow::showModal(const int argc, char* argv[]) +{ + if (NULL != window_) + { + window_->show(argc, argv); + Fl::run(); + } + Fl::check(); +} + +int PinWindow::init(const int cx, const int cy) +{ + assert(NULL == window_); + window_ = new Fl_Window(cx, cy, TITLE); + + Fl_RGB_Image app(&icon); + window_->icon(&app); + + icon_ = new Fl_Box(10, 10, 64, 64); + icon_->image(encrypt); + + message_ = new Fl_Box(79, 5, cx-99, 44, PROMPT); + message_->align(Fl_Align(FL_ALIGN_LEFT_TOP | FL_ALIGN_WRAP | FL_ALIGN_INSIDE)); // left + + input_ = new Fl_Secret_Input(79, 59, cx-99, 25); + input_->labeltype(FL_NO_LABEL); + + + const int button_y = cy-40; + ok_ = new Fl_Return_Button(cx-300, button_y, 120, 25, BUTTON_OK); + ok_->callback(ok_cb, this); + + cancel_ = new Fl_Button(cx-160, button_y, 120, 25); + update_cancel_label(); + cancel_->callback(cancel_cb, this); + + window_->hotspot(input_); + window_->set_modal(); + + return 84; +}; + +void PinWindow::update_cancel_label() +{ + if (timeout_ == 0) + { + cancel_->label(cancel_name_.c_str()); + } + else + { + const size_t len = cancel_name_.size()+strlen(timeout_format)+10+1; + char *buf = new char[len]; + snprintf(buf, len, timeout_format, cancel_name_.c_str(), timeout_); + cancel_->copy_label(buf); + delete[] buf; // no way to attach label + } +} + +void PinWindow::timeout_cb(void* val) +{ + PinWindow *self = reinterpret_cast<PinWindow*>(val); + if (self->timeout_ == 0) + { + cancel_cb(self->cancel_, self); + } + else + { + self->update_cancel_label(); + --self->timeout_; + Fl::repeat_timeout(1.0, timeout_cb, val); + } +} + +void PinWindow::cancel_cb(Fl_Widget *button, void *val) +{ + PinWindow *self = reinterpret_cast<PinWindow*>(val); + + self->wipe(); + self->release(); + self->window_->hide(); +} + +void PinWindow::ok_cb(Fl_Widget *button, void *val) +{ + PinWindow *self = reinterpret_cast<PinWindow*>(val); + + self->release(); + + const char *passwd = self->input_->value(); + size_t len = strlen(passwd)+1; + self->passwd_ = reinterpret_cast<char*>(secmem_malloc(len)); + if (NULL != self->passwd_) + memcpy(self->passwd_, passwd, len); + + self->wipe(); + self->window_->hide(); +} + +void PinWindow::wipe() +{ + int len = input_->size(); + char* emul = new char[len+1]; + for (int i=0; i<len; ++i) + { + emul[i] = 0x20 + rand()%(128-20); // [20..127] + } + emul[len] = 0; + input_->replace(0, len, emul, len); + delete[] emul; + + input_->value(TITLE); // hide size too +} + +PinWindow* PinWindow::create() +{ + PinWindow* p = new PinWindow; + p->init(410, 140); + p->window_->end(); + p->input_->take_focus(); + return p; +} |