diff options
Diffstat (limited to 'common')
-rw-r--r-- | common/ChangeLog | 11 | ||||
-rw-r--r-- | common/b64dec.c | 32 | ||||
-rw-r--r-- | common/b64enc.c | 22 | ||||
-rw-r--r-- | common/http.c | 45 | ||||
-rw-r--r-- | common/http.h | 1 | ||||
-rw-r--r-- | common/util.h | 1 |
6 files changed, 90 insertions, 22 deletions
diff --git a/common/ChangeLog b/common/ChangeLog index 3ce80cb1a..3b7506492 100644 --- a/common/ChangeLog +++ b/common/ChangeLog @@ -1,3 +1,14 @@ +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-18 Werner Koch <[email protected]> * iobuf.c (file_es_filter_ctx_t): New. 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/http.c b/common/http.c index 3d7c463b5..4d3536114 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. * @@ -742,14 +742,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)) { @@ -771,6 +771,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 @@ -792,6 +800,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 diff --git a/common/http.h b/common/http.h index aaa2d3a13..7eecbc004 100644 --- a/common/http.h +++ b/common/http.h @@ -117,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/util.h b/common/util.h index 1f7964fc4..f06701fc0 100644 --- a/common/util.h +++ b/common/util.h @@ -150,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); |