Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F35382245
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
34 KB
Subscribers
None
View Options
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
Details
Attached
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
Attached To
rP Pinentry
Event Timeline
Log In to Comment