Blob Blame History Raw
From cfb82199afe237b4e892aaf2816db63279d7cb21 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
Date: Tue, 28 Feb 2017 14:14:40 +0100
Subject: [PATCH 84/90] secrets: remove http-parser code in proxy provider

We switche to libcurl in previous patch. This just removes the unused code.

Resolves:
https://pagure.io/SSSD/sssd/issue/3192

Reviewed-by: Simo Sorce <simo@redhat.com>
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
(cherry picked from commit 06744bf5a47d5971a338281c8243b11cf72dac90)
---
 src/responder/secrets/proxy.c | 581 ------------------------------------------
 1 file changed, 581 deletions(-)

diff --git a/src/responder/secrets/proxy.c b/src/responder/secrets/proxy.c
index fe2f0134e233d9a98f499fe563abe0af69762514..3c495716010ac468c9e2f1fb6356529a8dbdc614 100644
--- a/src/responder/secrets/proxy.c
+++ b/src/responder/secrets/proxy.c
@@ -395,587 +395,6 @@ done:
     return ret;
 }
 
-struct proxy_http_request {
-    struct sec_data *data;
-    size_t written;
-};
-
-struct proxy_http_reply {
-    http_parser parser;
-    bool complete;
-
-    int status_code;
-    char *reason_phrase;
-    struct sec_kvp *headers;
-    int num_headers;
-    struct sec_data body;
-
-    size_t received;
-};
-
-struct proxy_http_req_state {
-    struct tevent_context *ev;
-
-    char *proxyname;
-    int port;
-
-    struct resolv_hostent *hostent;
-    int hostidx;
-
-    int sd;
-    struct tevent_fd *fde;
-
-    struct proxy_http_request request;
-    struct proxy_http_reply *reply;
-};
-
-static int proxy_http_req_state_destroy(void *data);
-static void proxy_http_req_gethostname_done(struct tevent_req *subreq);
-static void proxy_http_req_connect_step(struct tevent_req *req);
-static void proxy_http_req_connect_done(struct tevent_req *subreq);
-static void proxy_fd_handler(struct tevent_context *ev, struct tevent_fd *fde,
-                             uint16_t flags, void *ptr);
-
-struct tevent_req *proxy_http_req_send(struct proxy_context *pctx,
-                                       TALLOC_CTX *mem_ctx,
-                                       struct tevent_context *ev,
-                                       struct sec_req_ctx *secreq,
-                                       const char *http_uri,
-                                       struct sec_data *http_req)
-{
-    struct proxy_http_req_state *state;
-    struct http_parser_url parsed;
-    struct tevent_req *req, *subreq;
-    int ret;
-
-    req = tevent_req_create(mem_ctx, &state, struct proxy_http_req_state);
-    if (!req) return NULL;
-
-    state->ev = ev;
-    state->request.data = http_req;
-    state->sd = -1;
-    talloc_set_destructor((TALLOC_CTX *)state,
-                          proxy_http_req_state_destroy);
-
-    /* STEP1: reparse URL to get hostname and port */
-    ret = http_parser_parse_url(http_uri, strlen(http_uri), 0, &parsed);
-    if (ret) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "Failed to parse URL [%s]: %d: %s\n",
-                                   http_uri, ret, sss_strerror(ret));
-        goto done;
-    }
-
-    if (!(parsed.field_set & (1 << UF_HOST))) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "No UF_HOST flag found\n");
-        ret = EINVAL;
-        goto done;
-    }
-    state->proxyname =
-        talloc_strndup(state,
-                       &http_uri[parsed.field_data[UF_HOST].off],
-                       parsed.field_data[UF_HOST].len);
-    if (!state->proxyname) {
-        ret = ENOMEM;
-        goto done;
-    }
-    DEBUG(SSSDBG_TRACE_LIBS, "proxy name: %s\n", state->proxyname);
-
-    if (parsed.field_set & (1 << UF_PORT)) {
-        state->port = parsed.port;
-    } else if (parsed.field_set & (1 << UF_SCHEMA)) {
-        uint16_t off = parsed.field_data[UF_SCHEMA].off;
-        uint16_t len = parsed.field_data[UF_SCHEMA].len;
-
-        if ((len == 5) &&
-            (strncmp("https", &http_uri[off], len) == 0)) {
-            state->port = 443;
-        } else if ((len == 4) &&
-                   (strncmp("http", &http_uri[off], len) == 0)) {
-            state->port = 80;
-        }
-    }
-    DEBUG(SSSDBG_TRACE_LIBS, "proxy port: %d\n", state->port);
-
-    /* STEP2: resolve hostname first */
-    subreq = resolv_gethostbyname_send(state, ev, pctx->resctx,
-                                       state->proxyname, IPV4_FIRST,
-                                       default_host_dbs);
-    if (subreq == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    tevent_req_set_callback(subreq, proxy_http_req_gethostname_done, req);
-
-    return req;
-
-done:
-    if (ret == EOK) {
-        tevent_req_done(req);
-    } else {
-        tevent_req_error(req, ret);
-    }
-    tevent_req_post(req, ev);
-
-    return req;
-}
-
-static void proxy_http_req_gethostname_done(struct tevent_req *subreq)
-{
-    struct tevent_req *req;
-    struct proxy_http_req_state *state;
-    int resolv_status;
-    int ret;
-
-    req = tevent_req_callback_data(subreq, struct tevent_req);
-    state = tevent_req_data(req, struct proxy_http_req_state);
-
-    ret = resolv_gethostbyname_recv(subreq, state, &resolv_status, NULL,
-                                    &state->hostent);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        if (ret == ENOENT) {
-            /* Empty result, just quit */
-            DEBUG(SSSDBG_TRACE_INTERNAL, "No hostent found\n");
-        } else {
-            DEBUG(SSSDBG_OP_FAILURE,
-                  "Could not resolve fqdn for this machine, error [%d]: %s, "
-                  "resolver returned: [%d]: %s\n", ret, strerror(ret),
-                  resolv_status, resolv_strerror(resolv_status));
-        }
-        goto done;
-    }
-
-    /* EOK */
-    DEBUG(SSSDBG_TRACE_INTERNAL, "Found fqdn: %s\n", state->hostent->name);
-
-    /* STEP3: connect to one of the servers */
-    proxy_http_req_connect_step(req);
-    return;
-
-done:
-    if (ret == EOK) {
-        tevent_req_done(req);
-    } else {
-        tevent_req_error(req, ret);
-    }
-}
-
-static void proxy_http_req_connect_step(struct tevent_req *req)
-{
-    struct proxy_http_req_state *state;
-    struct sockaddr_storage *sockaddr;
-    char *ipaddr;
-    struct tevent_req *subreq;
-    int ret;
-
-    state = tevent_req_data(req, struct proxy_http_req_state);
-
-    if (!state->hostent->addr_list[state->hostidx]) {
-        DEBUG(SSSDBG_CRIT_FAILURE, "No more addresses to try.\n");
-        ret = ERR_SEC_NO_PROXY;
-        goto done;
-    }
-
-    sockaddr = resolv_get_sockaddr_address_index(state, state->hostent,
-                                                 state->port, state->hostidx);
-    if (sockaddr == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "resolv_get_sockaddr_address() failed\n");
-        ret = EIO;
-        goto done;
-    }
-
-    if (DEBUG_IS_SET(SSSDBG_TRACE_FUNC)) {
-        ipaddr = resolv_get_string_address_index(state, state->hostent,
-                                                 state->hostidx);
-        if (!ipaddr) {
-            ret = EFAULT;
-            goto done;
-        }
-        DEBUG(SSSDBG_TRACE_FUNC, "Connecting to %s:%d\n",
-              ipaddr, state->port);
-    }
-
-    /* increase idx for next attempt */
-    state->hostidx++;
-
-    subreq = sssd_async_socket_init_send(state, state->ev, sockaddr,
-                                         sizeof(struct sockaddr_storage),
-                                         SEC_NET_TIMEOUT);
-    if (!subreq) {
-        ret = EIO;
-        goto done;
-    }
-    tevent_req_set_callback(subreq, proxy_http_req_connect_done, req);
-    return;
-
-done:
-    if (ret == EOK) {
-        tevent_req_done(req);
-    } else {
-        tevent_req_error(req, ret);
-    }
-}
-
-static void proxy_http_req_connect_done(struct tevent_req *subreq)
-{
-    struct tevent_req *req;
-    struct proxy_http_req_state *state;
-    int ret;
-
-    req = tevent_req_callback_data(subreq, struct tevent_req);
-    state = tevent_req_data(req, struct proxy_http_req_state);
-
-    ret = sssd_async_socket_init_recv(subreq, &state->sd);
-    talloc_zfree(subreq);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "sssd_async_socket_init request failed: [%d]: %s.\n",
-              ret, sss_strerror(ret));
-
-        /* try next server if any */
-        proxy_http_req_connect_step(req);
-        return;
-    }
-
-    /* EOK */
-    DEBUG(SSSDBG_TRACE_FUNC, "Connected to %s\n", state->hostent->name);
-
-    state->fde = tevent_add_fd(state->ev, state, state->sd,
-                               TEVENT_FD_WRITE, proxy_fd_handler,
-                               req);
-    if (!state->fde) {
-        ret = EIO;
-        goto done;
-    }
-
-    return;
-
-done:
-    if (ret == EOK) {
-        tevent_req_done(req);
-    } else {
-        tevent_req_error(req, ret);
-    }
-}
-
-
-int proxy_http_req_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx,
-                        struct proxy_http_reply **reply)
-{
-    struct proxy_http_req_state *state =
-                tevent_req_data(req, struct proxy_http_req_state);
-
-    TEVENT_REQ_RETURN_ON_ERROR(req);
-
-    *reply = talloc_move(mem_ctx, &state->reply);
-
-    return EOK;
-}
-
-static int proxy_http_req_state_destroy(void *data)
-{
-    struct proxy_http_req_state *state =
-        talloc_get_type(data, struct proxy_http_req_state);
-
-    if (!state) return 0;
-
-    if (state->sd != -1) {
-        DEBUG(SSSDBG_TRACE_FUNC, "closing socket [%d]\n", state->sd);
-        close(state->sd);
-        state->sd = -1;
-    }
-
-    return 0;
-}
-
-static int proxy_wire_send(int fd, struct proxy_http_request *req)
-{
-    struct sec_data data;
-    int ret;
-
-    data.data = req->data->data + req->written;
-    data.length = req->data->length - req->written;
-
-    ret = sec_send_data(fd, &data);
-    if (ret != EOK && ret != EAGAIN) {
-        DEBUG(SSSDBG_CRIT_FAILURE,
-              "sec_send_data failed [%d]: %s\n", ret, sss_strerror(ret));
-        return ret;
-    }
-
-    req->written = req->data->length - data.length;
-    return ret;
-}
-
-static void proxy_fd_send(void *data)
-{
-    struct proxy_http_req_state *state;
-    struct tevent_req * req;
-    int ret;
-
-    req = talloc_get_type(data, struct tevent_req);
-    state = tevent_req_data(req, struct proxy_http_req_state);
-
-    ret = proxy_wire_send(state->sd, &state->request);
-    if (ret == EAGAIN) {
-        /* not all data was sent, loop again */
-        return;
-    }
-    if (ret != EOK) {
-        DEBUG(SSSDBG_FATAL_FAILURE, "Failed to send data, aborting!\n");
-        tevent_req_error(req, ret);
-        return;
-    }
-
-    /* ok all sent, wait for reply now */
-    TEVENT_FD_NOT_WRITEABLE(state->fde);
-    TEVENT_FD_READABLE(state->fde);
-    return;
-}
-
-static bool ph_received_data(struct proxy_http_reply *reply, size_t length)
-{
-    reply->received += length;
-    if (reply->received > SEC_REQUEST_MAX_SIZE) {
-        DEBUG(SSSDBG_FATAL_FAILURE, "Request too big, aborting!\n");
-        return true;
-    }
-    return false;
-}
-
-static void ph_append_string(TALLOC_CTX *memctx, char **dest,
-                             const char *src, size_t len)
-{
-    if (*dest) {
-        *dest = talloc_strndup_append_buffer(*dest, src, len);
-    } else {
-        *dest = talloc_strndup(memctx, src, len);
-    }
-}
-
-static int ph_on_message_begin(http_parser *parser)
-{
-    DEBUG(SSSDBG_TRACE_INTERNAL, "HTTP Message parsing begins\n");
-    return 0;
-}
-
-#if ((HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 2))
-static int ph_on_status(http_parser *parser, const char *at, size_t length)
-{
-    struct proxy_http_reply *reply =
-        talloc_get_type(parser->data, struct proxy_http_reply);
-
-    if (ph_received_data(reply, length)) return -1;
-
-    ph_append_string(reply, &reply->reason_phrase, at, length);
-    if (!reply->reason_phrase) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to store reason phrase, aborting client!\n");
-        return -1;
-    }
-
-    return 0;
-}
-#endif
-
-static int ph_on_header_field(http_parser *parser,
-                              const char *at, size_t length)
-{
-    struct proxy_http_reply *reply =
-        talloc_get_type(parser->data, struct proxy_http_reply);
-    int n = reply->num_headers;
-
-    if (ph_received_data(reply, length)) return -1;
-
-    if (!reply->headers) {
-        reply->headers = talloc_zero_array(reply, struct sec_kvp, 10);
-    } else if ((n % 10 == 0) &&
-               (reply->headers[n - 1].value)) {
-        reply->headers = talloc_realloc(reply, reply->headers,
-                                        struct sec_kvp, n + 10);
-        if (reply->headers) {
-            memset(&reply->headers[n], 0, sizeof(struct sec_kvp) * 10);
-        }
-    }
-    if (!reply->headers) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to store headers, aborting client!\n");
-        return -1;
-    }
-
-    if (!n || reply->headers[n - 1].value) {
-        /* new field */
-        n++;
-    }
-    ph_append_string(reply->headers, &reply->headers[n - 1].name, at, length);
-    if (!reply->headers[n - 1].name) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to store header name, aborting client!\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-static int ph_on_header_value(http_parser *parser,
-                              const char *at, size_t length)
-{
-    struct proxy_http_reply *reply =
-        talloc_get_type(parser->data, struct proxy_http_reply);
-    int n = reply->num_headers;
-
-    if (ph_received_data(reply, length)) return -1;
-
-    if (!reply->headers) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Invalid headers pointer, aborting client!\n");
-        return -1;
-    }
-
-    if (reply->headers[n].name && !reply->headers[n].value) {
-        /* we increment on new value */
-        n = ++reply->num_headers;
-    }
-
-    ph_append_string(reply->headers, &reply->headers[n - 1].value, at, length);
-    if (!reply->headers[n - 1].value) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to store header value, aborting client!\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-static int ph_on_headers_complete(http_parser *parser)
-{
-    /* TODO: if message has no body we should return 1 */
-    return 0;
-}
-
-static int ph_on_body(http_parser *parser, const char *at, size_t length)
-{
-    struct proxy_http_reply *reply =
-        talloc_get_type(parser->data, struct proxy_http_reply);
-
-    if (ph_received_data(reply, length)) return -1;
-
-    /* FIXME: body may be binary */
-    ph_append_string(reply, &reply->body.data, at, length);
-    if (!reply->body.data) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to store body, aborting!\n");
-        return -1;
-    }
-    reply->body.length += length;
-
-    return 0;
-}
-
-static int ph_on_message_complete(http_parser *parser)
-{
-    struct proxy_http_reply *reply =
-        talloc_get_type(parser->data, struct proxy_http_reply);
-
-    reply->status_code = parser->status_code;
-    reply->complete = true;
-
-    return 0;
-}
-
-static http_parser_settings ph_callbacks = {
-    .on_message_begin = ph_on_message_begin,
-#if ((HTTP_PARSER_VERSION_MAJOR >= 2) && (HTTP_PARSER_VERSION_MINOR >= 2))
-    .on_status = ph_on_status,
-#endif
-    .on_header_field = ph_on_header_field,
-    .on_header_value = ph_on_header_value,
-    .on_headers_complete = ph_on_headers_complete,
-    .on_body = ph_on_body,
-    .on_message_complete = ph_on_message_complete
-};
-
-static void proxy_fd_recv(void *data)
-{
-    char buffer[SEC_PACKET_MAX_RECV_SIZE];
-    struct sec_data packet = { buffer,
-                               SEC_PACKET_MAX_RECV_SIZE };
-    struct proxy_http_req_state *state;
-    struct tevent_req *req;
-    bool must_complete = false;
-    int ret;
-
-    req = talloc_get_type(data, struct tevent_req);
-    state = tevent_req_data(req, struct proxy_http_req_state);
-
-    if (!state->reply) {
-        /* A new reply */
-        state->reply = talloc_zero(state, struct proxy_http_reply);
-        if (!state->reply) {
-            DEBUG(SSSDBG_FATAL_FAILURE, "Failed to allocate reply, aborting!\n");
-            tevent_req_error(req, ENOMEM);
-            return;
-        }
-        http_parser_init(&state->reply->parser, HTTP_RESPONSE);
-        state->reply->parser.data = state->reply;
-    }
-
-    ret = sec_recv_data(state->sd, &packet);
-    switch (ret) {
-    case ENODATA:
-        DEBUG(SSSDBG_TRACE_ALL, "Server closed connection.\n");
-        /* if we got no content length and the request is not complete,
-         * then 0 length will indicate EOF to the parser, otherwise we
-         * have an error */
-        must_complete = true;
-        break;
-    case EAGAIN:
-        DEBUG(SSSDBG_TRACE_ALL,
-              "Interrupted before any data could be read, retry later\n");
-        return;
-    case EOK:
-        /* all fine */
-        break;
-    default:
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to receive data (%d, %s), aborting\n",
-              ret, sss_strerror(ret));
-        tevent_req_error(req, EIO);
-        return;
-    }
-
-    ret = http_parser_execute(&state->reply->parser, &ph_callbacks,
-                              packet.data, packet.length);
-    if (ret != packet.length) {
-        DEBUG(SSSDBG_FATAL_FAILURE,
-              "Failed to parse request, aborting!\n");
-        tevent_req_error(req, EIO);
-        return;
-    }
-
-    if (!state->reply->complete) {
-        if (must_complete) {
-            tevent_req_error(req, EIO);
-        }
-        return;
-    }
-
-    /* do not read anymore, server is done sending */
-    TEVENT_FD_NOT_READABLE(state->fde);
-    tevent_req_done(req);
-}
-
-static void proxy_fd_handler(struct tevent_context *ev, struct tevent_fd *fde,
-                             uint16_t flags, void *data)
-{
-    if (flags & TEVENT_FD_READ) {
-        proxy_fd_recv(data);
-    } else if (flags & TEVENT_FD_WRITE) {
-        proxy_fd_send(data);
-    }
-}
-
 struct proxy_secret_state {
     struct tevent_context *ev;
     struct sec_req_ctx *secreq;
-- 
2.9.3