[git] Pinentry - branch, justus/fltk, created. pinentry-1.0.0-15-g183fea8

by Anatoly madRat L. Berenblit cvs at cvs.gnupg.org
Wed Feb 8 10:08:04 CET 2017


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "The standard pinentry collection".

The branch, justus/fltk has been created
        at  183fea8ae35b693757deb719920414a334a3a936 (commit)

- Log -----------------------------------------------------------------
commit 183fea8ae35b693757deb719920414a334a3a936
Author: Anatoly madRat L. Berenblit <madrat- at users.noreply.github.com>
Date:   Tue Feb 7 17:18:41 2017 +0100

    fltk: Add a FLTK-based pinentry.
    
    * Makefile.am: Add new subdirectory.
    * configure.ac: Add configuration for FLTK.
    * fltk/Makefile.am: New file.
    * fltk/encrypt.xpm: Likewise.
    * fltk/icon.xpm: Likewise.
    * fltk/main.cxx: Likewise.
    * fltk/passwindow.cxx: Likewise.
    * fltk/passwindow.h: Likewise.
    * fltk/pinwindow.cxx: Likewise.
    * fltk/pinwindow.h: Likewise.
    * fltk/qualitypasswindow.cxx: Likewise.
    * fltk/qualitypasswindow.h: Likewise.
    
    Signed-off-by: Justus Winter <justus at gnupg.org>

diff --git a/Makefile.am b/Makefile.am
index ef80f6c..1f62939 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -70,9 +70,15 @@ else
 pinentry_w32 =
 endif
 
+if BUILD_PINENTRY_FLTK
+pinentry_fltk = fltk
+else
+pinentry_fltk =
+endif
+
 SUBDIRS = m4 secmem pinentry ${pinentry_curses} ${pinentry_tty} \
 	${pinentry_emacs} ${pinentry_gtk_2} ${pinentry_gnome_3} \
-	${pinentry_qt} ${pinentry_w32} doc
+	${pinentry_qt} ${pinentry_w32} ${pinentry_fltk} doc
 
 
 install-exec-local:
diff --git a/configure.ac b/configure.ac
index 5119e4a..8b38149 100644
--- a/configure.ac
+++ b/configure.ac
@@ -588,6 +588,42 @@ pinentry_w32=no
 test $have_w32_system = yes && pinentry_w32=yes
 AM_CONDITIONAL(BUILD_PINENTRY_W32, test "$pinentry_w32" = "yes")
 
+dnl
+dnl Check for FLTK pinentry program.
+dnl
+AC_ARG_ENABLE(pinentry-fltk,
+    AC_HELP_STRING([--enable-pinentry-fltk], [build FLTK 1.3 pinentry]),
+           pinentry_fltk=$enableval, pinentry_fltk=maybe)
+
+dnl check for fltk-config
+if test "$pinentry_fltk" != "no"; then
+   AC_PATH_PROG(FLTK_CONFIG, fltk-config, no)
+   if test x"${FLTK_CONFIG}" = xno ; then
+       AC_MSG_WARN([fltk-config is not found])
+       pinentry_fltk=no
+   fi
+fi
+
+dnl check for FLTK libraries and set flags
+if test "$pinentry_fltk" != "no"; then
+   AC_MSG_CHECKING([for FLTK 1.3])
+   FLTK_VERSION=`${FLTK_CONFIG} --api-version`
+   if test ${FLTK_VERSION} != "1.3" ; then
+       AC_MSG_RESULT([no])
+       AC_MSG_WARN([FLTK 1.3 not found (available $FLTK_VERSION)])
+       pinentry_fltk=no
+   else
+       AC_MSG_RESULT([yes])
+       FLTKCFLAGS=`${FLTK_CONFIG} --cflags`
+       FLTKCXXFLAGS=`${FLTK_CONFIG} --cxxflags`
+       FLTKLIBS=`${FLTK_CONFIG} --ldflags`
+       AC_SUBST(FLTKCFLAGS)
+       AC_SUBST(FLTKCXXFLAGS)
+       AC_SUBST(FLTKLIBS)
+       pinentry_fltk=yes
+   fi
+fi
+AM_CONDITIONAL(BUILD_PINENTRY_FLTK, test "$pinentry_fltk" = "yes")
 
 # Figure out the default pinentry.  We are very conservative here.
 # Please change the order only after verifying that the preferred
