[svn] pinentry - r159 - in trunk: . secmem w32
svn author wk
cvs at cvs.gnupg.org
Wed Jun 20 16:29:53 CEST 2007
Author: wk
Date: 2007-06-20 16:29:22 +0200 (Wed, 20 Jun 2007)
New Revision: 159
Added:
trunk/README.SVN
Removed:
trunk/README.CVS
Modified:
trunk/ChangeLog
trunk/Makefile.am
trunk/NEWS
trunk/autogen.sh
trunk/secmem/secmem.c
trunk/w32/Makefile.am
trunk/w32/main.c
Log:
Made W32 version work. There are still some glitches but it works with
gpg-agent.
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2007-05-10 17:37:07 UTC (rev 158)
+++ trunk/ChangeLog 2007-06-20 14:29:22 UTC (rev 159)
@@ -1,3 +1,25 @@
+2007-06-20 Werner Koch <wk at g10code.com>
+
+ * w32/main.c (wchar_to_utf8): New.
+ (ok_button_clicked): Use it.
+ (utf8_to_wchar): New.
+ (set_dlg_item_text): New.
+ (dlg_proc): Use new function so that we are able to correctly
+ display all prompts.
+ (main): Load LockSetForegroundWindow.
+ (dlg_proc): Call LockSetForegroundWindow via its fnc ptr.
+ (center_window): New. Taken from GPGol.
+ (dlg_proc): Call it.
+ (w32_cmd_handler): Revamped the confirm mode.
+
+2007-06-18 Werner Koch <wk at g10code.com>
+
+ * w32/main.c (dlg_proc): Call LockSetForegroundWindow.
+
+ * Makefile.am (signed-dist, %.sig): Remove.
+
+ * autogen.sh: Modernized.
+
2007-05-10 Marcus Brinkmann <marcus at g10code.de>
* pinentry/pinentry.h (pinentry_color_t): New type.
Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am 2007-05-10 17:37:07 UTC (rev 158)
+++ trunk/Makefile.am 2007-06-20 14:29:22 UTC (rev 159)
@@ -21,7 +21,7 @@
ACLOCAL_AMFLAGS = -I m4
-EXTRA_DIST = autogen.sh README.CVS Manifest
+EXTRA_DIST = autogen.sh README.SVN Manifest
if BUILD_PINENTRY_CURSES
pinentry_curses = curses
@@ -56,11 +56,7 @@
SUBDIRS = assuan secmem pinentry ${pinentry_curses} \
${pinentry_gtk} ${pinentry_gtk_2} ${pinentry_qt} ${pinentry_w32} doc
-signed-dist: $(distdir).tar.gz.sig
-%.sig: %
- gpg -sbav -u 0x57548DCD $@ $<
-
install-exec-local:
@list='$(bin_PROGRAMS)'; for p in $$list; do \
echo " $(SETCAP) cap_ipc_lock+p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
Modified: trunk/NEWS
===================================================================
--- trunk/NEWS 2007-05-10 17:37:07 UTC (rev 158)
+++ trunk/NEWS 2007-06-20 14:29:22 UTC (rev 159)
@@ -10,7 +10,9 @@
* New option --colors=FG,BG,SO to set the colors for the curses
pinentry.
+ * Pinentry-w32 does now work.
+
Noteworthy changes in version 0.7.2 (2005-01-27)
------------------------------------------------
Deleted: trunk/README.CVS
Added: trunk/README.SVN
===================================================================
--- trunk/README.SVN 2007-05-10 17:37:07 UTC (rev 158)
+++ trunk/README.SVN 2007-06-20 14:29:22 UTC (rev 159)
@@ -0,0 +1,51 @@
+If you are building from Subversion, run the script
+
+./autogen.sh
+
+first, to make sure that you have all the necessary maintainer tools
+are installed and to build the actual configuration files. If you
+have just updated from SVN, you should add the option "--force" to
+autogen.sh so that meta data from SVN is noticed. Then run
+
+./configure --enable-maintainer-mode
+
+followed by the usual make.
+
+If autogen.sh complains about insufficient versions of the required
+tools, or the tools are not installed, you may use environment
+variables to override the default tool names:
+
+ AUTOMAKE_SUFFIX is used as a suffix for all tools from the automake
+ package. For example
+ AUTOMAKE_SUFFIX="-1.7" ./autogen.sh
+ uses "automake-1.7" and "aclocal-1.7.
+ AUTOMAKE_PREFIX is used as a prefix for all tools from the automake
+ page and may be combined with AUTOMAKE_SUFFIX. e.g.:
+ AUTOMAKE_PREFIX=/usr/foo/bin ./autogen.sh
+ uses "automake" and "aclocal" in the /usr/foo/bin
+ directory.
+ AUTOCONF_SUFFIX is used as a suffix for all tools from the automake
+ package
+ AUTOCONF_PREFIX is used as a prefix for all tools from the automake
+ package
+ GETTEXT_SUFFIX is used as a suffix for all tools from the gettext
+ package
+ GETTEXT_PREFIX is used as a prefix for all tools from the gettext
+ package
+
+It is also possible to use the variable name AUTOMAKE, AUTOCONF,
+ACLOCAL, AUTOHEADER, GETTEXT and MSGMERGE to directly specify the name
+of the programs to run. It is however better to use the suffix and
+prefix forms as described above because that does not require
+knowledge about the actual tools used by autgen.sh.
+
+
+Please don't use autopoint, libtoolize or autoreconf unless you are
+the current maintainer and want to update the standard configuration
+files. All those files should be in the SVN and only updated manually
+if the maintainer decides that newer versions are required. The
+maintainer should also make sure that the required version of automake
+et al. are properly indicated at the top of configure.ac and take care
+to copy the files and not merely use symlinks.
+
+
Modified: trunk/autogen.sh
===================================================================
--- trunk/autogen.sh 2007-05-10 17:37:07 UTC (rev 158)
+++ trunk/autogen.sh 2007-06-20 14:29:22 UTC (rev 159)
@@ -28,7 +28,24 @@
return 1
}
+# Allow to override the default tool names
+AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
+AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
+AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX}
+ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX}
+
+GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX}
+MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
+
+DIE=no
+FORCE=
+if test x"$1" = x"--force"; then
+ FORCE=" --force"
+ shift
+fi
+
+
# ***** W32 build script *******
# Used to cross-compile for Windows.
if test "$1" = "--build-w32"; then
@@ -44,25 +61,22 @@
[ -z "$w32root" ] && w32root="$HOME/w32root"
echo "Using $w32root as standard install directory" >&2
- # See whether we have the Debian cross compiler package or the
- # old mingw32/cpd system
- if i586-mingw32msvc-gcc --version >/dev/null 2>&1 ; then
- host=i586-mingw32msvc
- crossbindir=/usr/$host/bin
- else
- host=i386--mingw32
- if ! mingw32 --version >/dev/null; then
- echo "We need at least version 0.3 of MingW32/CPD" >&2
- exit 1
- fi
- crossbindir=`mingw32 --install-dir`/bin
- # Old autoconf version required us to setup the environment
- # with the proper tool names.
- CC=`mingw32 --get-path gcc`
- CPP=`mingw32 --get-path cpp`
- AR=`mingw32 --get-path ar`
- RANLIB=`mingw32 --get-path ranlib`
- export CC CPP AR RANLIB
+
+ # Locate the cross compiler
+ crossbindir=
+ for host in i586-mingw32msvc i386-mingw32msvc mingw32; do
+ if ${host}-gcc --version >/dev/null 2>&1 ; then
+ crossbindir=/usr/${host}/bin
+ conf_CC="CC=${host}-gcc"
+ break;
+ fi
+ done
+ if [ -z "$crossbindir" ]; then
+ echo "Cross compiler kit not installed" >&2
+ echo "Under Debian GNU/Linux, you may install it using" >&2
+ echo " apt-get install mingw32 mingw32-runtime mingw32-binutils" >&2
+ echo "Stop." >&2
+ exit 1
fi
if [ -f "$tsdir/config.log" ]; then
@@ -73,16 +87,12 @@
fi
./configure --enable-maintainer-mode --prefix=${w32root} \
- --host=i586-mingw32msvc --build=${build} \
+ --host=${host} --build=${build} \
--disable-pinentry-gtk \
--disable-pinentry-gtk2 \
--disable-pinentry-qt
rc=$?
- # Ugly hack to overcome a gettext problem. Someone should look into
- # gettext to figure out why the po directory is not ignored as it used
- # to be.
- [ $rc = 0 ] && touch $tsdir/po/all
exit $rc
fi
# ***** end W32 build script *******
@@ -116,19 +126,6 @@
exit 1
fi
-# Allow to override the default tool names
-AUTOCONF=${AUTOCONF_PREFIX}${AUTOCONF:-autoconf}${AUTOCONF_SUFFIX}
-AUTOHEADER=${AUTOCONF_PREFIX}${AUTOHEADER:-autoheader}${AUTOCONF_SUFFIX}
-
-AUTOMAKE=${AUTOMAKE_PREFIX}${AUTOMAKE:-automake}${AUTOMAKE_SUFFIX}
-ACLOCAL=${AUTOMAKE_PREFIX}${ACLOCAL:-aclocal}${AUTOMAKE_SUFFIX}
-
-#GETTEXT=${GETTEXT_PREFIX}${GETTEXT:-gettext}${GETTEXT_SUFFIX}
-#MSGMERGE=${GETTEXT_PREFIX}${MSGMERGE:-msgmerge}${GETTEXT_SUFFIX}
-
-DIE=no
-
-
if check_version $AUTOCONF $autoconf_vers_num $autoconf_vers ; then
check_version $AUTOHEADER $autoconf_vers_num $autoconf_vers autoconf
fi
@@ -143,7 +140,7 @@
cat <<EOF
Note that you may use alternative versions of the tools by setting
-the corresponding environment variables; see README.CVS for details.
+the corresponding environment variables; see README.SVN for details.
EOF
exit 1
@@ -154,8 +151,8 @@
echo "Running autoheader..."
$AUTOHEADER
echo "Running automake --gnu ..."
-$AUTOMAKE --gnu;
-echo "Running autoconf..."
-$AUTOCONF
+$AUTOMAKE --gnu
+echo "Running autoconf${FORCE}..."
+$AUTOCONF${FORCE}
echo "You may now run \"./configure --enable-maintainer-mode && make\"."
Modified: trunk/secmem/secmem.c
===================================================================
--- trunk/secmem/secmem.c 2007-05-10 17:37:07 UTC (rev 158)
+++ trunk/secmem/secmem.c 2007-06-20 14:29:22 UTC (rev 159)
@@ -281,11 +281,11 @@
secmem_init( size_t n )
{
if( !n ) {
- #ifdef USE_CAPABILITIES
+#ifdef USE_CAPABILITIES
/* drop all capabilities */
cap_set_proc( cap_from_text("all-eip") );
- #elif !defined(HAVE_DOSISH_SYSTEM)
+#elif !defined(HAVE_DOSISH_SYSTEM)
uid_t uid;
disable_secmem=1;
@@ -294,7 +294,7 @@
if( setuid( uid ) || getuid() != geteuid() )
log_fatal("failed to drop setuid\n" );
}
- #endif
+#endif
}
else {
if( n < DEFAULT_POOLSIZE )
Modified: trunk/w32/Makefile.am
===================================================================
--- trunk/w32/Makefile.am 2007-05-10 17:37:07 UTC (rev 158)
+++ trunk/w32/Makefile.am 2007-06-20 14:29:22 UTC (rev 159)
@@ -27,10 +27,11 @@
-I$(top_srcdir)/pinentry
-
pinentry_w32_SOURCES = main.c pinentry-w32.rc resource.h
-pinentry_w32_LDFLAGS = -mwindows -mconsole
+# If you want to test pinnetry on the console, you should add
+# -mconsole to the ldflags.
+pinentry_w32_LDFLAGS = -mwindows
pinentry_w32_LDADD = pinentry-w32.o \
../pinentry/libpinentry.a ../assuan/libassuan.a ../secmem/libsecmem.a
Modified: trunk/w32/main.c
===================================================================
--- trunk/w32/main.c 2007-05-10 17:37:07 UTC (rev 158)
+++ trunk/w32/main.c 2007-06-20 14:29:22 UTC (rev 159)
@@ -29,22 +29,157 @@
#define PGMNAME "pinentry-w32"
+#ifndef LSFW_LOCK
+# define LSFW_LOCK 1
+# define LSFW_UNLOCK 2
+#endif
+
+/* This function pointer gets initialized in main. */
+static WINUSERAPI BOOL WINAPI (*lock_set_foreground_window)(UINT);
+
+
static int w32_cmd_handler (pinentry_t pe);
static void ok_button_clicked (HWND dlg, pinentry_t pe);
-/* We use gloabl variables for the state, becuase there should never
+/* We use gloabl variables for the state, because there should never
ever be a second instance. */
static HWND dialog_handle;
-static int passphrase_ok = 0;
+static int confirm_mode;
+static int passphrase_ok;
+static int confirm_yes;
-
/* Connect this module to the pinnetry framework. */
pinentry_cmd_handler_t pinentry_cmd_handler = w32_cmd_handler;
+
+
+/* Convert a wchar to UTF8. Caller needs to release the string.
+ Returns NULL on error. */
+static char *
+wchar_to_utf8 (const wchar_t *string, size_t len, int secure)
+{
+ int n;
+ char *result;
+
+ /* Note, that CP_UTF8 is not defined in Windows versions earlier
+ than NT. */
+ n = WideCharToMultiByte (CP_UTF8, 0, string, len, NULL, 0, NULL, NULL);
+ if (n < 0)
+ return NULL;
+
+ result = secure? secmem_malloc (n+1) : malloc (n+1);
+ if (!result)
+ return NULL;
+ n = WideCharToMultiByte (CP_UTF8, 0, string, len, result, n, NULL, NULL);
+ if (n < 0)
+ {
+ if (secure)
+ secmem_free (result);
+ else
+ free (result);
+ return NULL;
+ }
+ return result;
+}
+
+
+/* Convert a UTF8 string to wchar. Returns NULL on error. Caller
+ needs to free the returned value. */
+wchar_t *
+utf8_to_wchar (const char *string)
+{
+ int n;
+ wchar_t *result;
+ size_t len = strlen (string);
+
+ n = MultiByteToWideChar (CP_UTF8, 0, string, len, NULL, 0);
+ if (n < 0)
+ return NULL;
+
+ result = calloc ((n+1), sizeof *result);
+ if (!result)
+ return NULL;
+ n = MultiByteToWideChar (CP_UTF8, 0, string, len, result, n);
+ if (n < 0)
+ {
+ free (result);
+ return NULL;
+ }
+ result[n] = 0;
+ return result;
+}
+
+
+/* Center the window CHILDWND with the desktop as its parent
+ window. STYLE is passed as second arg to SetWindowPos.*/
+void
+center_window (HWND childwnd, HWND style)
+{
+ HWND parwnd;
+ RECT rchild, rparent;
+ HDC hdc;
+ int wchild, hchild, wparent, hparent;
+ int wscreen, hscreen, xnew, ynew;
+ int flags = SWP_NOSIZE | SWP_NOZORDER;
+
+ parwnd = GetDesktopWindow ();
+ GetWindowRect (childwnd, &rchild);
+ wchild = rchild.right - rchild.left;
+ hchild = rchild.bottom - rchild.top;
+
+ GetWindowRect (parwnd, &rparent);
+ wparent = rparent.right - rparent.left;
+ hparent = rparent.bottom - rparent.top;
+
+ hdc = GetDC (childwnd);
+ wscreen = GetDeviceCaps (hdc, HORZRES);
+ hscreen = GetDeviceCaps (hdc, VERTRES);
+ ReleaseDC (childwnd, hdc);
+ xnew = rparent.left + ((wparent - wchild) / 2);
+ if (xnew < 0)
+ xnew = 0;
+ else if ((xnew+wchild) > wscreen)
+ xnew = wscreen - wchild;
+ ynew = rparent.top + ((hparent - hchild) / 2);
+ if (ynew < 0)
+ ynew = 0;
+ else if ((ynew+hchild) > hscreen)
+ ynew = hscreen - hchild;
+ if (style == HWND_TOPMOST || style == HWND_NOTOPMOST)
+ flags = SWP_NOMOVE | SWP_NOSIZE;
+ SetWindowPos (childwnd, style? style : NULL, xnew, ynew, 0, 0, flags);
+}
+
+
+
+
+
+/* Call SetDlgItemTextW with an UTF8 string. */
+static void
+set_dlg_item_text (HWND dlg, int item, const char *string)
+{
+ if (!string || !*string)
+ SetDlgItemText (dlg, item, "");
+ else
+ {
+ wchar_t *wbuf;
+
+ wbuf = utf8_to_wchar (string);
+ if (!wbuf)
+ SetDlgItemText (dlg, item, "[out of core]");
+ else
+ {
+ SetDlgItemTextW (dlg, item, wbuf);
+ free (wbuf);
+ }
+ }
+}
+
+
/* Dialog processing loop. */
static BOOL CALLBACK
dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
@@ -57,24 +192,40 @@
pe = (pinentry_t)lparam;
if (!pe)
abort ();
- SetDlgItemText (dlg, IDC_PINENT_PROMPT, pe->prompt);
- SetDlgItemText (dlg, IDC_PINENT_DESC, pe->description);
- SetDlgItemText (dlg, IDC_PINENT_TEXT, "");
+ set_dlg_item_text (dlg, IDC_PINENT_PROMPT, pe->prompt);
+ set_dlg_item_text (dlg, IDC_PINENT_DESC, pe->description);
+ set_dlg_item_text (dlg, IDC_PINENT_TEXT, "");
if (pe->ok)
- SetDlgItemText (dlg, IDOK, pe->ok);
+ set_dlg_item_text (dlg, IDOK, pe->ok);
if (pe->cancel)
- SetDlgItemText (dlg, IDCANCEL, pe->cancel);
+ set_dlg_item_text (dlg, IDCANCEL, pe->cancel);
if (pe->error)
- SetDlgItemText (dlg, IDC_PINENT_ERR, pe->error);
+ set_dlg_item_text (dlg, IDC_PINENT_ERR, pe->error);
+
+ if (confirm_mode)
+ {
+ EnableWindow (GetDlgItem (dlg, IDC_PINENT_TEXT), FALSE);
+ SetWindowPos (GetDlgItem (dlg, IDC_PINENT_TEXT), NULL, 0, 0, 0, 0,
+ (SWP_NOMOVE|SWP_NOSIZE|SWP_NOZORDER|SWP_HIDEWINDOW));
+ }
+
dialog_handle = dlg;
- SetForegroundWindow (dlg);
+ center_window (dlg, HWND_TOP);
+ /* Fixme: There are two problems: A race condition between the
+ two calls and more important that SetForegroundWindow will
+ fail if a Menu is somewhere open. */
+ if (SetForegroundWindow (dlg) && lock_set_foreground_window)
+ lock_set_foreground_window (LSFW_LOCK);
break;
case WM_COMMAND:
switch (LOWORD (wparam))
{
case IDOK:
- ok_button_clicked (dlg, pe);
+ if (confirm_mode)
+ confirm_yes = 1;
+ else
+ ok_button_clicked (dlg, pe);
EndDialog (dlg, TRUE);
break;
@@ -95,27 +246,27 @@
ok_button_clicked (HWND dlg, pinentry_t pe)
{
char *s_utf8;
- char *s_buffer;
- size_t s_buffer_size = 256;
+ wchar_t *w_buffer;
+ size_t w_buffer_size = 255;
+ unsigned int nchar;
pe->locale_err = 1;
- s_buffer = secmem_malloc (s_buffer_size + 1);
- if (!s_buffer)
+ w_buffer = secmem_malloc ((w_buffer_size + 1) * sizeof *w_buffer);
+ if (!w_buffer)
return;
- pe->result = GetDlgItemText (dlg, IDC_PINENT_TEXT, s_buffer, s_buffer_size);
-/* s_utf8 = pinentry_local_to_utf8 (pe->lc_ctype, s_buffer, 1); */
-/* secmem_free (s_buffer); */
- s_utf8 = s_buffer; /* FIXME */
+ nchar = GetDlgItemTextW (dlg, IDC_PINENT_TEXT, w_buffer, w_buffer_size);
+ s_utf8 = wchar_to_utf8 (w_buffer, nchar, 1);
+ secmem_free (w_buffer);
if (s_utf8)
{
passphrase_ok = 1;
pinentry_setbufferlen (pe, strlen (s_utf8) + 1);
if (pe->pin)
strcpy (pe->pin, s_utf8);
-/* secmem_free (s_utf8); */
+ secmem_free (s_utf8);
pe->locale_err = 0;
- pe->result = strlen (pe->pin);
+ pe->result = pe->pin? strlen (pe->pin) : 0;
}
}
@@ -123,37 +274,31 @@
static int
w32_cmd_handler (pinentry_t pe)
{
- int want_pass = !!pe->pin;
+ confirm_mode = !pe->pin;
- passphrase_ok = 0;
+ passphrase_ok = confirm_yes = 0;
- if (want_pass)
- {
- DialogBoxParam (NULL, (LPCTSTR) IDD_PINENT,
- GetDesktopWindow (), dlg_proc, (LPARAM)pe);
- ShowWindow (dialog_handle, SW_SHOWNORMAL);
- return pe->result;
- }
- else /* Confirmation mode. */
- {
- int ret;
-
- if (pe->error)
- ret = MessageBox (NULL, pe->error, "Error", MB_YESNO | MB_ICONERROR);
- else
- ret = MessageBox (NULL, pe->description?pe->description:"",
- "Information", MB_YESNO | MB_ICONINFORMATION);
- if (ret == IDYES)
- return 1;
- else
- return 0;
- }
+ DialogBoxParam (NULL, (LPCTSTR) IDD_PINENT,
+ GetDesktopWindow (), dlg_proc, (LPARAM)pe);
+ ShowWindow (dialog_handle, SW_SHOWNORMAL);
+ if (lock_set_foreground_window)
+ lock_set_foreground_window (LSFW_UNLOCK);
+ DestroyWindow (dialog_handle);
+ dialog_handle = NULL;
+ if (confirm_mode)
+ return confirm_yes;
+ else if (passphrase_ok && pe->pin)
+ return strlen (pe->pin);
+ else
+ return -1;
}
int
main (int argc, char **argv)
{
+ void *handle;
+
pinentry_init (PGMNAME);
/* Consumes all arguments. */
@@ -163,6 +308,19 @@
exit (EXIT_SUCCESS);
}
+ /* We need to load a functuion because that one is only available
+ since W2000 but not in older NTs. */
+ handle = LoadLibrary ("user32.dll");
+ if (handle)
+ {
+ void *foo;
+ foo = GetProcAddress (handle, "LockSetForegroundWindow");
+ if (foo)
+ lock_set_foreground_window = foo;
+ else
+ CloseHandle (handle);
+ }
+
if (pinentry_loop ())
return 1;
More information about the Gnupg-commits
mailing list