diff options
author | Werner Koch <[email protected]> | 2011-01-24 11:24:11 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 2011-01-24 11:24:11 +0000 |
commit | c5e8a4c0fdde7f4aef2163a3710483c87bdf3161 (patch) | |
tree | ae9da511231485f5c8ba8faeb3e7db3b971fe8ff /common | |
parent | Fix regression introduced by "editing only change". (diff) | |
parent | Remove keyserver/ from the build system. (diff) | |
download | gnupg-c5e8a4c0fdde7f4aef2163a3710483c87bdf3161.tar.gz gnupg-c5e8a4c0fdde7f4aef2163a3710483c87bdf3161.zip |
Merge branch 'master' into ECC-INTEGRATION-2-1
Diffstat (limited to 'common')
-rw-r--r-- | common/ChangeLog | 52 | ||||
-rw-r--r-- | common/b64dec.c | 32 | ||||
-rw-r--r-- | common/b64enc.c | 22 | ||||
-rw-r--r-- | common/estream.c | 2 | ||||
-rw-r--r-- | common/homedir.c | 2 | ||||
-rw-r--r-- | common/http.c | 121 | ||||
-rw-r--r-- | common/http.h | 15 | ||||
-rw-r--r-- | common/iobuf.c | 127 | ||||
-rw-r--r-- | common/iobuf.h | 2 | ||||
-rw-r--r-- | common/keyserver.h | 24 | ||||
-rw-r--r-- | common/membuf.c | 45 | ||||
-rw-r--r-- | common/membuf.h | 3 | ||||
-rw-r--r-- | common/util.h | 4 |
13 files changed, 392 insertions, 59 deletions
diff --git a/common/ChangeLog b/common/ChangeLog index 6a6f6e071..61f6b292b 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,55 @@ +2011-01-20 Werner Koch <[email protected]> + + Fix bug#1313. + + * http.c (my_select): New. Define to pth_select if building with Pth. + (start_server, write_server, cookie_read, cookie_write): Use it. + (my_connect): New. Define to pth_connect if building with Pth. + (connect_server): Use it. + (my_accept): New. Define to pth_accept if building with Pth. + (start_server): Use it. + +2011-01-20 Werner Koch <[email protected]> + + * util.h (struct b64state): Add field LASTERR. + * b64enc.c (enc_start, b64enc_write, b64enc_finish): Handle + LASTERR. This is to make sure that we don't leak strduped data. + * b64dec.c (b64dec_start, b64dec_proc, b64dec_finish): Ditto. + + * http.c (escape_data): New. + (insert_escapes): Implement using escape_data. + (http_escape_data): New. + +2011-01-19 Werner Koch <[email protected]> + + * homedir.c (gnupg_module_name): Use NAME_OF_INSTALLED_GPG instead + of "gpg2". + +2011-01-18 Werner Koch <[email protected]> + + * iobuf.c (file_es_filter_ctx_t): New. + (file_es_filter): New. + (iobuf_esopen): New. + + * membuf.c (clear_membuf, peek_membuf): New. + + * util.h (GPG_ERR_NO_KEYSERVER): New. + + * keyserver.h (keyserver_spec): Move from ../g10/options.h to here. + + * http.c (do_parse_uri): Add arg NO_SCHEME_CHECK. Change all + callers. Support HKP and HKPS. + (_http_parse_uri): Do proper error management. + * http.h (parsed_uri_s): Add field IS_HTTP. + (http_parse_uri): Support NO_SCHEME_CHECK arg. + + * estream.c (es_func_mem_write): Fix computation of NEWSIZE. + +2011-01-10 Werner Koch <[email protected]> + + * session-env.c (update_var): Fix same value detection. Fixes + bug#1311. + 2011-01-10 Werner Koch <[email protected]> * session-env.c (update_var): Fix same value detection. Fixes diff --git a/common/b64dec.c b/common/b64dec.c index af223aef2..137dd7216 100644 --- a/common/b64dec.c +++ b/common/b64dec.c @@ -1,5 +1,5 @@ /* b64dec.c - Simple Base64 decoder. - * Copyright (C) 2008 Free Software Foundation, Inc. + * Copyright (C) 2008, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -72,16 +72,19 @@ b64dec_start (struct b64state *state, const char *title) if (title) { if (!strncmp (title, "PGP", 3) && (!title[3] || title[3] == ' ')) - return gpg_error (GPG_ERR_NOT_IMPLEMENTED); - - state->title = xtrystrdup (title); - if (!state->title) - return gpg_error_from_syserror (); - state->idx = s_init; + state->lasterr = gpg_error (GPG_ERR_NOT_IMPLEMENTED); + else + { + state->title = xtrystrdup (title); + if (!state->title) + state->lasterr = gpg_error_from_syserror (); + else + state->idx = s_init; + } } else state->idx = s_b64_0; - return 0; + return state->lasterr; } @@ -96,12 +99,18 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length, int pos = state->quad_count; char *d, *s; + if (state->lasterr) + return state->lasterr; + if (state->stop_seen) { *r_nbytes = 0; - return gpg_error (GPG_ERR_EOF); + state->lasterr = gpg_error (GPG_ERR_EOF); + xfree (state->title); + state->title = NULL; + return state->lasterr; } - + for (s=d=buffer; length && !state->stop_seen; length--, s++) { switch (ds) @@ -210,6 +219,9 @@ b64dec_proc (struct b64state *state, void *buffer, size_t length, gpg_error_t b64dec_finish (struct b64state *state) { + if (state->lasterr) + return state->lasterr; + xfree (state->title); state->title = NULL; return state->invalid_encoding? gpg_error(GPG_ERR_BAD_DATA): 0; diff --git a/common/b64enc.c b/common/b64enc.c index 1e277f4cb..5d616198e 100644 --- a/common/b64enc.c +++ b/common/b64enc.c @@ -1,5 +1,6 @@ /* b64enc.c - Simple Base64 encoder. - * Copyright (C) 2001, 2003, 2004, 2008, 2010 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2004, 2008, 2010, + * 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -143,6 +144,7 @@ enc_start (struct b64state *state, FILE *fp, estream_t stream, memset (state, 0, sizeof *state); state->fp = fp; state->stream = stream; + state->lasterr = 0; if (title && !*title) state->flags |= B64ENC_NO_LINEFEEDS; else if (title) @@ -154,9 +156,9 @@ enc_start (struct b64state *state, FILE *fp, estream_t stream, } state->title = xtrystrdup (title); if (!state->title) - return gpg_error_from_syserror (); + state->lasterr = gpg_error_from_syserror (); } - return 0; + return state->lasterr; } @@ -203,6 +205,8 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) int idx, quad_count; const unsigned char *p; + if (state->lasterr) + return state->lasterr; if (!nbytes) { @@ -285,7 +289,13 @@ b64enc_write (struct b64state *state, const void *buffer, size_t nbytes) return 0; write_error: - return gpg_error_from_syserror (); + state->lasterr = gpg_error_from_syserror (); + if (state->title) + { + xfree (state->title); + state->title = NULL; + } + return state->lasterr; } @@ -297,6 +307,9 @@ b64enc_finish (struct b64state *state) int idx, quad_count; char tmp[4]; + if (state->lasterr) + return state->lasterr; + if (!(state->flags & B64ENC_DID_HEADER)) goto cleanup; @@ -404,6 +417,7 @@ b64enc_finish (struct b64state *state) } state->fp = NULL; state->stream = NULL; + state->lasterr = err; return err; } diff --git a/common/estream.c b/common/estream.c index bc25452ed..416aa8376 100644 --- a/common/estream.c +++ b/common/estream.c @@ -641,7 +641,7 @@ es_func_mem_write (void *cookie, const void *buffer, size_t size) if (!mem_cookie->memory_size) newsize = size; /* Not yet allocated. */ else - newsize = mem_cookie->memory_size + (nleft - size); + newsize = mem_cookie->memory_size + (size - nleft); if (newsize < mem_cookie->offset) { _set_errno (EINVAL); diff --git a/common/homedir.c b/common/homedir.c index a6364f8b5..3d31bd376 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -528,7 +528,7 @@ gnupg_module_name (int which) X(bindir, "gpgsm"); case GNUPG_MODULE_NAME_GPG: - X(bindir, "gpg2"); + X(bindir, NAME_OF_INSTALLED_GPG); case GNUPG_MODULE_NAME_CONNECT_AGENT: X(bindir, "gpg-connect-agent"); diff --git a/common/http.c b/common/http.c index 1d84051a2..b50b6b8ad 100644 --- a/common/http.c +++ b/common/http.c @@ -1,6 +1,6 @@ /* http.c - HTTP protocol handler - * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, - * 2009, 2010 Free Software Foundation, Inc. + * Copyright (C) 1999, 2001, 2002, 2003, 2004, 2006, 2009, 2010, + * 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -105,6 +105,16 @@ struct srventry #endif/*!USE_DNS_SRV*/ +#ifdef HAVE_PTH +# define my_select(a,b,c,d,e) pth_select ((a), (b), (c), (d), (e)) +# define my_connect(a,b,c) pth_connect ((a), (b), (c)) +# define my_accept(a,b,c) pth_accept ((a), (b), (c)) +#else +# define my_select(a,b,c,d,e) select ((a), (b), (c), (d), (e)) +# define my_connect(a,b,c) connect ((a), (b), (c)) +# define my_accept(a,b,c) accept ((a), (b), (c)) +#endif + #ifdef HAVE_W32_SYSTEM #define sock_close(a) closesocket(a) #else @@ -138,7 +148,8 @@ typedef unsigned long longcounter_t; typedef void * gnutls_session_t; #endif -static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part); +static gpg_err_code_t do_parse_uri (parsed_uri_t uri, int only_local_part, + int no_scheme_check); static int remove_escapes (char *string); static int insert_escapes (char *buffer, const char *string, const char *special); @@ -356,7 +367,7 @@ _http_open (http_t *r_hd, http_req_t reqtype, const char *url, hd->flags = flags; hd->tls_context = tls_context; - err = _http_parse_uri (&hd->uri, url, errsource); + err = _http_parse_uri (&hd->uri, url, 0, errsource); if (!err) err = send_request (hd, auth, proxy, srvtag, headers, errsource); @@ -368,7 +379,6 @@ _http_open (http_t *r_hd, http_req_t reqtype, const char *url, es_fclose (hd->fp_read); if (hd->fp_write) es_fclose (hd->fp_write); - http_release_parsed_uri (hd->uri); xfree (hd); } else @@ -511,18 +521,27 @@ http_get_status_code (http_t hd) /* * Parse an URI and put the result into the newly allocated RET_URI. - * The caller must always use release_parsed_uri() to releases the - * resources (even on error). + * On success the caller must use release_parsed_uri() to releases the + * resources. If NO_SCHEME_CHECK is set, the function tries to parse + * the URL in the same way it would do for an HTTP style URI. */ gpg_error_t -_http_parse_uri (parsed_uri_t * ret_uri, const char *uri, - gpg_err_source_t errsource) +_http_parse_uri (parsed_uri_t *ret_uri, const char *uri, + int no_scheme_check, gpg_err_source_t errsource) { + gpg_err_code_t ec; + *ret_uri = xtrycalloc (1, sizeof **ret_uri + strlen (uri)); if (!*ret_uri) return gpg_err_make (errsource, gpg_err_code_from_syserror ()); strcpy ((*ret_uri)->buffer, uri); - return gpg_err_make (errsource, do_parse_uri (*ret_uri, 0)); + ec = do_parse_uri (*ret_uri, 0, no_scheme_check); + if (ec) + { + xfree (*ret_uri); + *ret_uri = NULL; + } + return gpg_err_make (errsource, ec); } void @@ -543,7 +562,7 @@ http_release_parsed_uri (parsed_uri_t uri) static gpg_err_code_t -do_parse_uri (parsed_uri_t uri, int only_local_part) +do_parse_uri (parsed_uri_t uri, int only_local_part, int no_scheme_check) { uri_tuple_t *tail; char *p, *p2, *p3, *pp; @@ -557,6 +576,7 @@ do_parse_uri (parsed_uri_t uri, int only_local_part) uri->port = 0; uri->params = uri->query = NULL; uri->use_tls = 0; + uri->is_http = 0; /* A quick validity check. */ if (strspn (p, VALID_URI_CHARS) != n) @@ -572,15 +592,24 @@ do_parse_uri (parsed_uri_t uri, int only_local_part) *pp = tolower (*(unsigned char*)pp); uri->scheme = p; if (!strcmp (uri->scheme, "http")) - uri->port = 80; + { + uri->port = 80; + uri->is_http = 1; + } + else if (!strcmp (uri->scheme, "hkp")) + { + uri->port = 11371; + uri->is_http = 1; + } #ifdef HTTP_USE_GNUTLS - else if (!strcmp (uri->scheme, "https")) + else if (!strcmp (uri->scheme, "https") || !strcmp (uri->scheme,"hkps")) { uri->port = 443; + uri->is_http = 1; uri->use_tls = 1; } #endif - else + else if (!no_scheme_check) return GPG_ERR_INV_URI; /* Unsupported scheme */ p = p2; @@ -723,14 +752,14 @@ remove_escapes (char *string) } -static int -insert_escapes (char *buffer, const char *string, - const char *special) +static size_t +escape_data (char *buffer, const void *data, size_t datalen, + const char *special) { - const unsigned char *s = (const unsigned char*)string; - int n = 0; + const unsigned char *s; + size_t n = 0; - for (; *s; s++) + for (s = data; datalen; s++, datalen--) { if (strchr (VALID_URI_CHARS, *s) && !strchr (special, *s)) { @@ -752,6 +781,14 @@ insert_escapes (char *buffer, const char *string, } +static int +insert_escapes (char *buffer, const char *string, + const char *special) +{ + return escape_data (buffer, string, strlen (string), special); +} + + /* Allocate a new string from STRING using standard HTTP escaping as well as escaping of characters given in SPECIALS. A common pattern for SPECIALS is "%;?&=". However it depends on the needs, for @@ -773,6 +810,27 @@ http_escape_string (const char *string, const char *specials) return buf; } +/* Allocate a new string from {DATA,DATALEN} using standard HTTP + escaping as well as escaping of characters given in SPECIALS. A + common pattern for SPECIALS is "%;?&=". However it depends on the + needs, for example "+" and "/: often needs to be escaped too. + Returns NULL on failure and sets ERRNO. */ +char * +http_escape_data (const void *data, size_t datalen, const char *specials) +{ + int n; + char *buf; + + n = escape_data (NULL, data, datalen, specials); + buf = xtrymalloc (n+1); + if (buf) + { + escape_data (buf, data, datalen, specials); + buf[n] = 0; + } + return buf; +} + static uri_tuple_t @@ -852,12 +910,11 @@ send_request (http_t hd, const char *auth, if (proxy) http_proxy = proxy; - err = _http_parse_uri (&uri, http_proxy, errsource); + err = _http_parse_uri (&uri, http_proxy, 0, errsource); if (err) { log_error ("invalid HTTP proxy (%s): %s\n", http_proxy, gpg_strerror (err)); - http_release_parsed_uri (uri); return gpg_err_make (errsource, GPG_ERR_CONFIGURATION); } @@ -1374,14 +1431,14 @@ start_server () FD_ZERO (&rfds); FD_SET (fd, &rfds); - if (select (fd + 1, &rfds, NULL, NULL, NULL) <= 0) + if (my_select (fd + 1, &rfds, NULL, NULL, NULL) <= 0) continue; /* ignore any errors */ if (!FD_ISSET (fd, &rfds)) continue; addrlen = sizeof peer; - client = accept (fd, (struct sockaddr *) &peer, &addrlen); + client = my_accept (fd, (struct sockaddr *) &peer, &addrlen); if (client == -1) continue; /* oops */ @@ -1451,7 +1508,7 @@ connect_server (const char *server, unsigned short port, addr.sin_port = htons(port); memcpy (&addr.sin_addr,&inaddr,sizeof(inaddr)); - if (!connect (sock,(struct sockaddr *)&addr,sizeof(addr)) ) + if (!my_connect (sock,(struct sockaddr *)&addr,sizeof(addr)) ) return sock; sock_close(sock); return -1; @@ -1519,7 +1576,7 @@ connect_server (const char *server, unsigned short port, return -1; } - if (connect (sock, ai->ai_addr, ai->ai_addrlen)) + if (my_connect (sock, ai->ai_addr, ai->ai_addrlen)) last_errno = errno; else connected = 1; @@ -1573,7 +1630,7 @@ connect_server (const char *server, unsigned short port, for (i = 0; host->h_addr_list[i] && !connected; i++) { memcpy (&addr.sin_addr, host->h_addr_list[i], host->h_length); - if (connect (sock, (struct sockaddr *) &addr, sizeof (addr))) + if (my_connect (sock, (struct sockaddr *) &addr, sizeof (addr))) last_errno = errno; else { @@ -1613,7 +1670,6 @@ write_server (int sock, const char *data, size_t length) int nleft; int nwritten; - /* FIXME: We would better use pth I/O functions. */ nleft = length; while (nleft > 0) { @@ -1640,7 +1696,7 @@ write_server (int sock, const char *data, size_t length) tv.tv_sec = 0; tv.tv_usec = 50000; - select (0, NULL, NULL, NULL, &tv); + my_select (0, NULL, NULL, NULL, &tv); continue; } log_info ("network write failed: %s\n", strerror (errno)); @@ -1686,7 +1742,7 @@ cookie_read (void *cookie, void *buffer, size_t size) tv.tv_sec = 0; tv.tv_usec = 50000; - select (0, NULL, NULL, NULL, &tv); + my_select (0, NULL, NULL, NULL, &tv); goto again; } if (nread == GNUTLS_E_REHANDSHAKE) @@ -1748,7 +1804,7 @@ cookie_write (void *cookie, const void *buffer, size_t size) tv.tv_sec = 0; tv.tv_usec = 50000; - select (0, NULL, NULL, NULL, &tv); + my_select (0, NULL, NULL, NULL, &tv); continue; } log_info ("TLS network write failed: %s\n", @@ -1882,11 +1938,10 @@ main (int argc, char **argv) http_register_tls_callback (verify_callback); #endif /*HTTP_USE_GNUTLS*/ - rc = http_parse_uri (&uri, *argv); + rc = http_parse_uri (&uri, *argv, 0); if (rc) { log_error ("`%s': %s\n", *argv, gpg_strerror (rc)); - http_release_parsed_uri (uri); return 1; } diff --git a/common/http.h b/common/http.h index ac9cb1513..7eecbc004 100644 --- a/common/http.h +++ b/common/http.h @@ -23,7 +23,8 @@ #include <gpg-error.h> #include "../common/estream.h" -struct uri_tuple_s { +struct uri_tuple_s +{ struct uri_tuple_s *next; const char *name; /* A pointer into name. */ char *value; /* A pointer to value (a Nul is always appended). */ @@ -36,8 +37,9 @@ typedef struct uri_tuple_s *uri_tuple_t; struct parsed_uri_s { /* All these pointers point into BUFFER; most stuff is not escaped. */ - char *scheme; /* Pointer to the scheme string (lowercase). */ - int use_tls; /* Whether TLS should be used. */ + char *scheme; /* Pointer to the scheme string (always lowercase). */ + unsigned int is_http:1; /* This is a HTTP style URI. */ + unsigned int use_tls:1; /* Whether TLS should be used. */ char *auth; /* username/password for basic auth */ char *host; /* Host (converted to lowercase). */ unsigned short port; /* Port (always set if the host is set). */ @@ -71,9 +73,9 @@ typedef struct http_context_s *http_t; void http_register_tls_callback (gpg_error_t (*cb) (http_t, void *, int)); gpg_error_t _http_parse_uri (parsed_uri_t *ret_uri, const char *uri, - gpg_err_source_t errsource); -#define http_parse_uri(a,b) \ - _http_parse_uri ((a), (b), GPG_ERR_SOURCE_DEFAULT) + int no_scheme_check, gpg_err_source_t errsource); +#define http_parse_uri(a,b,c) \ + _http_parse_uri ((a), (b), (c), GPG_ERR_SOURCE_DEFAULT) void http_release_parsed_uri (parsed_uri_t uri); @@ -115,6 +117,7 @@ unsigned int http_get_status_code (http_t hd); const char *http_get_header (http_t hd, const char *name); char *http_escape_string (const char *string, const char *specials); +char *http_escape_data (const void *data, size_t datalen, const char *specials); #endif /*GNUPG_COMMON_HTTP_H*/ diff --git a/common/iobuf.c b/common/iobuf.c index b9bed3218..9813d3da6 100644 --- a/common/iobuf.c +++ b/common/iobuf.c @@ -1,6 +1,6 @@ /* iobuf.c - File Handling for OpenPGP. * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, 2006, 2007, 2008, - * 2009, 2010 Free Software Foundation, Inc. + * 2009, 2010, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -78,6 +78,17 @@ typedef struct char fname[1]; /* Name of the file. */ } file_filter_ctx_t; +/* The context used by the estream filter. */ +typedef struct +{ + estream_t fp; /* Open estream handle. */ + int keep_open; + int no_cache; + int eof_seen; + int print_only_name; /* Flags indicating that fname is not a real file. */ + char fname[1]; /* Name of the file. */ +} file_es_filter_ctx_t; + /* Object to control the "close cache". */ struct close_cache_s @@ -577,6 +588,96 @@ file_filter (void *opaque, int control, iobuf_t chain, byte * buf, } +/* Similar to file_filter but using the estream system. */ +static int +file_es_filter (void *opaque, int control, iobuf_t chain, byte * buf, + size_t * ret_len) +{ + file_es_filter_ctx_t *a = opaque; + estream_t f = a->fp; + size_t size = *ret_len; + size_t nbytes = 0; + int rc = 0; + + (void)chain; /* Not used. */ + + if (control == IOBUFCTRL_UNDERFLOW) + { + assert (size); /* We need a buffer. */ + if (a->eof_seen) + { + rc = -1; + *ret_len = 0; + } + else + { + nbytes = 0; + rc = es_read (f, buf, size, &nbytes); + if (rc == -1) + { /* error */ + rc = gpg_error_from_syserror (); + log_error ("%s: read error: %s\n", a->fname, strerror (errno)); + } + else if (!nbytes) + { /* eof */ + a->eof_seen = 1; + rc = -1; + } + *ret_len = nbytes; + } + } + else if (control == IOBUFCTRL_FLUSH) + { + if (size) + { + byte *p = buf; + size_t nwritten; + + nbytes = size; + do + { + nwritten = 0; + if (es_write (f, p, nbytes, &nwritten)) + { + rc = gpg_error_from_syserror (); + log_error ("%s: write error: %s\n", + a->fname, strerror (errno)); + break; + } + p += nwritten; + nbytes -= nwritten; + } + while (nbytes); + nbytes = p - buf; + } + *ret_len = nbytes; + } + else if (control == IOBUFCTRL_INIT) + { + a->eof_seen = 0; + a->no_cache = 0; + } + else if (control == IOBUFCTRL_DESC) + { + *(char **) buf = "estream_filter"; + } + else if (control == IOBUFCTRL_FREE) + { + if (f != es_stdin && f != es_stdout) + { + if (DBG_IOBUF) + log_debug ("%s: es_fclose %p\n", a->fname, f); + if (!a->keep_open) + es_fclose (f); + } + f = NULL; + xfree (a); /* We can free our context now. */ + } + + return rc; +} + + #ifdef HAVE_W32_SYSTEM /* Because network sockets are special objects under Lose32 we have to use a dedicated filter for them. */ @@ -1258,6 +1359,30 @@ iobuf_fdopen_nc (int fd, const char *mode) iobuf_t +iobuf_esopen (estream_t estream, const char *mode, int keep_open) +{ + iobuf_t a; + file_es_filter_ctx_t *fcx; + size_t len; + + a = iobuf_alloc (strchr (mode, 'w') ? 2 : 1, IOBUF_BUFFER_SIZE); + fcx = xtrymalloc (sizeof *fcx + 30); + fcx->fp = estream; + fcx->print_only_name = 1; + fcx->keep_open = keep_open; + sprintf (fcx->fname, "[fd %p]", estream); + a->filter = file_es_filter; + a->filter_ov = fcx; + file_es_filter (fcx, IOBUFCTRL_DESC, NULL, (byte *) & a->desc, &len); + file_es_filter (fcx, IOBUFCTRL_INIT, NULL, NULL, &len); + if (DBG_IOBUF) + log_debug ("iobuf-%d.%d: esopen%s `%s'\n", + a->no, a->subno, keep_open? "_nc":"", fcx->fname); + return a; +} + + +iobuf_t iobuf_sockopen (int fd, const char *mode) { iobuf_t a; diff --git a/common/iobuf.h b/common/iobuf.h index 1d863fdcd..3ac4fa061 100644 --- a/common/iobuf.h +++ b/common/iobuf.h @@ -23,6 +23,7 @@ #include "../include/types.h" /* fixme: should be moved elsewhere. */ #include "../common/sysutils.h" +#include "../common/estream.h" #define DBG_IOBUF iobuf_debug_mode @@ -102,6 +103,7 @@ iobuf_t iobuf_open_fd_or_name (gnupg_fd_t fd, const char *fname, iobuf_t iobuf_open (const char *fname); iobuf_t iobuf_fdopen (int fd, const char *mode); iobuf_t iobuf_fdopen_nc (int fd, const char *mode); +iobuf_t iobuf_esopen (estream_t estream, const char *mode, int keep_open); iobuf_t iobuf_sockopen (int fd, const char *mode); iobuf_t iobuf_create (const char *fname); iobuf_t iobuf_append (const char *fname); diff --git a/common/keyserver.h b/common/keyserver.h index 6455e8c57..d286f7da7 100644 --- a/common/keyserver.h +++ b/common/keyserver.h @@ -1,5 +1,5 @@ /* keyserver.h - Public definitions for gpg keyserver helpers. - * Copyright (C) 2001, 2002 Free Software Foundation, Inc. + * Copyright (C) 2001, 2002, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -39,4 +39,26 @@ /* Must be 127 due to shell internal magic. */ #define KEYSERVER_SCHEME_NOT_FOUND 127 +/* Object to hold information pertaining to a keyserver; it further + allows to build a list of keyservers. Note that g10/options.h has + a typedef for this. FIXME: We should make use of the + parse_uri_t. */ +struct keyserver_spec +{ + struct keyserver_spec *next; + char *uri; + char *scheme; + char *auth; + char *host; + char *port; + char *path; + char *opaque; + strlist_t options; + struct + { + unsigned int direct_uri:1; + } flags; +}; + + #endif /*GNUPG_COMMON_KEYSERVER_H*/ diff --git a/common/membuf.c b/common/membuf.c index f9f82d357..8648044a7 100644 --- a/common/membuf.c +++ b/common/membuf.c @@ -1,5 +1,5 @@ /* membuf.c - A simple implementation of a dynamic buffer. - * Copyright (C) 2001, 2003, 2009 Free Software Foundation, Inc. + * Copyright (C) 2001, 2003, 2009, 2011 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -56,6 +56,26 @@ init_membuf_secure (membuf_t *mb, int initiallen) } +/* Shift the the content of the membuf MB by AMOUNT bytes. The next + operation will then behave as if AMOUNT bytes had not been put into + the buffer. If AMOUNT is greater than the actual accumulated + bytes, the membuf is basically reset to its initial state. */ +void +clear_membuf (membuf_t *mb, size_t amount) +{ + /* No need to clear if we are already out of core. */ + if (mb->out_of_core) + return; + if (amount >= mb->len) + mb->len = 0; + else + { + mb->len -= amount; + memmove (mb->buf, mb->buf+amount, mb->len); + } +} + + void put_membuf (membuf_t *mb, const void *buf, size_t len) { @@ -116,3 +136,26 @@ get_membuf (membuf_t *mb, size_t *len) mb->out_of_core = ENOMEM; /* hack to make sure it won't get reused. */ return p; } + + +/* Peek at the membuf MB. On success a pointer to the buffer is + returned which is valid until the next operation on MB. If LEN is + not NULL the current LEN of the buffer is stored there. On error + NULL is returned and ERRNO is set. */ +const void * +peek_membuf (membuf_t *mb, size_t *len) +{ + const char *p; + + if (mb->out_of_core) + { + gpg_err_set_errno (mb->out_of_core); + return NULL; + } + + p = mb->buf; + if (len) + *len = mb->len; + return p; +} + diff --git a/common/membuf.h b/common/membuf.h index 75b506d5d..9f1a7a33b 100644 --- a/common/membuf.h +++ b/common/membuf.h @@ -39,9 +39,10 @@ typedef struct private_membuf_s membuf_t; void init_membuf (membuf_t *mb, int initiallen); void init_membuf_secure (membuf_t *mb, int initiallen); +void clear_membuf (membuf_t *mb, size_t amount); void put_membuf (membuf_t *mb, const void *buf, size_t len); void put_membuf_str (membuf_t *mb, const char *string); void *get_membuf (membuf_t *mb, size_t *len); - +const void *peek_membuf (membuf_t *mb, size_t *len); #endif /*GNUPG_COMMON_MEMBUF_H*/ diff --git a/common/util.h b/common/util.h index 44a72d90c..99d58e172 100644 --- a/common/util.h +++ b/common/util.h @@ -36,6 +36,9 @@ #ifndef GPG_ERR_MISSING_ISSUER_CERT #define GPG_ERR_MISSING_ISSUER_CERT 185 #endif +#ifndef GPG_ERR_NO_KEYSERVER +#define GPG_ERR_NO_KEYSERVER 186 +#endif #ifndef GPG_ERR_FULLY_CANCELED #define GPG_ERR_FULLY_CANCELED 198 #endif @@ -147,6 +150,7 @@ struct b64state u32 crc; int stop_seen:1; int invalid_encoding:1; + gpg_error_t lasterr; }; gpg_error_t b64enc_start (struct b64state *state, FILE *fp, const char *title); |