Page MenuHome GnuPG

No OneTemporary

diff --git a/tty/pinentry-tty.c b/tty/pinentry-tty.c
index 3951bc8..a66241b 100644
--- a/tty/pinentry-tty.c
+++ b/tty/pinentry-tty.c
@@ -1,611 +1,611 @@
/* pinentry-tty.c - A minimalist dumb terminal mechanism for PIN entry
* Copyright (C) 2014 Serge Voilokov
* Copyright (C) 2015 Daniel Kahn Gillmor <dkg@fifthhorseman.net>
* Copyright (C) 2015 g10 Code GmbH
*
* This file is part of PINENTRY.
*
* PINENTRY 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.
*
* PINENTRY 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, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-2.0+
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <signal.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <termios.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif /*HAVE_UTIME_H*/
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include <gpg-error.h>
#include "pinentry.h"
#ifndef HAVE_DOSISH_SYSTEM
static int timed_out;
#endif
static struct termios n_term;
static struct termios o_term;
static int
terminal_save (int fd)
{
if ((tcgetattr (fd, &o_term)) == -1)
return -1;
return 0;
}
static void
terminal_restore (int fd)
{
tcsetattr (fd, TCSANOW, &o_term);
}
static int
terminal_setup (int fd, int line_edit)
{
n_term = o_term;
if (line_edit)
n_term.c_lflag &= ~(ECHO | ECHOE | ECHOK | ECHONL);
else
{
n_term.c_lflag &= ~(ECHO|ICANON);
n_term.c_lflag |= ISIG;
n_term.c_cc[VMIN] = 1;
n_term.c_cc[VTIME]= 0;
}
if ((tcsetattr(fd, TCSAFLUSH, &n_term)) == -1)
return -1;
return 1;
}
#define UNDERLINE_START "\033[4m"
/* Bold, red. */
#define ALERT_START "\033[1;31m"
#define NORMAL_RESTORE "\033[0m"
static void
fputs_highlighted (char *text, char *highlight, FILE *ttyfo)
{
for (; *text; text ++)
{
/* Skip accelerator prefix. */
if (*text == '_')
{
text ++;
if (! *text)
break;
}
if (text == highlight)
fputs (UNDERLINE_START, ttyfo);
fputc (*text, ttyfo);
if (text == highlight)
fputs (NORMAL_RESTORE, ttyfo);
}
}
static char
button (char *text, char *default_text, FILE *ttyfo)
{
char *highlight;
int use_default = 0;
if (! text)
return 0;
/* Skip any leading white space. */
while (*text == ' ')
text ++;
highlight = text;
while ((highlight = strchr (highlight, '_')))
{
highlight = highlight + 1;
if (*highlight == '_')
{
/* Escaped underscore. Skip both characters. */
highlight++;
continue;
}
- if (!isalnum (*highlight))
+ if (!isalnum (*(unsigned char*)highlight))
/* Unusable accelerator. */
continue;
break;
}
if (! highlight)
/* Not accelerator. Take the first alpha-numeric character. */
{
highlight = text;
- while (*highlight && !isalnum (*highlight))
+ while (*highlight && !isalnum (*(unsigned char*)highlight))
highlight ++;
}
if (! *highlight)
/* Hmm, no alpha-numeric characters. */
{
if (! default_text)
return 0;
highlight = default_text;
use_default = 1;
}
fputs (" ", ttyfo);
fputs_highlighted (text, highlight, ttyfo);
if (use_default)
{
fputs (" (", ttyfo);
fputs_highlighted (default_text, highlight, ttyfo);
fputc (')', ttyfo);
}
fputc ('\n', ttyfo);
return tolower (*highlight);
}
static void
dump_error_text (FILE *ttyfo, const char *text)
{
int lines = 0;
if (! text || ! *text)
return;
for (;;)
{
const char *eol = strchr (text, '\n');
if (! eol)
eol = text + strlen (text);
lines ++;
fwrite ("\n *** ", 6, 1, ttyfo);
fputs (ALERT_START, ttyfo);
fwrite (text, (size_t) (eol - text), 1, ttyfo);
fputs (NORMAL_RESTORE, ttyfo);
if (! *eol)
break;
text = eol + 1;
}
if (lines > 1)
fputc ('\n', ttyfo);
else
fwrite (" ***\n", 5, 1, ttyfo);
fputc ('\n', ttyfo);
}
static int
confirm (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo)
{
char *msg;
char *msgbuffer = NULL;
char ok = 0;
char notok = 0;
char cancel = 0;
int ret;
dump_error_text (ttyfo, pinentry->error);
msg = pinentry->description;
if (! msg)
{
/* If there is no description, fallback to the title. */
msg = msgbuffer = pinentry_get_title (pinentry);
}
if (! msg)
msg = "Confirm:";
if (msg)
{
fputs (msg, ttyfo);
fputc ('\n', ttyfo);
}
free (msgbuffer);
fflush (ttyfo);
if (pinentry->ok)
ok = button (pinentry->ok, "OK", ttyfo);
else if (pinentry->default_ok)
ok = button (pinentry->default_ok, "OK", ttyfo);
else
ok = button ("OK", NULL, ttyfo);
if (! pinentry->one_button)
{
if (pinentry->cancel)
cancel = button (pinentry->cancel, "Cancel", ttyfo);
else if (pinentry->default_cancel)
cancel = button (pinentry->default_cancel, "Cancel", ttyfo);
if (pinentry->notok)
notok = button (pinentry->notok, "No", ttyfo);
}
while (1)
{
int input;
if (pinentry->one_button)
fprintf (ttyfo, "Press any key to continue.");
else
{
fputc ('[', ttyfo);
if (ok)
fputc (ok, ttyfo);
if (cancel)
fputc (cancel, ttyfo);
if (notok)
fputc (notok, ttyfo);
fputs("]? ", ttyfo);
}
fflush (ttyfo);
input = fgetc (ttyfi);
if (input == EOF)
{
pinentry->close_button = 1;
pinentry->canceled = 1;
#ifndef HAVE_DOSISH_SYSTEM
if (!timed_out && errno == EINTR)
pinentry->specific_err = gpg_error (GPG_ERR_FULLY_CANCELED);
#endif
ret = 0;
break;
}
else
{
fprintf (ttyfo, "%c\n", input);
input = tolower (input);
}
if (pinentry->one_button)
{
ret = 1;
break;
}
if (cancel && input == cancel)
{
pinentry->canceled = 1;
ret = 0;
break;
}
else if (notok && input == notok)
{
ret = 0;
break;
}
else if (ok && input == ok)
{
ret = 1;
break;
}
else
{
fprintf (ttyfo, "Invalid selection.\n");
}
}
#ifndef HAVE_DOSISH_SYSTEM
if (timed_out)
pinentry->specific_err = gpg_error (GPG_ERR_TIMEOUT);
#endif
return ret;
}
static char *
read_password (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo)
{
int done = 0;
int len = 128;
int count = 0;
char *buffer;
(void) ttyfo;
buffer = secmem_malloc (len);
if (! buffer)
return NULL;
while (!done)
{
int c;
if (count == len - 1)
/* Double the buffer's size. Note: we check if count is len -
1 and not len so that we always have space for the NUL
character. */
{
int new_len = 2 * len;
char *tmp = secmem_realloc (buffer, new_len);
if (! tmp)
{
secmem_free (tmp);
return NULL;
}
buffer = tmp;
len = new_len;
}
c = fgetc (ttyfi);
switch (c)
{
case EOF:
done = -1;
#ifndef HAVE_DOSISH_SYSTEM
if (!timed_out && errno == EINTR)
pinentry->specific_err = gpg_error (GPG_ERR_FULLY_CANCELED);
#endif
break;
case '\n':
done = 1;
break;
default:
buffer[count ++] = c;
break;
}
}
buffer[count] = '\0';
if (done == -1)
{
secmem_free (buffer);
return NULL;
}
return buffer;
}
static int
password (pinentry_t pinentry, FILE *ttyfi, FILE *ttyfo)
{
char *msg;
char *msgbuffer = NULL;
int done = 0;
msg = pinentry->description;
if (! msg)
msg = msgbuffer = pinentry_get_title (pinentry);
if (! msg)
msg = "Enter your passphrase.";
dump_error_text (ttyfo, pinentry->error);
fprintf (ttyfo, "%s\n", msg);
free (msgbuffer);
while (! done)
{
char *passphrase;
char *prompt = pinentry->prompt;
if (! prompt || !*prompt)
prompt = "PIN";
fprintf (ttyfo, "%s%s ",
prompt,
/* Make sure the prompt ends in a : or a question mark. */
(prompt[strlen(prompt) - 1] == ':'
|| prompt[strlen(prompt) - 1] == '?') ? "" : ":");
fflush (ttyfo);
passphrase = read_password (pinentry, ttyfi, ttyfo);
fputc ('\n', ttyfo);
if (! passphrase)
{
done = -1;
break;
}
if (! pinentry->repeat_passphrase)
done = 1;
else
{
char *passphrase2;
prompt = pinentry->repeat_passphrase;
fprintf (ttyfo, "%s%s ",
prompt,
/* Make sure the prompt ends in a : or a question mark. */
(prompt[strlen(prompt) - 1] == ':'
|| prompt[strlen(prompt) - 1] == '?') ? "" : ":");
fflush (ttyfo);
passphrase2 = read_password (pinentry, ttyfi, ttyfo);
fputc ('\n', ttyfo);
if (! passphrase2)
{
done = -1;
break;
}
if (strcmp (passphrase, passphrase2) == 0)
{
pinentry->repeat_okay = 1;
done = 1;
}
else
dump_error_text (ttyfo,
pinentry->repeat_error_string
?: "Passphrases don't match.");
secmem_free (passphrase2);
}
if (done == 1)
pinentry_setbuffer_use (pinentry, passphrase, 0);
else
secmem_free (passphrase);
}
#ifndef HAVE_DOSISH_SYSTEM
if (timed_out)
pinentry->specific_err = gpg_error (GPG_ERR_TIMEOUT);
#endif
return done;
}
/* If a touch has been registered, touch that file. */
static void
do_touch_file(pinentry_t pinentry)
{
#ifdef HAVE_UTIME_H
struct stat st;
time_t tim;
if (!pinentry->touch_file || !*pinentry->touch_file)
return;
if (stat(pinentry->touch_file, &st))
return; /* Oops. */
/* Make sure that we actually update the mtime. */
while ((tim = time(NULL)) == st.st_mtime)
sleep(1);
/* Update but ignore errors as we can't do anything in that case.
Printing error messages may even clubber the display further. */
utime (pinentry->touch_file, NULL);
#endif /*HAVE_UTIME_H*/
}
#ifndef HAVE_DOSISH_SYSTEM
static void
catchsig (int sig)
{
if (sig == SIGALRM)
timed_out = 1;
}
#endif
int
tty_cmd_handler (pinentry_t pinentry)
{
int rc = 0;
FILE *ttyfi = stdin;
FILE *ttyfo = stdout;
int saved_errno = 0;
#ifndef HAVE_DOSISH_SYSTEM
timed_out = 0;
if (pinentry->timeout)
{
struct sigaction sa;
memset (&sa, 0, sizeof(sa));
sa.sa_handler = catchsig;
sigaction (SIGALRM, &sa, NULL);
sigaction (SIGINT, &sa, NULL);
alarm (pinentry->timeout);
}
#endif
if (pinentry->ttyname)
{
ttyfi = fopen (pinentry->ttyname, "r");
if (!ttyfi)
return -1;
ttyfo = fopen (pinentry->ttyname, "w");
if (!ttyfo)
{
saved_errno = errno;
fclose (ttyfi);
errno = saved_errno;
return -1;
}
}
if (terminal_save (fileno (ttyfi)) < 0)
rc = -1;
else
{
if (terminal_setup (fileno (ttyfi), !!pinentry->pin) == -1)
{
saved_errno = errno;
fprintf (stderr, "terminal_setup failure, exiting\n");
rc = -1;
}
else
{
if (pinentry->pin)
rc = password (pinentry, ttyfi, ttyfo);
else
rc = confirm (pinentry, ttyfi, ttyfo);
terminal_restore (fileno (ttyfi));
do_touch_file (pinentry);
}
}
if (pinentry->ttyname)
{
fclose (ttyfi);
fclose (ttyfo);
}
if (saved_errno)
errno = saved_errno;
return rc;
}
pinentry_cmd_handler_t pinentry_cmd_handler = tty_cmd_handler;
int
main (int argc, char *argv[])
{
pinentry_init ("pinentry-tty");
/* Consumes all arguments. */
pinentry_parse_opts(argc, argv);
if (pinentry_loop ())
return 1;
return 0;
}
diff --git a/w32/main.c b/w32/main.c
index bb41363..922e9c4 100644
--- a/w32/main.c
+++ b/w32/main.c
@@ -1,718 +1,480 @@
/* main.c - Secure W32 dialog for PIN entry.
* Copyright (C) 2004, 2007 g10 Code GmbH
*
* 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, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <stdio.h>
#include <stdlib.h>
+#include <unistd.h>
#if WINVER < 0x0403
# define WINVER 0x0403 /* Required for SendInput. */
#endif
#include <windows.h>
-#ifdef HAVE_W32CE_SYSTEM
-# include <winioctl.h>
-# include <sipapi.h>
-#endif
#include "pinentry.h"
#include "resource.h"
/* #include "msgcodes.h" */
#define PGMNAME "pinentry-w32"
-#ifndef LSFW_LOCK
-# define LSFW_LOCK 1
-# define LSFW_UNLOCK 2
-#endif
-
#ifndef debugfp
#define debugfp stderr
#endif
-/* This function pointer gets initialized in main. */
-#ifndef HAVE_W32CE_SYSTEM
-static BOOL WINAPI (*lock_set_foreground_window)(UINT);
-#endif
-
static int w32_cmd_handler (pinentry_t pe);
static void ok_button_clicked (HWND dlg, pinentry_t pe);
/* We use global variables for the state, because there should never
ever be a second instance. */
static HWND dialog_handle;
static int confirm_mode;
static int passphrase_ok;
static int confirm_yes;
/* The file descriptors for the loop. */
static int w32_infd;
static int w32_outfd;
/* Connect this module to the pinentry framework. */
pinentry_cmd_handler_t pinentry_cmd_handler = w32_cmd_handler;
const char *
w32_strerror (int ec)
{
static char strerr[256];
if (ec == -1)
ec = (int)GetLastError ();
#ifdef HAVE_W32CE_SYSTEM
/* There is only a wchar_t FormatMessage. It does not make much
sense to play the conversion game; we print only the code. */
snprintf (strerr, sizeof strerr, "ec=%d", ec);
#else
FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM, NULL, ec,
MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
strerr, sizeof strerr - 1, NULL);
#endif
return strerr;
}
-#ifdef HAVE_W32CE_SYSTEM
-/* Create a pipe. WRITE_END shall have the opposite value of the one
- pssed to _assuan_w32ce_prepare_pipe; see there for more
- details. */
-#define GPGCEDEV_IOCTL_MAKE_PIPE \
- CTL_CODE (FILE_DEVICE_STREAMS, 2049, METHOD_BUFFERED, FILE_ANY_ACCESS)
-static HANDLE
-w32ce_finish_pipe (int rvid, int write_end)
-{
- HANDLE hd;
-
- hd = CreateFile (L"GPG1:", write_end? GENERIC_WRITE : GENERIC_READ,
- FILE_SHARE_READ | FILE_SHARE_WRITE,
- NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL);
- if (hd != INVALID_HANDLE_VALUE)
- {
- if (!DeviceIoControl (hd, GPGCEDEV_IOCTL_MAKE_PIPE,
- &rvid, sizeof rvid, NULL, 0, NULL, NULL))
- {
- DWORD lastrc = GetLastError ();
- CloseHandle (hd);
- hd = INVALID_HANDLE_VALUE;
- SetLastError (lastrc);
- }
- }
-
- return hd;
-}
-#endif /*HAVE_W32CE_SYSTEM*/
-
-
/* static HWND */
/* show_window_hierarchy (HWND parent, int level) */
/* { */
/* HWND child; */
/* child = GetWindow (parent, GW_CHILD); */
/* while (child) */
/* { */
/* char buf[1024+1]; */
/* char name[200]; */
/* int nname; */
/* char *pname; */
/* memset (buf, 0, sizeof (buf)); */
/* GetWindowText (child, buf, sizeof (buf)-1); */
/* nname = GetClassName (child, name, sizeof (name)-1); */
/* if (nname) */
/* pname = name; */
/* else */
/* pname = NULL; */
/* fprintf (debugfp, "### %*shwnd=%p (%s) `%s'\n", level*2, "", child, */
/* pname? pname:"", buf); */
/* show_window_hierarchy (child, level+1); */
/* child = GetNextWindow (child, GW_HWNDNEXT); */
/* } */
/* return NULL; */
/* } */
/* 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;
}
-/* Raise the software input panel. */
-static void
-raise_sip (HWND dlg)
-{
-#ifdef HAVE_W32CE_SYSTEM
- SIPINFO si;
-
- SetForegroundWindow (dlg);
-
- memset (&si, 0, sizeof si);
- si.cbSize = sizeof si;
-
- if (SipGetInfo (&si))
- {
- si.fdwFlags |= SIPF_ON;
- SipSetInfo (&si);
- }
-#else
- (void)dlg;
-#endif
-}
-
/* Center the window CHILDWND with the desktop as its parent
window. STYLE is passed as second arg to SetWindowPos.*/
static void
center_window (HWND childwnd, HWND style)
{
-#ifndef HAVE_W32CE_SYSTEM
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);
-#endif
-}
-
-
-
-static void
-move_mouse_and_click (HWND hwnd)
-{
-#ifndef HAVE_W32CE_SYSTEM
- RECT rect;
- HDC hdc;
- int wscreen, hscreen, x, y, normx, normy;
- INPUT inp[3];
- int idx;
-
- hdc = GetDC (hwnd);
- wscreen = GetDeviceCaps (hdc, HORZRES);
- hscreen = GetDeviceCaps (hdc, VERTRES);
- ReleaseDC (hwnd, hdc);
- if (wscreen < 10 || hscreen < 10)
- return;
-
- GetWindowRect (hwnd, &rect);
- x = rect.left;
- y = rect.bottom;
-
- normx = x * (65535 / wscreen);
- if (normx < 0 || normx > 65535)
- return;
- normy = y * (65535 / hscreen);
- if (normy < 0 || normy > 65535)
- return;
-
- for (idx=0; idx < 3; idx++)
- memset (&inp[idx], 0, sizeof inp[idx]);
-
- idx=0;
- inp[idx].type = INPUT_MOUSE;
- inp[idx].mi.dx = normx;
- inp[idx].mi.dy = normy;
- inp[idx].mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_ABSOLUTE;
- idx++;
-
- inp[idx].type = INPUT_MOUSE;
- inp[idx].mi.dwFlags = MOUSEEVENTF_LEFTDOWN;
- idx++;
-
- inp[idx].type = INPUT_MOUSE;
- inp[idx].mi.dwFlags = MOUSEEVENTF_LEFTUP;
- idx++;
-
- if ( (SendInput (idx, inp, sizeof (INPUT)) != idx) && debugfp)
- fprintf (debugfp, "SendInput failed: %s\n", w32_strerror (-1));
-#endif
}
/* Resize the button so that STRING fits into it. */
static void
resize_button (HWND hwnd, const char *string)
{
if (!hwnd)
return;
- /* FIXME: Need to figure out how to convert dialog coorddnates to
+ (void)string;
+
+ /* FIXME: Need to figure out how to convert dialog coordinates to
screen coordinates and how buttons should be placed. */
/* SetWindowPos (hbutton, NULL, */
/* 10, 180, */
/* strlen (string+2), 14, */
/* (SWP_NOZORDER)); */
}
/* Call SetDlgItemTextW with an UTF8 string. */
static void
set_dlg_item_text (HWND dlg, int item, const char *string)
{
if (!string || !*string)
SetDlgItemTextW (dlg, item, L"");
else
{
wchar_t *wbuf;
wbuf = utf8_to_wchar (string);
if (!wbuf)
SetDlgItemTextW (dlg, item, L"[out of core]");
else
{
SetDlgItemTextW (dlg, item, wbuf);
free (wbuf);
}
}
}
/* Load our butmapped icon from the resource and display it. */
static void
set_bitmap (HWND dlg, int item)
{
HWND hwnd;
HBITMAP bitmap;
RECT rect;
int resid;
hwnd = GetDlgItem (dlg, item);
if (!hwnd)
return;
rect.left = 0;
rect.top = 0;
rect.right = 32;
rect.bottom = 32;
if (!MapDialogRect (dlg, &rect))
{
fprintf (stderr, "MapDialogRect failed: %s\n", w32_strerror (-1));
return;
}
/* fprintf (stderr, "MapDialogRect: %d/%d\n", rect.right, rect.bottom); */
switch (rect.right)
{
case 32: resid = IDB_ICON_32; break;
case 48: resid = IDB_ICON_48; break;
case 64: resid = IDB_ICON_64; break;
case 96: resid = IDB_ICON_96; break;
default: resid = IDB_ICON_128;break;
}
bitmap = LoadImage (GetModuleHandle (NULL),
MAKEINTRESOURCE (resid),
IMAGE_BITMAP,
rect.right, rect.bottom,
(LR_SHARED | LR_LOADTRANSPARENT | LR_LOADMAP3DCOLORS));
if (!bitmap)
{
fprintf (stderr, "LoadImage failed: %s\n", w32_strerror (-1));
return;
}
SendMessage(hwnd, STM_SETIMAGE, (WPARAM)IMAGE_BITMAP, (LPARAM)bitmap);
}
/* Dialog processing loop. */
-static BOOL CALLBACK
+static INT_PTR CALLBACK
dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
{
static pinentry_t pe;
/* static int item; */
/* { */
/* int idx; */
/* for (idx=0; msgcodes[idx].string; idx++) */
/* if (msg == msgcodes[idx].msg) */
/* break; */
/* if (msgcodes[idx].string) */
/* fprintf (debugfp, "received %s\n", msgcodes[idx].string); */
/* else */
/* fprintf (debugfp, "received WM_%u\n", msg); */
/* } */
switch (msg)
{
case WM_INITDIALOG:
dialog_handle = dlg;
pe = (pinentry_t)lparam;
if (!pe)
abort ();
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, "");
set_bitmap (dlg, IDC_PINENT_ICON);
if (pe->ok)
{
set_dlg_item_text (dlg, IDOK, pe->ok);
resize_button (GetDlgItem (dlg, IDOK), pe->ok);
}
if (pe->cancel)
{
set_dlg_item_text (dlg, IDCANCEL, pe->cancel);
resize_button (GetDlgItem (dlg, IDCANCEL), pe->cancel);
}
if (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));
/* item = IDOK; */
}
/* else */
/* item = IDC_PINENT_TEXT; */
center_window (dlg, HWND_TOP);
- /* Unfortunately we can't use SetForegroundWindow because there
- is no easy eay to have all the calling processes do an
- AllowSetForegroundWindow. What we do instead is to bad hack
- by simulating a click to the Window. */
-/* if (SetForegroundWindow (dlg) && lock_set_foreground_window) */
-/* { */
-/* lock_set_foreground_window (LSFW_LOCK); */
-/* } */
-
-/* show_window_hierarchy (GetDesktopWindow (), 0); */
-
ShowWindow (dlg, SW_SHOW);
- move_mouse_and_click ( GetDlgItem (dlg, IDC_PINENT_PROMPT) );
- raise_sip (dlg);
+
break;
case WM_COMMAND:
switch (LOWORD (wparam))
{
case IDOK:
if (confirm_mode)
confirm_yes = 1;
else
ok_button_clicked (dlg, pe);
EndDialog (dlg, TRUE);
break;
case IDCANCEL:
pe->result = -1;
EndDialog (dlg, FALSE);
break;
}
break;
case WM_KEYDOWN:
if (wparam == VK_RETURN)
{
if (confirm_mode)
confirm_yes = 1;
else
ok_button_clicked (dlg, pe);
EndDialog (dlg, TRUE);
}
break;
case WM_CTLCOLORSTATIC:
if ((HWND)lparam == GetDlgItem (dlg, IDC_PINENT_ERR))
{
/* Display the error prompt in red. */
SetTextColor ((HDC)wparam, RGB (255, 0, 0));
SetBkMode ((HDC)wparam, TRANSPARENT);
return (BOOL)GetStockObject (NULL_BRUSH);
}
break;
}
return FALSE;
}
/* The okay button has been clicked or the enter enter key in the text
field. */
static void
ok_button_clicked (HWND dlg, pinentry_t pe)
{
char *s_utf8;
wchar_t *w_buffer;
size_t w_buffer_size = 255;
unsigned int nchar;
pe->locale_err = 1;
w_buffer = secmem_malloc ((w_buffer_size + 1) * sizeof *w_buffer);
if (!w_buffer)
return;
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);
pe->locale_err = 0;
pe->result = pe->pin? strlen (pe->pin) : 0;
}
}
static int
w32_cmd_handler (pinentry_t pe)
{
-/* HWND lastwindow = GetForegroundWindow (); */
-
confirm_mode = !pe->pin;
passphrase_ok = confirm_yes = 0;
dialog_handle = NULL;
DialogBoxParam (GetModuleHandle (NULL), MAKEINTRESOURCE (IDD_PINENT),
GetDesktopWindow (), dlg_proc, (LPARAM)pe);
- if (dialog_handle)
- {
-/* if (lock_set_foreground_window) */
-/* lock_set_foreground_window (LSFW_UNLOCK); */
-/* if (lastwindow) */
-/* SetForegroundWindow (lastwindow); */
- }
- else
+ if (!dialog_handle)
return -1;
if (confirm_mode)
return confirm_yes;
else if (passphrase_ok && pe->pin)
return strlen (pe->pin);
else
return -1;
}
-/* WindowsCE uses a very strange way of handling the standard streams.
- There is a function SetStdioPath to associate a standard stream
- with a file or a device but what we really want is to use pipes as
- standard streams. Despite that we implement pipes using a device,
- we would have some limitations on the number of open pipes due to
- the 3 character limit of device file name. Thus we don't take this
- path. Another option would be to install a file system driver with
- support for pipes; this would allow us to get rid of the device
- name length limitation. However, with GnuPG we can get away be
- redefining the standard streams and passing the handles to be used
- on the command line. This has also the advantage that it makes
- creating a process much easier and does not require the
- SetStdioPath set and restore game. The caller needs to pass the
- rendezvous ids using up to three options:
-
- -&S0=<rvid> -&S1=<rvid> -&S2=<rvid>
-
- They are all optional but they must be the first arguments on the
- command line. Parsing stops as soon as an invalid option is found.
- These rendezvous ids are then used to finish the pipe creation.*/
-#ifdef HAVE_W32CE_SYSTEM
-static void
-parse_std_file_handles (int *argcp, char ***argvp)
-{
- int argc = *argcp;
- char **argv = *argvp;
- const char *s;
- int fd;
- int i;
- int fixup = 0;
-
- if (!argc)
- return;
-
- for (argc--, argv++; argc; argc--, argv++)
- {
- s = *argv;
- if (*s == '-' && s[1] == '&' && s[2] == 'S'
- && (s[3] == '0' || s[3] == '1' || s[3] == '2')
- && s[4] == '='
- && (strchr ("-01234567890", s[5]) || !strcmp (s+5, "null")))
- {
- if (s[5] == 'n')
- fd = (int)(-1);
- else
- fd = (int)w32ce_finish_pipe (atoi (s+5), s[3] != '0');
- if (s[3] == '0' && fd != -1)
- w32_infd = fd;
- else if (s[3] == '1' && fd != -1)
- w32_outfd = fd;
- fixup++;
- }
- else
- break;
- }
-
- if (fixup)
- {
- argc = *argcp;
- argc -= fixup;
- *argcp = argc;
-
- argv = *argvp;
- for (i=1; i < argc; i++)
- argv[i] = argv[i + fixup];
- for (; i < argc + fixup; i++)
- argv[i] = NULL;
- }
-
-
-}
-#endif /*HAVE_W32CE_SYSTEM*/
-
int
main (int argc, char **argv)
{
-#ifndef HAVE_W32CE_SYSTEM
- void *handle;
-#endif
-
w32_infd = STDIN_FILENO;
w32_outfd = STDOUT_FILENO;
-#ifdef HAVE_W32CE_SYSTEM
- parse_std_file_handles (&argc, &argv);
-#endif
-
pinentry_init (PGMNAME);
pinentry_parse_opts (argc, argv);
/* debugfp = fopen ("pinentry.log", "w"); */
/* if (!debugfp) */
/* debugfp = stderr; */
- /* We need to load a function because that one is only available
- since W2000 but not in older NTs. */
-#ifndef HAVE_W32CE_SYSTEM
- handle = LoadLibrary ("user32.dll");
- if (handle)
- {
- void *foo;
- foo = GetProcAddress (handle, "LockSetForegroundWindow");
- if (foo)
- lock_set_foreground_window = foo;
- else
- CloseHandle (handle);
- }
-#endif
if (pinentry_loop2 (w32_infd, w32_outfd))
return 1;
-#ifdef HAVE_W32CE_SYSTEM
- Sleep (400);
-#endif
return 0;
}
diff --git a/w32/pinentry-w32.rc b/w32/pinentry-w32.rc
index bc3dacb..28a2de0 100755
--- a/w32/pinentry-w32.rc
+++ b/w32/pinentry-w32.rc
@@ -1,74 +1,74 @@
/* dialog.rc - Resource definitions -*- c -*-
* Copyright (C) 2004, 2010 g10 Code GmbH
*
* 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, see <https://www.gnu.org/licenses/>.
* SPDX-License-Identifier: GPL-2.0+
*/
#include <config.h>
#include <winuser.h>
#include <windows.h>
#include "resource.h"
/*
* Main dialog
*/
#ifdef HAVE_W32CE_SYSTEM
IDD_PINENT DIALOG DISCARDABLE 0, 0, 150, 100
STYLE DS_MODALFRAME | DS_SYSMODAL | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Pinentry"
FONT 8, "MS Shell Dlg"
BEGIN
LTEXT "", IDC_PINENT_DESC, 2, 2, 140, 24
LTEXT "", IDC_PINENT_ERR, 2, 30, 140, 12
LTEXT "", IDC_PINENT_PROMPT, 2, 56, 20, 12
EDITTEXT IDC_PINENT_TEXT, 30, 56, 100, 12, ES_PASSWORD | ES_AUTOHSCROLL
DEFPUSHBUTTON "O&K", IDOK, 2, 70, 50, 14
PUSHBUTTON "&Cancel", IDCANCEL, 60, 70, 50, 14
END
#else /* Standard Windows. */
IDB_ICON_32 BITMAP DISCARDABLE "logo-32.bmp"
IDB_ICON_48 BITMAP DISCARDABLE "logo-48.bmp"
IDB_ICON_64 BITMAP DISCARDABLE "logo-64.bmp"
IDB_ICON_96 BITMAP DISCARDABLE "logo-96.bmp"
IDB_ICON_128 BITMAP DISCARDABLE "logo-128.bmp"
-IDD_PINENT DIALOG DISCARDABLE 0, 0, 186, 116
+IDD_PINENT DIALOG DISCARDABLE 0, 0, 230, 125
STYLE DS_MODALFRAME | DS_SYSMODAL | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Pinentry"
FONT 10, "MS Sans Serif"
BEGIN
CONTROL "", IDC_PINENT_ICON,
"Static", SS_BITMAP|SS_CENTERIMAGE,
- 4, 6, 32, 32
- LTEXT "", IDC_PINENT_DESC, 40, 6, 140, 50
- RTEXT "", IDC_PINENT_PROMPT, 6, 60, 60, 12
- EDITTEXT IDC_PINENT_TEXT, 70, 59, 110, 12, ES_PASSWORD | ES_AUTOHSCROLL
- CTEXT "", IDC_PINENT_ERR, 6, 76, 174, 12
- DEFPUSHBUTTON "O&K", IDOK, 74, 96, 50, 14
- PUSHBUTTON "&Cancel", IDCANCEL, 130, 96, 50, 14
+ 5, 5, 32, 32
+ LTEXT "", IDC_PINENT_DESC, 45, 5, 180, 65
+ RTEXT "", IDC_PINENT_PROMPT, 5, 75, 60, 12
+ EDITTEXT IDC_PINENT_TEXT, 70, 75, 155, 12, ES_PASSWORD | ES_AUTOHSCROLL
+ CTEXT "", IDC_PINENT_ERR, 5, 90, 220, 12
+ DEFPUSHBUTTON "O&K", IDOK, 50, 105, 85, 14
+ PUSHBUTTON "&Cancel", IDCANCEL, 140, 105, 85, 14
END
#endif /* Standard Windows. */

File Metadata

Mime Type
text/x-diff
Expires
Sat, Feb 7, 7:37 AM (1 d, 21 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
51/16/0f241c22189b65634f5a4bb54929

Event Timeline