@@ -611,7 +647,11 @@ else
           if test "$pinentry_w32" = "yes"; then
             PINENTRY_DEFAULT=pinentry-w32
           else
-            AC_MSG_ERROR([[No pinentry enabled.]])
+            if test "$pinentry_fltk" = "yes"; then
+              PINENTRY_DEFAULT=pinentry-fltk
+            else
+              AC_MSG_ERROR([[No pinentry enabled.]])
+            fi
           fi
         fi
       fi
@@ -690,6 +730,7 @@ gtk+-2/Makefile
 gnome3/Makefile
 qt/Makefile
 w32/Makefile
+fltk/Makefile
 doc/Makefile
 Makefile
 ])
@@ -710,6 +751,7 @@ AC_MSG_NOTICE([
 	GNOME 3 Pinentry .: $pinentry_gnome_3
 	Qt Pinentry ......: $pinentry_qt $pinentry_qt_lib_version
 	W32 Pinentry .....: $pinentry_w32
+	FLTK Pinentry ....: $pinentry_fltk
 
 	Fallback to Curses: $fallback_curses
 	Emacs integration : $inside_emacs
diff --git a/fltk/Makefile.am b/fltk/Makefile.am
new file mode 100644
index 0000000..2c9338f
--- /dev/null
+++ b/fltk/Makefile.am
@@ -0,0 +1,16 @@
+# Makefile.am - PIN entry FLTK frontend.
+
+bin_PROGRAMS = pinentry-fltk
+
+if FALLBACK_CURSES
+ncurses_include = $(NCURSES_INCLUDE)
+libcurses = ../pinentry/libpinentry-curses.a $(LIBCURSES) $(LIBICONV)
+else
+ncurses_include =
+libcurses =
+endif
+
+AM_CPPFLAGS = $(COMMON_CFLAGS) $(FLTKCXXFLAGS) $(ncurses_include) -I$(top_srcdir)/secmem -I$(top_srcdir)/pinentry
+LDADD = ../pinentry/libpinentry.a ../secmem/libsecmem.a $(COMMON_LIBS) $(LIBCAP) $(FLTKLIBS) $(libcurses)
+
+pinentry_fltk_SOURCES = main.cxx pinwindow.cxx passwindow.cxx qualitypasswindow.cxx
diff --git a/fltk/encrypt.xpm b/fltk/encrypt.xpm
new file mode 100644
index 0000000..80402e3
--- /dev/null
+++ b/fltk/encrypt.xpm
@@ -0,0 +1,83 @@
+/* XPM */
+static const char * const encrypt_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 45 32 1 ",
+"  c #9B7738",
+". c #B08830",
+"X c #CA9703",
+"o c #C99607",
+"O c #CD9A02",
+"+ c #D19D03",
+"@ c #D4A002",
+"# c #D7A305",
+"$ c #D8A501",
+"% c #DFAB01",
+"& c #DCA803",
+"* c #E3B103",
+"= c #E7B702",
+"- c #C39A31",
+"; c #D4AC2F",
+": c #E6BE26",
+"> c #EFC002",
+", c #F5CD06",
+"< c #FEE21D",
+"1 c #FCE01F",
+"2 c #F6D424",
+"3 c #B49A55",
+"4 c #CAAC5F",
+"5 c #FCE854",
+"6 c #888887",
+"7 c #9A9A9A",
+"8 c #A7A7A7",
+"9 c #B8B8B7",
+"0 c #F3F08F",
+"q c #C3C3C3",
+"w c gray85",
+"e c None",
+/* pixels */
+"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
+"eeeeeeeeeee889qqqq987eeeeeeeeeee",
+"eeeeeeeee89qwwwqqwwww88eeeeeeeee",
+"eeeeeeee99qq877777669wq8eeeeeeee",
+"eeeeeee99q888888888876ww9eeeeeee",
+"eeeeee99q888888887778869q9eeeeee",
+"eeeee89q8888eeeeeeee7786wq8eeeee",
+"eeeee999888eeeeeeeeee7777wqeeeee",
+"eeee899778eeeeeeeeeeee776wq8eeee",
+"eeee8q977eeeeeeeeeeeeee779q9eeee",
+"eeee8q977eeeeeeeeeeeeee777w9eeee",
+"eeee8q867eeeeeeeeeeeeee776wqeeee",
+"eeee8q768eeeeeeeeeeeeee766wqeeee",
+"eeee8q768eeeeeeeeeeeeee766wqeeee",
+"eeee8q778eeeeeeeeeeeeee776wqeeee",
+"eeee8q778eeeeeeeeeeeeee776wqeeee",
+"eeee8q888eeeeeeeeeeeeee786wqeeee",
+"eeee8q888eeeeeeeeeeeeee786wqeeee",
+"eeee8q898eeeeeeeeeeeeee796wqeeee",
+"eeee8q898eeeeeeeeeeeeee896wqeeee",
+"e45444443333         3333444003e",
+"e4552::;;--...    ...--;;:25003e",
+"e4552,>>=&@OXXooXO+@$&*=>,15003e",
+"e4552,>>*&#+ooooo++##&*=>,15003e",
+"e4552,>>*&#+XXXXXO+@#&*=>,<5003e",
+"e4552,>>=%$+OXXOO++##&*=>,15003e",
+"e4552,>>=%$OooXXO+@@#&%=,,<5003e",
+"e4552,>>=%$@OXXO+@@#&&*=>,15003e",
+"e4552,>>*&$+XXXXOO++@#%=>,<5003e",
+"e4552,>>=&$+OXXO++@@$&*=,,<5003e",
+"e4552,>>=%$+XXXXOO+@#&*=>,<5003e",
+"e4552,>>*&#+ooXO++@##&*>,,<5003e",
+"e4552,>>=%$@OXXO++@$$%*>,,<5003e",
+"e4552,>>=%$+OXXO++@#$&*=,,<5003e",
+"e4552,>>=%$@OOOO++@$&%*=>,<5003e",
+"e4552,>>=%$+OXXOO+@#&%=>,,<5003e",
+"e4552,>>=%$+OXXOO+@##%*=>,<5003e",
+"e4552,>>*&#+oooO++@#&&*>,,<5003e",
+"e4552,>>=%$@OOOO+@$&%%*>,,<5003e",
+"e4552,>>=%$@OOXO+@$&%%*>,,<5003e",
+"e4552,>>=%$+OXXO+@$&&%*>,,<5003e",
+"e4552,>>=%$@OOO+@@$&%%=>,,<5003e",
+"e4552,>>=%$@OOO+@@$&%%=>,,<5003e",
+"e4552,>>=%$@OOO+@@$&%%=>,,<5003e",
+"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"
+};
diff --git a/fltk/icon.xpm b/fltk/icon.xpm
new file mode 100644
index 0000000..eed3cd6
--- /dev/null
+++ b/fltk/icon.xpm
@@ -0,0 +1,37 @@
+/* XPM */
+static const char *const icon_xpm[] = {
+"31 29 3 1 ",
+"  c black",
+". c yellow",
+"X c None",
+
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"             XXXXXXXXXXXXXXXXXX",
+" ........... XXXXXXXXXXXXXXXXXX",
+" ........... XXXXXXXXXXXXXXXXXX",
+" ...     ... XXXXXXXXXXXXXXXXXX",
+" ... XXX ...                   ",
+" ... XXX ... ................. ",
+" ... XXX ... ................. ",
+" ... XXX ...         ...   ... ",
+" ...     ... XXXXXXX ... X ... ",
+" ........... XXXXXXX ... X ... ",
+" ........... XXXXXXX     X ... ",
+"             XXXXXXXXXXXXX     ",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
+"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
+};
diff --git a/fltk/main.cxx b/fltk/main.cxx
new file mode 100644
index 0000000..7526656
--- /dev/null
+++ b/fltk/main.cxx
@@ -0,0 +1,391 @@
+/*
+   main.cpp - A Fltk based dialog for PIN entry.
+
+   Copyright (C) 2016 Anatoly madRat L. Berenblit
+
+   Written by Anatoly madRat L. Berenblit <madrat- at 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.
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define PGMNAME (PACKAGE_NAME"-fltk")
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <errno.h>
+#include <getopt.h>
+#include <assert.h>
+
+#include "memory.h"
+#include <memory>
+
+#include <pinentry.h>
+#ifdef FALLBACK_CURSES
+#include <pinentry-curses.h>
+#endif
+
+#include <string>
+#include <string.h>
+#include <stdexcept>
+
+
+#include <FL/Fl.H>
+#include <FL/Fl_Window.H>
+#include <FL/fl_ask.H>
+
+#include "pinwindow.h"
+#include "passwindow.h"
+#include "qualitypasswindow.h"
+
+#define CONFIRM_STRING "Confirm"
+#define REPEAT_ERROR_STRING "Texts do not match"
+#define OK_STRING "OK"
+#define CANCEL_STRING "Cancel"
+
+char *application = NULL;
+
+static std::string escape_accel_utf8(const char *s)
+{
+	std::string result;
+	if (NULL != s)
+	{
+		result.reserve(strlen(s));
+		for (const char *p = s; *p; ++p)
+		{
+			if ('&' == *p)
+				result.push_back(*p);
+			result.push_back(*p);
+		}
+	}
+	return result;
+}
+
+class cancel_exception
+{
+
+};
+
+static int get_quality(const char *passwd, void *ptr)
+{
+	if (NULL == passwd || 0 == *passwd)
+		return 0;
+
+	pinentry_t* pe = reinterpret_cast<pinentry_t*>(ptr);
+	return pinentry_inq_quality(*pe, passwd, strlen(passwd));
+}
+
+bool is_short(const char *str)
+{
+	return fl_utf_nb_char(reinterpret_cast<const unsigned char*>(str), strlen(str)) < 16;
+}
+
+bool is_empty(const char *str)
+{
+	return (NULL == str) || (0 == *str);
+}
+
+static int fltk_cmd_handler(pinentry_t pe)
+{
+	int ret = -1;
+
+	try
+	{
+		// TODO: Add parent window to pinentry-fltk window
+		//if (pe->parent_wid){}
+		std::string title  = !is_empty(pe->title)?pe->title:PGMNAME;
+		std::string ok 	   = escape_accel_utf8(pe->ok?pe->ok:(pe->default_ok?pe->default_ok:OK_STRING));
+		std::string cancel = escape_accel_utf8(pe->cancel?pe->cancel:(pe->default_cancel?pe->default_cancel:CANCEL_STRING));
+
+		if (!!pe->pin) // password (or confirmation)
+		{
+			std::auto_ptr<PinWindow> window;
+
+			bool isSimple = (NULL == pe->quality_bar) &&	// pinenty.h: If this is not NULL ...
+							is_empty(pe->error) && is_empty(pe->description) &&
+							is_short(pe->prompt);
+			if (isSimple)
+			{
+				assert(NULL == pe->description);
+				window.reset(PinWindow::create());
+				window->prompt(pe->prompt);
+			}
+			else
+			{
+				PassWindow *pass = NULL;
+
+				if (pe->quality_bar) // pinenty.h: If this is not NULL ...
+				{
+					QualityPassWindow *p = QualityPassWindow::create(get_quality, &pe);
+					window.reset(p);
+					pass = p;
+					p->quality(pe->quality_bar);
+				}
+				else
+				{
+					pass = PassWindow::create();
+					window.reset(pass);
+				}
+
+				if (NULL == pe->description)
+				{
+					pass->description(pe->prompt);
+					pass->prompt(" ");
+				}
+				else
+				{
+					pass->description(pe->description);
+					pass->prompt(escape_accel_utf8(pe->prompt).c_str());
+				}
+				pass->description(pe->description);
+				pass->prompt(escape_accel_utf8(pe->prompt).c_str());
+
+
+				if (NULL != pe->error)
+					pass->error(pe->error);
+			}
+
+			window->ok(ok.c_str());
+			window->cancel(cancel.c_str());
+			window->title(title.c_str());
+			window->showModal((NULL != application)?1:0, &application);
+
+			if (NULL == window->passwd())
+				throw cancel_exception();
+
+			const std::string password = window->passwd();
+			window.reset();
+
+			if (pe->repeat_passphrase)
+			{
+				const char *dont_match = NULL;
+				do
+				{
+					if (NULL == dont_match && is_short(pe->repeat_passphrase))
+					{
+						window.reset(PinWindow::create());
+						window->prompt(escape_accel_utf8(pe->repeat_passphrase).c_str());
+					}
+					else
+					{
+						PassWindow *pass = PassWindow::create();
+						window.reset(pass);
+						pass->description(pe->repeat_passphrase);
+						pass->prompt(" ");
+						pass->error(dont_match);
+					}
+
+					window->ok(ok.c_str());
+					window->cancel(cancel.c_str());
+					window->title(title.c_str());
+					window->showModal();
+
+					if (NULL == window->passwd())
+						throw cancel_exception();
+
+					if (password == window->passwd())
+					{
+						pe->repeat_okay = 1;
+						ret = 1;
+						break;
+					}
+					else
+					{
+							dont_match = (NULL!=pe->repeat_error_string)? pe->repeat_error_string:REPEAT_ERROR_STRING;
+						}
+					} while (true);
+				}
+				else
+					ret = 1;
+
+				pinentry_setbufferlen(pe, password.size()+1);
+				if (pe->pin)
+				{
+					memcpy(pe->pin, password.c_str(), password.size()+1);
+					pe->result = password.size();
+					ret = password.size();
+				}
+			}
+			else
+			{
+				// Confirmation or Message Dialog title, desc
+				Fl_Window dummy(0,0, 1,1);
+
+				dummy.border(0);
+				dummy.show((NULL != application)?1:0, &application);
+				dummy.hide();
+
+				fl_message_title(title.c_str());
+
+				int result = -1;
+
+				const char *message = (NULL != pe->description)?pe->description:CONFIRM_STRING;
+
+				if (pe->one_button)
+				{
+					fl_ok = ok.c_str();
+					fl_message(message);
+					result = 1; // OK
+				}
+				else if (pe->notok)
+				{
+					switch (fl_choice(message, ok.c_str(), cancel.c_str(), pe->notok))
+					{
+					case 0: result = 1; break;
+					case 2: result = 0; break;
+					default:
+					case 1: result = -1;break;
+					}
+				}
+				else
+				{
+					switch (fl_choice(message, ok.c_str(), cancel.c_str(), NULL))
+					{
+					case 0: result = 1; break;
+					default:
+					case 1: result = -1;break;
+					}
+				}
+
+				// cancel ->         pe->canceled = true, 0
+				// ok/y -> 1
+				// no -> 0
+				if (-1 == result)
+					pe->canceled = true;
+				ret = (1 == result);
+			}
+			Fl::check();
+		}
+		catch (const cancel_exception&)
+		{
+			ret = -1;
+		}
+		catch (...)
+		{
+			ret = -1;
+		}
+			// do_touch_file(pe); only for NCURSES?
+		return ret;
+	}
+
+pinentry_cmd_handler_t pinentry_cmd_handler = fltk_cmd_handler;
+
+int main(int argc, char *argv[])
+{
+	application = *argv;
+	pinentry_init(PGMNAME);
+
+#ifdef FALLBACK_CURSES
+	if (!pinentry_have_display(argc, argv))
+		pinentry_cmd_handler = curses_cmd_handler;
+	else
+#endif
+	{
+		//FLTK understood only -D (--display)
+		// and should be converted into -di[splay]
+		const static struct option long_options[] =
+		{
+			{"display", required_argument,	0, 'D' },
+			{NULL, 		no_argument,		0, 0   }
+		};
+
+		for (int i = 0; i < argc-1; ++i)
+		{
+			switch (getopt_long(argc-i, argv+i, "D:", long_options, NULL))
+			{
+				case 'D':
+					{
+						char* emul[] = {application, (char*)"-display", optarg};
+						Fl::args(3, emul);
+						i = argc;
+						break;
+					}
+				default:
+					break;
+			}
+		}
+	}
+
+	pinentry_parse_opts(argc, argv);
+	return pinentry_loop() ?EXIT_FAILURE:EXIT_SUCCESS;
+}
+
+/*
+int get_quality(const char *pass)
+{
+	size_t len = strlen(pass);
+	return len>4?(80+len):-len*10;
+}
+
+int main(int argc, char *argv[])
+{
+	std::auto_ptr<PassWindow> window;
+	window.reset(QualityPassWindow::create(get_quality));
+
+//	window->message("Lorem ipsum dolor sit amet");
+//	window->message("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor. Phasellus tempor orci vel metus eleifend ultrices. Curabitur tempor euismod lorem");
+	window->prompt("Lorem ipsum:");
+	window->ok("YES!");
+	window->cancel("OTMEHA");
+//	window->error("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla");
+//	window->error("Some error  ellus adipiscing elit portt text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor a porttitor!");
+	window->timeout(100);
+	window->title(PGMNAME);
+	window->showModal(argc, argv);
+	return 0;
+}
+// */
+
+/*
+int main(int argc, char *argv[])
+{
+	Fl::args(argc, argv);
+	std::auto_ptr<PinWindow> window;
+	window.reset(PinWindow::create());
+//	window->message("PIN:");
+//	window->message("Phasellus adipiscing elit porttitor nisi a fringilla porttitor:");
+	window->ok("YES!");
+	window->cancel("OTMEHA");
+	window->timeout(100);
+	window->title(PGMNAME);
+	window->showModal(argc, argv);
+	return 0;
+}
+// */
+
+/*
+int main(int argc, char *argv[])
+{
+	Fl::args(argc, argv);
+	std::auto_ptr<PassWindow> window;
+	window.reset(PassWindow::create());
+//	window->message("Descr&iption");
+//	window->message("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor:");
+//	window->prompt("Prompt sit amet:");
+	window->ok("YES!");
+	window->cancel("OTMEHA");
+//	window->error("Password is empty.");
+//	window->error("Some error text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor!");
+//	window->error("Some error  ellus adipiscing elit portt text dolor sit amet, consectetur adipiscing elit. Phasellus porttitor nisi a fringilla porttitor!");
+	window->timeout(100);
+	window->title(PGMNAME);
+	window->showModal(argc, argv);
+	return 0;
+}
+// */
diff --git a/fltk/passwindow.cxx b/fltk/passwindow.cxx
new file mode 100644
index 0000000..78b3b2c
--- /dev/null
+++ b/fltk/passwindow.cxx
@@ -0,0 +1,85 @@
+/*
+    passwindow.cxx - PassWindow is a more complex fltk dialog with more longer
+    desc field and possibility to show some error text.
+    if needed qualitybar - should be used QualityPassWindow.
+
+    Copyright (C) 2016 Anatoly madRat L. Berenblit
+
+    Written by Anatoly madRat L. Berenblit <madrat- at 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.
+*/
+
+#include "passwindow.h"
+
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Input.H>
+
+const char *PassWindow::DESCRIPTION  = "Please enter the passphrase:";
+
+PassWindow::PassWindow() : error_(NULL)
+{
+}
+
+void PassWindow::prompt(const char *name)
+{
+	set_label(input_, name, PROMPT);
+}
+
+void PassWindow::description(const char *name)
+{
+	set_label(message_, name, DESCRIPTION);
+}
+
+void PassWindow::error(const char *name)
+{
+	set_label(error_, name, "");
+}
+
+int PassWindow::init(const int cx, const int cy)
+{
+	int y = PinWindow::init(cx, cy);
+
+	assert(window_ == Fl_Group::current()); // make_window should all add current
+
+	y = icon_->y(); // move back to icon's
+
+	const int mx = icon_->x()+icon_->w();
+	message_->resize(mx, icon_->y(), cx-mx-10, icon_->h());
+	message_->align(Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP | FL_ALIGN_WRAP | FL_ALIGN_INSIDE));
+	description(NULL);
+	y += icon_->h();
+
+	input_->resize(130, y+5, cx-150, 25);
+	input_->labeltype(FL_NORMAL_LABEL);
+	prompt(NULL);
+	y = input_->y()+input_->h();
+
+	error_ = new Fl_Box(20, y+5, cx-30, 30);
+	error_->labelcolor(FL_RED);
+	error_->align(Fl_Align(FL_ALIGN_CENTER | FL_ALIGN_WRAP | FL_ALIGN_INSIDE)); // if not fit - user can read
+	y = error_->y()+error_->h();
+	return y;
+}
+
+PassWindow* PassWindow::create()
+{
+	PassWindow* p = new PassWindow;
+	 p->init(460, 185);
+	 p->window_->end();
+	 p->input_->take_focus();
+	 return p;
+}
diff --git a/fltk/passwindow.h b/fltk/passwindow.h
new file mode 100644
index 0000000..43813cd
--- /dev/null
+++ b/fltk/passwindow.h
@@ -0,0 +1,50 @@
+/*
+    passwindow.h - PassWindow is a more complex fltk dialog with more longer
+    desc field and possibility to show some error text.
+    if needed qualitybar - should be used QualityPassWindow.
+
+    Copyright (C) 2016 Anatoly madRat L. Berenblit
+
+    Written by Anatoly madRat L. Berenblit <madrat- at 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.
+*/
+
+#ifndef __PASSWINDOW_H__
+#define __PASSWINDOW_H__
+
+#include "pinwindow.h"
+
+class PassWindow : public PinWindow
+{
+protected:
+	static const char *DESCRIPTION;
+
+protected:
+	Fl_Box      *error_;
+	PassWindow();
+
+public:
+	virtual void prompt(const char *message);
+	virtual void description(const char *desc);
+	virtual void error(const char *err);
+
+	static PassWindow* create();
+
+protected:
+	virtual int init(const int cx, const int cy);
+};
+
+#endif //#ifndef __PASSWINDOW_H__
diff --git a/fltk/pinwindow.cxx b/fltk/pinwindow.cxx
new file mode 100644
index 0000000..ad11e91
--- /dev/null
+++ b/fltk/pinwindow.cxx
@@ -0,0 +1,250 @@
+/*
+    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- at 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.
+*/
+
+#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;
+}
diff --git a/fltk/pinwindow.h b/fltk/pinwindow.h
new file mode 100644
index 0000000..e1d009e
--- /dev/null
+++ b/fltk/pinwindow.h
@@ -0,0 +1,108 @@
+/*
+    pinwindow.h - 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- at 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.
+*/
+
+#ifndef __PINWINDOW_H__
+#define __PINWINDOW_H__
+
+#include "config.h"
+
+class Fl_Window;
+class Fl_Box;
+class Fl_Input;
+class Fl_Button;
+class Fl_Widget;
+
+#include <assert.h>
+#include <string>
+
+class PinWindow
+{
+protected:
+	static const char *TITLE;
+	static const char *BUTTON_OK;
+	static const char *BUTTON_CANCEL;
+	static const char *PROMPT;
+
+protected:
+	PinWindow(const PinWindow&);
+	PinWindow& operator=(const PinWindow&);
+
+	Fl_Window	*window_;
+	Fl_Box		*icon_;
+
+	Fl_Box		*message_;
+	Fl_Input	*input_;
+
+	Fl_Button	*ok_, *cancel_;
+
+	std::string cancel_name_;
+	char *passwd_;			// SECURE_MEMORY
+	unsigned int timeout_; 	// click cancel if timeout
+
+public:
+	virtual ~PinWindow();
+
+	static PinWindow* create();
+
+	inline const char*   passwd() const { return passwd_; }
+
+	virtual void timeout(unsigned int time);						// 0 - infinity, seconds
+	virtual void title(const char *title);
+	virtual void ok(const char* ok);
+	virtual void cancel(const char* cancel);
+	virtual void prompt(const char *message);
+
+	virtual void showModal();
+	virtual void showModal(const int argc, char* argv[]);
+
+protected:
+	PinWindow();
+
+	void wipe();		// clear UI memory
+	void release();		// clear secure memory
+	void update_cancel_label();
+
+	virtual int init(const int cx, const int cy);
+
+	//callbacks
+	static void cancel_cb(Fl_Widget *button, void *val);
+	static void ok_cb(Fl_Widget *button, void *val);
+	static void timeout_cb(void*);
+
+	// ISSUE: Fl_Window component in tinycore works only as Fl_Window::label(...); not Fl_Widget
+	template <class TWidget> void set_label(TWidget* widget, const char *label, const char *def)
+	{
+		assert(NULL != widget); // widget must be created
+
+		if (NULL != widget)
+		{
+			if (NULL != label && 0 != *label)
+				widget->copy_label(label);
+			else
+				widget->label(def);
+		}
+	};
+};
+
+#endif //#ifndef __PINWINDOW_H__
diff --git a/fltk/qualitypasswindow.cxx b/fltk/qualitypasswindow.cxx
new file mode 100644
index 0000000..6d7f7cc
--- /dev/null
+++ b/fltk/qualitypasswindow.cxx
@@ -0,0 +1,92 @@
+/*
+    qualitypasswindow.cxx - QualityPassWindow pin entry
+    with Password QualityBar and etc
+
+    Copyright (C) 2016 Anatoly madRat L. Berenblit
+
+    Written by Anatoly madRat L. Berenblit <madrat- at 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.
+*/
+
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Box.H>
+#include <FL/Fl_Input.H>
+#include <FL/Fl_Progress.H>
+
+#include "qualitypasswindow.h"
+
+const char *QualityPassWindow::QUALITY = "Quality";
+
+QualityPassWindow::QualityPassWindow(QualityPassWindow::GetQualityFn qualify, void* ptr)
+						: get_quality_(qualify)
+						,get_quality_user_(ptr)
+						,quality_(NULL)
+{
+	assert(NULL != qualify);
+}
+
+void QualityPassWindow::input_changed(Fl_Widget *input, void *val)
+{
+    QualityPassWindow  *self = reinterpret_cast<QualityPassWindow*>(val);
+
+    assert(NULL != self->get_quality_);   // function should be assigned in ctor
+    assert(NULL != self->quality_);       // quality progress bar must be created in init
+
+	if (NULL != self->quality_ && NULL != self->get_quality_)
+	{
+		int result = self->get_quality_(self->input_->value(), self->get_quality_user_);
+		bool isErr = (result <= 0);
+		if (isErr)
+			result = -result;
+		self->quality_->selection_color(isErr?FL_RED:FL_GREEN);
+		self->quality_->value(std::min(result, 100));
+	}
+}
+
+QualityPassWindow* QualityPassWindow::create(QualityPassWindow::GetQualityFn qualify, void *user)
+{
+	QualityPassWindow *p = new QualityPassWindow(qualify, user);
+	p->init(460, 215);
+	p->window_->end();
+	p->input_->take_focus();
+	return p;
+}
+
+void QualityPassWindow::quality(const char *name)
+{
+	set_label(quality_, name, QUALITY);
+}
+
+int QualityPassWindow::init(const int cx, const int cy)
+{
+	int y = PassWindow::init(cx, cy);
+	assert(window_ == Fl_Group::current()); // make_window should all add current
+
+	input_->when(FL_WHEN_CHANGED);
+	input_->callback(input_changed, this);
+
+	y = input_->y() + input_->h();
+
+	quality_ = new Fl_Progress(input_->x(), y+5, input_->w(), 25, QUALITY);
+	quality_->align(Fl_Align(FL_ALIGN_LEFT | FL_ALIGN_CLIP | FL_ALIGN_WRAP));
+	quality_->maximum(100.1);
+	quality_->minimum(0.0);
+	y = quality_->y() + quality_->h();
+
+	error_->position(error_->x(), y+5);
+
+	return error_->y() + error_->h();
+}
diff --git a/fltk/qualitypasswindow.h b/fltk/qualitypasswindow.h
new file mode 100644
index 0000000..164c10d
--- /dev/null
+++ b/fltk/qualitypasswindow.h
@@ -0,0 +1,54 @@
+/*
+    qualitypasswindow.h - QualityPassWindow pin entry with Password QualityBar
+    and etc
+
+    Copyright (C) 2016 Anatoly madRat L. Berenblit
+
+    Written by Anatoly madRat L. Berenblit <madrat- at 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.
+*/
+
+#ifndef __QUALITYPASSWINDOW_H__
+#define __QUALITYPASSWINDOW_H__
+
+#include "passwindow.h"
+class Fl_Progress;
+
+class QualityPassWindow : public PassWindow
+{
+protected:
+	static const char *QUALITY;
+
+public:
+	typedef int (*GetQualityFn)(const char *passwd, void *ptr);
+
+	static QualityPassWindow* create(GetQualityFn qualify, void* user);
+
+	void quality(const char *name);
+
+protected:
+	QualityPassWindow(GetQualityFn qualify, void*);
+
+	const GetQualityFn  get_quality_;
+	void* const         get_quality_user_;
+
+	Fl_Progress *quality_;
+	virtual int init(const int cx, const int cy);
+
+	static void input_changed(Fl_Widget *input, void *val);
+};
+
+#endif //#ifndef __QUALITYPASSWINDOW_H__

-----------------------------------------------------------------------


hooks/post-receive
-- 
The standard pinentry collection
http://git.gnupg.org




More information about the Gnupg-commits mailing list