aboutsummaryrefslogtreecommitdiffstats
path: root/common/simple-pwquery.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/simple-pwquery.c')
-rw-r--r--common/simple-pwquery.c124
1 files changed, 112 insertions, 12 deletions
diff --git a/common/simple-pwquery.c b/common/simple-pwquery.c
index e7f992a88..0b70ddecc 100644
--- a/common/simple-pwquery.c
+++ b/common/simple-pwquery.c
@@ -1,5 +1,5 @@
/* simple-pwquery.c - A simple password query cleint for gpg-agent
- * Copyright (C) 2002 Free Software Foundation, Inc.
+ * Copyright (C) 2002, 2004 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -40,6 +40,10 @@
#ifdef HAVE_LOCALE_H
#include <locale.h>
#endif
+#ifdef HAVE_W32_SYSTEM
+#include "../jnlib/w32-afunix.h"
+#endif
+
#define SIMPLE_PWQUERY_IMPLEMENTATION 1
#include "simple-pwquery.h"
@@ -63,6 +67,25 @@
#endif
+
+
+
+
+#ifndef HAVE_STPCPY
+static char *
+my_stpcpy(char *a,const char *b)
+{
+ while( *b )
+ *a++ = *b++;
+ *a = 0;
+
+ return (char*)a;
+}
+#define stpcpy(a,b) my_stpcpy((a), (b))
+#endif
+
+
+
/* Write NBYTES of BUF to file descriptor FD. */
static int
writen (int fd, const void *buf, size_t nbytes)
@@ -72,7 +95,11 @@ writen (int fd, const void *buf, size_t nbytes)
while (nleft > 0)
{
- nwritten = write( fd, buf, nleft );
+#ifdef HAVE_W32_SYSTEM
+ nwritten = send (fd, buf, nleft, 0);
+#else
+ nwritten = write (fd, buf, nleft);
+#endif
if (nwritten < 0)
{
if (errno == EINTR)
@@ -102,7 +129,11 @@ readline (int fd, char *buf, size_t buflen)
while (nleft > 0)
{
+#ifdef HAVE_W32_SYSTEM
+ int n = recv (fd, buf, nleft, 0);
+#else
int n = read (fd, buf, nleft);
+#endif
if (n < 0)
{
if (errno == EINTR)
@@ -182,8 +213,10 @@ agent_send_all_options (int fd)
}
dft_ttyname = getenv ("GPG_TTY");
+#ifndef HAVE_W32_SYSTEM
if ((!dft_ttyname || !*dft_ttyname) && ttyname (0))
dft_ttyname = ttyname (0);
+#endif
if (dft_ttyname && *dft_ttyname)
{
if ((rc=agent_send_option (fd, "ttyname", dft_ttyname)))
@@ -259,9 +292,6 @@ agent_send_all_options (int fd)
static int
agent_open (int *rfd)
{
-#ifdef HAVE_W32_SYSTEM
- return SPWQ_NO_AGENT; /* FIXME */
-#else
int rc;
int fd;
char *infostr, *p;
@@ -286,7 +316,7 @@ agent_open (int *rfd)
strcpy (p, infostr);
infostr = p;
- if ( !(p = strchr ( infostr, ':')) || p == infostr
+ if ( !(p = strchr ( infostr, PATHSEP_C)) || p == infostr
|| (p-infostr)+1 >= sizeof client_addr.sun_path )
{
#ifdef SPWQ_USE_LOGGING
@@ -296,7 +326,7 @@ agent_open (int *rfd)
}
*p++ = 0;
- while (*p && *p != ':')
+ while (*p && *p != PATHSEP_C)
p++;
prot = *p? atoi (p+1) : 0;
if ( prot != 1)
@@ -306,8 +336,13 @@ agent_open (int *rfd)
#endif
return SPWQ_PROTOCOL_ERROR;
}
-
- if( (fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1 )
+
+#ifdef HAVE_W32_SYSTEM
+ fd = _w32_sock_new (AF_UNIX, SOCK_STREAM, 0);
+#else
+ fd = socket (AF_UNIX, SOCK_STREAM, 0);
+#endif
+ if (fd == -1)
{
#ifdef SPWQ_USE_LOGGING
log_error ("can't create socket: %s\n", strerror(errno) );
@@ -321,7 +356,12 @@ agent_open (int *rfd)
len = (offsetof (struct sockaddr_un, sun_path)
+ strlen(client_addr.sun_path) + 1);
- if (connect (fd, (struct sockaddr*)&client_addr, len ) == -1)
+#ifdef HAVE_W32_SYSTEM
+ rc = _w32_sock_connect (fd, (struct sockaddr*)&client_addr, len );
+#else
+ rc = connect (fd, (struct sockaddr*)&client_addr, len );
+#endif
+ if (rc == -1)
{
#ifdef SPWQ_USE_LOGGING
log_error ( _("can't connect to `%s': %s\n"), infostr, strerror (errno));
@@ -353,12 +393,11 @@ agent_open (int *rfd)
*rfd = fd;
return 0;
-#endif
}
/* Copy text to BUFFER and escape as required. Return a pointer to
- the end of the new buffer. NOte that BUFFER must be large enough
+ the end of the new buffer. Note that BUFFER must be large enough
to keep the entire text; allocataing it 3 times the size of TEXT
is sufficient. */
static char *
@@ -505,3 +544,64 @@ simple_pwquery (const char *cacheid,
spwq_free (pw);
return result;
}
+
+
+/* Perform the simple query QUERY (which must be new-line and 0
+ terminated) and return the error code. */
+int
+simple_query (const char *query)
+{
+ int fd = -1;
+ int nread;
+ char response[500];
+ int rc;
+
+ rc = agent_open (&fd);
+ if (rc)
+ goto leave;
+
+ rc = writen (fd, query, strlen (query));
+ if (rc)
+ goto leave;
+
+ /* get response */
+ nread = readline (fd, response, 499);
+ if (nread < 0)
+ {
+ rc = -nread;
+ goto leave;
+ }
+ if (nread < 3)
+ {
+ rc = SPWQ_PROTOCOL_ERROR;
+ goto leave;
+ }
+
+ if (response[0] == 'O' && response[1] == 'K')
+ /* OK, do nothing. */;
+ else if ((nread > 7 && !memcmp (response, "ERR 111", 7)
+ && (response[7] == ' ' || response[7] == '\n') )
+ || ((nread > 4 && !memcmp (response, "ERR ", 4)
+ && (strtoul (response+4, NULL, 0) & 0xffff) == 99)) )
+ {
+ /* 111 is the old Assuan code for canceled which might still
+ be in use by old installations. 99 is GPG_ERR_CANCELED as
+ used by modern gpg-agents; 0xffff is used to mask out the
+ error source. */
+#ifdef SPWQ_USE_LOGGING
+ log_info (_("canceled by user\n") );
+#endif
+ }
+ else
+ {
+#ifdef SPWQ_USE_LOGGING
+ log_error (_("problem with the agent\n"));
+#endif
+ rc = SPWQ_ERR_RESPONSE;
+ }
+
+ leave:
+ if (fd != -1)
+ close (fd);
+ return rc;
+}