[Winpt-commits] r181 - trunk/Src
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Tue Mar 14 12:01:38 CET 2006
Author: twoaday
Date: 2006-03-14 12:01:22 +0100 (Tue, 14 Mar 2006)
New Revision: 181
Added:
trunk/Src/wptHTTP.cpp
trunk/Src/wptSafeEditCtrl.cpp
Removed:
trunk/Src/wptHTTP.c
Modified:
trunk/Src/ChangeLog
trunk/Src/Makefile.am
trunk/Src/WinPT-en.rc
trunk/Src/WinPT.cpp
trunk/Src/resource.h
trunk/Src/wptClipVerifyDlg.cpp
trunk/Src/wptCommonDlg.cpp
trunk/Src/wptGPG.cpp
trunk/Src/wptGPGME.cpp
trunk/Src/wptGPGPrefsDlg.cpp
trunk/Src/wptGPGUtil.cpp
trunk/Src/wptKeyCache.cpp
trunk/Src/wptKeyEdit.cpp
trunk/Src/wptKeyEditCB.cpp
trunk/Src/wptKeyEditDlgs.cpp
trunk/Src/wptKeyManager.cpp
trunk/Src/wptKeyManagerDlg.cpp
trunk/Src/wptKeyPropsDlg.cpp
trunk/Src/wptKeylist.cpp
trunk/Src/wptKeyserver.cpp
trunk/Src/wptKeyserverDlg.cpp
trunk/Src/wptKeysignDlg.cpp
trunk/Src/wptListView.cpp
trunk/Src/wptPassphraseCB.cpp
trunk/Src/wptPassphraseDlg.cpp
trunk/Src/wptPreferencesDlg.cpp
trunk/Src/wptRegistry.cpp
trunk/Src/wptSymEnc.cpp
trunk/Src/wptUTF8.cpp
trunk/Src/wptW32API.cpp
Log:
2006-03-12 Timo Schulz <ts at g10code.de>
* wptGPG.cpp (gnupg_load_config): Search for 'ask-cert-expire'.
* wptKeyPropsDlg.cpp (display_key_info): Automatically update
sym algorithm preferences if needed.
* wptKeysignDlg.cpp (date_is_today): New.
(keysign_dlg_proc): Only allow to set cert expire date if
the option was found.
* wptGPGPrefsDlg.cpp (gpgprefs_dlg_proc): Allow to set
'ask-cert-expire'.
Modified: trunk/Src/ChangeLog
===================================================================
--- trunk/Src/ChangeLog 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/ChangeLog 2006-03-14 11:01:22 UTC (rev 181)
@@ -1,3 +1,52 @@
+2006-03-12 Timo Schulz <ts at g10code.de>
+
+ * wptGPG.cpp (gnupg_load_config): Search for 'ask-cert-expire'.
+ * wptKeyPropsDlg.cpp (display_key_info): Automatically update
+ sym algorithm preferences if needed.
+ * wptKeysignDlg.cpp (date_is_today): New.
+ (keysign_dlg_proc): Only allow to set cert expire date if
+ the option was found.
+ * wptGPGPrefsDlg.cpp (gpgprefs_dlg_proc): Allow to set
+ 'ask-cert-expire'.
+
+2006-03-10 Timo Schulz <ts at g10code.de>
+
+ * wptHTTP.c: deleted.
+ * wptHTTP.cpp (wHTTP): Transformed old code into an object.
+ * wptKeyManager.cpp (km_http_import): Use new code.
+ (km_refresh_one_key): Use preferred keyserver if possible.
+ * wptComonDlg.cpp (check_URL): Better conformance checking.
+ * wptKeyEditCB.cpp (cmd_keyserver_handler): By default
+ set keyserver for all userids.
+ * wptKeyManagerDlg.cpp (keymanager_dlg_proc): Enable code
+ to set preferred keyserver.
+ * wptKeyCache.cpp (decode_subpacket): New.
+ (gpg_keycache_update_attr): New.
+ * wptGPGUtil.cpp (gpg_find_key_subpacket): New.
+ * wptKeyEditDlgs.cpp (keyedit_set_pref_keyserver): Use
+ -1 as an index for all userids.
+
+2006-03-07 Timo Schulz <ts at g10code.de>
+
+ * WinPT.cpp (set_default_keyserver): New.
+ * wptKeyserver.cpp (kserver_set_socket_timeout): New.
+ (kserver_set_default_keyserver): Initialize default settings
+ if needed.
+ * wptSymEnc.cpp (gpg_encrypt_symmetric): Disallow empty passwords.
+ * wptPassphraseDlg.cpp (request_passphrase): Handle new flag.
+ (passphrase_dlg_proc): Support new safe edit window procedure.
+ * wptPassphraseCB.cpp (passphrase_callback_proc): Likewise.
+ * wptPreferencesDlg.cpp (prefs_dlg_proc): Flush passphrase cache
+ if user disable it.
+ * wptKeylist.cpp (keylist_build): Do not scale images but use
+ original size.
+ * wptListView.cpp (listview_set_image_list): New size params.
+ Change all callers.
+
+2006-03-01 Timo Schulz <ts at g10code.de>
+
+ * wptW32API.cpp (set_clip_text): Free all memory.
+
2006-02-27 Timo Schulz <twoaday at freakmail.de>
* wptSOCKS.cpp (socks_handshake): New.
Modified: trunk/Src/Makefile.am
===================================================================
--- trunk/Src/Makefile.am 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/Makefile.am 2006-03-14 11:01:22 UTC (rev 181)
@@ -89,7 +89,7 @@
wptGPGME.cpp \
wptGPGParser.cpp \
wptHotkey.cpp \
- wptHTTP.c \
+ wptHTTP.cpp \
wptImagelist.cpp \
wptImportList.cpp \
wptKeylist.cpp \
@@ -120,7 +120,8 @@
wptGPGMEData.cpp \
wptGroupManager.cpp \
wptGPGMEWrapper.cpp \
- wptSOCKS.cpp
+ wptSOCKS.cpp \
+ wptSafeEditCtrl.cpp
WinPT_SOURCES = $(resource_files) $(dialog_files) $(code_files)
Modified: trunk/Src/WinPT-en.rc
===================================================================
--- trunk/Src/WinPT-en.rc 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/WinPT-en.rc 2006-03-14 11:01:22 UTC (rev 181)
@@ -337,8 +337,8 @@
CONTROL "List1",IDC_KEYSERVER_LIST,"SysListView32",LVS_REPORT |
LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_SORTASCENDING |
WS_BORDER | WS_TABSTOP,6,5,208,133
- LTEXT "HTTP proxy: none",IDC_KEYSERVER_PROXY,6,145,146,9
- PUSHBUTTON "C&hange",IDC_KEYSERVER_PROXSETT,168,145,46,10
+ LTEXT "Proxy: none",IDC_KEYSERVER_PROXY,6,145,146,9
+ PUSHBUTTON "C&hange",IDC_KEYSERVER_PROXSETT,168,142,46,13
GROUPBOX "",IDC_STATIC,5,157,209,36
LTEXT "Please enter the key ID or email address you search for",
IDC_KEYSERVER_INFO,8,165,199,8
@@ -476,39 +476,42 @@
PUSHBUTTON "&Cancel",IDCANCEL,227,188,54,15
END
-IDD_WINPT_GPGPREFS DIALOG DISCARDABLE 0, 0, 222, 226
+IDD_WINPT_GPGPREFS DIALOG DISCARDABLE 0, 0, 222, 242
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "GnuPG Preferences"
FONT 8, "MS Sans Serif"
BEGIN
- GROUPBOX "",IDC_STATIC,5,4,208,67
LTEXT "GnuPG home directory (where both keyrings are located)",
- IDC_GPGPREFS_HOMEINF,12,12,181,8
+ IDC_GPGPREFS_HOMEINF,12,12,196,8
EDITTEXT IDC_GPGPREFS_HOMEDIR,12,22,152,12,ES_AUTOHSCROLL
PUSHBUTTON "Browse...",IDC_GPGPREFS_HOMEDLG,167,21,41,14
LTEXT "GnuPG exe file location (full path with added gpg.exe)",
- IDC_GPGPREFS_EXEINF,12,41,170,8
+ IDC_GPGPREFS_EXEINF,12,41,192,8
EDITTEXT IDC_GPGPREFS_EXEDIR,12,52,152,12,ES_AUTOHSCROLL
PUSHBUTTON "Browse...",IDC_GPGREFS_EXEDLG,167,51,41,14
+ GROUPBOX "",IDC_STATIC,5,4,208,67
GROUPBOX "",IDC_STATIC,6,76,209,37
LTEXT "Locale directory (to access the translation files)",
- IDC_GPGPREFS_LOCALINF,12,85,148,8
+ IDC_GPGPREFS_LOCALINF,12,85,180,8
EDITTEXT IDC_GPGPREFS_LOCALE,12,96,152,12,ES_AUTOHSCROLL
PUSHBUTTON "Browse...",IDC_GPGPREFS_LOCDLG,167,95,41,14
CONTROL "&Overwrite default settings",IDC_GPGPREFS_OVRDEFAULT,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,6,115,121,10
GROUPBOX "General GPG options",IDC_GPGPREFS_ALLOPTINF,5,130,210,
- 74
+ 86
CONTROL "Ask for the signature class during key sign",
IDC_GPGPREFS_ASKLEVEL,"Button",BS_AUTOCHECKBOX |
- WS_TABSTOP,11,144,166,10
- LTEXT "Comment in armored files",IDC_GPGPREFS_CMTINF,11,157,
+ WS_TABSTOP,11,144,189,10
+ CONTROL "Allow to set an expiration date for signatures",
+ IDC_GPGPREFS_ASKEXPIRE,"Button",BS_AUTOCHECKBOX |
+ WS_TABSTOP,11,156,188,9
+ LTEXT "Comment in armored files",IDC_GPGPREFS_CMTINF,11,170,
124,8
- EDITTEXT IDC_GPGPREFS_COMMENT,11,168,188,12,ES_AUTOHSCROLL
- LTEXT "Encrypt to this key",IDC_GPGPREFS_ENCINF,11,187,66,8
- EDITTEXT IDC_GPGPREFS_ENCTO,78,185,121,13,ES_AUTOHSCROLL
- PUSHBUTTON "&OK",IDC_GPGPREFS_SAVE,101,207,55,14
- PUSHBUTTON "&Cancel",IDCANCEL,159,206,55,14
+ EDITTEXT IDC_GPGPREFS_COMMENT,11,181,188,12,ES_AUTOHSCROLL
+ LTEXT "Encrypt to this key",IDC_GPGPREFS_ENCINF,11,200,66,8
+ EDITTEXT IDC_GPGPREFS_ENCTO,78,198,121,13,ES_AUTOHSCROLL
+ PUSHBUTTON "&OK",IDC_GPGPREFS_SAVE,101,223,55,14
+ PUSHBUTTON "&Cancel",IDCANCEL,159,223,55,14
END
IDD_WINPT_IMPORT DIALOG DISCARDABLE 0, 0, 321, 118
@@ -1513,7 +1516,7 @@
LEFTMARGIN, 3
RIGHTMARGIN, 215
TOPMARGIN, 4
- BOTTOMMARGIN, 221
+ BOTTOMMARGIN, 237
END
IDD_WINPT_IMPORT, DIALOG
@@ -2182,7 +2185,7 @@
MENUITEM "&Disable", ID_KEYCTX_DISABLE
MENUITEM "Set Implicit &Trust", ID_KEYCTX_MAXTRUST, GRAYED
MENUITEM SEPARATOR
- MENUITEM "Set preferred Keyserver URL", ID_KEYCTX_SETPREFKS, GRAYED
+ MENUITEM "Set preferred Keyserver", ID_KEYCTX_SETPREFKS
MENUITEM "Re&fresh from Keyserver", ID_KEYCTX_RECVFROM
POPUP "Send to Keyserver"
BEGIN
Modified: trunk/Src/WinPT.cpp
===================================================================
--- trunk/Src/WinPT.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/WinPT.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -70,7 +70,8 @@
/* Set GPGME debug mode. If @val is 0, the debug mode is disabled. */
void
gpg_set_debug_mode (int val)
-{
+{
+ /* XXX: create the file in $user\$temp */
if (val)
putenv ("GPGME_DEBUG=5:gpgme.dbg");
else
@@ -376,6 +377,25 @@
}
+void
+set_default_keyserver (void)
+{
+ char *host = get_reg_entry_keyserver ("Default");
+ char *str_port = get_reg_entry_keyserver ("Default_Port");
+ WORD port = HKP_PORT;
+
+ if (!host)
+ keyserver_set_default (NULL, 0);
+ else {
+ if (str_port && *str_port)
+ port = atoi (str_port);
+ keyserver_set_default (host, port);
+ }
+ free_if_alloc (host);
+ free_if_alloc (str_port);
+}
+
+
/* Main entry point. */
int WINAPI
WinMain (HINSTANCE hinst, HINSTANCE hprev, LPSTR cmdline, int showcmd)
@@ -451,7 +471,7 @@
mobile = 1;
}
- set_default_kserver ();
+ set_default_keyserver ();
load_gettext (winpt_inst_found);
if (!mobile) {
Modified: trunk/Src/resource.h
===================================================================
--- trunk/Src/resource.h 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/resource.h 2006-03-14 11:01:22 UTC (rev 181)
@@ -641,6 +641,7 @@
#define IDC_PROXY_PROTOINF 1516
#define IDC_PROXY_PROTO 1517
#define IDC_PROXY_AUTHINF 1518
+#define IDC_GPGPREFS_ASKEXPIRE 1520
#define ID_GPG_ENCRYPT 40003
#define ID_GPG_DECRYPT 40004
#define ID_GPG_SIGN 40005
@@ -821,7 +822,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 245
#define _APS_NEXT_COMMAND_VALUE 40186
-#define _APS_NEXT_CONTROL_VALUE 1519
+#define _APS_NEXT_CONTROL_VALUE 1521
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif
Modified: trunk/Src/wptClipVerifyDlg.cpp
===================================================================
--- trunk/Src/wptClipVerifyDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptClipVerifyDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -149,7 +149,7 @@
gpg_keycache_t kc = NULL;
gpgme_ctx_t c=NULL;
const char *det_data=NULL;
- u16 port = HKP_PORT;
+ WORD port = HKP_PORT;
int rc = 0, det_len=0;
switch( msg ) {
Modified: trunk/Src/wptCommonDlg.cpp
===================================================================
--- trunk/Src/wptCommonDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptCommonDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -1,5 +1,5 @@
/* wptCommonDlg.cpp
- * Copyright (C) 2004, 2005 Timo Schulz
+ * Copyright (C) 2004, 2005, 2006 Timo Schulz
*
* This file is part of WinPT.
*
@@ -22,6 +22,7 @@
#endif
#include <windows.h>
+#include <ctype.h>
#include "resource.h"
@@ -37,11 +38,25 @@
static int
check_URL (const char *buf)
{
- /* XXX: be more strict */
+ size_t i;
+ const char *allowed = "-./#_:";
+
+ if (strncmp (buf, "http://", 7))
+ return -1;
if (!strchr (buf, ':'))
return -1;
if (!strstr (buf, "//"))
return -1;
+ if (strstr (buf, " "))
+ return -1;
+ buf += 7;
+ for (i=0; i < strlen (buf); i++) {
+ if (isalpha (buf[i]) || isdigit (buf[i]))
+ continue;
+ if (!strchr (allowed, buf[i]))
+ return -1;
+ }
+
return 0;
}
@@ -59,12 +74,8 @@
BUG (0);
if (ctx->desc != NULL)
SetWindowText (dlg, ctx->desc);
- else
- SetWindowText (dlg, _("HTTP Key Import"));
if (ctx->title != NULL)
SetDlgItemText (dlg, IDC_HTTP_TITLE, ctx->title);
- else
- SetDlgItemText (dlg, IDC_HTTP_TITLE, _("Enter URL to retrieve the public key"));
SetDlgItemText (dlg, IDCANCEL, _("&Cancel"));
SetForegroundWindow (dlg);
break;
@@ -103,7 +114,9 @@
if (!ctx)
BUG (0);
memset (ctx, 0, sizeof *ctx);
- ctx->check = 1;
+ ctx->check = 1;
+ ctx->desc = _("HTTP Key Import");
+ ctx->title = _("Enter URL to retrieve the public key");
DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_HTTP, root,
http_dlg_proc, (LPARAM)ctx);
return ctx;
Modified: trunk/Src/wptGPG.cpp
===================================================================
--- trunk/Src/wptGPG.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptGPG.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -243,6 +243,9 @@
o = find_option (opt, "ask-cert-level");
if (o)
reg_prefs.gpg.ask_cert_level = 1;
+ o = find_option (opt, "ask-cert-expire");
+ if (o)
+ reg_prefs.gpg.ask_cert_expire = 1;
release_gpg_options (opt);
free_if_alloc (conf);
return 0;
Modified: trunk/Src/wptGPGME.cpp
===================================================================
--- trunk/Src/wptGPGME.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptGPGME.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -123,10 +123,10 @@
p = get_reg_entry (HKEY_CURRENT_USER, "Software\\WinPT", "nKeys");
if (p && *p != ' ') {
val = atoi (p);
- free_if_alloc (p);
- memset (&pfx, 0, sizeof (pfx));
+ free_if_alloc (p);
}
+ memset (&pfx, 0, sizeof (pfx));
/* Release old contexts first. */
keycache_release (0);
@@ -141,7 +141,7 @@
if (!err)
err = gpg_keycache_init (sec, NULL, 1);
if (!err && pubring && *pubring)
- err = gpg_keycache_prepare( pub, pubring, NULL);
+ err = gpg_keycache_prepare (pub, pubring, NULL);
if (!err && secring && * secring)
err = gpg_keycache_prepare (sec, NULL, secring);
if (!err)
@@ -177,7 +177,7 @@
*r_key = NULL;
cache = keycache_get_ctx (mode);
if (!cache)
- BUG( NULL );
+ BUG (0);
if (!c)
err = gpg_keycache_find_key (cache, keyid, 0, r_key);
else
Modified: trunk/Src/wptGPGPrefsDlg.cpp
===================================================================
--- trunk/Src/wptGPGPrefsDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptGPGPrefsDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -146,6 +146,7 @@
SetDlgItemText ( dlg, IDC_GPGPREFS_LOCALINF,
_("Locale directory (to access the translation files)"));
SetDlgItemText (dlg, IDC_GPGPREFS_ASKLEVEL, _("Ask for the signature class during key sign"));
+ SetDlgItemText (dlg, IDC_GPGPREFS_ASKEXPIRE, _("Allow to set an expiration date for signatures"));
SetDlgItemText (dlg, IDC_GPGPREFS_CMTINF, _("Comment in armored files"));
SetDlgItemText (dlg, IDC_GPGPREFS_ENCINF, _("Encrypt to this key"));
SetDlgItemText (dlg, IDC_GPGPREFS_ALLOPTINF, _("General GPG options"));
@@ -166,6 +167,8 @@
parse_gpg_options (p, &opt);
free_if_alloc (p);
if (opt) {
+ if (find_option (opt, "ask-cert-expire"))
+ CheckDlgButton (dlg, IDC_GPGPREFS_ASKEXPIRE, BST_CHECKED);
if (find_option (opt, "ask-cert-level"))
CheckDlgButton (dlg, IDC_GPGPREFS_ASKLEVEL, BST_CHECKED);
e = find_option (opt, "comment");
@@ -271,6 +274,15 @@
delete_option (opt, "ask-cert-level");
reg_prefs.gpg.ask_cert_level = 0;
}
+ if (IsDlgButtonChecked (dlg, IDC_GPGPREFS_ASKEXPIRE)) {
+ modify_entry (opt, ENTRY_SINGLE, "ask-cert-expire", NULL);
+ reg_prefs.gpg.ask_cert_expire = 1;
+ }
+ else {
+ delete_option (opt, "ask-cert-expire");
+ reg_prefs.gpg.ask_cert_expire = 0;
+ }
+
n = GetDlgItemText(dlg, IDC_GPGPREFS_COMMENT, t, sizeof t - 1);
if (n > 0)
modify_entry (opt, ENTRY_MULTI, "comment", t);
Modified: trunk/Src/wptGPGUtil.cpp
===================================================================
--- trunk/Src/wptGPGUtil.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptGPGUtil.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -773,7 +773,7 @@
case PKT_SECRET_KEY:
quit = 1;
break;
-
+
default:
break;
}
@@ -804,3 +804,44 @@
err = file_extract_recipient (file, r_list);
return err;
}
+
+
+/* Try to find a subpacket with the given id @subpktid
+ inside the key @key.
+ Return value: 0 on success. */
+gpgme_error_t
+gpg_find_key_subpacket (const char *key, int subpktid,
+ char **value)
+{
+ gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
+ const char *fmt;
+ const char *spk;
+ char *p, *cmd;
+ HANDLE out;
+
+ *value = NULL;
+ p = read_gpg_program ();
+ fmt = "%s --with-colons --list-options show-sig-subpackets=%d --list-sigs %s";
+ cmd = (char*)calloc (1, strlen (fmt) + strlen (p) + strlen (key) + 32 + 1);
+ sprintf (cmd, fmt, p, subpktid, key);
+
+ out = create_tmpfile ("gpg_subpackets");
+ if (create_process (cmd, NULL, out, NULL))
+ err = gpg_error (GPG_ERR_INTERNAL);
+
+ free (p);
+ free (cmd);
+
+ p = map_tmpfile (out, NULL);
+ if (p && (spk=strstr (p, "spk"))) {
+ char *end = strstr (spk, "\n");
+ if (end) {
+ *value = (char*)calloc (1, (end-spk)+1);
+ memcpy (*value, spk, (end-spk)-1);
+ }
+ }
+
+ free (p);
+ CloseHandle (out);
+ return err;
+}
Deleted: trunk/Src/wptHTTP.c
===================================================================
--- trunk/Src/wptHTTP.c 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptHTTP.c 2006-03-14 11:01:22 UTC (rev 181)
@@ -1,496 +0,0 @@
-/* wptHTTP.c - Generic HTTP support
- * Copyright (C) 2004, 2005 Timo Schulz
- *
- * This file is part of WinPT.
- *
- * WinPT 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.
- *
- * WinPT 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 WinPT; if not, write to the Free Software Foundation,
- * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <windows.h>
-#include <ctype.h>
-#include <errno.h>
-
-#include "wptHTTP.h"
-#include "wptTypes.h"
-#include "wptErrors.h"
-
-
-static int parse_headers (int fd, http_head_t *r_head);
-
-
-static int
-http_head_new (http_head_t * head, const char * val)
-{
- http_head_t h;
-
- h = calloc (1, sizeof *h + strlen (val) + 1);
- if (!h)
- BUG (0);
- strcpy (h->d, val);
- *head = h;
- return 0;
-}
-
-
-static void
-http_head_free (http_head_t head)
-{
- http_head_t h;
-
- while (head) {
- h = head->next;
- free (head);
- head = h;
- }
-}
-
-
-static void
-http_head_add (http_head_t root, http_head_t node)
-{
- http_head_t n;
-
- for (n = root; n->next; n=n->next)
- ;
- n->next = node;
-}
-
-
-static http_head_t
-http_head_find (http_head_t root, const char * name,
- const char ** val)
-{
- http_head_t n;
-
- for (n = root; n; n = n->next) {
- if (strlen (n->d) >= strlen (name) &&
- !strncmp (n->d, name, strlen (name))) {
- *val = n->d + strlen (name);
- return n;
- }
- }
- return NULL;
-}
-
-
-static int
-http_connect (const char * host, int port, int * r_fd)
-{
- struct hostent * hp;
- struct sockaddr_in srv;
- unsigned long addr = 0;
- int i = 1;
- int fd;
-
- *r_fd = 0;
- memset (&srv, 0, sizeof srv);
- srv.sin_port = htons ((unsigned short)port);
- srv.sin_family = AF_INET;
-
- if (isalpha (*host)) {
- hp = gethostbyname (host);
- if (hp == NULL)
- return WPTERR_WINSOCK_CONNECT;
- memcpy (&srv.sin_addr, hp->h_addr, hp->h_length);
- }
- else {
- addr = inet_addr (host);
- if (addr == -1)
- return WPTERR_WINSOCK_CONNECT;
- memcpy (&srv.sin_addr, &addr, sizeof addr);
- }
-
- fd = socket (AF_INET, SOCK_STREAM, 0);
- if (fd < 0)
- return WPTERR_WINSOCK_SOCKET;
-
- if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&i, sizeof i)) {
- closesocket (fd);
- return WPTERR_WINSOCK_SOCKET;
- }
-
- if (connect (fd, (struct sockaddr *)&srv, sizeof srv)) {
- closesocket (fd);
- return WPTERR_WINSOCK_CONNECT;
- }
-
- *r_fd = fd;
- return 0;
-}
-
-
-static int
-http_close (int fd)
-{
- closesocket (fd);
- return 0;
-}
-
-
-static int
-http_data_avail (int fd)
-{
- struct timeval tv;
- fd_set inp;
- int n;
-
- FD_ZERO (&inp);
- FD_SET (fd, &inp);
- tv.tv_sec = 1;
- tv.tv_usec = 0;
-
- n = select (fd+1, &inp, NULL, NULL, &tv);
- if (n && FD_ISSET (fd, &inp))
- return n;
- return 0;
-}
-
-
-static int
-http_read_line (int fd, char * buf, size_t nbuf,
- int nonblock, int * nn, int * eof)
-{
- char c;
- int n, i;
-
- if (nn)
- *nn = 0;
- if (eof)
- *eof = 0;
- i = 0;
- do {
- if (nonblock == 1 && http_data_avail (fd) == 0) {
- buf[i++] = '\0';
- i = -1;
- break;
- }
- n = recv (fd, &c, 1, 0);
- if (n == -1)
- break;
- if (n == 0 || nbuf == 0 || c == '\n') {
- if (n == 0) {
- if (eof)
- *eof = 1;
- buf[i++] = '\0';
- }
- else {
- buf[i++] = c;
- buf[i] = '\0';
- }
- break;
- }
- else {
- buf[i++] = c;
- nbuf--;
- }
- } while (n > 0 && i != -1);
-
- if (nn)
- *nn = i;
- return 0;
-}
-
-
-static int
-http_send_req (int fd, const char * host, const char * url)
-{
- char * p;
- int n;
-
- if (*url == '/')
- url++;
- if (url == NULL)
- url = "";
- p = malloc (strlen (url) + strlen (host) + 64);
- if (p == NULL)
- BUG (0);
- sprintf (p, "GET /%s HTTP/1.1\r\n"
- "Host: %s\r\n"
- "\r\n"
- "\r\n",
- url, host);
- n = send (fd, p, strlen (p), 0);
- free (p);
- if (n == -1)
- return SOCKET_ERROR;
- return 0;
-}
-
-
-int
-http_send_request2 (const char * url, http_hd_t * r_hd)
-{
- http_hd_t hd;
- char * host = NULL, * p;
- char tmpbuf[512];
- int rc;
-
- memset (tmpbuf, 0, 512);
- strncpy (tmpbuf, url, 512);
-
- if (strlen (url) < 10 || strncmp (url, "http://", 7))
- return WPTERR_GENERAL;
- url += 7;
- p = strtok (tmpbuf+7, "/");
- if (p == NULL)
- return WPTERR_GENERAL;
- host = strdup (p);
- if (host == NULL)
- BUG (0);
- p = strchr (url, '/');
- if (p == NULL) {
- free (host);
- return WPTERR_GENERAL;
- }
- rc = http_send_request (host, 80, p+1, &hd);
- *r_hd = hd;
- free (host);
- return rc;
-}
-
-
-int
-http_send_request (const char * host, int port, const char * url,
- http_hd_t * r_hd)
-{
- http_hd_t hd;
- int rc;
-
- http_hd_new (&hd);
- rc = http_connect (host, port, &hd->fd);
- if (!rc)
- rc = http_send_req (hd->fd, host, url);
- if (r_hd)
- *r_hd = hd;
- else
- http_hd_free (hd);
- return rc;
-}
-
-
-int
-http_req_new (http_req_t * ctx)
-{
- http_req_t c;
- c = calloc (1, sizeof * c);
- if (c == NULL)
- BUG (0);
- *ctx = c;
- return 0;
-}
-
-
-void
-http_req_free (http_req_t ctx)
-{
- if (!ctx)
- return;
- http_head_free (ctx->head);
- if (ctx->url)
- free (ctx->url);
- free (ctx);
-}
-
-
-static int
-parse_statline (const char * buf, int * code)
-{
- int tmp = 0;
-
- if (strlen (buf) < 8 ||
- (strncmp (buf, "HTTP/1.", 7)))
- return WPTERR_GENERAL;
- buf += 8; /* skip HTTP/1.x */
- buf++; /* white space */
- tmp = atoi (buf);
- if (tmp == 0)
- return WPTERR_GENERAL;
- *code = tmp;
- buf += 3;
- buf++; /* whitespace */
- return 0;
-}
-
-
-static int
-parse_headers (int fd, http_head_t * r_head)
-{
- http_head_t h, head = NULL;
- char buf[300];
- int nn;
- int rc;
-
- do {
- rc = http_read_line (fd, buf, 299, 1, &nn, NULL);
- if (rc)
- return rc;
- if (nn == 2)
- break; /* reach empty line */
- http_head_new (&h, buf);
- if (head == NULL)
- head = h;
- else
- http_head_add (head, h);
- } while (rc == 0);
- if (r_head)
- *r_head = head;
- else
- http_head_free (head);
- return 0;
-}
-
-
-static int
-read_binary (int fd, int nlen, FILE * out)
-{
- char buf[1024+1];
- int n;
-
- do
- {
- n = recv (fd, buf, nlen > 1024? 1024 : nlen, 0);
- if (n == -1)
- return SOCKET_ERROR;
- if (n == 0)
- break;
- nlen -= n;
- fwrite (buf, 1, n, out);
- } while (nlen > 0);
- return 0;
-}
-
-
-static int
-parse_data (int fd, http_head_t head, FILE * out)
-{
- http_head_t h;
- const char * s = "Content-Length: ", * val;
- char buf[1024+1];
- int nlen = 0, nn = 0, n, eof=0;
- int rc;
-
- h = http_head_find (head, s, &val);
- if (h)
- nlen = atoi (val);
- else {
- h = http_head_find (head, "Connection: ", &val);
- if (h == NULL || strncmp (val, "close", 4))
- return WPTERR_GENERAL;
- }
-
- h = http_head_find (head, "Content-Type: ", &val);
- if (h == NULL)
- return WPTERR_GENERAL;
- if (strncmp (val, "text", 4))
- return read_binary (fd, nlen, out);
-
- do {
- rc = http_read_line (fd, buf, 1024, 1, &n, &eof);
- if (rc)
- return rc;
- if (n > 0)
- fwrite (buf, 1, n, out);
- if (nlen > 0) {
- nn += n;
- if (nlen == nn)
- break;
- }
- } while (eof == 0);
- return 0;
-}
-
-
-static int
-check_status (int code, int * statcode)
-{
- if (code != HTTP_STAT_200) {
- if (statcode)
- *statcode = code;
- if (code == HTTP_STAT_400 ||
- code == HTTP_STAT_403 ||
- code == HTTP_STAT_404 ||
- code == HTTP_STAT_405)
- return WPTERR_GENERAL;
- }
- return 0;
-}
-
-
-int
-http_parse_response (http_hd_t hd, int * statcode)
-{
- char buf[300];
- int rc;
- int code = 0, nn = 0;
-
- if (statcode)
- *statcode = 0;
- rc = http_read_line (hd->fd, buf, 299, 1, &nn, NULL);
- if (rc)
- return rc;
- rc = parse_statline (buf, &code);
- if (rc)
- return rc;
- rc = check_status (code, statcode);
- if (rc)
- return rc;
- rc = parse_headers (hd->fd, &hd->head);
- if (rc)
- return rc;
- return 0;
-}
-
-
-int
-http_parse_data (http_hd_t hd, FILE * out)
-{
- int rc = 0;
- rc = parse_data (hd->fd, hd->head, out);
- http_close (hd->fd);
- return rc;
-}
-
-
-int
-http_hd_new (http_hd_t * r_hd)
-{
- http_hd_t hd;
-
- if (!r_hd)
- return -1;
- hd = calloc (1, sizeof * hd);
- if (hd == NULL)
- abort ();
- *r_hd = hd;
- return 0;
-}
-
-
-void
-http_hd_free (http_hd_t hd)
-{
- if (!hd)
- return;
- http_head_free (hd->head);
- http_close (hd->fd);
- free (hd);
-}
Added: trunk/Src/wptHTTP.cpp
===================================================================
--- trunk/Src/wptHTTP.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptHTTP.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -0,0 +1,592 @@
+/* wptHTTP.cpp - Generic HTTP support
+ * Copyright (C) 2004, 2005, 2006 Timo Schulz
+ *
+ * This file is part of WinPT.
+ *
+ * WinPT 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.
+ *
+ * WinPT 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 WinPT; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <windows.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include "wptHTTP.h"
+#include "wptTypes.h"
+#include "wptErrors.h"
+
+#define free_if_malloc(buf) if ((buf)) { free ((buf)); (buf) = NULL; }
+
+/* Empty constructur to allow advanced requests. */
+wHTTP::wHTTP (void)
+{
+ reset ();
+}
+
+
+/* Constructur to allow alternative syntax. */
+wHTTP::wHTTP (const char *_host, int _port, const char *_url)
+{
+ reset ();
+ this->host = strdup (_host);
+ this->port = _port;
+ this->url = strdup (_url);
+ if (!sendRequest (_host, _port, _url))
+ parseResponse (&statcode);
+
+}
+
+
+/* Standard constructur. */
+wHTTP::wHTTP (const char *_url)
+{
+ reset ();
+ extractHostInfo (_url, &this->host, &this->url);
+ /* XXX: if the connection fails, return the error code to the user. */
+ if (!sendRequest (this->host, this->port, this->url))
+ parseResponse (&statcode);
+}
+
+
+/* Reset object contents for first use. */
+void
+wHTTP::reset (void)
+{
+ ver = 1;
+ port = 80;
+ host = url = NULL;
+ req_headers = resp_headers = NULL;
+ fd = statcode = 0;
+ method = HTTP_GET;
+ nleft = -1;
+}
+
+
+/* Perform a HTTP 'HEAD' request. */
+int
+wHTTP::head (const char *_url)
+{
+ free_if_malloc (host);
+ free_if_malloc (url);
+
+ extractHostInfo (_url, &this->host, &this->url);
+ method = HTTP_HEAD;
+
+ if (!sendRequest (host, port, url))
+ parseResponse (&statcode);
+
+ return 0;
+}
+
+
+/* Perform a HTTP 'GET' request. */
+int
+wHTTP::get (const char *_url)
+{
+ free_if_malloc (host);
+ free_if_alloc (url);
+
+ extractHostInfo (_url, &this->host, &this->url);
+
+ method = HTTP_GET;
+ if (!sendRequest (this->host, this->port, this->url))
+ parseResponse (&statcode);
+
+ return 0;
+}
+
+
+/* Return HTTP status code. */
+int
+wHTTP::getStatusCode (void)
+{
+ return statcode;
+}
+
+
+/* Return MIME content type. */
+const char*
+wHTTP::getContentType (void)
+{
+ const char *type = NULL;
+
+ findHeader (resp_headers, "Content-Type", &type);
+ return type;
+}
+
+
+/* Return content length. */
+unsigned int
+wHTTP::getContentLength (void)
+{
+ const char *len = NULL;
+
+ if (findHeader (resp_headers, "Content-Length", &len))
+ return strtoul (len, NULL, 10);
+ return 0;
+}
+
+
+void
+wHTTP::addHeader (http_head_t *root, const char *val)
+{
+ http_head_t n, t;
+
+ t = (http_head_t)calloc (1, sizeof *t+strlen (val)+2);
+ if (!t)
+ BUG (0);
+ strcpy (t->d, val);
+
+ if (!*root)
+ *root = t;
+ else {
+ for (n = *root; n->next; n=n->next)
+ ;
+ n->next = t;
+ }
+}
+
+
+bool
+wHTTP::findHeader (http_head_t root,
+ const char *name, const char **val)
+{
+ http_head_t n;
+ char *p;
+
+ *val = NULL;
+ for (n = root; n; n = n->next) {
+ if (strlen (n->d) >= strlen (name) &&
+ strstr (n->d, name)) {
+ p = strchr (n->d, ':');
+ *val = p? n->d + (p - n->d + 1 + 1) : NULL;
+ return true;
+ }
+ }
+ return false;
+}
+
+
+int
+wHTTP::connect (const char *_host, int _port)
+{
+ struct hostent *hp;
+ struct sockaddr_in srv;
+ unsigned long addr = 0;
+ int i = 1;
+
+ memset (&srv, 0, sizeof srv);
+ srv.sin_port = htons ((unsigned short)_port);
+ srv.sin_family = AF_INET;
+
+ if (isalpha (*_host)) {
+ hp = gethostbyname (_host);
+ if (!hp)
+ return WPTERR_WINSOCK_CONNECT;
+ memcpy (&srv.sin_addr, hp->h_addr, hp->h_length);
+ }
+ else {
+ addr = inet_addr (_host);
+ if (addr == INADDR_NONE)
+ return WPTERR_WINSOCK_CONNECT;
+ memcpy (&srv.sin_addr, &addr, sizeof addr);
+ }
+
+ fd = socket (AF_INET, SOCK_STREAM, 0);
+ if (fd < 0)
+ return WPTERR_WINSOCK_SOCKET;
+
+ if (setsockopt (fd, SOL_SOCKET, SO_REUSEADDR,
+ (const char*)&i, sizeof i)) {
+ closesocket (fd);
+ fd = 0;
+ return WPTERR_WINSOCK_SOCKET;
+ }
+
+ if (::connect (fd, (struct sockaddr *)&srv, sizeof srv)) {
+ closesocket (fd);
+ fd = 0;
+ return WPTERR_WINSOCK_CONNECT;
+ }
+
+ return 0;
+}
+
+
+int
+wHTTP::isDataAvailable (int _fd)
+{
+ struct timeval tv;
+ fd_set inp;
+ int n;
+
+ FD_ZERO (&inp);
+ FD_SET (_fd, &inp);
+ tv.tv_sec = 1;
+ tv.tv_usec = 0;
+
+ n = select (_fd+1, &inp, NULL, NULL, &tv);
+ if (n && FD_ISSET (_fd, &inp))
+ return n;
+ return 0;
+}
+
+
+int
+wHTTP::readLine (char *buf, unsigned int nbuf,
+ int nonblock, int *nn, int *eof)
+{
+ char c;
+ int n, i;
+
+ if (nn)
+ *nn = 0;
+ if (eof)
+ *eof = 0;
+ i = 0;
+ do {
+ if (nonblock == 1 && isDataAvailable (fd) == 0) {
+ buf[i++] = '\0';
+ i = -1;
+ break;
+ }
+ n = recv (fd, &c, 1, 0);
+ if (n == -1)
+ break;
+ if (n == 0 || nbuf == 0 || c == '\n') {
+ if (n == 0) {
+ if (eof)
+ *eof = 1;
+ buf[i++] = '\0';
+ }
+ else {
+ buf[i++] = c;
+ buf[i] = '\0';
+ }
+ break;
+ }
+ else {
+ buf[i++] = c;
+ nbuf--;
+ }
+ } while (n > 0 && i != -1);
+
+ if (nn)
+ *nn = i;
+ return 0;
+}
+
+
+
+/* Extract the host from the given url @url. Return the host in
+ @host and also return the resource part of the url in @new_url. */
+int
+wHTTP::extractHostInfo (const char *_url, char **_host, char **new_url)
+{
+ char *p;
+ char tmpbuf[512];
+
+ *_host = NULL;
+ *new_url = NULL;
+
+ /* XXX: do not use static buffers. */
+ memset (tmpbuf, 0, sizeof (tmpbuf));
+ strncpy (tmpbuf, _url, 512);
+
+ p = "http://";
+ if (strlen (_url) < 10 || strncmp (_url, p, 7))
+ return WPTERR_GENERAL;
+ _url += strlen (p);
+ p = strtok (tmpbuf+7, "/");
+ if (!p)
+ return WPTERR_GENERAL;
+ *_host = strdup (p);
+ p = strchr (_url, '/');
+ if (!p) {
+ free_if_malloc (*_host);
+ return WPTERR_GENERAL;
+ }
+ *new_url = strdup (p);
+ return 0;
+}
+
+
+/* Add a request header. */
+int
+wHTTP::addRequestHeader (const char *name, const char *val)
+{
+ char *p;
+ char *fmt = "%s: %s";
+
+ p = (char*) malloc (strlen (name)+strlen (val)+strlen (fmt)+1);
+ sprintf (p, fmt, name, val);
+ addHeader (&req_headers, p);
+ free_if_malloc (p);
+
+ return 0;
+}
+
+
+void
+wHTTP::setVersion (int _ver)
+{
+ if (_ver > 9)
+ _ver = 0;
+ this->ver = _ver;
+}
+
+
+int
+wHTTP::addRequestHeader (const char *name, unsigned int val)
+{
+ char buf[32];
+
+ sprintf (buf, "%lu", (DWORD)val);
+ return addRequestHeader (name, buf);
+}
+
+
+/* Prepare the request resource @url and send
+ it to host @host (port @port). */
+int
+wHTTP::sendRequest (const char *_host, int _port, const char *_url)
+{
+ const char *id[] = {"GET", "HEAD", "PUT", "POST"};
+ http_head_t h;
+ const char *h_head;
+ char *p;
+ int n;
+ int rc;
+
+ if (!this->fd) {
+ rc = connect (_host, _port);
+ if (rc)
+ return rc;
+ }
+
+ if (*_url == '/')
+ url++;
+ if (_url == NULL)
+ _url = "";
+
+ addRequestHeader ("Host", _host);
+ if (ver < 1)
+ addRequestHeader ("Connection", "close");
+
+ n = 0;
+ for (h = req_headers; h; h = h->next)
+ n += strlen (h->d) + 2 + 1;
+
+ h_head = "%s /%s HTTP/1.%d\r\n";
+ p = (char*)calloc (1, strlen (id[method]) + strlen (h_head)
+ + strlen (url) + n + 2 + 1 + 4);
+ if (!p)
+ BUG (0);
+ sprintf (p, h_head, id[method], url, ver);
+ for (h = req_headers; h; h = h->next) {
+ strcat (p, h->d);
+ strcat (p, "\r\n");
+ }
+ strcat (p, "\r\n");
+ printf ("p='%s'\n", p);
+ n = send (fd, p, strlen (p), 0);
+ free_if_malloc (p);
+ return n > 0? 0 : WPTERR_GENERAL;
+}
+
+
+/* Parse all response resp_headers. */
+int
+wHTTP::parseHeaders (http_head_t *r_head)
+{
+ char buf[300];
+ int nn;
+ int rc;
+
+ if (!r_head)
+ return WPTERR_GENERAL;
+
+ do {
+ rc = readLine (buf, 299, 1, &nn, NULL);
+ if (rc)
+ return rc;
+ if (nn == 2)
+ break; /* reach empty line */
+ addHeader (r_head, buf);
+ } while (rc == 0);
+ return 0;
+}
+
+
+/* Read data from the response and write it to @out. */
+int
+wHTTP::readData (FILE *out)
+{
+ const char *val;
+ char buf[1024+1];
+ int nlen = 0, nn = 0, n, eof=0;
+ int rc = 0;
+
+ if (this->fd == 0 || this->resp_headers == NULL)
+ return -1;
+
+ nlen = getContentLength ();
+ if (nlen == 0) {
+ if (!findHeader (resp_headers, "Connection", &val) ||
+ strnicmp (val, "close", 4))
+ return WPTERR_GENERAL;
+ }
+
+ val = getContentType ();
+ if (!val)
+ return WPTERR_GENERAL;
+ if (strnicmp (val, "text", 4)) { /* binary */
+ do {
+ n = recv (fd, buf, nlen > 1024? 1024 : nlen, 0);
+ if (n == -1)
+ return SOCKET_ERROR;
+ if (n == 0)
+ break;
+ nlen -= n;
+ fwrite (buf, 1, n, out);
+ } while (nlen > 0);
+ return 0;
+ }
+
+ do {
+ rc = readLine (buf, 1024, 1, &n, &eof);
+ if (rc)
+ return rc;
+ if (n > 0)
+ fwrite (buf, 1, n, out);
+ if (nlen > 0) {
+ nn += n;
+ if (nlen == nn)
+ break;
+ }
+ } while (eof == 0);
+
+ return 0;
+}
+
+
+/* Parse the HTTP response line. */
+int
+wHTTP::parseResponse (int *_statcode)
+{
+ http_head_t n;
+ const char *tmp, *p;
+ char buf[300];
+ int code = 0, nn = 0;
+ int rc;
+
+ *_statcode = 0;
+ rc = readLine (buf, 299, 1, &nn, NULL);
+ if (rc)
+ return rc;
+
+ tmp = "HTTP/1.";
+ if (strlen (buf) < 8 || strncmp (buf, tmp, strlen (tmp)))
+ return WPTERR_GENERAL;
+ p = buf;
+ p += strlen (tmp)+1 + 1; /* skip HTTP/1.x and WS */
+ *_statcode = atoi (p);
+ if (tmp == 0)
+ return WPTERR_GENERAL;
+ p += 3 + 1; /* number + WS */
+
+ if (code == HTTP_STAT_400 ||
+ code == HTTP_STAT_403 ||
+ code == HTTP_STAT_404 ||
+ code == HTTP_STAT_405)
+ return WPTERR_GENERAL;
+
+ while (resp_headers) {
+ n = resp_headers->next;
+ free (resp_headers);
+ resp_headers = n;
+ }
+ resp_headers = NULL;
+ rc = parseHeaders (&resp_headers);
+ if (rc)
+ return rc;
+ return 0;
+}
+
+
+/* Destroy HTTP object. */
+wHTTP::~wHTTP (void)
+{
+
+ http_head_t h;
+
+ while (resp_headers) {
+ h = resp_headers->next;
+ free (resp_headers);
+ resp_headers = h;
+ }
+ while (req_headers) {
+ h = req_headers->next;
+ free (req_headers);
+ req_headers = h;
+ }
+ free_if_malloc (url);
+ free_if_malloc (host);
+ if (fd != 0)
+ closesocket (fd);
+}
+
+
+int
+wHTTP::read (void *buf, unsigned int buflen)
+{
+ int n;
+
+ if (this->fd == 0 || this->resp_headers == NULL)
+ return -1;
+ if (method != HTTP_GET)
+ return -1;
+
+ if (nleft == -1)
+ nleft = getContentLength ();
+ if ((int)buflen > nleft)
+ buflen = nleft;
+ if (nleft == 0)
+ return -1;
+
+ n = recv (fd, (char*)buf, (int)buflen, 0);
+ if (n > 0) {
+ nleft -= n;
+ if (nleft < 0) nleft = 0;
+ }
+ return n;
+}
+
+
+int
+wHTTP::write (const void *buf, unsigned buflen)
+{
+ if (this->fd == 0)
+ return -1;
+ if (method == HTTP_GET || method == HTTP_HEAD)
+ return -1;
+ return send (fd, (const char*)buf, (int)buflen, 0);
+}
Modified: trunk/Src/wptKeyCache.cpp
===================================================================
--- trunk/Src/wptKeyCache.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyCache.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -36,6 +36,7 @@
#include "wptErrors.h"
#include "wptW32API.h"
#include "wptGPG.h"
+#include "wptTypes.h"
/* Attribute list which holds the image data. */
@@ -49,6 +50,7 @@
typedef struct attr_list_s *attr_list_t;
+/* Free attribute list @ctx. */
void
free_attr_list (attr_list_t ctx)
{
@@ -81,6 +83,8 @@
buffer = buf+9+10;
pos = 0;
c = (attr_list_t)calloc (1, sizeof *c);
+ if (!c)
+ BUG (0);
p = strtok (buffer, " ");
while (p != NULL) {
switch (pos) {
@@ -102,7 +106,6 @@
pos++;
p = strtok (NULL, " ");
}
- /*printf ("id=%s octets=%d flags=%d\n", c->fpr, c->octets, c->flags);*/
if (!*ctx)
*ctx = c;
else {
@@ -111,6 +114,8 @@
t->next = c;
}
c->d = (unsigned char*)malloc (c->octets);
+ if (!c->d)
+ BUG (0);
memcpy (c->d, data, c->octets);
data += c->octets;
datlen -= c->octets;
@@ -173,6 +178,8 @@
gpg_iobuf_ioctl (inp, 3, 1, NULL);
pkt = (PACKET*)calloc (1, sizeof *pkt);
+ if (!pkt)
+ BUG (0);
gpg_init_packet (pkt);
while (gpg_parse_packet (inp, pkt) != -1) {
if (pkt->pkttype == PKT_SECRET_KEY) {
@@ -216,6 +223,8 @@
fnd->attrib.flags = dat->flags;
fnd->attrib.len = dat->octets;
fnd->attrib.d = (unsigned char*)malloc (dat->octets);
+ if (!fnd->attrib.d)
+ BUG (0);
memcpy (fnd->attrib.d, dat->d, dat->octets);
return 0;
}
@@ -267,6 +276,8 @@
gpg_iobuf_ioctl (inp, 3, 1, NULL); /* disable cache */
pkt = (PACKET*)calloc (1, sizeof * pkt);
+ if (!pkt)
+ BUG (0);
gpg_init_packet (pkt);
while (gpg_parse_packet (inp, pkt) != -1) {
if (pkt->pkttype == PKT_PUBLIC_KEY) {
@@ -302,7 +313,7 @@
else if (nsym > 0) {
c->sym_prefs = (unsigned char*)calloc (1, nsym+1);
if (!c->sym_prefs)
- return gpg_error (GPG_ERR_ENOMEM);
+ BUG (0);
memcpy (c->sym_prefs, sym_prefs, nsym);
}
}
@@ -344,7 +355,7 @@
return gpg_error (GPG_ERR_INV_ARG);
ctx = (gpg_keycache_t)calloc (1, sizeof *ctx);
if (!ctx)
- return gpg_error (GPG_ERR_ENOMEM);
+ BUG (0);
ctx->secret = 0;
ctx->pos = 0;
*r_ctx = ctx;
@@ -365,6 +376,7 @@
c2 = c->next;
gpgme_key_release (c->key);
c->key = NULL;
+ safe_free (c->pref_keyserver);
safe_free (c->sym_prefs);
safe_free (c->attrib.d);
safe_free (c->card_type);
@@ -404,7 +416,7 @@
c = (struct keycache_s*)calloc (1, sizeof *c);
if (!c)
- return gpg_error (GPG_ERR_ENOMEM);
+ BUG (0);
c->gloflags.is_protected = 1; /*default: assume protection. */
c->key = key;
if (!ctx->item)
@@ -682,7 +694,7 @@
pos++;
p = (unsigned char*)calloc (1, pos+1);
if (!p)
- abort ();
+ BUG (0);
memcpy (p, prefs, pos);
return p;
}
@@ -779,6 +791,7 @@
return err;
}
+
/* Search for a key with the pattern @pattern and mark
this key as the default signing key if found.
Return value: 0 on success. */
@@ -821,4 +834,98 @@
}
+static gpgme_error_t
+decode_subpacket (const char *subpkt_data, int *type,
+ char **out, WORD *outlen)
+{
+ char tmp[128], *p = tmp, *val;
+ char *enc;
+ size_t pos = 0, i=0;
+ /* example: spk:24:1:21:http%3A//subkeys.pgp.de */
+ *outlen = 0;
+ *out = NULL;
+
+ if (strncmp (subpkt_data, "spk:", 4))
+ return gpg_error (GPG_ERR_NO_DATA);
+
+ strncpy (tmp, subpkt_data, 62);
+ val = strtok (tmp, ":");
+ while (val != NULL) {
+ switch (pos++) {
+ case 0:
+ break;
+
+ case 1:
+ if (type)
+ *type = atoi (val);
+ break;
+
+ case 2:
+ break;
+
+ case 3:
+ *outlen = atoi (val);
+ break;
+
+ case 4:
+ enc = strdup (val);
+ break;
+ }
+ val = strtok (NULL, ":");
+ }
+ if (!enc)
+ return gpg_error (GPG_ERR_NO_DATA);;
+ *out = (char*)calloc (1, strlen (enc)+1);
+ for (pos = 0; pos < strlen (enc); pos++) {
+ if (enc[pos] == '%' && enc[pos+1] == '%')
+ (*out)[i++] = '%';
+ else if (enc[pos] == '%') {
+ char tmp[3];
+ tmp[0] = enc[++pos];
+ tmp[1] = enc[++pos];
+ tmp[2] = 0;
+ (*out)[i++] = (char)strtoul (tmp, NULL, 16);
+ }
+ else
+ (*out)[i++] = enc[pos];
+ }
+ (*out)[i] = 0;
+ free (enc);
+ return 0;
+}
+
+
+/* If the attribute given in @attr is not set in the
+ key cache object, try to update it. */
+gpgme_error_t
+gpg_keycache_update_attr (struct keycache_s *item,
+ int attr, int force)
+{
+ gpgme_error_t err = gpg_error (GPG_ERR_NO_ERROR);
+ char *val = NULL;
+ WORD n = 0;
+
+ switch (attr) {
+ case KC_ATTR_PREFSYM:
+ if (!force && item->sym_prefs)
+ break;
+ safe_free (item->sym_prefs);
+ err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);
+ if (!err && val != NULL)
+ err = decode_subpacket (val, NULL, (char**)&item->sym_prefs, &n);
+ break;
+
+ case KC_ATTR_PREFKSERV:
+ if (!force && item->pref_keyserver)
+ break;
+ safe_free (item->pref_keyserver);
+ err = gpg_find_key_subpacket (item->key->subkeys->keyid+8, attr, &val);
+ if (!err && val != NULL)
+ err = decode_subpacket (val, NULL, &item->pref_keyserver, &n);
+ break;
+ }
+ safe_free (val);
+ return err;
+}
+
Modified: trunk/Src/wptKeyEdit.cpp
===================================================================
--- trunk/Src/wptKeyEdit.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyEdit.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -816,6 +816,7 @@
}
/* Set the preferred keyserver for the given key to @url.
+ If @_uid_index is -1, set the keyserver for all user-ids.
Return value: 0 on success. */
gpgme_error_t
GpgKeyEdit::setPreferredKeyserver (int _uid_index, const char *_url)
Modified: trunk/Src/wptKeyEditCB.cpp
===================================================================
--- trunk/Src/wptKeyEditCB.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyEditCB.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -48,9 +48,12 @@
static char buf[32];
if (!ctx->cmd_sent && !strcmp (key, "keyedit.prompt")) {
+ int uid = ctx->getUseridIndex ();
ctx->cmd_sent = 1;
- sprintf (buf, "uid %d", ctx->getUseridIndex ());
- return buf;
+ if (uid != -1) {
+ sprintf (buf, "uid %d", ctx->getUseridIndex ());
+ return buf;
+ }
}
if (!strcmp (key, "keyedit.prompt") && !ctx->cnt) {
ctx->cnt = 1;
@@ -58,7 +61,7 @@
}
if (!strcmp (key, "keyedit.add_keyserver"))
return ctx->url;
- if ( !strcmp (key, "keyedit.confirm_keyserver"))
+ if (!strcmp (key, "keyedit.confirm_keyserver"))
return "Y";
if (!strcmp (key, "passphrase.enter"))
return ctx->pass;
Modified: trunk/Src/wptKeyEditDlgs.cpp
===================================================================
--- trunk/Src/wptKeyEditDlgs.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyEditDlgs.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -875,13 +875,13 @@
ke->setPassphrase (pass);
else
ke->setNoPassphrase (true);
- err = ke->setPreferredKeyserver (0 /* XXX */, url->url);
+ err = ke->setPreferredKeyserver (-1, url->url);
if (!err)
msg_box (dlg, _("Preferred keyserver successfully set."), _("Key Edit"), MB_OK);
sfree_if_alloc (pass);
delete ke;
- delete url;
+ delete url;
return err == 0? 0 : WPTERR_GENERAL;
}
Modified: trunk/Src/wptKeyManager.cpp
===================================================================
--- trunk/Src/wptKeyManager.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyManager.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -530,10 +530,9 @@
int
km_http_import (HWND dlg, const char *url)
{
- http_hd_t hd;
FILE *fp;
+ wHTTP *hd;
char tmpfile[500];
- int statcode;
int rc = 0;
if (strncmp (url, "http://", 7)) {
@@ -549,19 +548,19 @@
return WPTERR_FILE_CREAT;
}
- /* parse URL */
- rc = http_send_request2 (url, &hd);
- if (!rc)
- rc = http_parse_response (hd, &statcode);
- if (!rc)
- rc = http_parse_data (hd, fp);
- http_hd_free (hd);
- fclose (fp);
- if (rc) {
- msg_box (dlg, winpt_strerror (rc), _("Key Import HTTP"), MB_ERR);
+ hd = new wHTTP (url);
+ if (hd->getStatusCode () == HTTP_STAT_200)
+ hd->readData (fp);
+ else {
+ log_box (_("Key Import HTTP"), MB_ERR,
+ _("Could not fetch key from URL: %s"), url);
rc = WPTERR_GENERAL;
}
- km_file_import (dlg, tmpfile, NULL, NULL);
+
+ delete hd;
+ fclose (fp);
+ if (!rc)
+ km_file_import (dlg, tmpfile, NULL, NULL);
DeleteFile (tmpfile);
return rc;
}
@@ -817,7 +816,8 @@
/* Send the select key in @lv to the keyserver @host:@port. */
int
-km_send_to_keyserver (listview_ctrl_t lv, HWND dlg, const char *host, u16 port)
+km_send_to_keyserver (listview_ctrl_t lv, HWND dlg,
+ const char *host, WORD port)
{
gpgme_key_t key;
int id;
@@ -891,13 +891,17 @@
}
+/* Refresh the selected key in the listview @lv at position @pos.
+ Legal flags are 0 = single key. */
static void
km_refresh_one_key (listview_ctrl_t lv, HWND dlg, int pos, int flags)
{
+ winpt_key_s pk;
gpgme_key_t key;
+ const char *pref_kserv = default_keyserver;
char keyid[16+1];
int idx, err = 0;
-
+
if (pos != 0)
idx = pos;
else
@@ -906,8 +910,13 @@
key = (gpgme_key_t)listview_get_item2 (lv, idx);
if (!key)
BUG (0);
+ /* In single refresh mode, try to use the users preferred keyserver. */
+ if (flags == 0 &&
+ !winpt_get_pubkey (key->subkeys->keyid+8, &pk) &&
+ !gpg_keycache_update_attr (pk.ext, KC_ATTR_PREFKSERV, 0))
+ pref_kserv = pk.ext->pref_keyserver;
_snprintf (keyid, sizeof (keyid)-1, "%s", key->subkeys->keyid+8);
- err = hkp_recv_key (dlg, default_keyserver, default_keyserver_port,
+ err = hkp_recv_key (dlg, pref_kserv, default_keyserver_port,
keyid, 0, flags);
/* if we receive just a single key (no refresh mode), update it. */
if (!flags && !err)
Modified: trunk/Src/wptKeyManagerDlg.cpp
===================================================================
--- trunk/Src/wptKeyManagerDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyManagerDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -1692,7 +1692,7 @@
case ID_KEYMISC_IMPORT_HTTP:
url = (struct URL_ctx_s*)get_http_file_dlg (dlg);
- if (url->cancel == 0) {
+ if (url && url->cancel == 0) {
km_http_import (dlg, url->url);
refresh_keylist (kmi);
}
@@ -1811,7 +1811,9 @@
if (!key)
BUG (NULL);
memset (&k, 0, sizeof (k));
- k.keyid = key->subkeys->keyid+8;
+ strncpy (k.tmp_keyid, key->subkeys->keyid+8, 8);
+ k.keyid = k.tmp_keyid;
+ k.is_protected = km_check_if_protected (kmi->lv, kmi->lv_idx);
keyedit_set_pref_keyserver (&k, dlg);
break;
Modified: trunk/Src/wptKeyPropsDlg.cpp
===================================================================
--- trunk/Src/wptKeyPropsDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyPropsDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -208,7 +208,7 @@
{
static char buf[64];
- if (!k->ext->card_type)
+ if (!k->ext || !k->ext->card_type)
return "";
_snprintf (buf, sizeof (buf)-1, _("Card-Type: %s\r\n"), k->ext->card_type);
return buf;
@@ -220,24 +220,22 @@
static void
display_key_info (HWND dlg, winpt_key_t k, gpgme_key_t *r_key)
{
- struct winpt_key_s k2;
- gpgme_key_t sk, key;
+ gpgme_key_t key;
+ struct winpt_key_s pk, sk;
char info[512];
const char *inf;
- u32 created, expires;
+ DWORD created, expires;
- memset (&k2, 0, sizeof (k2));
- if (k->key_pair)
- winpt_get_seckey (k->keyid, &k2);
- else
- winpt_get_pubkey (k->keyid, &k2);
- sk = k2.ctx;
- if (sk)
- k->is_protected = k2.is_protected;
- if (get_pubkey (k->keyid, &key))
- BUG (0);
- created = key->subkeys->timestamp;
- expires = key->subkeys->expires;
+ memset (&pk, 0, sizeof (pk));
+ if (winpt_get_pubkey (k->keyid, &pk))
+ BUG (0);
+ gpg_keycache_update_attr (pk.ext, KC_ATTR_PREFSYM, 0);
+ memset (&sk, 0, sizeof (sk));
+ if (k->key_pair && !winpt_get_seckey (k->keyid, &sk))
+ k->is_protected = sk.is_protected;
+ key = pk.ext->key;
+ created = key->subkeys->timestamp;
+ expires = key->subkeys->expires;
_snprintf (info, DIM (info)-1,
_("Type: %s\r\n"
"Key ID: %s\r\n"
@@ -255,8 +253,8 @@
get_key_created (created),
get_key_expire_date (expires),
get_validity (key),
- get_pref_cipher (&k2),
- get_card_type (&k2));
+ get_pref_cipher (&pk),
+ get_card_type (&sk));
SetDlgItemText (dlg, IDC_KEYPROPS_INFO, info);
SetDlgItemText (dlg, IDC_KEYPROPS_FPR, get_key_fpr (key));
@@ -289,7 +287,7 @@
SetDlgItemText (dlg, IDC_KEYPROPS_REVOKERS, _("&Revokers"));
SetDlgItemText (dlg, IDC_KEYPROPS_CHANGE_PWD, _("Change &Password"));
SetDlgItemText (dlg, IDC_KEYPROPS_OTINF, _("Ownertrust"));
-
+
display_key_info (dlg, k, &key);
if (!keyprops_load_photo (dlg, key, &valid)) {
k->has_photo = 1;
Modified: trunk/Src/wptKeylist.cpp
===================================================================
--- trunk/Src/wptKeylist.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeylist.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -592,7 +592,7 @@
listview_set_chkbox_style (lv);
ico[0] = LoadIcon (glob_hinst, (LPCTSTR)IDI_PUBKEY);
ico[1] = LoadIcon (glob_hinst, (LPCTSTR)IDI_KEYPAIR);
- listview_set_image_list (lv, ico, 2);
+ listview_set_image_list (lv, 22, 14, ico, 2);
listview_del_all_items (lv);
*r_lv = lv;
Modified: trunk/Src/wptKeyserver.cpp
===================================================================
--- trunk/Src/wptKeyserver.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyserver.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -37,10 +37,9 @@
#include "wptGPG.h"
#include "wptRegistry.h"
+/* just map net_errno to a winsock error. */
#define net_errno ((int)WSAGetLastError ())
-static char base64code[] =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
keyserver server[MAX_KEYSERVERS] = {0};
keyserver_proxy_s proxy = {0};
@@ -70,11 +69,15 @@
char *default_keyserver = NULL;
WORD default_keyserver_port = 0;
+/* Default socket timeout. */
+static int default_socket_timeout = 10;
/* Basic64 encode the input @inbuf to @outbuf. */
static void
base64_encode (const char *inbuf, char *outbuf)
-{
+{
+ char base64code[] =
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
int index = 0, temp = 0, res = 0;
int i = 0, inputlen = 0, len = 0;
@@ -213,13 +216,13 @@
Return value: 0 on success. */
static int
sock_read (int fd, char *buf, int buflen, int *nbytes)
-{
+{
DWORD nread;
int nleft = buflen;
int rc, n = 0;
while (nleft > 0) {
- if (n >= 10)
+ if (n >= default_socket_timeout)
return WPTERR_WINSOCK_TIMEOUT;
rc = sock_select (fd, 1);
if (rc == SOCKET_ERROR)
@@ -304,23 +307,6 @@
}
-/* Set the default keyserver. */
-void
-set_default_kserver (void)
-{
- char *p = get_reg_entry_keyserver ("Default");
- free_if_alloc (default_keyserver);
- default_keyserver = p && *p != ' ' ? p : m_strdup (DEF_HKP_KEYSERVER);
- p = get_reg_entry_keyserver ("Default_Port");
- if (p && *p) {
- default_keyserver_port = (WORD)strtoul (p, NULL, 10);
- free_if_alloc (p);
- }
- else
- default_keyserver_port = HKP_PORT;
-}
-
-
/* Initialize the Winsock2 interface.*/
int
wsock_init (void)
@@ -331,7 +317,6 @@
log_debug ("wsock_init: WSAStartup failed ec=%d\r\n", net_errno);
return WPTERR_WINSOCK_INIT;
}
- set_default_kserver ();
return 0;
}
@@ -348,7 +333,7 @@
free_if_alloc (p);
free_if_alloc (default_keyserver);
for (i=0; i < MAX_KEYSERVERS; i++) {
- if (server[i].used)
+ if (server[i].used && server[i].name != NULL)
free_if_alloc (server[i].name);
}
kserver_proxy_release (&proxy);
@@ -378,6 +363,16 @@
}
+/* Set default socket timeout for all reading operations. */
+void
+kserver_set_socket_timeout (int nsec)
+{
+ if (nsec < 0)
+ nsec = 0;
+ default_socket_timeout = nsec;
+}
+
+
/* Return the last keyserver error as a string. */
const char*
kserver_strerror (void)
@@ -504,13 +499,17 @@
void
keyserver_set_default (const char *hostname, WORD port)
{
- if (hostname) {
+ if (hostname != NULL) {
free_if_alloc (default_keyserver);
default_keyserver = m_strdup (hostname);
if (!default_keyserver)
BUG (0);
default_keyserver_port = port;
}
+ if (!port)
+ port = HKP_PORT;
+ if (!default_keyserver)
+ default_keyserver = m_strdup (DEF_HKP_KEYSERVER);
server[0].name = m_strdup (default_keyserver);
server[0].used = 1;
server[0].port = port;
Modified: trunk/Src/wptKeyserverDlg.cpp
===================================================================
--- trunk/Src/wptKeyserverDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeyserverDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -326,14 +326,14 @@
static void
set_proxy (HWND dlg)
{
- char t[512];
+ char buf[384];
if (proxy.host)
- _snprintf (t, sizeof (t)-1, "%s proxy: \"%s:%d\"",
+ _snprintf (buf, sizeof (buf)-1, "%s proxy: \"%s:%d\"",
name_from_proto (proxy.proto), proxy.host, proxy.port);
else
- strcpy (t, "Proxy: none");
- SetDlgItemText (dlg, IDC_KEYSERVER_PROXY, t);
+ strcpy (buf, _("Proxy: none"));
+ SetDlgItemText (dlg, IDC_KEYSERVER_PROXY, buf);
}
@@ -346,13 +346,13 @@
}
-static u16 inline
+static WORD inline
kserver_get_port (listview_ctrl_t lv)
{
char buf[16];
listview_get_item_text (lv, kserver_get_pos (lv), KS_COL_PORT, buf, 15);
- return (u16)strtoul (buf, NULL, 10);
+ return (WORD)strtoul (buf, NULL, 10);
}
@@ -366,7 +366,7 @@
p = get_reg_entry_keyserver ("Default");
if (!p)
return;
- for (i = 0; i < listview_count_items( lv, 0); i++ ) {
+ for (i = 0; i < listview_count_items (lv, 0); i++) {
listview_get_item_text (lv, i, KS_COL_NAME, buf, sizeof (buf)-1);
if (!strncmp (p, buf, strlen (p))) {
listview_add_sub_item (lv, i, KS_COL_DEFAULT, "x");
@@ -402,7 +402,7 @@
i = kserver_get_port (lv);
sprintf (port, "%d", i);
set_reg_entry_keyserver ("Default_Port", port);
- keyserver_set_default (buf, (u16)i);
+ keyserver_set_default (buf, (WORD)i);
return 0;
}
@@ -426,7 +426,7 @@
lv->ctrl = hwnd;
for (j=0; keyserver[j].fieldname; j++)
listview_add_column (lv, &keyserver[j]);
- listview_set_image_list (lv, ico, 1);
+ listview_set_image_list (lv, 16, 16, ico, 1);
for (j = 0; j<MAX_KEYSERVERS; j++) {
if (!server[j].used)
continue;
Modified: trunk/Src/wptKeysignDlg.cpp
===================================================================
--- trunk/Src/wptKeysignDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptKeysignDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -23,6 +23,7 @@
#include <windows.h>
#include <commctrl.h>
+#include <time.h>
#include "resource.h"
#include "wptGPG.h"
@@ -218,6 +219,23 @@
}
+/* Check if the given system time @st points to today. */
+static int
+date_is_today (SYSTEMTIME *st)
+{
+ time_t t;
+ struct tm *tm;
+
+ t = time (NULL);
+ tm = localtime (&t);
+ if (st->wDay == tm->tm_mday &&
+ st->wYear == tm->tm_year+1900 &&
+ st->wMonth == tm->tm_mon+1)
+ return -1;
+ return 0;
+}
+
+
/* Dialog box procedure to sign a key. */
BOOL CALLBACK
keysign_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
@@ -279,6 +297,8 @@
EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_SHOWIMG), TRUE);
if (!reg_prefs.gpg.ask_cert_level)
EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_ASKLEVEL), FALSE);
+ if (!reg_prefs.gpg.ask_cert_expire)
+ EnableWindow (GetDlgItem (dlg, IDC_KEYSIGN_EXPSIG), FALSE);
CheckDlgButton (dlg, IDC_KEYSIGN_HIDE, BST_CHECKED);
SetForegroundWindow (dlg);
h = GetDlgItem (dlg, IDC_KEYSIGN_PASSPHRASE);
@@ -330,8 +350,14 @@
type = GPG_EDITKEY_NRLSIGN;
}
if (IsDlgButtonChecked (dlg, IDC_KEYSIGN_EXPSIG)) {
- expires = 1;
DateTime_GetSystemtime (GetDlgItem (dlg, IDC_KEYSIGN_EXPIRES), &st);
+ if (date_is_today (&st)) {
+ msg_box (dlg, _("You cannot select today as the expiration date."),
+ _("Key Signing"), MB_INFO);
+ return TRUE;
+ }
+ else
+ expires = 1;
sprintf (keymsg, "%04d-%02d-%02d", st.wYear, st.wMonth, st.wDay);
}
Modified: trunk/Src/wptListView.cpp
===================================================================
--- trunk/Src/wptListView.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptListView.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -410,12 +410,16 @@
void
-listview_set_image_list (listview_ctrl_t ctx, HICON *ico, DWORD nicons)
+listview_set_image_list (listview_ctrl_t ctx, int cx, int cy,
+ HICON *ico, DWORD nicons)
{
HIMAGELIST hil;
DWORD i;
- hil = ImageList_Create (16, 16, ILC_COLOR8|ILC_MASK, nicons, 1);
+ if (cx == 0 || cy == 0)
+ cx = cy = 16;
+
+ hil = ImageList_Create (cx, cy, ILC_COLOR8|ILC_MASK, nicons, 1);
ImageList_SetBkColor (hil, CLR_NONE);
for (i=0; i < nicons; i++)
ImageList_AddIcon (hil, ico[i]);
Modified: trunk/Src/wptPassphraseCB.cpp
===================================================================
--- trunk/Src/wptPassphraseCB.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptPassphraseCB.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -43,7 +43,7 @@
const char* get_symkey_algo (int algo);
-#define item_ctrl_id( cmd ) \
+#define item_ctrl_id(cmd) \
((cmd) == GPG_CMD_DECRYPT? IDC_DECRYPT_PWD : IDC_DECRYPT_SIGN_PWD)
#define item_ctrl_id2(cmd) \
@@ -76,6 +76,14 @@
int n;
switch (msg) {
+ case WM_ACTIVATE:
+ safe_edit_control_init (dlg, item_ctrl_id (c->gpg_cmd));
+ break;
+
+ case WM_DESTROY:
+ safe_edit_control_free (dlg, item_ctrl_id (c->gpg_cmd));
+ break;
+
case WM_INITDIALOG:
c = (passphrase_cb_s *)lparam;
if (!c)
@@ -208,7 +216,8 @@
c->pwd = new char[n+2];
if (!c->pwd)
BUG (NULL);
- GetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd), c->pwd, n+1);
+ SafeGetDlgItemText (dlg, item_ctrl_id (c->gpg_cmd),
+ c->pwd, n+1);
}
res = gpgme_op_decrypt_result (c->gpg);
if (!res)
@@ -392,7 +401,7 @@
}
else if (uid_hint)
parse_gpg_description (uid_hint, passphrase_info,
- c->info, sizeof c->info - 1);
+ c->info, sizeof (c->info) - 1);
if (c->gpg_cmd == GPG_CMD_DECRYPT) {
rc = DialogBoxParam (glob_hinst, (LPCSTR)IDD_WINPT_DECRYPT,
(HWND)c->hwnd, passphrase_callback_proc,
Modified: trunk/Src/wptPassphraseDlg.cpp
===================================================================
--- trunk/Src/wptPassphraseDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptPassphraseDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -41,6 +41,7 @@
int strict; /* do a simple check how good the passphrase is. */
int repeat; /* Indicate last try was wrong. */
int cancel; /* 1 if user cancelled operation. */
+ int not_empty;
};
@@ -48,7 +49,7 @@
static BOOL CALLBACK
passwd_dlg_proc (HWND dlg, UINT msg, WPARAM wparam, LPARAM lparam)
{
- static passphrase_s * pwd;
+ static passphrase_s *pwd;
int nbytes;
switch (msg) {
@@ -71,6 +72,14 @@
center_window (dlg, NULL);
SetForegroundWindow (dlg);
return FALSE;
+
+ case WM_ACTIVATE:
+ safe_edit_control_init (dlg, IDC_PASSWD_PWD);
+ break;
+
+ case WM_DESTROY:
+ safe_edit_control_free (dlg, IDC_PASSWD_PWD);
+ break;
case WM_COMMAND:
if (HIWORD (wparam) == BN_CLICKED &&
@@ -84,7 +93,13 @@
switch (LOWORD (wparam)) {
case IDOK:
pwd->cancel = 0;
- nbytes = GetDlgItemText (dlg, IDC_PASSWD_PWD, pwd->pwd, DIM (pwd->pwd)-1);
+ nbytes = SafeGetDlgItemText (dlg, IDC_PASSWD_PWD,
+ pwd->pwd, DIM (pwd->pwd)-1);
+ if (!nbytes && pwd->not_empty) {
+ msg_box (dlg, _("Please enter a passphrase."), _("Passphrase Dialog"), MB_ERR);
+ return TRUE;
+ }
+
if (!nbytes)
strcpy (pwd->pwd, "");
else if (pwd->strict && check_passwd_quality (pwd->pwd, 0)) {
@@ -129,6 +144,7 @@
}
pass.repeat = flags & PASSDLG_INIT? 0 : 1;
pass.strict = flags & PASSDLG_STRICT? 1 : 0;
+ pass.not_empty = flags & PASSDLG_NOTEMPTY? 1: 0;
DialogBoxParam (glob_hinst, (LPCTSTR)IDD_WINPT_PASSWD, glob_hwnd,
passwd_dlg_proc, (LPARAM)&pass);
if (pass.cancel == 1) {
Modified: trunk/Src/wptPreferencesDlg.cpp
===================================================================
--- trunk/Src/wptPreferencesDlg.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptPreferencesDlg.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -250,8 +250,10 @@
case IDOK:
rc = GetDlgItemInt (dlg, IDC_PREFS_CACHETIME, NULL, FALSE);
- if (rc <= 0)
+ if (rc <= 0) {
reg_prefs.cache_time = 0;
+ agent_flush_cache ();
+ }
else if (rc > 720) {
msg_box( dlg, _("Please enter a value that is between 1-720.\nIt is not "
"a good idea to cache the passphrase more than 12 hours."),
Modified: trunk/Src/wptRegistry.cpp
===================================================================
--- trunk/Src/wptRegistry.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptRegistry.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -693,8 +693,8 @@
char*
get_reg_entry_keyserver (const char *name)
{
- char * p = get_reg_entry (HKEY_CURRENT_USER, WINPT_REG"\\Keyserver", name);
- if (p && !strcmp (p, "")) {
+ char *p = get_reg_entry (HKEY_CURRENT_USER, WINPT_REG"\\Keyserver", name);
+ if (p && (!strcmp (p, "") || strlen (p) == 0)) {
free_if_alloc (p);
return NULL;
}
@@ -712,7 +712,7 @@
get_reg_entry_keyserver_int (const char *key)
{
char *p;
- int val;
+ int val = 0;
p = get_reg_entry_keyserver (key);
if (p && *p)
Added: trunk/Src/wptSafeEditCtrl.cpp
===================================================================
--- trunk/Src/wptSafeEditCtrl.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptSafeEditCtrl.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -0,0 +1,249 @@
+/* wptSafeEditCtrl.cpp - Safe edit control for passwords
+ * Copyright (C) 2006 Timo Schulz, g10 Code GmbH
+ *
+ * This file is part of WinPT.
+ *
+ * WinPT 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.
+ *
+ * WinPT 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 WinPT; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+#include <windows.h>
+#include <stdio.h>
+#include <richedit.h>
+#include "resource.h"
+
+#include "wptTypes.h"
+#include "wptW32API.h"
+
+/* New message to retrieve text. */
+#define WM_SAFE_GETTEXT (WM_USER+11)
+
+/* Hook context. */
+struct hook_ctx_s {
+ HHOOK keyb; /* handle for the keyboard. */
+ HHOOK cbt; /* handle for computer based training (CBT) */
+};
+typedef struct hook_ctx_s *hook_ctx_t;
+
+/* Subclassing context. */
+struct subclass_ctx_s {
+ WNDPROC new_wnd_fnc; /* old window procedure. */
+ WNDPROC old_wnd_fnc; /* new window procedure. */
+ HWND wnd; /* window handle that is subclassed. */
+ void *opaque;
+};
+typedef struct subclass_ctx_s *subclass_ctx_t;
+
+
+/* Dummy hook procedure to avoid channing. */
+static LRESULT CALLBACK
+dummy_hook_proc (int code, WPARAM wparam, LPARAM lparam)
+{
+ return FALSE;
+}
+
+
+/* Set dummy hooks to prevent that the control is monitored
+ by some external hook functions. */
+static hook_ctx_t
+install_dummy_hooks (void)
+{
+ hook_ctx_t hc;
+
+ hc = (hook_ctx_t)calloc (1, sizeof *hc);
+ if (!hc)
+ return NULL;
+ hc->cbt = SetWindowsHookEx (WH_CBT, dummy_hook_proc,
+ GetModuleHandle (NULL), 0);
+ if (hc->cbt == NULL) {
+ free (hc);
+ return NULL;
+ }
+ hc->keyb = SetWindowsHookEx (WH_KEYBOARD, dummy_hook_proc,
+ GetModuleHandle (NULL), 0);
+ if (hc->keyb == NULL) {
+ free (hc);
+ return NULL;
+ }
+ return hc;
+}
+
+
+/* Remove dummy hooks and free memory. */
+static void
+deinstall_dummy_hooks (hook_ctx_t hc)
+{
+ UnhookWindowsHookEx (hc->cbt);
+ UnhookWindowsHookEx (hc->keyb);
+ free (hc);
+}
+
+
+/* Filtered window procedure for the passphrase edit control. */
+static LRESULT CALLBACK
+safe_edit_dlg_proc (HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
+{
+ static subclass_ctx_t ctx = NULL;
+
+ /* XXX: filter all messages which were not send from
+ the current process. */
+
+ if (ctx == NULL)
+ ctx = (subclass_ctx_t)GetWindowLong (hwnd, GWL_USERDATA);
+
+ switch (msg) {
+ case WM_CUT:
+ case WM_COPY:
+ case WM_PASTE:
+ /* do not allow to copy or paste the inserted text. */
+ return TRUE;
+
+ case WM_KEYUP:
+ case WM_KEYDOWN:
+ /* XXX: maybe in a future release, we might want to provide
+ our own buffer implementation. */
+
+ /* ignore 'end' and 'home' to make text selection more difficult. */
+ if ((int)wparam == VK_END || (int)wparam == VK_HOME)
+ return TRUE;
+ break;
+
+ case WM_GETTEXT:
+ /* disallow normal gettext message. */
+ return TRUE;
+
+ case WM_SAFE_GETTEXT:
+ { /* transform WM_GETTEXT request into EM_GETLINE request. */
+ char *buffer = (char*)wparam;
+ int n;
+ buffer[0] = (char)lparam;
+ n = SendMessage (hwnd, EM_GETLINE, 0, wparam);
+ buffer[n] = 0;
+ }
+ break;
+
+ case EM_GETLINE:
+ break;
+
+ case WM_LBUTTONDBLCLK:
+ case WM_RBUTTONUP:
+ case WM_RBUTTONDOWN:
+ /* prevent that the popup menu is displayed. */
+ return TRUE;
+
+ case EM_SETSEL:
+ case EM_SCROLLCARET:
+ case EM_FINDTEXT:
+ case EM_FINDTEXTEX:
+ case EM_GETSELTEXT:
+ case EM_PASTESPECIAL:
+ case EM_GETTEXTRANGE:
+ case EM_STREAMIN:
+ case EM_STREAMOUT:
+ /* disallow message which could be used to copy the text. */
+ return TRUE;
+ }
+
+ return CallWindowProc (ctx->old_wnd_fnc, hwnd, msg, wparam, lparam);
+}
+
+
+/* Sublclass the window in the dialog @dlg with the id @ctrlid.
+ @new_wnd_fnc is the new window procedure. */
+static int
+subclass_window (HWND dlg, int ctrlid, WNDPROC new_wnd_fnc,
+ subclass_ctx_t *r_ctx)
+{
+ subclass_ctx_t ctx;
+
+ *r_ctx = NULL;
+ ctx = (subclass_ctx_t)calloc (1, sizeof *ctx);
+ if (!ctx)
+ return -1;
+ ctx->wnd = GetDlgItem (dlg, ctrlid);
+ ctx->new_wnd_fnc = new_wnd_fnc;
+ ctx->old_wnd_fnc = (WNDPROC)GetWindowLong (ctx->wnd, GWL_WNDPROC);
+ if (!ctx->old_wnd_fnc) {
+ free (ctx);
+ return -1;
+ }
+ SetLastError (0);
+ SetWindowLong (ctx->wnd, GWL_WNDPROC, (LONG)new_wnd_fnc);
+ if (GetLastError () != 0) {
+ free (ctx);
+ return -1;
+ }
+ SetLastError (0);
+ SetWindowLong (ctx->wnd, GWL_USERDATA, (LONG)ctx);
+ if (GetLastError () != 0) {
+ free (ctx);
+ return -1;
+ }
+ if (r_ctx)
+ *r_ctx = ctx;
+ return 0;
+}
+
+
+/* Restore the old window procedure for the subclassed control
+ and free the memory. */
+static void
+subclass_free_memory (HWND dlg, int ctrlid)
+{
+ subclass_ctx_t ctx;
+ HWND wnd;
+
+ wnd = GetDlgItem (dlg, ctrlid);
+ ctx = (subclass_ctx_t)GetWindowLong (wnd, GWL_USERDATA);
+ SetWindowLong (ctx->wnd, GWL_WNDPROC, (LONG)ctx->old_wnd_fnc);
+ if (ctx != NULL)
+ free (ctx);
+}
+
+
+/* Init subclassing to provide a safer edit control
+ for the dialog @dlg control @ctlid. */
+void
+safe_edit_control_init (HWND dlg, int ctlid)
+{
+ subclass_ctx_t ctx;
+
+ subclass_window (dlg, ctlid, safe_edit_dlg_proc, &ctx);
+ if (ctx != NULL)
+ ctx->opaque = install_dummy_hooks ();
+}
+
+
+/* Reset subclassing for the edit control @ctlid. */
+void
+safe_edit_control_free (HWND dlg, int ctlid)
+{
+ subclass_ctx_t ctx;
+ HWND wnd;
+
+ wnd = GetDlgItem (dlg, ctlid);
+ ctx = (subclass_ctx_t)GetWindowLong (wnd, GWL_USERDATA);
+ if (ctx != NULL && ctx->opaque != NULL)
+ deinstall_dummy_hooks ((hook_ctx_t)ctx->opaque);
+ subclass_free_memory (dlg, ctlid);
+}
+
+
+UINT
+SafeGetDlgItemText (HWND dlg, int id, char *buf, int buflen)
+{
+ /* XXX: use memset (buf, 0, buflen)? */
+ SendDlgItemMessage (dlg, id, WM_SAFE_GETTEXT, (WPARAM)buf, (LPARAM)buflen);
+ return strlen (buf);
+}
Modified: trunk/Src/wptSymEnc.cpp
===================================================================
--- trunk/Src/wptSymEnc.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptSymEnc.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -69,7 +69,8 @@
char *pass = NULL;
int cancel = 0;
- pass = request_passphrase2 (_("Symmetric Encryption"), 0, &cancel);
+ pass = request_passphrase2 (_("Symmetric Encryption"),
+ PASSDLG_NOTEMPTY, &cancel);
if (cancel)
return 0;
rc = gpgme_new (&ctx);
Modified: trunk/Src/wptUTF8.cpp
===================================================================
--- trunk/Src/wptUTF8.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptUTF8.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -33,7 +33,7 @@
#include "wptErrors.h"
-static u16 latin2_unicode[128] = {
+static WORD latin2_unicode[128] = {
0x0080,0x0081,0x0082,0x0083,0x0084,0x0085,0x0086,0x0087,
0x0088,0x0089,0x008A,0x008B,0x008C,0x008D,0x008E,0x008F,
0x0090,0x0091,0x0092,0x0093,0x0094,0x0095,0x0096,0x0097,
@@ -54,7 +54,7 @@
static const char *active_charset_name = "iso-8859-1";
-static u16 *active_charset = NULL;
+static WORD *active_charset = NULL;
static int no_translation = 0;
@@ -127,7 +127,7 @@
buffer = (char *)malloc( length + 1 );
for(p=(byte *)buffer, s=(byte *)string; *s; s++ ) {
if( *s & 0x80 ) {
- u16 val = active_charset[ *s & 0x7f ];
+ WORD val = active_charset[ *s & 0x7f ];
if( val < 0x0800 ) {
*p++ = 0xc0 | ( (val >> 6) & 0x1f );
*p++ = 0x80 | ( val & 0x3f );
Modified: trunk/Src/wptW32API.cpp
===================================================================
--- trunk/Src/wptW32API.cpp 2006-03-06 14:41:58 UTC (rev 180)
+++ trunk/Src/wptW32API.cpp 2006-03-14 11:01:22 UTC (rev 181)
@@ -246,11 +246,12 @@
GlobalUnlock (clipmem);
SetClipboardData (CF_TEXT, clipmem);
+ GlobalFree (clipmem);
leave:
CloseClipboard ();
return rc;
-} /* set_clip_text */
+}
/* Append or prepend some text to the clipboard contents.
More information about the Winpt-commits
mailing list