diff --git a/src/http/client.c b/src/http/client.c index 856158e64..224270c23 100644 --- a/src/http/client.c +++ b/src/http/client.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "http.h" @@ -27,6 +28,7 @@ #define DEBUG_LEVEL 5 #include +#define PEMBUF_SIZE 512 enum { CONN_TIMEOUT = 30000, @@ -45,8 +47,8 @@ struct http_cli { struct dnsc *dnsc; struct tls *tls; char *tlshn; - char *cert; - char *key; + struct mbuf *cert; + struct mbuf *key; struct sa laddr; #ifdef HAVE_INET6 struct sa laddr6; @@ -725,45 +727,52 @@ static void query_handler(int err, const struct dnshdr *hdr, struct list *ansl, #ifdef USE_TLS -static int read_file(char **pbuf, const char *path) +static int read_file(struct mbuf **mbp, const char *path) { FILE *f = NULL; - long s = 0; size_t n = 0; - char *buf; + void *buf = NULL; + struct mbuf *mb = NULL; + int err; - if (!pbuf || !path) + if (!mbp || !path) return EINVAL; - f = fopen(path, "r"); - if (!f) { + err = fs_fopen(&f, path, "r"); + if (err) { DEBUG_WARNING("Could not open cert file '%s'\n", path); - return EIO; + return err; } - fseek(f, 0L, SEEK_END); - s = ftell(f); - if (s < 0) { - fclose(f); - return errno; + mb = mbuf_alloc(PEMBUF_SIZE); + buf = mem_zalloc(PEMBUF_SIZE, NULL); + if (!mb || !buf) { + err = ENOMEM; + goto out; } - fseek(f, 0L, SEEK_SET); - buf = mem_zalloc(s + 1, NULL); - if (!buf) { - DEBUG_WARNING("Could not allocate cert file buffer\n"); - fclose(f); - return ENOMEM; + while (1) { + n = fread(buf, 1, PEMBUF_SIZE, f); + if (!n) + goto out; + + err = mbuf_write_mem(mb, buf, n); + if (err) { + DEBUG_WARNING("Error reading cert file"\ + "'%s' (%m)\n", path, err); + goto out; + } } - n = fread(buf, 1, s, f); +out: fclose(f); - if (n < (size_t)s) { - mem_deref(buf); - return EIO; - } - *pbuf = buf; + mem_deref(buf); + if (err) + mem_deref(mb); + else + *mbp = mb; + return 0; } #endif @@ -901,12 +910,12 @@ int http_request(struct http_req **reqp, struct http_cli *cli, const char *met, #ifdef USE_TLS if (cli->cert && cli->key) { err = tls_set_certificate_pem(cli->tls, - cli->cert, strlen(cli->cert), - cli->key, strlen(cli->key)); + (char *)cli->cert->buf, cli->cert->end, + (char *)cli->key->buf, cli->key->end); } else if (cli->cert) { err = tls_set_certificate(cli->tls, - cli->cert, strlen(cli->cert)); + (char *)cli->cert->buf, cli->cert->end); } if (err) goto out; @@ -1161,8 +1170,8 @@ int http_client_set_certpem(struct http_cli *cli, const char *pem) return EINVAL; cli->cert = mem_deref(cli->cert); - - return str_dup(&cli->cert, pem); + cli->cert = mbuf_alloc(PEMBUF_SIZE); + return mbuf_write_str(cli->cert, pem); } @@ -1191,7 +1200,8 @@ int http_client_set_keypem(struct http_cli *cli, const char *pem) cli->key = mem_deref(cli->key); - return str_dup(&cli->key, pem); + cli->key = mbuf_alloc(PEMBUF_SIZE); + return mbuf_write_str(cli->key, pem); }