aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/ChangeLog33
-rw-r--r--common/Makefile.am4
-rw-r--r--common/estream.c29
-rw-r--r--common/homedir.c149
-rw-r--r--common/http.c12
-rw-r--r--common/init.c73
-rw-r--r--common/simple-pwquery.c49
-rw-r--r--common/simple-pwquery.h41
-rw-r--r--common/util.h16
9 files changed, 381 insertions, 25 deletions
diff --git a/common/ChangeLog b/common/ChangeLog
index 3f4675de1..f0381229e 100644
--- a/common/ChangeLog
+++ b/common/ChangeLog
@@ -1,3 +1,36 @@
+2007-06-14 Werner Koch <[email protected]>
+
+ * simple-pwquery.h (MAP_SPWQ_ERROR_IMPL): New.
+ (SPWQ_NO_PIN_ENTRY): New.
+ * simple-pwquery.c (simple_pw_set_socket): New.
+ (agent_open): Use it if GPG_AGENT_INFO is not set.
+ (simple_pwquery): Extended to allow returning of otehyr error codes.
+
+ * util.h (GNUPG_MODULE_NAME_AGENT, GNUPG_MODULE_NAME_PINENTRY)
+ (GNUPG_MODULE_NAME_SCDAEMON, GNUPG_MODULE_NAME_DIRMNGR)
+ (GNUPG_MODULE_NAME_PROTECT_TOOL): New.
+ * homedir.c (gnupg_module_name): New.
+ (gnupg_bindir): New.
+
+2007-06-12 Werner Koch <[email protected]>
+
+ * homedir.c (gnupg_sysconfdir): New.
+ (gnupg_libexecdir): New. Taken from g10/misc.c:get_libexecdir.
+ (gnupg_datadir): New.
+ (gnupg_libdir): New.
+
+ * http.c (connect_server) [W32]: Do not call init_sockets if
+ HTTP_NO_WSASTARTUP is defined.
+
+ * init.c: New.
+
+ * estream.c (es_init_do): Init stream lock here because we can't
+ use a static initialization with W32pth.
+
+2007-06-11 Werner Koch <[email protected]>
+
+ * Makefile.am (t_common_ldadd): Use libcommonstd macro.
+
2007-06-06 Werner Koch <[email protected]>
* Makefile.am: Include am/cmacros.am.
diff --git a/common/Makefile.am b/common/Makefile.am
index 8f70cdc28..51682306d 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -37,6 +37,7 @@ common_sources = \
openpgpdefs.h \
keyserver.h \
sexp-parse.h \
+ init.c \
sexputil.c \
sysutils.c sysutils.h \
homedir.c \
@@ -59,6 +60,7 @@ common_sources = \
pka.c pka.h \
http.c http.h
+
libcommon_a_SOURCES = $(common_sources)
if USE_DNS_SRV
libcommon_a_SOURCES += srv.c
@@ -83,7 +85,7 @@ libgpgrl_a_SOURCES = \
#
module_tests = t-convert
-t_common_ldadd = ../jnlib/libjnlib.a ../common/libcommon.a ../gl/libgnu.a \
+t_common_ldadd = ../jnlib/libjnlib.a $(libcommon) ../gl/libgnu.a \
$(LIBGCRYPT_LIBS) $(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)
t_convert_DEPENDENCIES = convert.c libcommon.a
diff --git a/common/estream.c b/common/estream.c
index 05b1230ad..131ddc232 100644
--- a/common/estream.c
+++ b/common/estream.c
@@ -109,8 +109,6 @@ typedef pth_mutex_t estream_mutex_t;
((pth_mutex_acquire (&(mutex), 1, NULL) == TRUE) ? 0 : -1)
# define ESTREAM_MUTEX_INITIALIZE(mutex) \
pth_mutex_init (&(mutex))
-# define ESTREAM_THREADING_INIT() ((pth_init () == TRUE) ? 0 : -1)
-
#else
typedef void *estream_mutex_t;
@@ -119,8 +117,6 @@ typedef void *estream_mutex_t;
# define ESTREAM_MUTEX_UNLOCK(mutex) (void) 0
# define ESTREAM_MUTEX_TRYLOCK(mutex) 0
# define ESTREAM_MUTEX_INITIALIZE(mutex) (void) 0
-# define ESTREAM_THREADING_INIT() 0
-
#endif
/* Memory allocator functions. */
@@ -194,13 +190,9 @@ struct estream_list
static estream_list_t estream_list;
#ifdef HAVE_PTH
-/* Note that we can't use a static initialization with W32Pth; however
- W32Pth does an implicit initialization anyway. */
-static estream_mutex_t estream_list_lock
-# ifndef _W32_PTH_H
- = ESTREAM_MUTEX_INITIALIZER
-# endif
- ;
+/* Note that we can't use a static initialization with W32Pth, thus we
+ do it in es_init. */
+static estream_mutex_t estream_list_lock;
#endif
#define ESTREAM_LIST_LOCK ESTREAM_MUTEX_LOCK (estream_list_lock)
@@ -308,11 +300,18 @@ es_list_iterate (estream_iterator_t iterator)
static int
es_init_do (void)
{
- int err;
-
- err = ESTREAM_THREADING_INIT ();
+#ifdef HAVE_PTH
+ static int initialized;
- return err;
+ if (!initialized)
+ {
+ if (!pth_init ())
+ return -1;
+ if (pth_mutex_init (&estream_list_lock))
+ initialized = 1;
+ }
+#endif
+ return 0;
}
diff --git a/common/homedir.c b/common/homedir.c
index 39d6dce20..654c96bec 100644
--- a/common/homedir.c
+++ b/common/homedir.c
@@ -124,3 +124,152 @@ default_homedir (void)
return dir;
}
+
+
+/* Return the name of the sysconfdir. This is a static string. This
+ function is required because under Windows we can't simply compile
+ it in. */
+const char *
+gnupg_sysconfdir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+#warning get the sysconfdir from somewhere else
+ return GNUPG_SYSCONFDIR;
+#else /*!HAVE_W32_SYSTEM*/
+ return GNUPG_SYSCONFDIR;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+const char *
+gnupg_bindir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+ return gnupg_libexecdir ();
+#else /*!HAVE_W32_SYSTEM*/
+ return GNUPG_BINDIR;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+/* Return the name of the libexec directory. The name is allocated in
+ a static area on the first use. This function won't fail. */
+const char *
+gnupg_libexecdir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+ static int got_dir;
+ static char dir[MAX_PATH+5];
+
+ if (!got_dir)
+ {
+ char *p;
+
+ if ( !GetModuleFileName ( NULL, dir, MAX_PATH) )
+ {
+ log_debug ("GetModuleFileName failed: %s\n", w32_strerror (0));
+ *dir = 0;
+ }
+ got_dir = 1;
+ p = strrchr (dir, DIRSEP_C);
+ if (p)
+ *p = 0;
+ else
+ {
+ log_debug ("bad filename `%s' returned for this process\n", dir);
+ *dir = 0;
+ }
+ }
+
+ if (*dir)
+ return dir;
+ /* Fallback to the hardwired value. */
+#endif /*HAVE_W32_SYSTEM*/
+
+ return GNUPG_LIBEXECDIR;
+}
+
+const char *
+gnupg_libdir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+#warning get the libdir from somewhere else
+ return GNUPG_LIBDIR;
+#else /*!HAVE_W32_SYSTEM*/
+ return GNUPG_LIBDIR;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+const char *
+gnupg_datadir (void)
+{
+#ifdef HAVE_W32_SYSTEM
+#warning get the datadir from somewhere else
+ return GNUPG_DATADIR;
+#else /*!HAVE_W32_SYSTEM*/
+ return GNUPG_DATADIR;
+#endif /*!HAVE_W32_SYSTEM*/
+}
+
+
+/* Return the file name of a helper tool. WHICH is one of the
+ GNUPG_MODULE_NAME_foo constants. */
+const char *
+gnupg_module_name (int which)
+{
+ const char *s, *s2;
+
+#define X(a,b) do { \
+ static char *name; \
+ if (!name) \
+ { \
+ s = gnupg_ ## a (); \
+ s2 = DIRSEP_S b EXEEXT_S; \
+ name = xmalloc (strlen (s) + strlen (s2) + 1); \
+ strcpy (stpcpy (name, s), s2); \
+ } \
+ return name; \
+ } while (0)
+
+ switch (which)
+ {
+ case GNUPG_MODULE_NAME_AGENT:
+#ifdef GNUPG_DEFAULT_AGENT
+ return GNUPG_DEFAULT_AGENT;
+#else
+ X(bindir, "gpg-agent");
+#endif
+
+ case GNUPG_MODULE_NAME_PINENTRY:
+#ifdef GNUPG_DEFAULT_PINENTRY
+ return GNUPG_DEFAULT_PINENTRY;
+#else
+ X(bindir, "pinentry");
+#endif
+
+ case GNUPG_MODULE_NAME_SCDAEMON:
+#ifdef GNUPG_DEFAULT_SCDAEMON
+ return GNUPG_DEFAULT_SCDAEMON;
+#else
+ X(bindir, "scdaemon");
+#endif
+
+ case GNUPG_MODULE_NAME_DIRMNGR:
+#ifdef GNUPG_DEFAULT_DIRMNGR
+ return GNUPG_DEFAULT_DIRMNGR;
+#else
+ X(bindir, "dirmngr");
+#endif
+
+ case GNUPG_MODULE_NAME_PROTECT_TOOL:
+#ifdef GNUPG_DEFAULT_PROTECT_TOOL
+ return GNUPG_DEFAULT_PROTECT_TOOL;
+#else
+ X(libexecdir, "gpg-protect-tool");
+#endif
+
+ default:
+ BUG ();
+ }
+#undef X
+}
diff --git a/common/http.c b/common/http.c
index 4693c33e2..293a96a2b 100644
--- a/common/http.c
+++ b/common/http.c
@@ -30,6 +30,10 @@
- With HTTP_USE_ESTREAM defined, all I/O is done through estream.
- With HTTP_USE_GNUTLS support for https is provided (this also
requires estream).
+ - With HTTP_NO_WSASTARTUP the socket initialization is not done
+ under Windows. This is useful if the socket layer has already
+ been initialized elsewhere. This also avoids the installation of
+ an exit handler to cleanup the socket layer.
*/
#ifdef HAVE_CONFIG_H
@@ -200,7 +204,7 @@ struct http_context_s
-#ifdef HAVE_W32_SYSTEM
+#if defined(HAVE_W32_SYSTEM) && !defined(HTTP_NO_WSASTARTUP)
#if GNUPG_MAJOR_VERSION == 1
#define REQ_WINSOCK_MAJOR 1
@@ -244,7 +248,7 @@ init_sockets (void)
atexit ( deinit_sockets );
initialized = 1;
}
-#endif /*HAVE_W32_SYSTEM*/
+#endif /*HAVE_W32_SYSTEM && !HTTP_NO_WSASTARTUP*/
@@ -1504,7 +1508,9 @@ connect_server (const char *server, unsigned short port,
#ifdef HAVE_W32_SYSTEM
unsigned long inaddr;
- init_sockets();
+#ifndef HTTP_NO_WSASTARTUP
+ init_sockets ();
+#endif
/* Win32 gethostbyname doesn't handle IP addresses internally, so we
try inet_addr first on that platform only. */
inaddr = inet_addr(server);
diff --git a/common/init.c b/common/init.c
new file mode 100644
index 000000000..9ac6006c2
--- /dev/null
+++ b/common/init.c
@@ -0,0 +1,73 @@
+/* init.c - Various initializations
+ * Copyright (C) 2007 Free Software Foundation, Inc.
+ *
+ * This file is part of GnuPG.
+ *
+ * GnuPG 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.
+ *
+ * GnuPG is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ * USA.
+ */
+
+#include <config.h>
+
+#ifdef WITHOUT_GNU_PTH /* Give the Makefile a chance to build without Pth. */
+#undef HAVE_PTH
+#undef USE_GNU_PTH
+#endif
+
+#ifdef HAVE_W32_SYSTEM
+#include <windows.h>
+#endif
+#ifdef HAVE_PTH
+#include <pth.h>
+#endif
+
+#include "estream.h"
+#include "util.h"
+
+
+/* This function is to be used early at program startup to make sure
+ that some subsystems are initialized. This is in particualr
+ important for W32 to initialize the sockets so that our socket
+ emulation code used directly as well as in libassuan may be used.
+ It should best be called before any I/O is done so that setup
+ required for logging is ready. CAUTION: This might be called while
+ running suid(root). */
+void
+init_common_subsystems (void)
+{
+ /* Try to auto set the character set. */
+ set_native_charset (NULL);
+
+#ifdef HAVE_W32_SYSTEM
+ /* For W32 we need to initialize the socket layer. This is becuase
+ we use recv and send in libassuan as well as at some other
+ places. If we are building with PTH we let pth_init do it. We
+ can't do much on error so we ignore them. An error would anyway
+ later pop up if one of the socket functions is used. */
+# ifdef HAVE_PTH
+ pth_init ();
+# else
+ {
+ WSADATA wsadat;
+
+ WSAStartup (0x202, &wsadat);
+ }
+# endif /*!HAVE_PTH*/
+#endif
+
+ /* Initialize the Estream library. */
+ es_init ();
+}
+
diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c
index f0c1cdc00..217ca69cd 100644
--- a/common/simple-pwquery.c
+++ b/common/simple-pwquery.c
@@ -1,5 +1,5 @@
/* simple-pwquery.c - A simple password query client for gpg-agent
- * Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2004, 2007 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -68,6 +68,11 @@
#endif
+/* Name of the socket to be used if GPG_AGENT_INFO has not been
+ set. No default socket is used if this is NULL. */
+static char *default_gpg_agent_info;
+
+
@@ -154,9 +159,9 @@ readline (int fd, char *buf, size_t buflen)
;
if (n)
{
- break; /* at least one full line available - that's enough.
+ break; /* At least one full line available - that's enough.
This function is just a simple implementation, so
- it is okay to forget about pending bytes */
+ it is okay to forget about pending bytes. */
}
}
@@ -305,6 +310,8 @@ agent_open (int *rfd)
*rfd = -1;
infostr = getenv ( "GPG_AGENT_INFO" );
if ( !infostr || !*infostr )
+ infostr = default_gpg_agent_info;
+ if ( !infostr || !*infostr )
{
#ifdef SPWQ_USE_LOGGING
log_error (_("gpg-agent is not available in this session\n"));
@@ -322,6 +329,9 @@ agent_open (int *rfd)
{
#ifdef SPWQ_USE_LOGGING
log_error ( _("malformed GPG_AGENT_INFO environment variable\n"));
+ log_debug ( "a='%s'\n", infostr);
+ log_debug ( "a='%s'\n", strchr ( infostr, PATHSEP_C));
+ log_debug ( "a=%td\n", (p-infostr));
#endif
return SPWQ_NO_AGENT;
}
@@ -425,13 +435,34 @@ copy_and_escape (char *buffer, const char *text)
}
+/* Set the name of the default socket to NAME. */
+int
+simple_pw_set_socket (const char *name)
+{
+ spwq_free (default_gpg_agent_info);
+ if (name)
+ {
+ default_gpg_agent_info = spwq_malloc (strlen (name) + 4 + 1);
+ if (!default_gpg_agent_info)
+ return SPWQ_OUT_OF_CORE;
+ /* We don't know the PID thus we use 0. */
+ strcpy (stpcpy (default_gpg_agent_info, name),
+ PATHSEP_S "0" PATHSEP_S "1");
+ }
+ else
+ default_gpg_agent_info = NULL;
+
+ return 0;
+}
+
+
/* Ask the gpg-agent for a passphrase and present the user with a
DESCRIPTION, a PROMPT and optionally with a TRYAGAIN extra text.
If a CACHEID is not NULL it is used to locate the passphrase in in
the cache and store it under this ID. If OPT_CHECK is true
gpg-agent is asked to apply some checks on the passphrase security.
If ERRORCODE is not NULL it should point a variable receiving an
- errorcode; this errocode might be 0 if the user canceled the
+ errorcode; this error code might be 0 if the user canceled the
operation. The function returns NULL to indicate an error. */
char *
simple_pwquery (const char *cacheid,
@@ -530,7 +561,15 @@ simple_pwquery (const char *cacheid,
#ifdef SPWQ_USE_LOGGING
log_info (_("canceled by user\n") );
#endif
- *errorcode = 0; /* canceled */
+ *errorcode = 0; /* Special error code to indicate Cancel. */
+ }
+ else if (nread > 4 && !memcmp (pw, "ERR ", 4))
+ {
+ switch ( (strtoul (pw+4, NULL, 0) & 0xffff) )
+ {
+ case 85: rc = SPWQ_NO_PIN_ENTRY; break;
+ default: rc = SPWQ_GENERAL_ERROR; break;
+ }
}
else
{
diff --git a/common/simple-pwquery.h b/common/simple-pwquery.h
index ab2724ffa..cb5d9354b 100644
--- a/common/simple-pwquery.h
+++ b/common/simple-pwquery.h
@@ -41,7 +41,6 @@
#define spwq_secure_malloc(a) gcry_malloc_secure (a)
#define spwq_secure_free(a) gcry_free (a)
-
#endif /*SIMPLE_PWQUERY_IMPLEMENTATION*/ /* End configuration stuff. */
@@ -67,6 +66,11 @@ int simple_pwclear (const char *cacheid);
terminated) and return the error code. */
int simple_query (const char *query);
+/* Set the name of the standard socket to be used if GPG_AGENT_INFO is
+ not defined. The use of this function is optional but if it needs
+ to be called before any other function. Returns 0 on success. */
+int simple_pw_set_socket (const char *name);
+
#define SPWQ_OUT_OF_CORE 1
#define SPWQ_IO_ERROR 2
#define SPWQ_PROTOCOL_ERROR 3
@@ -74,5 +78,40 @@ int simple_query (const char *query);
#define SPWQ_NO_AGENT 5
#define SPWQ_SYS_ERROR 6
#define SPWQ_GENERAL_ERROR 7
+#define SPWQ_NO_PIN_ENTRY 8
+
+
+/* We often need to map error codes to gpg-error style error codes.
+ To have a consistent mapping this macro may be used to implemt the
+ mapping function. */
+#define MAP_SPWQ_ERROR_IMPL \
+ static gpg_error_t \
+ map_spwq_error (int err) \
+ { \
+ switch (err) \
+ { \
+ case 0: \
+ return 0; \
+ case SPWQ_OUT_OF_CORE: \
+ return gpg_error_from_errno (ENOMEM); \
+ case SPWQ_IO_ERROR: \
+ return gpg_error_from_errno (EIO); \
+ case SPWQ_PROTOCOL_ERROR: \
+ return gpg_error (GPG_ERR_PROTOCOL_VIOLATION); \
+ case SPWQ_ERR_RESPONSE: \
+ return gpg_error (GPG_ERR_INV_RESPONSE); \
+ case SPWQ_NO_AGENT: \
+ return gpg_error (GPG_ERR_NO_AGENT); \
+ case SPWQ_SYS_ERROR: \
+ return gpg_error_from_syserror (); \
+ case SPWQ_NO_PIN_ENTRY: \
+ return gpg_error (GPG_ERR_NO_PIN_ENTRY); \
+ case SPWQ_GENERAL_ERROR: \
+ default: \
+ return gpg_error (GPG_ERR_GENERAL); \
+ } \
+ }
+/* End of MAP_SPWQ_ERROR_IMPL. */
+
#endif /*SIMPLE_PWQUERY_H*/
diff --git a/common/util.h b/common/util.h
index 3b7050132..42df1274f 100644
--- a/common/util.h
+++ b/common/util.h
@@ -120,6 +120,8 @@ gnupg_copy_time (gnupg_isotime_t d, const gnupg_isotime_t s)
strcpy (d, s);
}
+/*-- init.c --*/
+void init_common_subsystems (void);
/*-- signal.c --*/
void gnupg_init_signals (int mode, void (*fast_cleanup)(void));
@@ -170,6 +172,20 @@ char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
/*-- homedir.c --*/
const char *default_homedir (void);
+const char *gnupg_sysconfdir (void);
+const char *gnupg_bindir (void);
+const char *gnupg_libexecdir (void);
+const char *gnupg_libdir (void);
+const char *gnupg_datadir (void);
+
+#define GNUPG_MODULE_NAME_AGENT 1
+#define GNUPG_MODULE_NAME_PINENTRY 2
+#define GNUPG_MODULE_NAME_SCDAEMON 3
+#define GNUPG_MODULE_NAME_DIRMNGR 4
+#define GNUPG_MODULE_NAME_PROTECT_TOOL 5
+const char *gnupg_module_name (int which);
+
+
/*-- gpgrlhelp.c --*/
void gnupg_rl_initialize (void);