diff options
-rw-r--r-- | g10/import.c | 4 | ||||
-rw-r--r-- | g10/keydb.c | 4 | ||||
-rw-r--r-- | g10/keyedit.c | 4 | ||||
-rw-r--r-- | g10/keyring.c | 8 | ||||
-rw-r--r-- | g10/mainproc.c | 4 | ||||
-rw-r--r-- | g10/packet.h | 96 | ||||
-rw-r--r-- | g10/parse-packet.c | 94 |
7 files changed, 137 insertions, 77 deletions
diff --git a/g10/import.c b/g10/import.c index ea7a92f58..9aa6c8b66 100644 --- a/g10/import.c +++ b/g10/import.c @@ -762,6 +762,7 @@ static int read_block( IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys) { int rc; + struct parse_packet_ctx_s parsectx; PACKET *pkt; kbnode_t root = NULL; int in_cert, in_v3key; @@ -779,8 +780,9 @@ read_block( IOBUF a, PACKET **pending_pkt, kbnode_t *ret_root, int *r_v3keys) pkt = xmalloc (sizeof *pkt); init_packet (pkt); + init_parse_packet (&parsectx, a); in_v3key = 0; - while ((rc=parse_packet(a, pkt)) != -1) + while ((rc=parse_packet (&parsectx, pkt)) != -1) { if (rc && (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY && (pkt->pkttype == PKT_PUBLIC_KEY diff --git a/g10/keydb.c b/g10/keydb.c index 27dacf2d5..c0bc9f521 100644 --- a/g10/keydb.c +++ b/g10/keydb.c @@ -1156,6 +1156,7 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no, const u32 *sigstatus, kbnode_t *r_keyblock) { gpg_error_t err; + struct parse_packet_ctx_s parsectx; PACKET *pkt; kbnode_t keyblock = NULL; kbnode_t node, *tail; @@ -1169,12 +1170,13 @@ parse_keyblock_image (iobuf_t iobuf, int pk_no, int uid_no, if (!pkt) return gpg_error_from_syserror (); init_packet (pkt); + init_parse_packet (&parsectx, iobuf); save_mode = set_packet_list_mode (0); in_cert = 0; n_sigs = 0; tail = NULL; pk_count = uid_count = 0; - while ((err = parse_packet (iobuf, pkt)) != -1) + while ((err = parse_packet (&parsectx, pkt)) != -1) { if (gpg_err_code (err) == GPG_ERR_UNKNOWN_PACKET) { diff --git a/g10/keyedit.c b/g10/keyedit.c index 9a7fe1308..76d188927 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -2431,6 +2431,7 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, char *fname; PACKET *pkt; IOBUF a; + struct parse_packet_ctx_s parsectx; if (!*arg_string) { @@ -2464,7 +2465,8 @@ keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr, /* Parse and check that file. */ pkt = xmalloc (sizeof *pkt); init_packet (pkt); - err = parse_packet (a, pkt); + init_parse_packet (&parsectx, a); + err = parse_packet (&parsectx, pkt); iobuf_close (a); iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char *) fname); if (!err && pkt->pkttype != PKT_SECRET_KEY diff --git a/g10/keyring.c b/g10/keyring.c index 31f60f9fc..e4fc111ed 100644 --- a/g10/keyring.c +++ b/g10/keyring.c @@ -378,6 +378,7 @@ int keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) { PACKET *pkt; + struct parse_packet_ctx_s parsectx; int rc; KBNODE keyblock = NULL, node, lastnode; IOBUF a; @@ -407,10 +408,11 @@ keyring_get_keyblock (KEYRING_HANDLE hd, KBNODE *ret_kb) pkt = xmalloc (sizeof *pkt); init_packet (pkt); + init_parse_packet (&parsectx, a); hd->found.n_packets = 0;; lastnode = NULL; save_mode = set_packet_list_mode(0); - while ((rc=parse_packet (a, pkt)) != -1) { + while ((rc=parse_packet (&parsectx, pkt)) != -1) { hd->found.n_packets++; if (gpg_err_code (rc) == GPG_ERR_UNKNOWN_PACKET) { free_packet (pkt); @@ -985,6 +987,7 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, { int rc; PACKET pkt; + struct parse_packet_ctx_s parsectx; int save_mode; off_t offset, main_offset; size_t n; @@ -1120,12 +1123,13 @@ keyring_search (KEYRING_HANDLE hd, KEYDB_SEARCH_DESC *desc, if (DBG_LOOKUP) log_debug ("%s: %ssearching from start of resource.\n", __func__, scanned_from_start ? "" : "not "); + init_parse_packet (&parsectx, hd->current.iobuf); while (1) { byte afp[MAX_FINGERPRINT_LEN]; size_t an; - rc = search_packet (hd->current.iobuf, &pkt, &offset, need_uid); + rc = search_packet (&parsectx, &pkt, &offset, need_uid); if (ignore_legacy && gpg_err_code (rc) == GPG_ERR_LEGACY_KEY) { free_packet (&pkt); diff --git a/g10/mainproc.c b/g10/mainproc.c index 4c5dce1e0..30d9b1812 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1330,6 +1330,7 @@ static int do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) { PACKET *pkt; + struct parse_packet_ctx_s parsectx; int rc = 0; int any_data = 0; int newpkt; @@ -1341,7 +1342,8 @@ do_proc_packets (ctrl_t ctrl, CTX c, iobuf_t a) pkt = xmalloc( sizeof *pkt ); c->iobuf = a; init_packet(pkt); - while ((rc=parse_packet(a, pkt)) != -1) + init_parse_packet (&parsectx, a); + while ((rc=parse_packet (&parsectx, pkt)) != -1) { any_data = 1; if (rc) diff --git a/g10/packet.h b/g10/packet.h index efccc7659..ffa1fe9d3 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -592,12 +592,26 @@ int list_packets( iobuf_t a ); */ int set_packet_list_mode( int mode ); + +/* A context used with parse_packet. */ +struct parse_packet_ctx_s +{ + iobuf_t inp; /* The input stream with the packets. */ +}; +typedef struct parse_packet_ctx_s *parse_packet_ctx_t; + +#define init_parse_packet(a,i) do { (a)->inp = (i); \ + /**/ } while (0) + + + #if DEBUG_PARSE_PACKET /* There are debug functions and should not be used directly. */ -int dbg_search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid, +int dbg_search_packet (parse_packet_ctx_t ctx, PACKET *pkt, + off_t *retpos, int with_uid, const char* file, int lineno ); -int dbg_parse_packet( iobuf_t inp, PACKET *ret_pkt, - const char* file, int lineno ); +int dbg_parse_packet (parse_packet_ctx_t ctx, PACKET *ret_pkt, + const char *file, int lineno); int dbg_copy_all_packets( iobuf_t inp, iobuf_t out, const char* file, int lineno ); int dbg_copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff, @@ -616,51 +630,53 @@ int dbg_skip_some_packets( iobuf_t inp, unsigned n, dbg_skip_some_packets((a),(b), __FILE__, __LINE__ ) #else /* Return the next valid OpenPGP packet in *PKT. (This function will - skip any packets whose type is 0.) - - Returns 0 on success, -1 if EOF is reached, and an error code - otherwise. In the case of an error, the packet in *PKT may be - partially constructed. As such, even if there is an error, it is - necessary to free *PKT to avoid a resource leak. To detect what - has been allocated, clear *PKT before calling this function. */ -int parse_packet( iobuf_t inp, PACKET *pkt); + * skip any packets whose type is 0.) CTX must have been setup prior to + * calling this function. + * + * Returns 0 on success, -1 if EOF is reached, and an error code + * otherwise. In the case of an error, the packet in *PKT may be + * partially constructed. As such, even if there is an error, it is + * necessary to free *PKT to avoid a resource leak. To detect what + * has been allocated, clear *PKT before calling this function. */ +int parse_packet (parse_packet_ctx_t ctx, PACKET *pkt); /* Return the first OpenPGP packet in *PKT that contains a key (either - a public subkey, a public key, a secret subkey or a secret key) or, - if WITH_UID is set, a user id. - - Saves the position in the pipeline of the start of the returned - packet (according to iobuf_tell) in RETPOS, if it is not NULL. - - The return semantics are the same as parse_packet. */ -int search_packet( iobuf_t inp, PACKET *pkt, off_t *retpos, int with_uid ); + * a public subkey, a public key, a secret subkey or a secret key) or, + * if WITH_UID is set, a user id. + * + * Saves the position in the pipeline of the start of the returned + * packet (according to iobuf_tell) in RETPOS, if it is not NULL. + * + * The return semantics are the same as parse_packet. */ +int search_packet (parse_packet_ctx_t ctx, PACKET *pkt, + off_t *retpos, int with_uid); /* Copy all packets (except invalid packets, i.e., those with a type - of 0) from INP to OUT until either an error occurs or EOF is - reached. - - Returns -1 when end of file is reached or an error code, if an - error occurred. (Note: this function never returns 0, because it - effectively keeps going until it gets an EOF.) */ -int copy_all_packets( iobuf_t inp, iobuf_t out ); + * of 0) from INP to OUT until either an error occurs or EOF is + * reached. + * + * Returns -1 when end of file is reached or an error code, if an + * error occurred. (Note: this function never returns 0, because it + * effectively keeps going until it gets an EOF.) */ +int copy_all_packets (iobuf_t inp, iobuf_t out ); /* Like copy_all_packets, but stops at the first packet that starts at - or after STOPOFF (as indicated by iobuf_tell). - - Example: if STOPOFF is 100, the first packet in INP goes from 0 to - 110 and the next packet starts at offset 111, then the packet - starting at offset 0 will be completely processed (even though it - extends beyond STOPOFF) and the packet starting at offset 111 will - not be processed at all. */ -int copy_some_packets( iobuf_t inp, iobuf_t out, off_t stopoff ); + * or after STOPOFF (as indicated by iobuf_tell). + * + * Example: if STOPOFF is 100, the first packet in INP goes from + * 0 to 110 and the next packet starts at offset 111, then the packet + * starting at offset 0 will be completely processed (even though it + * extends beyond STOPOFF) and the packet starting at offset 111 will + * not be processed at all. */ +int copy_some_packets (iobuf_t inp, iobuf_t out, off_t stopoff); /* Skips the next N packets from INP. - - If parsing a packet returns an error code, then the function stops - immediately and returns the error code. Note: in the case of an - error, this function does not indicate how many packets were - successfully processed. */ -int skip_some_packets( iobuf_t inp, unsigned n ); + * + * If parsing a packet returns an error code, then the function stops + * immediately and returns the error code. Note: in the case of an + * error, this function does not indicate how many packets were + * successfully processed. */ +int skip_some_packets (iobuf_t inp, unsigned int n); #endif /* Parse a signature packet and store it in *SIG. diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 06b286bd7..7766a45f6 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -48,7 +48,7 @@ static int mpi_print_mode; static int list_mode; static estream_t listfp; -static int parse (IOBUF inp, PACKET * pkt, int onlykeypkts, +static int parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos, int *skip, IOBUF out, int do_skip #ifdef DEBUG_PARSE_PACKET , const char *dbg_w, const char *dbg_f, int dbg_l @@ -263,26 +263,27 @@ unknown_pubkey_warning (int algo) #ifdef DEBUG_PARSE_PACKET int -dbg_parse_packet (IOBUF inp, PACKET *pkt, const char *dbg_f, int dbg_l) +dbg_parse_packet (parse_packet_ctx_t ctx, PACKET *pkt, + const char *dbg_f, int dbg_l) { int skip, rc; do { - rc = parse (inp, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l); + rc = parse (ctx, pkt, 0, NULL, &skip, NULL, 0, "parse", dbg_f, dbg_l); } while (skip && ! rc); return rc; } #else /*!DEBUG_PARSE_PACKET*/ int -parse_packet (IOBUF inp, PACKET * pkt) +parse_packet (parse_packet_ctx_t ctx, PACKET *pkt) { int skip, rc; do { - rc = parse (inp, pkt, 0, NULL, &skip, NULL, 0); + rc = parse (ctx, pkt, 0, NULL, &skip, NULL, 0); } while (skip && ! rc); return rc; @@ -296,29 +297,30 @@ parse_packet (IOBUF inp, PACKET * pkt) */ #ifdef DEBUG_PARSE_PACKET int -dbg_search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid, +dbg_search_packet (parse_packet_ctx_t ctx, PACKET *pkt, + off_t * retpos, int with_uid, const char *dbg_f, int dbg_l) { int skip, rc; do { - rc = - parse (inp, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0, "search", - dbg_f, dbg_l); + rc = parse (ctx, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0, "search", + dbg_f, dbg_l); } while (skip && ! rc); return rc; } #else /*!DEBUG_PARSE_PACKET*/ int -search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid) +search_packet (parse_packet_ctx_t ctx, PACKET *pkt, + off_t * retpos, int with_uid) { int skip, rc; do { - rc = parse (inp, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0); + rc = parse (ctx, pkt, with_uid ? 2 : 1, retpos, &skip, NULL, 0); } while (skip && ! rc); return rc; @@ -331,38 +333,45 @@ search_packet (IOBUF inp, PACKET * pkt, off_t * retpos, int with_uid) */ #ifdef DEBUG_PARSE_PACKET int -dbg_copy_all_packets (IOBUF inp, IOBUF out, const char *dbg_f, int dbg_l) +dbg_copy_all_packets (iobuf_t inp, iobuf_t out, const char *dbg_f, int dbg_l) { PACKET pkt; + struct parse_packet_ctx_s parsectx; int skip, rc = 0; if (! out) log_bug ("copy_all_packets: OUT may not be NULL.\n"); + init_parse_packet (&parsectx, inp); + do { init_packet (&pkt); } while (! (rc = - parse (inp, &pkt, 0, NULL, &skip, out, 0, "copy", dbg_f, dbg_l))); + parse (&parsectx, &pkt, 0, NULL, &skip, out, 0, "copy", + dbg_f, dbg_l))); return rc; } #else /*!DEBUG_PARSE_PACKET*/ int -copy_all_packets (IOBUF inp, IOBUF out) +copy_all_packets (iobuf_t inp, iobuf_t out) { PACKET pkt; + struct parse_packet_ctx_s parsectx; int skip, rc = 0; if (! out) log_bug ("copy_all_packets: OUT may not be NULL.\n"); + init_parse_packet (&parsectx, inp); + do { init_packet (&pkt); } - while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0))); + while (!(rc = parse (&parsectx, &pkt, 0, NULL, &skip, out, 0))); return rc; } #endif /*!DEBUG_PARSE_PACKET*/ @@ -375,34 +384,44 @@ copy_all_packets (IOBUF inp, IOBUF out) */ #ifdef DEBUG_PARSE_PACKET int -dbg_copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff, +dbg_copy_some_packets (iobuf_t inp, iobuf_t out, off_t stopoff, const char *dbg_f, int dbg_l) { + int rc = 0; PACKET pkt; - int skip, rc = 0; + int skip; + struct parse_packet_ctx_s parsectx; + + init_parse_packet (&parsectx, inp); + do { if (iobuf_tell (inp) >= stopoff) return 0; init_packet (&pkt); } - while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0, + while (!(rc = parse (&parsectx, &pkt, 0, NULL, &skip, out, 0, "some", dbg_f, dbg_l))); return rc; } #else /*!DEBUG_PARSE_PACKET*/ int -copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff) +copy_some_packets (iobuf_t inp, iobuf_t out, off_t stopoff) { + int rc = 0; PACKET pkt; - int skip, rc = 0; + struct parse_packet_ctx_s parsectx; + int skip; + + init_parse_packet (&parsectx, inp); + do { if (iobuf_tell (inp) >= stopoff) return 0; init_packet (&pkt); } - while (!(rc = parse (inp, &pkt, 0, NULL, &skip, out, 0))); + while (!(rc = parse (&parsectx, &pkt, 0, NULL, &skip, out, 0))); return rc; } #endif /*!DEBUG_PARSE_PACKET*/ @@ -413,29 +432,38 @@ copy_some_packets (IOBUF inp, IOBUF out, off_t stopoff) */ #ifdef DEBUG_PARSE_PACKET int -dbg_skip_some_packets (IOBUF inp, unsigned n, const char *dbg_f, int dbg_l) +dbg_skip_some_packets (iobuf_t inp, unsigned n, const char *dbg_f, int dbg_l) { - int skip, rc = 0; + int rc = 0; + int skip; PACKET pkt; + struct parse_packet_ctx_s parsectx; + + init_parse_packet (&parsectx, inp); for (; n && !rc; n--) { init_packet (&pkt); - rc = parse (inp, &pkt, 0, NULL, &skip, NULL, 1, "skip", dbg_f, dbg_l); + rc = parse (&parsectx, &pkt, 0, NULL, &skip, NULL, 1, "skip", + dbg_f, dbg_l); } return rc; } #else /*!DEBUG_PARSE_PACKET*/ int -skip_some_packets (IOBUF inp, unsigned n) +skip_some_packets (iobuf_t inp, unsigned int n) { - int skip, rc = 0; + int rc = 0; + int skip; PACKET pkt; + struct parse_packet_ctx_s parsectx; + + init_parse_packet (&parsectx, inp); for (; n && !rc; n--) { init_packet (&pkt); - rc = parse (inp, &pkt, 0, NULL, &skip, NULL, 1); + rc = parse (&parsectx, &pkt, 0, NULL, &skip, NULL, 1); } return rc; } @@ -466,18 +494,20 @@ skip_some_packets (IOBUF inp, unsigned n) Note: ONLYKEYPKTS and DO_SKIP are only respected if OUT is NULL, i.e., the packets are not simply being copied. - If RETPOS is not NULL, then the position of INP (as returned by - iobuf_tell) is saved there before any data is read from INP. + If RETPOS is not NULL, then the position of CTX->INP (as returned by + iobuf_tell) is saved there before any data is read from CTX->INP. */ static int -parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos, +parse (parse_packet_ctx_t ctx, PACKET *pkt, int onlykeypkts, off_t * retpos, int *skip, IOBUF out, int do_skip #ifdef DEBUG_PARSE_PACKET , const char *dbg_w, const char *dbg_f, int dbg_l #endif ) { - int rc = 0, c, ctb, pkttype, lenbytes; + int rc = 0; + iobuf_t inp; + int c, ctb, pkttype, lenbytes; unsigned long pktlen; byte hdr[8]; int hdrlen; @@ -486,6 +516,8 @@ parse (IOBUF inp, PACKET * pkt, int onlykeypkts, off_t * retpos, off_t pos; *skip = 0; + inp = ctx->inp; + log_assert (!pkt->pkt.generic); if (retpos || list_mode) { |