diff --git a/src/common.c b/src/common.c
index 5d4c6fb..724aebe 100644
--- a/src/common.c
+++ b/src/common.c
@@ -1,1030 +1,1059 @@
/* common.c - Common routines used by GpgOL
* Copyright (C) 2005, 2007, 2008 g10 Code GmbH
* 2015, 2016, 2017 Bundesamt für Sicherheit in der Informationstechnik
* Software engineering by Intevation GmbH
*
* This file is part of GpgOL.
*
* GpgOL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* GpgOL 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 Lesser General Public License
* along with this program; if not, see .
*/
#include
#define OEMRESOURCE /* Required for OBM_CHECKBOXES. */
#include
#include
#ifndef CSIDL_APPDATA
#define CSIDL_APPDATA 0x001a
#endif
#ifndef CSIDL_LOCAL_APPDATA
#define CSIDL_LOCAL_APPDATA 0x001c
#endif
#ifndef CSIDL_FLAG_CREATE
#define CSIDL_FLAG_CREATE 0x8000
#endif
#include
#include
#include
#include "common.h"
+#include "dialogs.h"
+
HINSTANCE glob_hinst = NULL;
void
set_global_hinstance (HINSTANCE hinst)
{
glob_hinst = hinst;
}
/* Center the given window with the desktop window as the
parent window. */
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);
}
/* Return the system's bitmap of the check bar used which check boxes.
If CHECKED is set, this check mark is returned; if it is not set,
the one used for not-checked is returned. May return NULL on
error. Taken from an example in the platform reference.
Not used as of now. */
HBITMAP
get_system_check_bitmap (int checked)
{
COLORREF bg_color;
HBRUSH bg_brush, saved_dst_brush;
HDC src_dc, dst_dc;
WORD xsize, ysize;
HBITMAP result, saved_dst_bitmap, saved_src_bitmap, checkboxes;
BITMAP bitmap;
RECT rect;
bg_color = GetSysColor (COLOR_MENU);
bg_brush = CreateSolidBrush (bg_color);
src_dc = CreateCompatibleDC (NULL);
dst_dc = CreateCompatibleDC (src_dc);
xsize = GetSystemMetrics (SM_CXMENUCHECK);
ysize = GetSystemMetrics (SM_CYMENUCHECK);
result = CreateCompatibleBitmap(src_dc, xsize, ysize);
saved_dst_brush = SelectObject (dst_dc, bg_brush);
saved_dst_bitmap = SelectObject (dst_dc, result);
PatBlt (dst_dc, 0, 0, xsize, ysize, PATCOPY);
checkboxes = LoadBitmap (NULL, (LPTSTR)OBM_CHECKBOXES);
saved_src_bitmap = SelectObject (src_dc, checkboxes);
GetObject (checkboxes, sizeof (BITMAP), &bitmap);
rect.top = 0;
rect.bottom = (bitmap.bmHeight / 3);
if (checked)
{
/* Select row 1, column 1. */
rect.left = 0;
rect.right = (bitmap.bmWidth / 4);
}
else
{
/* Select row 1, column 2. */
rect.left = (bitmap.bmWidth / 4);
rect.right = (bitmap.bmWidth / 4) * 2;
}
if ( ((rect.right - rect.left) > (int)xsize)
|| ((rect.bottom - rect.top) > (int)ysize) )
StretchBlt (dst_dc, 0, 0, xsize, ysize, src_dc, rect.left, rect.top,
rect.right - rect.left, rect.bottom - rect.top, SRCCOPY);
else
BitBlt (dst_dc, 0, 0, rect.right - rect.left, rect.bottom - rect.top,
src_dc, rect.left, rect.top, SRCCOPY);
SelectObject (src_dc, saved_src_bitmap);
SelectObject (dst_dc, saved_dst_brush);
result = SelectObject (dst_dc, saved_dst_bitmap);
DeleteObject (bg_brush);
DeleteObject (src_dc);
DeleteObject (dst_dc);
return result;
}
/* Return the path to a file that should be worked with.
Returns a malloced string (UTF-8) on success.
HWND is the current Window.
Title is a UTF-8 encoded string containing the
dialog title and may be NULL.
On error (i.e. cancel) NULL is returned. */
char *
get_open_filename (HWND root, const char *title)
{
OPENFILENAMEW ofn;
wchar_t fname[MAX_PATH+1];
wchar_t *wTitle = NULL;
if (title)
{
wTitle = utf8_to_wchar2 (title, strlen(title));
}
memset (fname, 0, sizeof (fname));
/* Set up the ofn structure */
memset (&ofn, 0, sizeof (ofn));
ofn.lStructSize = sizeof (ofn);
ofn.hwndOwner = root;
ofn.lpstrFile = fname;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrTitle = wTitle;
ofn.Flags = OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
if (GetOpenFileNameW (&ofn))
{
xfree (wTitle);
return wchar_to_utf8_2 (fname, MAX_PATH);
}
xfree (wTitle);
return NULL;
}
/* Return a filename to be used for saving an attachment. Returns a
malloced string on success. HWND is the current Window and SRCNAME
the filename to be used as suggestion. On error (i.e. cancel) NULL
is returned. */
char *
get_save_filename (HWND root, const char *srcname)
{
char filter[21] = "All Files (*.*)\0*.*\0\0";
char fname[MAX_PATH+1];
char filterBuf[32];
char* extSep;
OPENFILENAME ofn;
memset (fname, 0, sizeof (fname));
memset (filterBuf, 0, sizeof (filterBuf));
strncpy (fname, srcname, MAX_PATH-1);
fname[MAX_PATH] = 0;
if ((extSep = strrchr (srcname, '.')) && strlen (extSep) <= 4)
{
/* Windows removes the file extension by default so we
need to set the first filter to the file extension.
*/
strcpy (filterBuf, extSep);
strcpy (filterBuf + strlen (filterBuf) + 1, extSep);
memcpy (filterBuf + strlen (extSep) * 2 + 2, filter, 21);
}
else
memcpy (filterBuf, filter, 21);
memset (&ofn, 0, sizeof (ofn));
ofn.lStructSize = sizeof (ofn);
ofn.hwndOwner = root;
ofn.lpstrFile = fname;
ofn.nMaxFile = MAX_PATH;
ofn.lpstrFileTitle = NULL;
ofn.nMaxFileTitle = 0;
ofn.Flags |= OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT;
ofn.lpstrTitle = _("GpgOL - Save attachment");
ofn.lpstrFilter = filterBuf;
if (GetSaveFileName (&ofn))
return xstrdup (fname);
return NULL;
}
void
bring_to_front (HWND wid)
{
if (wid)
{
if (!SetForegroundWindow (wid))
{
log_debug ("%s:%s: SetForegroundWindow failed", SRCNAME, __func__);
/* Yet another fallback which will not work on some
* versions and is not recommended by msdn */
if (!ShowWindow (wid, SW_SHOWNORMAL))
{
log_debug ("%s:%s: ShowWindow failed.", SRCNAME, __func__);
}
}
}
}
void
fatal_error (const char *format, ...)
{
va_list arg_ptr;
char buf[512];
va_start (arg_ptr, format);
vsnprintf (buf, sizeof buf -1, format, arg_ptr);
buf[sizeof buf - 1] = 0;
va_end (arg_ptr);
MessageBox (NULL, buf, "Fatal Error", MB_OK);
abort ();
}
/* This is a helper function to load a Windows function from either of
one DLLs. */
static HRESULT
w32_shgetfolderpath (HWND a, int b, HANDLE c, DWORD d, LPSTR e)
{
static int initialized;
static HRESULT (WINAPI * func)(HWND,int,HANDLE,DWORD,LPSTR);
if (!initialized)
{
static char *dllnames[] = { "shell32.dll", "shfolder.dll", NULL };
void *handle;
int i;
initialized = 1;
for (i=0, handle = NULL; !handle && dllnames[i]; i++)
{
handle = LoadLibrary (dllnames[i]);
if (handle)
{
func = (HRESULT (WINAPI *)(HWND,int,HANDLE,DWORD,LPSTR))
GetProcAddress (handle, "SHGetFolderPathA");
if (!func)
{
FreeLibrary (handle);
handle = NULL;
}
}
}
}
if (func)
return func (a,b,c,d,e);
else
return -1;
}
/* Same as above, but only convert the first LEN wchars. */
char *
wchar_to_utf8_2 (const wchar_t *string, size_t len)
{
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 = xmalloc (n+1);
n = WideCharToMultiByte (CP_UTF8, 0, string, len, result, n, NULL, NULL);
if (n < 0)
{
xfree (result);
return NULL;
}
return result;
}
/* Same as above but convert only the first LEN characters. STRING
must be at least LEN characters long. */
wchar_t *
utf8_to_wchar2 (const char *string, size_t len)
{
int n;
wchar_t *result;
n = MultiByteToWideChar (CP_UTF8, 0, string, len, NULL, 0);
if (n < 0)
return NULL;
result = xmalloc ((n+1) * sizeof *result);
n = MultiByteToWideChar (CP_UTF8, 0, string, len, result, n);
if (n < 0)
{
xfree (result);
return NULL;
}
result[n] = 0;
return result;
}
/* Helper for read_w32_registry_string(). */
static HKEY
get_root_key(const char *root)
{
HKEY root_key;
if( !root )
root_key = HKEY_CURRENT_USER;
else if( !strcmp( root, "HKEY_CLASSES_ROOT" ) )
root_key = HKEY_CLASSES_ROOT;
else if( !strcmp( root, "HKEY_CURRENT_USER" ) )
root_key = HKEY_CURRENT_USER;
else if( !strcmp( root, "HKEY_LOCAL_MACHINE" ) )
root_key = HKEY_LOCAL_MACHINE;
else if( !strcmp( root, "HKEY_USERS" ) )
root_key = HKEY_USERS;
else if( !strcmp( root, "HKEY_PERFORMANCE_DATA" ) )
root_key = HKEY_PERFORMANCE_DATA;
else if( !strcmp( root, "HKEY_CURRENT_CONFIG" ) )
root_key = HKEY_CURRENT_CONFIG;
else
return NULL;
return root_key;
}
/* Return a string from the Win32 Registry or NULL in case of error.
Caller must release the return value. A NULL for root is an alias
for HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE in turn. NOTE: The value
is allocated with a plain malloc() - use free() and not the usual
xfree(). */
char *
read_w32_registry_string (const char *root, const char *dir, const char *name)
{
HKEY root_key, key_handle;
DWORD n1, nbytes, type;
char *result = NULL;
if ( !(root_key = get_root_key(root) ) )
return NULL;
if( RegOpenKeyEx( root_key, dir, 0, KEY_READ, &key_handle ) )
{
if (root)
return NULL; /* no need for a RegClose, so return direct */
/* It seems to be common practise to fall back to HKLM. */
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) )
return NULL; /* still no need for a RegClose, so return direct */
}
nbytes = 1;
if( RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes ) ) {
if (root)
goto leave;
/* Try to fallback to HKLM also vor a missing value. */
RegCloseKey (key_handle);
if (RegOpenKeyEx (HKEY_LOCAL_MACHINE, dir, 0, KEY_READ, &key_handle) )
return NULL; /* Nope. */
if (RegQueryValueEx( key_handle, name, 0, NULL, NULL, &nbytes))
goto leave;
}
result = malloc( (n1=nbytes+1) );
if( !result )
goto leave;
if( RegQueryValueEx( key_handle, name, 0, &type, result, &n1 ) ) {
free(result); result = NULL;
goto leave;
}
result[nbytes] = 0; /* make sure it is really a string */
if (type == REG_EXPAND_SZ && strchr (result, '%')) {
char *tmp;
n1 += 1000;
tmp = malloc (n1+1);
if (!tmp)
goto leave;
nbytes = ExpandEnvironmentStrings (result, tmp, n1);
if (nbytes && nbytes > n1) {
free (tmp);
n1 = nbytes;
tmp = malloc (n1 + 1);
if (!tmp)
goto leave;
nbytes = ExpandEnvironmentStrings (result, tmp, n1);
if (nbytes && nbytes > n1) {
free (tmp); /* oops - truncated, better don't expand at all */
goto leave;
}
tmp[nbytes] = 0;
free (result);
result = tmp;
}
else if (nbytes) { /* okay, reduce the length */
tmp[nbytes] = 0;
free (result);
result = malloc (strlen (tmp)+1);
if (!result)
result = tmp;
else {
strcpy (result, tmp);
free (tmp);
}
}
else { /* error - don't expand */
free (tmp);
}
}
leave:
RegCloseKey( key_handle );
return result;
}
/* Get the standard home directory. In general this function should
not be used as it does not consider a registry value or the
GNUPGHOME environment variable. Please use default_homedir(). */
static const char *
standard_homedir (void)
{
static char *dir;
if (!dir)
{
char path[MAX_PATH];
/* It might be better to use LOCAL_APPDATA because this is
defined as "non roaming" and thus more likely to be kept
locally. For private keys this is desired. However, given
that many users copy private keys anyway forth and back,
using a system roaming services might be better than to let
them do it manually. A security conscious user will anyway
use the registry entry to have better control. */
if (w32_shgetfolderpath (NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE,
NULL, 0, path) >= 0)
{
char *tmp = malloc (strlen (path) + 6 + 1);
strcpy (tmp, path);
strcat (tmp, "\\gnupg");
dir = tmp;
/* Try to create the directory if it does not yet exists. */
if (access (dir, F_OK))
CreateDirectory (dir, NULL);
}
else
dir = xstrdup ("C:\\gnupg");
}
return dir;
}
/* Retrieve the default home directory. */
const char *
default_homedir (void)
{
static char *dir;
if (!dir)
{
dir = getenv ("GNUPGHOME");
if (!dir || !*dir)
{
char *tmp;
tmp = read_w32_registry_string (NULL, GPG4WIN_REGKEY_3, "HomeDir");
if (!tmp)
{
tmp = read_w32_registry_string (NULL, GPG4WIN_REGKEY_2, "HomeDir");
}
if (tmp && !*tmp)
{
free (tmp);
tmp = NULL;
}
if (tmp)
dir = tmp;
else
dir = xstrdup (standard_homedir ());
}
else
dir = xstrdup (dir);
}
return dir;
}
/* Return the data dir used for forms etc. Returns NULL on error. */
char *
get_data_dir (void)
{
char *instdir;
char *p;
char *dname;
instdir = get_gpg4win_dir();
if (!instdir)
return NULL;
/* Build the key: "/share/gpgol". */
#define SDDIR "\\share\\gpgol"
dname = malloc (strlen (instdir) + strlen (SDDIR) + 1);
if (!dname)
{
free (instdir);
return NULL;
}
p = dname;
strcpy (p, instdir);
p += strlen (instdir);
strcpy (p, SDDIR);
free (instdir);
#undef SDDIR
return dname;
}
/* Percent-escape the string STR by replacing colons with '%3a'. If
EXTRA is not NULL all characters in it are also escaped. */
char *
percent_escape (const char *str, const char *extra)
{
int i, j;
char *ptr;
if (!str)
return NULL;
for (i=j=0; str[i]; i++)
if (str[i] == ':' || str[i] == '%' || (extra && strchr (extra, str[i])))
j++;
ptr = (char *) malloc (i + 2 * j + 1);
i = 0;
while (*str)
{
/* FIXME: Work around a bug in Kleo. */
if (*str == ':')
{
ptr[i++] = '%';
ptr[i++] = '3';
ptr[i++] = 'a';
}
else
{
if (*str == '%')
{
ptr[i++] = '%';
ptr[i++] = '2';
ptr[i++] = '5';
}
else if (extra && strchr (extra, *str))
{
ptr[i++] = '%';
ptr[i++] = tohex_lower ((*str >> 4) & 15);
ptr[i++] = tohex_lower (*str & 15);
}
else
ptr[i++] = *str;
}
str++;
}
ptr[i] = '\0';
return ptr;
}
/* Fix linebreaks.
This replaces all consecutive \r or \n characters
by a single \n.
There can be extremly weird combinations of linebreaks
like \r\r\n\r\r\n at the end of each line when
getting the body of a mail message.
*/
void
fix_linebreaks (char *str, int *len)
{
char *src;
char *dst;
src = str;
dst = str;
while (*src)
{
if (*src == '\r' || *src == '\n')
{
do
src++;
while (*src == '\r' || *src == '\n');
*(dst++) = '\n';
}
else
{
*(dst++) = *(src++);
}
}
*dst = '\0';
*len = dst - str;
}
/* Get a pretty name for the file at path path. File extension
will be set to work for the protocol as provided in protocol and
depends on the signature setting. Set signature to 0 if the
extension should not be a signature extension.
Returns NULL on success.
Caller must free result. */
wchar_t *
get_pretty_attachment_name (wchar_t *path, protocol_t protocol,
int signature)
{
wchar_t* pretty;
wchar_t* buf;
if (!path || !wcslen (path))
{
log_error("%s:%s: No path given", SRCNAME, __func__);
return NULL;
}
pretty = (wchar_t*) xmalloc ((MAX_PATH + 1) * sizeof (wchar_t));
memset (pretty, 0, (MAX_PATH + 1) * sizeof (wchar_t));
buf = wcsrchr (path, '\\') + 1;
if (!buf || !*buf)
{
log_error("%s:%s: No filename found in path", SRCNAME, __func__);
xfree (pretty);
return NULL;
}
wcscpy (pretty, buf);
buf = pretty + wcslen(pretty);
if (signature)
{
if (protocol == PROTOCOL_SMIME)
{
*(buf++) = '.';
*(buf++) = 'p';
*(buf++) = '7';
*(buf++) = 's';
}
else
{
*(buf++) = '.';
*(buf++) = 's';
*(buf++) = 'i';
*(buf++) = 'g';
}
}
else
{
if (protocol == PROTOCOL_SMIME)
{
*(buf++) = '.';
*(buf++) = 'p';
*(buf++) = '7';
*(buf++) = 'm';
}
else
{
*(buf++) = '.';
*(buf++) = 'g';
*(buf++) = 'p';
*(buf++) = 'g';
}
}
return pretty;
}
/* Open a file in a temporary directory, take name as a
suggestion and put the open Handle in outHandle.
Returns the actually used file name in case there
were other files with that name. */
wchar_t*
get_tmp_outfile (wchar_t *name, HANDLE *outHandle)
{
wchar_t tmpPath[MAX_PATH];
wchar_t *outName;
wchar_t *fileExt = NULL;
int tries = 1;
if (!name || !wcslen(name))
{
log_error ("%s:%s: Needs a name.",
SRCNAME, __func__);
return NULL;
}
/* We should probably use the unicode variants here
but this would mean adding OpenStreamOnFileW to
out mapi */
if (!GetTempPathW (MAX_PATH, tmpPath))
{
log_error ("%s:%s: Could not get tmp path.",
SRCNAME, __func__);
return NULL;
}
outName = (wchar_t*) xmalloc ((MAX_PATH + 1) * sizeof(wchar_t));
memset (outName, 0, (MAX_PATH + 1) * sizeof (wchar_t));
snwprintf (outName, MAX_PATH, L"%s%s", tmpPath, name);
while ((*outHandle = CreateFileW (outName,
GENERIC_WRITE | GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_DELETE,
NULL,
CREATE_NEW,
FILE_ATTRIBUTE_TEMPORARY,
NULL)) == INVALID_HANDLE_VALUE)
{
wchar_t fnameBuf[MAX_PATH + 1];
wchar_t origName[MAX_PATH + 1];
memset (fnameBuf, 0, MAX_PATH + 1);
memset (origName, 0, MAX_PATH + 1);
snwprintf (origName, MAX_PATH, L"%s%s", tmpPath, name);
fileExt = wcschr (wcsrchr(origName, '\\'), '.');
if (fileExt)
{
wcsncpy (fnameBuf, origName, fileExt - origName);
}
else
{
wcsncpy (fnameBuf, origName, wcslen (origName));
}
snwprintf (outName, MAX_PATH, L"%s%i%s", fnameBuf, tries++,
fileExt ? fileExt : L"");
if (tries > 100)
{
/* You have to know when to give up,.. */
log_error ("%s:%s: Could not get a name out of 100 tries",
SRCNAME, __func__);
xfree (outName);
return NULL;
}
}
return outName;
}
/** Get the Gpg4win Install directory.
*
* Looks first for the Gpg4win 3.x registry key. Then for the Gpg4win
* 2.x registry key. And checks that the directory can be read.
*
* @returns NULL if no dir could be found. Otherwise a malloced string.
*/
char *
get_gpg4win_dir()
{
const char *g4win_keys[] = {GPG4WIN_REGKEY_3,
GPG4WIN_REGKEY_2,
NULL};
const char **key;
for (key = g4win_keys; *key; key++)
{
char *tmp = read_w32_registry_string (NULL, *key, "Install Directory");
if (!tmp)
{
continue;
}
if (!access(tmp, R_OK))
{
return tmp;
}
else
{
log_debug ("Failed to access: %s\n", tmp);
xfree (tmp);
}
}
return NULL;
}
static void
epoch_to_file_time (unsigned long time, LPFILETIME pft)
{
LONGLONG ll;
ll = Int32x32To64(time, 10000000) + 116444736000000000;
pft->dwLowDateTime = (DWORD)ll;
pft->dwHighDateTime = ll >> 32;
}
char *
format_date_from_gpgme (unsigned long time)
{
wchar_t buf[256];
FILETIME ft;
SYSTEMTIME st;
epoch_to_file_time (time, &ft);
FileTimeToSystemTime(&ft, &st);
int ret = GetDateFormatEx (NULL,
DATE_SHORTDATE,
&st,
NULL,
buf,
256,
NULL);
if (ret == 0)
{
return NULL;
}
return wchar_to_utf8 (buf);
}
/* Return the name of the default UI server. This name is used to
auto start an UI server if an initial connect failed. */
char *
get_uiserver_name (void)
{
char *name = NULL;
char *dir, *uiserver, *p;
int extra_arglen = 9;
const char * server_names[] = {"kleopatra.exe",
"bin\\kleopatra.exe",
"gpa.exe",
"bin\\gpa.exe",
NULL};
const char **tmp = NULL;
dir = get_gpg4win_dir ();
if (!dir)
{
log_error ("Failed to find gpg4win dir");
return NULL;
}
uiserver = read_w32_registry_string (NULL, GPG4WIN_REGKEY_3,
"UI Server");
if (!uiserver)
{
uiserver = read_w32_registry_string (NULL, GPG4WIN_REGKEY_2,
"UI Server");
}
if (uiserver)
{
name = xmalloc (strlen (dir) + strlen (uiserver) + extra_arglen + 2);
strcpy (stpcpy (stpcpy (name, dir), "\\"), uiserver);
for (p = name; *p; p++)
if (*p == '/')
*p = '\\';
xfree (uiserver);
}
if (name && !access (name, F_OK))
{
/* Set through registry and is accessible */
xfree(dir);
return name;
}
/* Fallbacks */
for (tmp = server_names; *tmp; tmp++)
{
if (name)
{
xfree (name);
}
name = xmalloc (strlen (dir) + strlen (*tmp) + extra_arglen + 2);
strcpy (stpcpy (stpcpy (name, dir), "\\"), *tmp);
for (p = name; *p; p++)
if (*p == '/')
*p = '\\';
if (!access (name, F_OK))
{
/* Found a viable candidate */
if (strstr (name, "kleopatra.exe"))
{
strcat (name, " --daemon");
}
xfree (dir);
return name;
}
}
xfree (dir);
log_error ("Failed to find a viable UIServer");
return NULL;
}
int
has_high_integrity(HANDLE hToken)
{
PTOKEN_MANDATORY_LABEL integrity_label = NULL;
DWORD integrity_level = 0,
size = 0;
if (hToken == NULL || hToken == INVALID_HANDLE_VALUE)
{
log_debug ("Invalid parameters.");
return 0;
}
/* Get the required size */
if (!GetTokenInformation (hToken, TokenIntegrityLevel,
NULL, 0, &size))
{
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
log_debug ("Failed to get required size.\n");
return 0;
}
}
integrity_label = (PTOKEN_MANDATORY_LABEL) LocalAlloc(0, size);
if (integrity_label == NULL)
{
log_debug ("Failed to allocate label. \n");
return 0;
}
if (!GetTokenInformation (hToken, TokenIntegrityLevel,
integrity_label, size, &size))
{
log_debug ("Failed to get integrity level.\n");
LocalFree(integrity_label);
return 0;
}
/* Get the last integrity level */
integrity_level = *GetSidSubAuthority(integrity_label->Label.Sid,
(DWORD)(UCHAR)(*GetSidSubAuthorityCount(
integrity_label->Label.Sid) - 1));
LocalFree (integrity_label);
return integrity_level >= SECURITY_MANDATORY_HIGH_RID;
}
int
is_elevated()
{
int ret = 0;
HANDLE hToken = NULL;
if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken))
{
DWORD elevation;
DWORD cbSize = sizeof (DWORD);
if (GetTokenInformation (hToken, TokenElevation, &elevation,
sizeof (TokenElevation), &cbSize))
{
ret = elevation;
}
}
/* Elevation will be true and ElevationType TokenElevationTypeFull even
if the token is a user token created by SAFER so we additionally
check the integrity level of the token which will only be high in
the real elevated process and medium otherwise. */
ret = ret && has_high_integrity (hToken);
if (hToken)
CloseHandle (hToken);
return ret;
}
+
+int
+gpgol_message_box (HWND parent, const char *utf8_text,
+ const char *utf8_caption, UINT type)
+{
+ wchar_t *w_text = utf8_to_wchar (utf8_text);
+ wchar_t *w_caption = utf8_to_wchar (utf8_caption);
+ int ret = 0;
+
+ MSGBOXPARAMSW mbp;
+ mbp.cbSize = sizeof (MSGBOXPARAMS);
+ mbp.hwndOwner = parent;
+ mbp.hInstance = glob_hinst;
+ mbp.lpszText = w_text;
+ mbp.lpszCaption = w_caption;
+ mbp.dwStyle = type | MB_USERICON;
+ mbp.dwLanguageId = MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT);
+ mbp.lpfnMsgBoxCallback = NULL;
+ mbp.dwContextHelpId = 0;
+ mbp.lpszIcon = (LPCWSTR) MAKEINTRESOURCE (IDI_GPGOL_LOCK_ICON);
+
+ ret = MessageBoxIndirectW (&mbp);
+
+ xfree (w_text);
+ xfree (w_caption);
+ return ret;
+}
diff --git a/src/common.h b/src/common.h
index d306d16..ed7b87a 100644
--- a/src/common.h
+++ b/src/common.h
@@ -1,147 +1,150 @@
/* common.h - Common declarations for GpgOL
* Copyright (C) 2004 Timo Schulz
* Copyright (C) 2005, 2006, 2007, 2008 g10 Code GmbH
* Copyright (C) 2015, 2016 by Bundesamt für Sicherheit in der Informationstechnik
* Software engineering by Intevation GmbH
*
* This file is part of GpgOL.
*
* GpgOL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1
* of the License, or (at your option) any later version.
*
* GpgOL 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 Lesser General Public License
* along with this program; if not, see .
*/
#ifndef GPGOL_COMMON_H
#define GPGOL_COMMON_H
#ifdef HAVE_CONFIG_H
#include
#endif
#include
#include "common_indep.h"
#include
#ifdef MIME_SEND
# define MIME_UI_DEFAULT 1
#else
# define MIME_UI_DEFAULT 0
#endif
#ifdef __cplusplus
extern "C" {
#if 0
}
#endif
#endif
extern HINSTANCE glob_hinst;
extern UINT this_dll;
/*-- common.c --*/
void set_global_hinstance (HINSTANCE hinst);
void center_window (HWND childwnd, HWND style);
HBITMAP get_system_check_bitmap (int checked);
char *get_save_filename (HWND root, const char *srcname);
char *get_open_filename (HWND root, const char *title);
char *utf8_to_wincp (const char *string);
const char *default_homedir (void);
char *get_data_dir (void);
char *get_gpg4win_dir (void);
/* Get a temporary filename with and its name */
wchar_t *get_tmp_outfile (wchar_t *name, HANDLE *outHandle);
wchar_t *get_pretty_attachment_name (wchar_t *path, protocol_t protocol,
int signature);
/*-- recipient-dialog.c --*/
unsigned int recipient_dialog_box (gpgme_key_t **ret_rset);
unsigned int recipient_dialog_box2 (gpgme_key_t *fnd, char **unknown,
gpgme_key_t **ret_rset);
/*-- passphrase-dialog.c --*/
int signer_dialog_box (gpgme_key_t *r_key, char **r_passwd, int encrypting);
gpgme_error_t passphrase_callback_box (void *opaque, const char *uid_hint,
const char *pass_info,
int prev_was_bad, int fd);
void free_decrypt_key (struct passphrase_cb_s *ctx);
const char *get_pubkey_algo_str (gpgme_pubkey_algo_t id);
/*-- config-dialog.c --*/
void config_dialog_box (HWND parent);
int store_extension_value (const char *key, const char *val);
int load_extension_value (const char *key, char **val);
/*-- verify-dialog.c --*/
int verify_dialog_box (gpgme_protocol_t protocol,
gpgme_verify_result_t res,
const char *filename);
/*-- inspectors.cpp --*/
int initialize_inspectors (void);
#if __GNUC__ >= 4
# define GPGOL_GCC_A_SENTINEL(a) __attribute__ ((sentinel(a)))
#else
# define GPGOL_GCC_A_SENTINEL(a)
#endif
/* i18n stuff */
#include "w32-gettext.h"
#define _(a) gettext (a)
#define N_(a) gettext_noop (a)
/*-- common.c --*/
void fatal_error (const char *format, ...);
char *wchar_to_utf8_2 (const wchar_t *string, size_t len);
wchar_t *utf8_to_wchar2 (const char *string, size_t len);
char *read_w32_registry_string (const char *root, const char *dir,
const char *name);
char *percent_escape (const char *str, const char *extra);
void fix_linebreaks (char *str, int *len);
/* Format a date from gpgme (seconds since epoch)
with windows system locale. */
char *format_date_from_gpgme (unsigned long time);
/* Get the name of the uiserver */
char *get_uiserver_name (void);
int is_elevated (void);
/*-- main.c --*/
const void *get_128bit_session_key (void);
const void *get_64bit_session_marker (void);
void *create_initialization_vector (size_t nbytes);
void read_options (void);
int write_options (void);
extern int g_ol_version_major;
void log_window_hierarchy (HWND window, const char *fmt,
...) __attribute__ ((format (printf,2,3)));
void bring_to_front (HWND wid);
+
+int gpgol_message_box (HWND parent, const char *utf8_text,
+ const char *utf8_caption, UINT type);
#ifdef __cplusplus
}
#endif
#endif /*GPGOL_COMMON_H*/
diff --git a/src/dialogs.h b/src/dialogs.h
index 2cce4ad..ff6466c 100644
--- a/src/dialogs.h
+++ b/src/dialogs.h
@@ -1,140 +1,141 @@
/* dialogs.h
Resouces IDs for the dialogs.
*/
#ifndef DIALOGS_H
#define DIALOGS_H
/* Ids used for bitmaps. There is some magic in the identifiers: In
the code we only use the first ID value and add 1 to find the mask.
*/
#define IDB_ENCRYPT_16 0x1000
#define IDB_ENCRYPT_16M 0x1001
#define IDB_SIGN_16 0x1010
#define IDB_SIGN_16M 0x1011
#define IDB_KEY_MANAGER_16 0x1020
#define IDB_KEY_MANAGER_16M 0x1021
#define IDB_DECRYPT_16 0x1030
#define IDB_DECRYPT_16M 0x1031
#define IDB_VERIFY_16 0x1040
#define IDB_VERIFY_16M 0x1041
#define IDB_DECRYPT_VERIFY_16 0x1050
#define IDB_DECRYPT_VERIFY_16M 0x1051
#define IDB_LOGO 0x1060
/* Ids for the extended options dialog. */
#define IDD_EXT_OPTIONS 0x4110
#define IDC_T_DEBUG_LOGFILE 0x4120
#define IDC_DEBUG_LOGFILE 0x4130
/* Ids for the recipient selection dialog. */
#define IDD_ENC 0x4210
#define IDC_ENC_RSET1 0x4220
#define IDC_ENC_RSET2_T 0x4230
#define IDC_ENC_RSET2 0x4240
#define IDC_ENC_NOTFOUND_T 0x4250
#define IDC_ENC_NOTFOUND 0x4260
/* Ids for the two decryption dialogs. */
#define IDD_DEC 0x4310
#define IDD_DECEXT 0x4320
#define IDC_DEC_KEYLIST 0x4330
#define IDC_DEC_HINT 0x4340
#define IDC_DEC_PASSINF 0x4350
#define IDC_DEC_PASS 0x4360
#define IDC_DEC_HIDE 0x4370
#define IDC_DECEXT_RSET_T 0x4380
#define IDC_DECEXT_RSET 0x4390
#define IDC_DECEXT_KEYLIST 0x43A0
#define IDC_DECEXT_HINT 0x43B0
#define IDC_DECEXT_PASSINF 0x43C0
#define IDC_DECEXT_PASS 0x43D0
#define IDC_DECEXT_HIDE 0x43E0
/* Ids for the verification dialog. */
#define IDD_VRY 0x4410
#define IDC_VRY_TIME_T 0x4420
#define IDC_VRY_TIME 0x4430
#define IDC_VRY_PKALGO_T 0x4440
#define IDC_VRY_PKALGO 0x4450
#define IDC_VRY_KEYID_T 0x4460
#define IDC_VRY_KEYID 0x4470
#define IDC_VRY_STATUS 0x4480
#define IDC_VRY_ISSUER_T 0x4490
#define IDC_VRY_ISSUER 0x44A0
#define IDC_VRY_AKALIST_T 0x44B0
#define IDC_VRY_AKALIST 0x44C0
#define IDC_VRY_HINT 0x44D0
/* Ids used for the main config dialog. */
#define IDD_GPG_OPTIONS 0x5000
#define IDD_ADDIN_OPTIONS 0x5001
#define IDC_TIME_PHRASES 0x5010
#define IDC_ENCRYPT_DEFAULT 0x5020
#define IDC_SIGN_DEFAULT 0x5030
#define IDC_ENCRYPT_WITH_STANDARD_KEY 0x5040
#define IDC_OPENPGP_DEFAULT 0x5050
#define IDC_SMIME_DEFAULT 0x5060
#define IDC_GPG_OPTIONS 0x5070
#define IDC_ADDIN_OPTIONS 0x5071
#define IDC_BITMAP 0x5080
#define IDC_VERSION_INFO 0x5090
#define IDC_ENCRYPT_TO 0x50A0
#define IDC_ENABLE_SMIME 0x50B0
#define IDC_PREVIEW_DECRYPT 0x50C0
#define IDC_PREFER_HTML 0x50D0
#define IDC_G_GENERAL 0x50E0
#define IDC_G_SEND 0x50F0
#define IDC_G_RECV 0x5100
#define IDC_BODY_AS_ATTACHMENT 0x5110
#define IDC_GPG_CONF 0x5120
#define IDC_G10CODE_STRING 0x5130
#define IDC_GPG4WIN_STRING 0x5131
#define IDC_START_CERTMAN 0x5132
#define IDC_MIME_UI 0x5133
#define IDC_INLINE_PGP 0x5134
#define IDC_AUTORRESOLVE 0x5135
#define IDC_REPLYCRYPT 0x5136
/* Ids for PNG Images */
#define IDI_ENCRYPT_16_PNG 0x6000
#define IDI_ENCRYPT_48_PNG 0x6010
#define IDI_DECRYPT_16_PNG 0x6020
#define IDI_DECRYPT_48_PNG 0x6030
#define IDI_KEY_MANAGER_64_PNG 0x6040
#define IDI_ENCSIGN_FILE_48_PNG 0x6050
#define IDI_SIGN_48_PNG 0x6060
#define IDI_VERIFY_48_PNG 0x6070
#define IDI_EMBLEM_WARNING_64_PNG 0x6071
#define IDI_EMBLEM_QUESTION_64_PNG 0x6074
#define IDI_SIGN_ENCRYPT_40_PNG 0x6075
#define IDI_ENCRYPT_20_PNG 0x6076
#define IDI_SIGN_20_PNG 0x6077
+#define IDI_GPGOL_LOCK_ICON 0x6078
/* Status icons */
#define ENCRYPT_ICON_OFFSET 0x10
#define IDI_LEVEL_0 0x6080
#define IDI_LEVEL_1 0x6081
#define IDI_LEVEL_2 0x6082
#define IDI_LEVEL_3 0x6083
#define IDI_LEVEL_4 0x6084
#define IDI_LEVEL_0_ENC (IDI_LEVEL_0 + ENCRYPT_ICON_OFFSET)
#define IDI_LEVEL_1_ENC (IDI_LEVEL_1 + ENCRYPT_ICON_OFFSET)
#define IDI_LEVEL_2_ENC (IDI_LEVEL_2 + ENCRYPT_ICON_OFFSET)
#define IDI_LEVEL_3_ENC (IDI_LEVEL_3 + ENCRYPT_ICON_OFFSET)
#define IDI_LEVEL_4_ENC (IDI_LEVEL_4 + ENCRYPT_ICON_OFFSET)
#endif /*DIALOGS_H*/
diff --git a/src/dialogs.rc b/src/dialogs.rc
index 71409da..aab9831 100644
--- a/src/dialogs.rc
+++ b/src/dialogs.rc
@@ -1,375 +1,377 @@
/* dialogs.rc - GpgOL dialog resources. -*- c -*-
* Copyright (C) 2004, 2005, 2006, 2007 g10 Code GmbH
*
* This file is part of GpgOL.
*
* GpgOL is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* GpgOL 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, see .
*/
#include "dialogs.h"
#include "config.h"
#include "afxres.h"
IDB_ENCRYPT_16 BITMAP DISCARDABLE "icons/encrypt-16.bmp"
IDB_ENCRYPT_16M BITMAP DISCARDABLE "icons/encrypt-16m.bmp"
IDI_ENCRYPT_16_PNG RCDATA "icons/encrypt-16.png"
IDI_ENCRYPT_48_PNG RCDATA "icons/encrypt-48.png"
IDB_SIGN_16 BITMAP DISCARDABLE "icons/sign-16.bmp"
IDB_SIGN_16M BITMAP DISCARDABLE "icons/sign-16m.bmp"
IDI_SIGN_48_PNG RCDATA "icons/sign-48.png"
IDB_KEY_MANAGER_16 BITMAP DISCARDABLE "icons/key-manager-16.bmp"
IDB_KEY_MANAGER_16M BITMAP DISCARDABLE "icons/key-manager-16m.bmp"
IDI_KEY_MANAGER_64_PNG RCDATA "icons/key-manager-64.png"
IDB_DECRYPT_16 BITMAP DISCARDABLE "icons/decrypt-16.bmp"
IDB_DECRYPT_16M BITMAP DISCARDABLE "icons/decrypt-16m.bmp"
IDI_DECRYPT_16_PNG RCDATA "icons/decrypt-16.png"
IDI_DECRYPT_48_PNG RCDATA "icons/decrypt-48.png"
IDB_VERIFY_16 BITMAP DISCARDABLE "icons/verify-16.bmp"
IDB_VERIFY_16M BITMAP DISCARDABLE "icons/verify-16m.bmp"
IDI_VERIFY_48_PNG RCDATA "icons/verify-48.png"
IDB_DECRYPT_VERIFY_16 BITMAP DISCARDABLE "icons/decrypt-verify-16.bmp"
IDB_DECRYPT_VERIFY_16M BITMAP DISCARDABLE "icons/decrypt-verify-16m.bmp"
IDI_ENCSIGN_FILE_48_PNG RCDATA "icons/encrypt-sign-file-48.png"
IDI_LEVEL_0_ENC RCDATA "icons/level-0-enc.png"
IDI_LEVEL_1_ENC RCDATA "icons/level-1-enc.png"
/* We use the same icon for level 2 and 3 */
IDI_LEVEL_2_ENC RCDATA "icons/level-3-enc.png"
IDI_LEVEL_3_ENC RCDATA "icons/level-3-enc.png"
IDI_LEVEL_4_ENC RCDATA "icons/level-4-enc.png"
IDI_LEVEL_0 RCDATA "icons/level-0.png"
IDI_LEVEL_1 RCDATA "icons/level-1.png"
IDI_LEVEL_2 RCDATA "icons/level-3.png"
IDI_LEVEL_3 RCDATA "icons/level-3.png"
IDI_LEVEL_4 RCDATA "icons/level-4.png"
IDI_SIGN_ENCRYPT_40_PNG RCDATA "icons/sign-enc-40.png"
IDI_ENCRYPT_20_PNG RCDATA "icons/encrypt-20.png"
IDI_SIGN_20_PNG RCDATA "icons/sign-20.png"
+IDI_GPGOL_LOCK_ICON ICON DISCARDABLE "icons/lock.ico"
+
IDB_LOGO BITMAP DISCARDABLE "icons/logo.bmp"
IDD_GPG_OPTIONS DIALOG DISCARDABLE 0, 0, 266, 274
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "GpgOL"
FONT 8, "MS Sans Serif"
BEGIN
/* General options box. */
GROUPBOX "general-options", IDC_G_GENERAL,
9, 9, 250, 25
CONTROL "enable-smime", IDC_ENABLE_SMIME,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 19, 215, 10
/* Send options box. */
GROUPBOX "send-options", IDC_G_SEND,
9, 40, 250, 38
CONTROL "encrypt-by-default", IDC_ENCRYPT_DEFAULT,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 50, 215, 10
CONTROL "sign-by-default", IDC_SIGN_DEFAULT,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 61, 215, 10
/* Receive options box. */
GROUPBOX "recv-options", IDC_G_RECV,
9, 82, 250, 36
/* We have no reliable way to detect the preview window, thus we
don't show this option. */
/* CONTROL "preview-decrypt", IDC_PREVIEW_DECRYPT, */
/* "Button", BS_AUTOCHECKBOX | WS_TABSTOP, */
/* 24, 114, 215, 10 */
CONTROL "prefer-html", IDC_PREFER_HTML,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 94, 215, 10
CONTROL "body-as-attachment", IDC_BODY_AS_ATTACHMENT,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 103, 215, 10
/* Stuff at the lower left corner. */
LTEXT "GpgOL by g10 Code GmbH", IDC_G10CODE_STRING,
8, 229, 100, 8
LTEXT "Version x ", IDC_VERSION_INFO,
8, 240, 100, 9
/* No more logo due to problems with the background colour. */
/* CONTROL IDB_BANNER, IDC_BITMAP, */
/* "Static", SS_BITMAP | SS_REALSIZEIMAGE, */
/* 8, 212, 150, 64 */
PUSHBUTTON "advanced", IDC_GPG_OPTIONS,
130, 240, 50, 14
PUSHBUTTON "gpgconf", IDC_GPG_CONF,
190, 240, 70, 14
END
IDD_EXT_OPTIONS DIALOG DISCARDABLE 0, 0, 155, 70
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "GpgOL - Debug Options"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "debug-logfile", IDC_T_DEBUG_LOGFILE,
8, 10, 122, 8
EDITTEXT IDC_DEBUG_LOGFILE,
8, 20, 138, 12, ES_AUTOHSCROLL
DEFPUSHBUTTON "&OK", IDOK,
90, 50, 50, 14
END
/*
The dialog to select recipient keys
*/
IDD_ENC DIALOG DISCARDABLE 0, 0, 332, 215
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "GpgOL - Select Recipients"
FONT 8, "MS Sans Serif"
BEGIN
CONTROL "List1", IDC_ENC_RSET1,
"SysListView32", LVS_REPORT | LVS_NOSORTHEADER |
WS_BORDER | WS_TABSTOP,
8, 4, 314, 92
LTEXT "Ausgewählte Empfänger:", IDC_ENC_RSET2_T,
8, 98, 130, 8
CONTROL "List2", IDC_ENC_RSET2,
"SysListView32", LVS_REPORT | LVS_NOSORTHEADER |
WS_BORDER | WS_TABSTOP,
8, 110, 313, 49
LTEXT "Recipient which were NOT found", IDC_ENC_NOTFOUND_T,
8, 161, 128, 8
LISTBOX IDC_ENC_NOTFOUND,
8, 170, 313, 22, LBS_SORT | LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
DEFPUSHBUTTON "&OK", IDOK,
221, 196, 50, 14
PUSHBUTTON "&Cancel-btn", IDCANCEL,
273, 196, 50, 14
END
/*
The decryption dialog used to select the secret key.
*/
IDD_DEC DIALOG DISCARDABLE 0, 0, 225, 101
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Secret Key Selection"
FONT 8, "MS Sans Serif"
BEGIN
COMBOBOX IDC_DEC_KEYLIST,
9, 7, 209, 58, CBS_DROPDOWNLIST | WS_VSCROLL |
WS_TABSTOP
LTEXT "", IDC_DEC_HINT,
9, 25, 201, 10
LTEXT "enter-passphrase", IDC_DEC_PASSINF,
9, 37, 158, 8
EDITTEXT IDC_DEC_PASS,
9, 51, 207, 12, ES_PASSWORD | ES_AUTOHSCROLL
CONTROL "&Hide Typing", IDC_DEC_HIDE,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
138, 64, 81, 10
DEFPUSHBUTTON "&OK", IDOK,
115, 83, 50, 14
PUSHBUTTON "&Cancel-btn", IDCANCEL,
167, 83, 50, 14
END
/*
The extended decryption dialog used to select the secret key.
*/
IDD_DECEXT DIALOG DISCARDABLE 0, 0, 207, 134
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "GpgOL - Secret Key Selection"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "encrypted-to",IDC_DECEXT_RSET_T,
7, 4, 128, 8
LISTBOX IDC_DECEXT_RSET,
7, 16, 193, 25, LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_DECEXT_KEYLIST,
8, 54, 191, 14, CBS_DROPDOWN | CBS_SORT |
WS_DISABLED | WS_VSCROLL | WS_TABSTOP
LTEXT "", IDC_DECEXT_HINT,
7, 73, 193, 8
LTEXT "enter-passphrase", IDC_DECEXT_PASSINF,
7, 85, 158, 8
EDITTEXT IDC_DECEXT_PASS,
7, 96, 192, 12, ES_PASSWORD | ES_AUTOHSCROLL
CONTROL "hide-typing", IDC_DECEXT_HIDE,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
122, 108, 81, 10
DEFPUSHBUTTON "OK", IDOK,
98, 125, 50, 14
PUSHBUTTON "&Cancel-btn", IDCANCEL,
149, 125, 50, 14
END
/*
The dialog to display verification results.
*/
IDD_VRY DIALOG DISCARDABLE 0, 0, 253, 116
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
CAPTION "GpgOL - Signature Verification Result"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "made-at", IDC_VRY_TIME_T,
3, 6, 50, 8
EDITTEXT IDC_VRY_TIME,
55, 4, 76, 12, ES_AUTOHSCROLL | ES_READONLY
LTEXT "using", IDC_VRY_PKALGO_T,
132, 6, 18, 8
EDITTEXT IDC_VRY_PKALGO,
152, 4, 20, 12, ES_AUTOHSCROLL | ES_READONLY
LTEXT "key-id", IDC_VRY_KEYID_T,
174, 7, 50, 8
EDITTEXT IDC_VRY_KEYID,
196, 4, 51, 12, ES_AUTOHSCROLL | ES_READONLY
EDITTEXT IDC_VRY_STATUS,
3, 29, 92, 12, ES_AUTOHSCROLL | ES_READONLY
LTEXT "from", IDC_VRY_ISSUER_T,
98, 31, 14, 8
EDITTEXT IDC_VRY_ISSUER,
117, 29, 131, 13, ES_AUTOHSCROLL | ES_READONLY
LTEXT "aka", IDC_VRY_AKALIST_T,
3, 47, 56, 8
LISTBOX IDC_VRY_AKALIST,
3, 56, 245, 25, LBS_SORT | LBS_NOINTEGRALHEIGHT |
WS_VSCROLL | WS_TABSTOP
LTEXT "", IDC_VRY_HINT,
3, 83, 245, 10
DEFPUSHBUTTON "&OK", IDOK,
198, 96, 50, 14
END
IDD_ADDIN_OPTIONS DIALOGEX DISCARDABLE 300, 300, 286, 190
STYLE DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | DS_SHELLFONT | DS_SETFONT
CAPTION "GpgOL"
FONT 8, "MS Shell Dlg"
BEGIN
/* General options box. */
#ifdef MIME_SEND
GROUPBOX "general-options", IDC_G_GENERAL,
9, 9, 270, 25
#else
GROUPBOX "general-options", IDC_G_GENERAL,
9, 9, 270, 35
#endif
CONTROL "enable-smime", IDC_ENABLE_SMIME,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 19, 235, 10
#ifndef MIME_SEND
CONTROL "enable-mime-ui", IDC_MIME_UI,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 29, 235, 10
#endif
/* Send options box. */
GROUPBOX "send-options", IDC_G_SEND,
9, 50, 270, 67
CONTROL "encrypt-by-default", IDC_ENCRYPT_DEFAULT,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 60, 235, 10
CONTROL "sign-by-default", IDC_SIGN_DEFAULT,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 71, 235, 10
CONTROL "inline-pgp", IDC_INLINE_PGP,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 82, 235, 10
CONTROL "replycrypt", IDC_REPLYCRYPT,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 93, 235, 10
CONTROL "autoresolve", IDC_AUTORRESOLVE,
"Button", BS_AUTOCHECKBOX | WS_TABSTOP,
24, 104, 235, 10
/* Stuff at the lower left corner. */
CONTROL IDB_LOGO, IDC_BITMAP,
"Static", SS_BITMAP | SS_REALSIZEIMAGE,
10, 125, 128, 80
LTEXT "Version x ", IDC_VERSION_INFO,
10, 175, 100, 9
PUSHBUTTON "advanced", IDC_GPG_OPTIONS,
180, 140, 90, 14
PUSHBUTTON "gpgconf", IDC_GPG_CONF,
180, 155, 90, 14
DEFPUSHBUTTON "&OK", IDOK,
180, 170, 90, 14
END
diff --git a/src/icons/Makefile.am b/src/icons/Makefile.am
index 71cf74c..9eaec10 100644
--- a/src/icons/Makefile.am
+++ b/src/icons/Makefile.am
@@ -1,34 +1,34 @@
# Makefile.am - makefile for GPGol icons
# Copyright (C) 2016 Bundesamt für Sicherheit in der Informationstechnik
# Software engineering by Intevation GmbH
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
## Process this file with automake to produce Makefile.in
EXTRA_DIST= \
encrypt-16.bmp encrypt-16m.bmp \
sign-16.bmp sign-16m.bmp \
key-manager-16.bmp key-manager-16m.bmp \
decrypt-16.bmp decrypt-16m.bmp \
verify-16.bmp verify-16m.bmp \
decrypt-verify-16.bmp decrypt-verify-16m.bmp \
encrypt-16.png encrypt-48.png \
key-manager-64.png \
decrypt-16.png decrypt-48.png \
encrypt-sign-file-48.png \
sign-48.png verify-48.png \
README.icons\
sign.svg sign-enc.svg encrypt.svg \
sign-enc-40.png sign-20.png encrypt-20.png \
level-0.svg level-0-enc.svg level-0.png level-0-enc.png \
level-1.svg level-1-enc.svg level-1.png level-1-enc.png \
level-2.svg level-2-enc.svg level-2.png level-2-enc.png \
level-3.svg level-3-enc.svg level-3.png level-3-enc.png \
level-4.svg level-4-enc.svg level-4.png level-4-enc.png \
- logo.svg logo.bmp
+ logo.svg logo.bmp lock.ico
diff --git a/src/icons/lock.ico b/src/icons/lock.ico
new file mode 100644
index 0000000..e721db7
Binary files /dev/null and b/src/icons/lock.ico differ