commit e0b2498d20b2082339ac02a098b40a11bdbe3ab7
parent ea0fa924213696c5be26a10a20044c23ed83de9e
Author: Hiltjo Posthuma <hiltjo@codemadness.org>
Date: Mon, 18 May 2020 19:15:04 +0200
improve libtls return code handling, check header for truncation
Diffstat:
M | hurl.c | | | 40 | +++++++++++++++++++++++++++++----------- |
1 file changed, 29 insertions(+), 11 deletions(-)
diff --git a/hurl.c b/hurl.c
@@ -209,7 +209,7 @@ https_request(void)
stdport = u.port[0] == '\0' || strcmp(u.port, "443") == 0;
/* create and send HTTP header */
- snprintf(buf, sizeof(buf),
+ r = snprintf(buf, sizeof(buf),
"GET %s HTTP/1.0\r\n"
"Host: %s%s%s\r\n"
"Connection: close\r\n"
@@ -218,22 +218,36 @@ https_request(void)
stdport ? "" : ":",
stdport ? "" : u.port,
config_headers, config_headers[0] ? "\r\n" : "");
- if ((r = tls_write(t, buf, strlen(buf))) < 0) {
- fprintf(stderr, "tls_write: %s\n", tls_error(t));
- goto err;
+ if (r < 0 || (size_t)r >= sizeof(buf))
+ errx(1, "not writing header because it is truncated");
+
+ for (len = r, p = buf; len > 0; ) {
+ r = tls_write(t, p, len);
+ if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) {
+ continue;
+ } else if (r == -1) {
+ fprintf(stderr, "tls_write: %s\n", tls_error(t));
+ goto err;
+ }
+ p += r;
+ len -= r;
}
/* NOTE: HTTP header must fit in the buffer */
- for (len = 0; len < sizeof(buf); len += r) {
+ for (len = 0; len < sizeof(buf);) {
/* NOTE: buffer size is -1 to NUL terminate the buffer for a
string comparison. */
- if ((r = tls_read(t, &buf[len], sizeof(buf) - len - 1)) == 0)
+ r = tls_read(t, &buf[len], sizeof(buf) - len - 1);
+ if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) {
+ continue;
+ } else if (r == 0) {
break;
- if (r < 0) {
+ } else if (r == -1) {
errstr = tls_error(t);
fprintf(stderr, "tls_read: %s\n", errstr ? errstr : "");
goto err;
}
+ len += r;
}
buf[len] = '\0';
@@ -264,9 +278,11 @@ https_request(void)
while (1) {
r = tls_read(t, &buf, sizeof(buf));
- if (r == 0)
+ if (r == TLS_WANT_POLLIN || r == TLS_WANT_POLLOUT) {
+ continue;
+ } else if (r == 0) {
break;
- if (r < 0) {
+ } else if (r == -1) {
errstr = tls_error(t);
fprintf(stderr, "tls_read: %s\n", errstr ? errstr : "");
goto err;
@@ -319,7 +335,7 @@ http_request(void)
stdport = u.port[0] == '\0' || strcmp(u.port, "80") == 0;
/* create and send HTTP header */
- snprintf(buf, sizeof(buf),
+ r = snprintf(buf, sizeof(buf),
"GET %s HTTP/1.0\r\n"
"Host: %s%s%s\r\n"
"Connection: close\r\n"
@@ -328,7 +344,9 @@ http_request(void)
stdport ? "" : ":",
stdport ? "" : u.port,
config_headers, config_headers[0] ? "\r\n" : "");
- if ((r = write(fd, buf, strlen(buf))) == -1) {
+ if (r < 0 || (size_t)r >= sizeof(buf))
+ errx(1, "not writing header because it is truncated");
+ if ((r = write(fd, buf, r)) == -1) {
fprintf(stderr, "write: %s\n", strerror(errno));
goto err;
}