OK job@

On Tue, Oct 26, 2021 at 05:43:32PM +0200, Claudio Jeker wrote:
> This is part 3 of the BIO removal. Switch tal_parse to pass a file buffer
> like all other callers. The parent process can now just use load_file()
> and pass that buffer to the parser. From there on the magic just happens.
> 
> -- 
> :wq Claudio
> 
> Index: encoding.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/encoding.c,v
> retrieving revision 1.4
> diff -u -p -r1.4 encoding.c
> --- encoding.c        11 Oct 2021 16:06:36 -0000      1.4
> +++ encoding.c        26 Oct 2021 14:40:47 -0000
> @@ -29,11 +29,11 @@
>   * Returns 0 on success or -1 for any errors.
>   */
>  int
> -base64_decode(const unsigned char *in, unsigned char **out, size_t *outlen)
> +base64_decode(const unsigned char *in, size_t inlen,
> +    unsigned char **out, size_t *outlen)
>  {
>       static EVP_ENCODE_CTX *ctx;
>       unsigned char *to;
> -     size_t inlen;
>       int tolen;
>  
>       if (ctx == NULL && (ctx = EVP_ENCODE_CTX_new()) == NULL)
> @@ -42,7 +42,6 @@ base64_decode(const unsigned char *in, u
>       *out = NULL;
>       *outlen = 0;
>  
> -     inlen = strlen(in);
>       if (inlen >= INT_MAX - 3)
>               return -1;
>       tolen = ((inlen + 3) / 4) * 3 + 1;
> Index: extern.h
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/extern.h,v
> retrieving revision 1.79
> diff -u -p -r1.79 extern.h
> --- extern.h  26 Oct 2021 13:31:05 -0000      1.79
> +++ extern.h  26 Oct 2021 14:40:37 -0000
> @@ -337,12 +337,12 @@ enum publish_type {
>   * and parsed.
>   */
>  struct entity {
> -     enum rtype       type; /* type of entity (not RTYPE_EOF) */
> -     char            *file; /* local path to file */
> -     int              has_pkey; /* whether pkey/sz is specified */
> -     unsigned char   *pkey; /* public key (optional) */
> -     size_t           pkeysz; /* public key length (optional) */
> -     char            *descr; /* tal description */
> +     enum rtype       type;          /* type of entity (not RTYPE_EOF) */
> +     char            *file;          /* local path to file */
> +     int              has_data;      /* whether data blob is specified */
> +     unsigned char   *data;          /* optional data blob */
> +     size_t           datasz;        /* length of optional data blob */
> +     char            *descr;         /* tal description */
>       TAILQ_ENTRY(entity) entries;
>  };
>  TAILQ_HEAD(entityq, entity);
> @@ -397,8 +397,7 @@ extern int verbose;
>  
>  void          tal_buffer(struct ibuf *, const struct tal *);
>  void          tal_free(struct tal *);
> -struct tal   *tal_parse(const char *, char *);
> -char         *tal_read_file(const char *);
> +struct tal   *tal_parse(const char *, char *, size_t);
>  struct tal   *tal_read(struct ibuf *);
>  
>  void          cert_buffer(struct ibuf *, const struct cert *);
> @@ -534,8 +533,8 @@ void               cryptoerrx(const char *, ...)
>  
>  /* Encoding functions for hex and base64. */
>  
> -int           base64_decode(const unsigned char *, unsigned char **,
> -                 size_t *);
> +int           base64_decode(const unsigned char *, size_t,
> +                 unsigned char **, size_t *);
>  int           base64_encode(const unsigned char *, size_t, char **);
>  char         *hex_encode(const unsigned char *, size_t);
>  
> @@ -595,8 +594,9 @@ int                output_csv(FILE *, struct vrp_tree
>  int           output_json(FILE *, struct vrp_tree *, struct brk_tree *,
>                   struct stats *);
>  
> -void logx(const char *fmt, ...)
> +void         logx(const char *fmt, ...)
>                   __attribute__((format(printf, 1, 2)));
> +unsigned char        *load_file(const char *, size_t *);
>  
>  int  mkpath(const char *);
>  
> Index: main.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/main.c,v
> retrieving revision 1.154
> diff -u -p -r1.154 main.c
> --- main.c    24 Oct 2021 21:24:19 -0000      1.154
> +++ main.c    26 Oct 2021 14:38:40 -0000
> @@ -20,6 +20,7 @@
>  #include <sys/queue.h>
>  #include <sys/socket.h>
>  #include <sys/resource.h>
> +#include <sys/stat.h>
>  #include <sys/statvfs.h>
>  #include <sys/tree.h>
>  #include <sys/wait.h>
> @@ -82,13 +83,46 @@ logx(const char *fmt, ...)
>       }
>  }
>  
> +unsigned char *
> +load_file(const char *name, size_t *len)
> +{
> +     unsigned char *buf = NULL;
> +     struct stat st;
> +     ssize_t n;
> +     size_t size;
> +     int fd;
> +
> +     *len = 0;
> +
> +     if ((fd = open(name, O_RDONLY)) == -1)
> +             return NULL;
> +     if (fstat(fd, &st) != 0)
> +             goto err;
> +     if (st.st_size < 0)
> +             goto err;
> +     size = (size_t)st.st_size;
> +     if ((buf = malloc(size)) == NULL)
> +             goto err;
> +     n = read(fd, buf, size);
> +     if (n < 0 || (size_t)n != size)
> +             goto err;
> +     close(fd);
> +     *len = size;
> +     return buf;
> +
> +err:
> +     close(fd);
> +     free(buf);
> +     return NULL;
> +}
> +
>  void
>  entity_free(struct entity *ent)
>  {
>       if (ent == NULL)
>               return;
>  
> -     free(ent->pkey);
> +     free(ent->data);
>       free(ent->file);
>       free(ent->descr);
>       free(ent);
> @@ -104,10 +138,10 @@ entity_read_req(struct ibuf *b, struct e
>  {
>       io_read_buf(b, &ent->type, sizeof(ent->type));
>       io_read_str(b, &ent->file);
> -     io_read_buf(b, &ent->has_pkey, sizeof(ent->has_pkey));
> -     if (ent->has_pkey)
> -             io_read_buf_alloc(b, (void **)&ent->pkey, &ent->pkeysz);
>       io_read_str(b, &ent->descr);
> +     io_read_buf(b, &ent->has_data, sizeof(ent->has_data));
> +     if (ent->has_data)
> +             io_read_buf_alloc(b, (void **)&ent->data, &ent->datasz);
>  }
>  
>  /*
> @@ -128,10 +162,10 @@ entity_write_req(const struct entity *en
>       b = io_new_buffer();
>       io_simple_buffer(b, &ent->type, sizeof(ent->type));
>       io_str_buffer(b, ent->file);
> -     io_simple_buffer(b, &ent->has_pkey, sizeof(int));
> -     if (ent->has_pkey)
> -             io_buf_buffer(b, ent->pkey, ent->pkeysz);
>       io_str_buffer(b, ent->descr);
> +     io_simple_buffer(b, &ent->has_data, sizeof(int));
> +     if (ent->has_data)
> +             io_buf_buffer(b, ent->data, ent->datasz);
>       io_close_buffer(&procq, b);
>  }
>  
> @@ -169,7 +203,7 @@ entityq_flush(struct entityq *q, struct 
>   */
>  static void
>  entityq_add(char *file, enum rtype type, struct repo *rp,
> -    const unsigned char *pkey, size_t pkeysz, char *descr)
> +    unsigned char *data, size_t datasz, char *descr)
>  {
>       struct entity   *p;
>  
> @@ -178,12 +212,10 @@ entityq_add(char *file, enum rtype type,
>  
>       p->type = type;
>       p->file = file;
> -     p->has_pkey = pkey != NULL;
> -     if (p->has_pkey) {
> -             p->pkeysz = pkeysz;
> -             if ((p->pkey = malloc(pkeysz)) == NULL)
> -                     err(1, NULL);
> -             memcpy(p->pkey, pkey, pkeysz);
> +     p->has_data = data != NULL;
> +     if (p->has_data) {
> +             p->data = data;
> +             p->datasz = datasz;
>       }
>       if (descr != NULL)
>               if ((p->descr = strdup(descr)) == NULL)
> @@ -388,11 +420,13 @@ queue_add_from_mft_set(const struct mft 
>  static void
>  queue_add_tal(const char *file)
>  {
> -     char    *nfile, *buf;
> +     unsigned char   *buf;
> +     char            *nfile;
> +     size_t           len;
>  
>       if ((nfile = strdup(file)) == NULL)
>               err(1, NULL);
> -     buf = tal_read_file(file);
> +     buf = load_file(file, &len);
>  
>       /* Record tal for later reporting */
>       if (stats.talnames == NULL) {
> @@ -408,9 +442,7 @@ queue_add_tal(const char *file)
>       }
>  
>       /* Not in a repository, so directly add to queue. */
> -     entityq_add(nfile, RTYPE_TAL, NULL, NULL, 0, buf);
> -     /* entityq_add makes a copy of buf */
> -     free(buf);
> +     entityq_add(nfile, RTYPE_TAL, NULL, buf, len, buf);
>  }
>  
>  /*
> @@ -420,13 +452,17 @@ static void
>  queue_add_from_tal(struct tal *tal)
>  {
>       struct repo     *repo;
> +     unsigned char   *data;
>  
>       assert(tal->urisz);
>  
>       /* Look up the repository. */
>       repo = ta_lookup(tal);
>  
> -     entityq_add(NULL, RTYPE_CER, repo, tal->pkey,
> +     /* steal the pkey from the tal structure */
> +     data = tal->pkey;
> +     tal->pkey = NULL;
> +     entityq_add(NULL, RTYPE_CER, repo, data,
>           tal->pkeysz, tal->descr);
>  }
>  
> @@ -683,6 +719,7 @@ main(int argc, char *argv[])
>       char            *bind_addr = NULL;
>       const char      *cachedir = NULL, *outputdir = NULL;
>       const char      *tals[TALSZ_MAX], *errs, *name;
> +     const char      *file = NULL;
>       struct vrp_tree  vrps = RB_INITIALIZER(&vrps);
>       struct brk_tree  brks = RB_INITIALIZER(&brks);
>       struct rusage   ru;
> @@ -709,7 +746,7 @@ main(int argc, char *argv[])
>           "proc exec unveil", NULL) == -1)
>               err(1, "pledge");
>  
> -     while ((c = getopt(argc, argv, "b:Bcd:e:jnorRs:t:T:vV")) != -1)
> +     while ((c = getopt(argc, argv, "b:Bcd:e:f:jnorRs:t:T:vV")) != -1)
>               switch (c) {
>               case 'b':
>                       bind_addr = optarg;
> @@ -725,6 +762,10 @@ main(int argc, char *argv[])
>                       break;
>               case 'e':
>                       rsync_prog = optarg;
> +                     break;
> +             case 'f':
> +                     file = optarg;
> +                     noop = 1;
>                       break;
>               case 'j':
>                       outformats |= FORMAT_JSON;
> Index: parser.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/parser.c,v
> retrieving revision 1.19
> diff -u -p -r1.19 parser.c
> --- parser.c  26 Oct 2021 13:31:05 -0000      1.19
> +++ parser.c  26 Oct 2021 14:24:53 -0000
> @@ -17,13 +17,11 @@
>   */
>  
>  #include <sys/queue.h>
> -#include <sys/stat.h>
>  #include <sys/tree.h>
>  #include <sys/types.h>
>  
>  #include <assert.h>
>  #include <err.h>
> -#include <fcntl.h>
>  #include <poll.h>
>  #include <stdio.h>
>  #include <stdlib.h>
> @@ -201,7 +199,7 @@ proc_parser_cert(const struct entity *en
>       STACK_OF(X509)          *chain;
>       STACK_OF(X509_CRL)      *crls;
>  
> -     assert(!entp->has_pkey);
> +     assert(!entp->has_data);
>  
>       /* Extract certificate data and X509. */
>  
> @@ -294,11 +292,11 @@ proc_parser_root_cert(const struct entit
>       struct auth             *na;
>       char                    *tal;
>  
> -     assert(entp->has_pkey);
> +     assert(entp->has_data);
>  
>       /* Extract certificate data and X509. */
>  
> -     cert = ta_parse(&x509, entp->file, der, len, entp->pkey, entp->pkeysz);
> +     cert = ta_parse(&x509, entp->file, der, len, entp->data, entp->datasz);
>       if (cert == NULL)
>               return NULL;
>  
> @@ -510,39 +508,6 @@ build_crls(const struct crl *crl, STACK_
>               err(1, "sk_X509_CRL_push");
>  }
>  
> -static unsigned char *
> -load_file(const char *name, size_t *len)
> -{
> -     unsigned char *buf = NULL;
> -     struct stat st;
> -     ssize_t n;
> -     size_t size;
> -     int fd;
> -
> -     *len = 0;
> -
> -     if ((fd = open(name, O_RDONLY)) == -1)
> -             return NULL;
> -     if (fstat(fd, &st) != 0)
> -             goto err;
> -     if (st.st_size < 0)
> -             goto err;
> -     size = (size_t)st.st_size;
> -     if ((buf = malloc(size)) == NULL)
> -             goto err;
> -     n = read(fd, buf, size);
> -     if (n < 0 || (size_t)n != size)
> -             goto err;
> -     close(fd);
> -     *len = size;
> -     return buf;
> -
> -err:
> -     close(fd);
> -     free(buf);
> -     return NULL;
> -}
> -
>  static void
>  parse_entity(struct entityq *q, struct msgbuf *msgq)
>  {
> @@ -571,14 +536,15 @@ parse_entity(struct entityq *q, struct m
>  
>               switch (entp->type) {
>               case RTYPE_TAL:
> -                     if ((tal = tal_parse(entp->file, entp->descr)) == NULL)
> +                     if ((tal = tal_parse(entp->file, entp->data,
> +                         entp->datasz)) == NULL)
>                               errx(1, "%s: could not parse tal file",
>                                   entp->file);
>                       tal_buffer(b, tal);
>                       tal_free(tal);
>                       break;
>               case RTYPE_CER:
> -                     if (entp->has_pkey)
> +                     if (entp->has_data)
>                               cert = proc_parser_root_cert(entp, f, flen);
>                       else
>                               cert = proc_parser_cert(entp, f, flen);
> Index: rrdp.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/rrdp.c,v
> retrieving revision 1.14
> diff -u -p -r1.14 rrdp.c
> --- rrdp.c    23 Oct 2021 20:01:16 -0000      1.14
> +++ rrdp.c    26 Oct 2021 14:42:12 -0000
> @@ -661,7 +661,8 @@ publish_done(struct rrdp *s, struct publ
>       size_t datasz = 0;
>  
>       if (pxml->data_length > 0)
> -             if ((base64_decode(pxml->data, &data, &datasz)) == -1)
> +             if ((base64_decode(pxml->data, pxml->data_length,
> +                 &data, &datasz)) == -1)
>                       return -1;
>  
>       /* only send files if the fetch did not fail already */
> Index: tal.c
> ===================================================================
> RCS file: /cvs/src/usr.sbin/rpki-client/tal.c,v
> retrieving revision 1.31
> diff -u -p -r1.31 tal.c
> --- tal.c     23 Oct 2021 16:06:04 -0000      1.31
> +++ tal.c     26 Oct 2021 14:39:52 -0000
> @@ -41,7 +41,7 @@ tal_cmp(const void *a, const void *b)
>   * The pointer must be freed with tal_free().
>   */
>  static struct tal *
> -tal_parse_buffer(const char *fn, char *buf)
> +tal_parse_buffer(const char *fn, char *buf, size_t len)
>  {
>       char            *nl, *line, *f, *file = NULL;
>       unsigned char   *der;
> @@ -49,18 +49,31 @@ tal_parse_buffer(const char *fn, char *b
>       int              rc = 0;
>       struct tal      *tal = NULL;
>       EVP_PKEY        *pkey = NULL;
> +     int              optcomment = 1;
>  
>       if ((tal = calloc(1, sizeof(struct tal))) == NULL)
>               err(1, NULL);
>  
>       /* Begin with the URI section, comment section already removed. */
> -     while ((nl = strchr(buf, '\n')) != NULL) {
> +     while ((nl = memchr(buf, '\n', len)) != NULL) {
>               line = buf;
> +
> +             /* replace LF and optional CR with NUL */
>               *nl = '\0';
> +             if (nl > line && nl[-1] == '\r')
> +                     nl[-1] = '\0';
>  
>               /* advance buffer to next line */
> +             len -= nl + 1 - buf;
>               buf = nl + 1;
>  
> +             if (optcomment) {
> +                     /* if this is a comment, just eat the line */
> +                     if (line[0] == '#')
> +                             continue;
> +                     optcomment = 0;
> +             }
> +
>               /* Zero-length line is end of section. */
>               if (*line == '\0')
>                       break;
> @@ -112,7 +125,7 @@ tal_parse_buffer(const char *fn, char *b
>       qsort(tal->uri, tal->urisz, sizeof(tal->uri[0]), tal_cmp);
>  
>       /* Now the Base64-encoded public key. */
> -     if ((base64_decode(buf, &der, &dersz)) == -1) {
> +     if ((base64_decode(buf, len, &der, &dersz)) == -1) {
>               warnx("%s: RFC 7730 section 2.1: subjectPublicKeyInfo: "
>                   "bad public key", fn);
>               goto out;
> @@ -144,13 +157,13 @@ out:
>   * Returns the encoded data or NULL on syntax failure.
>   */
>  struct tal *
> -tal_parse(const char *fn, char *buf)
> +tal_parse(const char *fn, char *buf, size_t len)
>  {
>       struct tal      *p;
>       const char      *d;
>       size_t           dlen;
>  
> -     p = tal_parse_buffer(fn, buf);
> +     p = tal_parse_buffer(fn, buf, len);
>       if (p == NULL)
>               return NULL;
>  
> @@ -167,76 +180,6 @@ tal_parse(const char *fn, char *buf)
>               err(1, NULL);
>  
>       return p;
> -}
> -
> -/*
> - * Read the file named "file" into a returned, NUL-terminated buffer.
> - * This replaces CRLF terminators with plain LF, if found, and also
> - * elides document-leading comment lines starting with "#".
> - * Files may not exceeds 4096 bytes.
> - * This function exits on failure, so it always returns a buffer with
> - * TAL data.
> - */
> -char *
> -tal_read_file(const char *file)
> -{
> -     char            *nbuf, *line = NULL, *buf = NULL;
> -     FILE            *in;
> -     ssize_t          n, i;
> -     size_t           sz = 0, bsz = 0;
> -     int              optcomment = 1;
> -
> -     if ((in = fopen(file, "r")) == NULL)
> -             err(1, "fopen: %s", file);
> -
> -     while ((n = getline(&line, &sz, in)) != -1) {
> -             /* replace CRLF with just LF */
> -             if (n > 1 && line[n - 1] == '\n' && line[n - 2] == '\r') {
> -                     line[n - 2] = '\n';
> -                     line[n - 1] = '\0';
> -                     n--;
> -             }
> -             if (optcomment) {
> -                     /* if this is comment, just eat the line */
> -                     if (line[0] == '#')
> -                             continue;
> -                     optcomment = 0;
> -                     /*
> -                      * Empty line is end of section and needs
> -                      * to be eaten as well.
> -                      */
> -                     if (line[0] == '\n')
> -                             continue;
> -             }
> -
> -             /* make sure every line is valid ascii */
> -             for (i = 0; i < n; i++)
> -                     if (!isprint((unsigned char)line[i]) &&
> -                         !isspace((unsigned char)line[i]))
> -                             errx(1, "getline: %s: "
> -                                 "invalid content", file);
> -
> -             /* concat line to buf */
> -             if ((nbuf = realloc(buf, bsz + n + 1)) == NULL)
> -                     err(1, NULL);
> -             if (buf == NULL)
> -                     nbuf[0] = '\0'; /* initialize buffer */
> -             buf = nbuf;
> -             bsz += n + 1;
> -             if (strlcat(buf, line, bsz) >= bsz)
> -                     errx(1, "strlcat overflow");
> -             /* limit the buffer size */
> -             if (bsz > 4096)
> -                     errx(1, "%s: file too big", file);
> -     }
> -
> -     free(line);
> -     if (ferror(in))
> -             err(1, "getline: %s", file);
> -     fclose(in);
> -     if (buf == NULL)
> -             errx(1, "%s: no data", file);
> -     return buf;
>  }
>  
>  /*
> 

Reply via email to