diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/usr.sbin/ocspcheck/http.c | 110 |
1 files changed, 54 insertions, 56 deletions
diff --git a/src/usr.sbin/ocspcheck/http.c b/src/usr.sbin/ocspcheck/http.c index df76a04e60..13b621a064 100644 --- a/src/usr.sbin/ocspcheck/http.c +++ b/src/usr.sbin/ocspcheck/http.c | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | /* $Id: http.c,v 1.5 2017/01/24 10:57:48 deraadt Exp $ */ | 1 | /* $Id: http.c,v 1.6 2017/01/25 13:31:01 benno Exp $ */ |
| 2 | /* | 2 | /* |
| 3 | * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv> | 3 | * Copyright (c) 2016 Kristaps Dzonsons <kristaps@bsd.lv> |
| 4 | * | 4 | * |
| @@ -74,7 +74,7 @@ dosysread(char *buf, size_t sz, const struct http *http) | |||
| 74 | rc = read(http->fd, buf, sz); | 74 | rc = read(http->fd, buf, sz); |
| 75 | if (rc < 0) | 75 | if (rc < 0) |
| 76 | warn("%s: read", http->src.ip); | 76 | warn("%s: read", http->src.ip); |
| 77 | return (rc); | 77 | return rc; |
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static ssize_t | 80 | static ssize_t |
| @@ -85,7 +85,7 @@ dosyswrite(const void *buf, size_t sz, const struct http *http) | |||
| 85 | rc = write(http->fd, buf, sz); | 85 | rc = write(http->fd, buf, sz); |
| 86 | if (rc < 0) | 86 | if (rc < 0) |
| 87 | warn("%s: write", http->src.ip); | 87 | warn("%s: write", http->src.ip); |
| 88 | return (rc); | 88 | return rc; |
| 89 | } | 89 | } |
| 90 | 90 | ||
| 91 | static ssize_t | 91 | static ssize_t |
| @@ -100,7 +100,7 @@ dotlsread(char *buf, size_t sz, const struct http *http) | |||
| 100 | if (rc < 0) | 100 | if (rc < 0) |
| 101 | warnx("%s: tls_read: %s", http->src.ip, | 101 | warnx("%s: tls_read: %s", http->src.ip, |
| 102 | tls_error(http->ctx)); | 102 | tls_error(http->ctx)); |
| 103 | return (rc); | 103 | return rc; |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | static ssize_t | 106 | static ssize_t |
| @@ -115,14 +115,14 @@ dotlswrite(const void *buf, size_t sz, const struct http *http) | |||
| 115 | if (rc < 0) | 115 | if (rc < 0) |
| 116 | warnx("%s: tls_write: %s", http->src.ip, | 116 | warnx("%s: tls_write: %s", http->src.ip, |
| 117 | tls_error(http->ctx)); | 117 | tls_error(http->ctx)); |
| 118 | return (rc); | 118 | return rc; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | int | 121 | int |
| 122 | http_init() | 122 | http_init() |
| 123 | { | 123 | { |
| 124 | if (tlscfg != NULL) | 124 | if (tlscfg != NULL) |
| 125 | return (0); | 125 | return 0; |
| 126 | 126 | ||
| 127 | if (tls_init() == -1) { | 127 | if (tls_init() == -1) { |
| 128 | warn("tls_init"); | 128 | warn("tls_init"); |
| @@ -140,13 +140,13 @@ http_init() | |||
| 140 | goto err; | 140 | goto err; |
| 141 | } | 141 | } |
| 142 | 142 | ||
| 143 | return (0); | 143 | return 0; |
| 144 | 144 | ||
| 145 | err: | 145 | err: |
| 146 | tls_config_free(tlscfg); | 146 | tls_config_free(tlscfg); |
| 147 | tlscfg = NULL; | 147 | tlscfg = NULL; |
| 148 | 148 | ||
| 149 | return (-1); | 149 | return -1; |
| 150 | } | 150 | } |
| 151 | 151 | ||
| 152 | static ssize_t | 152 | static ssize_t |
| @@ -157,7 +157,7 @@ http_read(char *buf, size_t sz, const struct http *http) | |||
| 157 | xfer = 0; | 157 | xfer = 0; |
| 158 | do { | 158 | do { |
| 159 | if ((ssz = http->reader(buf, sz, http)) < 0) | 159 | if ((ssz = http->reader(buf, sz, http)) < 0) |
| 160 | return (-1); | 160 | return -1; |
| 161 | if (ssz == 0) | 161 | if (ssz == 0) |
| 162 | break; | 162 | break; |
| 163 | xfer += ssz; | 163 | xfer += ssz; |
| @@ -165,7 +165,7 @@ http_read(char *buf, size_t sz, const struct http *http) | |||
| 165 | buf += ssz; | 165 | buf += ssz; |
| 166 | } while (ssz > 0 && sz > 0); | 166 | } while (ssz > 0 && sz > 0); |
| 167 | 167 | ||
| 168 | return (xfer); | 168 | return xfer; |
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static int | 171 | static int |
| @@ -176,11 +176,11 @@ http_write(const char *buf, size_t sz, const struct http *http) | |||
| 176 | xfer = sz; | 176 | xfer = sz; |
| 177 | while (sz > 0) { | 177 | while (sz > 0) { |
| 178 | if ((ssz = http->writer(buf, sz, http)) < 0) | 178 | if ((ssz = http->writer(buf, sz, http)) < 0) |
| 179 | return (-1); | 179 | return -1; |
| 180 | sz -= ssz; | 180 | sz -= ssz; |
| 181 | buf += (size_t)ssz; | 181 | buf += (size_t)ssz; |
| 182 | } | 182 | } |
| 183 | return (xfer); | 183 | return xfer; |
| 184 | } | 184 | } |
| 185 | 185 | ||
| 186 | void | 186 | void |
| @@ -235,7 +235,7 @@ http_alloc(const struct source *addrs, size_t addrsz, | |||
| 235 | /* Do this while we still have addresses to connect. */ | 235 | /* Do this while we still have addresses to connect. */ |
| 236 | again: | 236 | again: |
| 237 | if (i == addrsz) | 237 | if (i == addrsz) |
| 238 | return (NULL); | 238 | return NULL; |
| 239 | cur = i++; | 239 | cur = i++; |
| 240 | 240 | ||
| 241 | /* Convert to PF_INET or PF_INET6 address from string. */ | 241 | /* Convert to PF_INET or PF_INET6 address from string. */ |
| @@ -287,7 +287,7 @@ again: | |||
| 287 | if (http == NULL) { | 287 | if (http == NULL) { |
| 288 | warn("calloc"); | 288 | warn("calloc"); |
| 289 | close(fd); | 289 | close(fd); |
| 290 | return (NULL); | 290 | return NULL; |
| 291 | } | 291 | } |
| 292 | http->fd = fd; | 292 | http->fd = fd; |
| 293 | http->port = port; | 293 | http->port = port; |
| @@ -305,7 +305,7 @@ again: | |||
| 305 | if (port != 443) { | 305 | if (port != 443) { |
| 306 | http->writer = dosyswrite; | 306 | http->writer = dosyswrite; |
| 307 | http->reader = dosysread; | 307 | http->reader = dosysread; |
| 308 | return (http); | 308 | return http; |
| 309 | } | 309 | } |
| 310 | 310 | ||
| 311 | http->writer = dotlswrite; | 311 | http->writer = dotlswrite; |
| @@ -326,10 +326,10 @@ again: | |||
| 326 | goto err; | 326 | goto err; |
| 327 | } | 327 | } |
| 328 | 328 | ||
| 329 | return (http); | 329 | return http; |
| 330 | err: | 330 | err: |
| 331 | http_free(http); | 331 | http_free(http); |
| 332 | return (NULL); | 332 | return NULL; |
| 333 | } | 333 | } |
| 334 | 334 | ||
| 335 | struct httpxfer * | 335 | struct httpxfer * |
| @@ -349,21 +349,19 @@ http_open(const struct http *http, const void *p, size_t psz) | |||
| 349 | c = asprintf(&req, | 349 | c = asprintf(&req, |
| 350 | "POST %s HTTP/1.0\r\n" | 350 | "POST %s HTTP/1.0\r\n" |
| 351 | "Host: %s\r\n" | 351 | "Host: %s\r\n" |
| 352 | "Content-Type: application/ocsp-request\r\n" | ||
| 353 | "Accept: application/ocsp-response\r\n" | ||
| 354 | "Content-Length: %zu\r\n" | 352 | "Content-Length: %zu\r\n" |
| 355 | "\r\n", | 353 | "\r\n", |
| 356 | http->path, http->host, psz); | 354 | http->path, http->host, psz); |
| 357 | } | 355 | } |
| 358 | if (c == -1) { | 356 | if (c == -1) { |
| 359 | warn("asprintf"); | 357 | warn("asprintf"); |
| 360 | return (NULL); | 358 | return NULL; |
| 361 | } else if (!http_write(req, c, http)) { | 359 | } else if (!http_write(req, c, http)) { |
| 362 | free(req); | 360 | free(req); |
| 363 | return (NULL); | 361 | return NULL; |
| 364 | } else if (p != NULL && !http_write(p, psz, http)) { | 362 | } else if (p != NULL && !http_write(p, psz, http)) { |
| 365 | free(req); | 363 | free(req); |
| 366 | return (NULL); | 364 | return NULL; |
| 367 | } | 365 | } |
| 368 | 366 | ||
| 369 | free(req); | 367 | free(req); |
| @@ -371,7 +369,7 @@ http_open(const struct http *http, const void *p, size_t psz) | |||
| 371 | trans = calloc(1, sizeof(struct httpxfer)); | 369 | trans = calloc(1, sizeof(struct httpxfer)); |
| 372 | if (trans == NULL) | 370 | if (trans == NULL) |
| 373 | warn("calloc"); | 371 | warn("calloc"); |
| 374 | return (trans); | 372 | return trans; |
| 375 | } | 373 | } |
| 376 | 374 | ||
| 377 | void | 375 | void |
| @@ -409,9 +407,9 @@ http_body_read(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 409 | 407 | ||
| 410 | if (trans->bodyok > 0) { | 408 | if (trans->bodyok > 0) { |
| 411 | *sz = trans->bbufsz; | 409 | *sz = trans->bbufsz; |
| 412 | return (trans->bbuf); | 410 | return trans->bbuf; |
| 413 | } else if (trans->bodyok < 0) | 411 | } else if (trans->bodyok < 0) |
| 414 | return (NULL); | 412 | return NULL; |
| 415 | 413 | ||
| 416 | *sz = 0; | 414 | *sz = 0; |
| 417 | trans->bodyok = -1; | 415 | trans->bodyok = -1; |
| @@ -419,22 +417,22 @@ http_body_read(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 419 | do { | 417 | do { |
| 420 | /* If less than sizeof(buf), at EOF. */ | 418 | /* If less than sizeof(buf), at EOF. */ |
| 421 | if ((ssz = http_read(buf, sizeof(buf), http)) < 0) | 419 | if ((ssz = http_read(buf, sizeof(buf), http)) < 0) |
| 422 | return (NULL); | 420 | return NULL; |
| 423 | else if (ssz == 0) | 421 | else if (ssz == 0) |
| 424 | break; | 422 | break; |
| 425 | pp = realloc(trans->bbuf, trans->bbufsz + ssz); | 423 | pp = realloc(trans->bbuf, trans->bbufsz + ssz); |
| 426 | if (pp == NULL) { | 424 | if (pp == NULL) { |
| 427 | warn("realloc"); | 425 | warn("realloc"); |
| 428 | return (NULL); | 426 | return NULL; |
| 429 | } | 427 | } |
| 430 | trans->bbuf = pp; | 428 | trans->bbuf = pp; |
| 431 | memcpy(trans->bbuf + trans->bbufsz, buf, ssz); | 429 | memcpy(trans->bbuf + trans->bbufsz, buf, ssz); |
| 432 | trans->bbufsz += ssz; | 430 | trans->bbufsz += ssz; |
| 433 | } while (sizeof(buf) == ssz); | 431 | } while (ssz == sizeof(buf)); |
| 434 | 432 | ||
| 435 | trans->bodyok = 1; | 433 | trans->bodyok = 1; |
| 436 | *sz = trans->bbufsz; | 434 | *sz = trans->bbufsz; |
| 437 | return (trans->bbuf); | 435 | return trans->bbuf; |
| 438 | } | 436 | } |
| 439 | 437 | ||
| 440 | struct httphead * | 438 | struct httphead * |
| @@ -445,9 +443,9 @@ http_head_get(const char *v, struct httphead *h, size_t hsz) | |||
| 445 | for (i = 0; i < hsz; i++) { | 443 | for (i = 0; i < hsz; i++) { |
| 446 | if (strcmp(h[i].key, v)) | 444 | if (strcmp(h[i].key, v)) |
| 447 | continue; | 445 | continue; |
| 448 | return (&h[i]); | 446 | return &h[i]; |
| 449 | } | 447 | } |
| 450 | return (NULL); | 448 | return NULL; |
| 451 | } | 449 | } |
| 452 | 450 | ||
| 453 | /* | 451 | /* |
| @@ -463,18 +461,18 @@ http_head_status(const struct http *http, struct httphead *h, size_t sz) | |||
| 463 | 461 | ||
| 464 | if ((st = http_head_get("Status", h, sz)) == NULL) { | 462 | if ((st = http_head_get("Status", h, sz)) == NULL) { |
| 465 | warnx("%s: no status header", http->src.ip); | 463 | warnx("%s: no status header", http->src.ip); |
| 466 | return (-1); | 464 | return -1; |
| 467 | } | 465 | } |
| 468 | 466 | ||
| 469 | rc = sscanf(st->val, "%*s %u %*s", &code); | 467 | rc = sscanf(st->val, "%*s %u %*s", &code); |
| 470 | if (rc < 0) { | 468 | if (rc < 0) { |
| 471 | warn("sscanf"); | 469 | warn("sscanf"); |
| 472 | return (-1); | 470 | return -1; |
| 473 | } else if (rc != 1) { | 471 | } else if (rc != 1) { |
| 474 | warnx("%s: cannot convert status header", http->src.ip); | 472 | warnx("%s: cannot convert status header", http->src.ip); |
| 475 | return (-1); | 473 | return -1; |
| 476 | } | 474 | } |
| 477 | return (code); | 475 | return code; |
| 478 | } | 476 | } |
| 479 | 477 | ||
| 480 | /* | 478 | /* |
| @@ -507,13 +505,13 @@ http_head_parse(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 507 | 505 | ||
| 508 | if (trans->head != NULL) { | 506 | if (trans->head != NULL) { |
| 509 | *sz = trans->headsz; | 507 | *sz = trans->headsz; |
| 510 | return (trans->head); | 508 | return trans->head; |
| 511 | } else if (trans->headok <= 0) | 509 | } else if (trans->headok <= 0) |
| 512 | return (NULL); | 510 | return NULL; |
| 513 | 511 | ||
| 514 | if ((buf = strdup(trans->hbuf)) == NULL) { | 512 | if ((buf = strdup(trans->hbuf)) == NULL) { |
| 515 | warn("strdup"); | 513 | warn("strdup"); |
| 516 | return (NULL); | 514 | return NULL; |
| 517 | } | 515 | } |
| 518 | hsz = 0; | 516 | hsz = 0; |
| 519 | cp = buf; | 517 | cp = buf; |
| @@ -535,7 +533,7 @@ http_head_parse(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 535 | if (h == NULL) { | 533 | if (h == NULL) { |
| 536 | warn("calloc"); | 534 | warn("calloc"); |
| 537 | free(buf); | 535 | free(buf); |
| 538 | return (NULL); | 536 | return NULL; |
| 539 | } | 537 | } |
| 540 | 538 | ||
| 541 | *sz = hsz; | 539 | *sz = hsz; |
| @@ -569,7 +567,7 @@ http_head_parse(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 569 | trans->headbuf = buf; | 567 | trans->headbuf = buf; |
| 570 | trans->head = h; | 568 | trans->head = h; |
| 571 | trans->headsz = hsz; | 569 | trans->headsz = hsz; |
| 572 | return (h); | 570 | return h; |
| 573 | } | 571 | } |
| 574 | 572 | ||
| 575 | /* | 573 | /* |
| @@ -595,9 +593,9 @@ http_head_read(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 595 | 593 | ||
| 596 | if (trans->headok > 0) { | 594 | if (trans->headok > 0) { |
| 597 | *sz = trans->hbufsz; | 595 | *sz = trans->hbufsz; |
| 598 | return (trans->hbuf); | 596 | return trans->hbuf; |
| 599 | } else if (trans->headok < 0) | 597 | } else if (trans->headok < 0) |
| 600 | return (NULL); | 598 | return NULL; |
| 601 | 599 | ||
| 602 | *sz = 0; | 600 | *sz = 0; |
| 603 | ep = NULL; | 601 | ep = NULL; |
| @@ -613,13 +611,13 @@ http_head_read(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 613 | do { | 611 | do { |
| 614 | /* If less than sizeof(buf), at EOF. */ | 612 | /* If less than sizeof(buf), at EOF. */ |
| 615 | if ((ssz = http_read(buf, sizeof(buf), http)) < 0) | 613 | if ((ssz = http_read(buf, sizeof(buf), http)) < 0) |
| 616 | return (NULL); | 614 | return NULL; |
| 617 | else if (ssz == 0) | 615 | else if (ssz == 0) |
| 618 | break; | 616 | break; |
| 619 | pp = realloc(trans->hbuf, trans->hbufsz + ssz); | 617 | pp = realloc(trans->hbuf, trans->hbufsz + ssz); |
| 620 | if (pp == NULL) { | 618 | if (pp == NULL) { |
| 621 | warn("realloc"); | 619 | warn("realloc"); |
| 622 | return (NULL); | 620 | return NULL; |
| 623 | } | 621 | } |
| 624 | trans->hbuf = pp; | 622 | trans->hbuf = pp; |
| 625 | memcpy(trans->hbuf + trans->hbufsz, buf, ssz); | 623 | memcpy(trans->hbuf + trans->hbufsz, buf, ssz); |
| @@ -630,7 +628,7 @@ http_head_read(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 630 | 628 | ||
| 631 | if (ep == NULL) { | 629 | if (ep == NULL) { |
| 632 | warnx("%s: partial transfer", http->src.ip); | 630 | warnx("%s: partial transfer", http->src.ip); |
| 633 | return (NULL); | 631 | return NULL; |
| 634 | } | 632 | } |
| 635 | *ep = '\0'; | 633 | *ep = '\0'; |
| 636 | 634 | ||
| @@ -643,7 +641,7 @@ http_head_read(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 643 | 641 | ||
| 644 | if (strlen(trans->hbuf) != (uintptr_t)(ep - trans->hbuf)) { | 642 | if (strlen(trans->hbuf) != (uintptr_t)(ep - trans->hbuf)) { |
| 645 | warnx("%s: binary data in header", http->src.ip); | 643 | warnx("%s: binary data in header", http->src.ip); |
| 646 | return (NULL); | 644 | return NULL; |
| 647 | } | 645 | } |
| 648 | 646 | ||
| 649 | /* | 647 | /* |
| @@ -655,13 +653,13 @@ http_head_read(const struct http *http, struct httpxfer *trans, size_t *sz) | |||
| 655 | trans->bbuf = malloc(trans->bbufsz); | 653 | trans->bbuf = malloc(trans->bbufsz); |
| 656 | if (trans->bbuf == NULL) { | 654 | if (trans->bbuf == NULL) { |
| 657 | warn("malloc"); | 655 | warn("malloc"); |
| 658 | return (NULL); | 656 | return NULL; |
| 659 | } | 657 | } |
| 660 | memcpy(trans->bbuf, ep, trans->bbufsz); | 658 | memcpy(trans->bbuf, ep, trans->bbufsz); |
| 661 | 659 | ||
| 662 | trans->headok = 1; | 660 | trans->headok = 1; |
| 663 | *sz = trans->hbufsz; | 661 | *sz = trans->hbufsz; |
| 664 | return (trans->hbuf); | 662 | return trans->hbuf; |
| 665 | } | 663 | } |
| 666 | 664 | ||
| 667 | void | 665 | void |
| @@ -689,19 +687,19 @@ http_get(const struct source *addrs, size_t addrsz, const char *domain, | |||
| 689 | 687 | ||
| 690 | h = http_alloc(addrs, addrsz, domain, port, path); | 688 | h = http_alloc(addrs, addrsz, domain, port, path); |
| 691 | if (h == NULL) | 689 | if (h == NULL) |
| 692 | return (NULL); | 690 | return NULL; |
| 693 | 691 | ||
| 694 | if ((x = http_open(h, post, postsz)) == NULL) { | 692 | if ((x = http_open(h, post, postsz)) == NULL) { |
| 695 | http_free(h); | 693 | http_free(h); |
| 696 | return (NULL); | 694 | return NULL; |
| 697 | } else if ((headr = http_head_read(h, x, &headrsz)) == NULL) { | 695 | } else if ((headr = http_head_read(h, x, &headrsz)) == NULL) { |
| 698 | http_close(x); | 696 | http_close(x); |
| 699 | http_free(h); | 697 | http_free(h); |
| 700 | return (NULL); | 698 | return NULL; |
| 701 | } else if ((bod = http_body_read(h, x, &bodsz)) == NULL) { | 699 | } else if ((bod = http_body_read(h, x, &bodsz)) == NULL) { |
| 702 | http_close(x); | 700 | http_close(x); |
| 703 | http_free(h); | 701 | http_free(h); |
| 704 | return (NULL); | 702 | return NULL; |
| 705 | } | 703 | } |
| 706 | 704 | ||
| 707 | http_disconnect(h); | 705 | http_disconnect(h); |
| @@ -709,18 +707,18 @@ http_get(const struct source *addrs, size_t addrsz, const char *domain, | |||
| 709 | if ((head = http_head_parse(h, x, &headsz)) == NULL) { | 707 | if ((head = http_head_parse(h, x, &headsz)) == NULL) { |
| 710 | http_close(x); | 708 | http_close(x); |
| 711 | http_free(h); | 709 | http_free(h); |
| 712 | return (NULL); | 710 | return NULL; |
| 713 | } else if ((code = http_head_status(h, head, headsz)) < 0) { | 711 | } else if ((code = http_head_status(h, head, headsz)) < 0) { |
| 714 | http_close(x); | 712 | http_close(x); |
| 715 | http_free(h); | 713 | http_free(h); |
| 716 | return (NULL); | 714 | return NULL; |
| 717 | } | 715 | } |
| 718 | 716 | ||
| 719 | if ((g = calloc(1, sizeof(struct httpget))) == NULL) { | 717 | if ((g = calloc(1, sizeof(struct httpget))) == NULL) { |
| 720 | warn("calloc"); | 718 | warn("calloc"); |
| 721 | http_close(x); | 719 | http_close(x); |
| 722 | http_free(h); | 720 | http_free(h); |
| 723 | return (NULL); | 721 | return NULL; |
| 724 | } | 722 | } |
| 725 | 723 | ||
| 726 | g->headpart = headr; | 724 | g->headpart = headr; |
| @@ -732,7 +730,7 @@ http_get(const struct source *addrs, size_t addrsz, const char *domain, | |||
| 732 | g->code = code; | 730 | g->code = code; |
| 733 | g->xfer = x; | 731 | g->xfer = x; |
| 734 | g->http = h; | 732 | g->http = h; |
| 735 | return (g); | 733 | return g; |
| 736 | } | 734 | } |
| 737 | 735 | ||
| 738 | #if 0 | 736 | #if 0 |
