diff options
-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 |