]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: http-client-connection - Create function for obtaining client settings...
authorStephan Bosch <stephan.bosch@dovecot.fi>
Wed, 20 Feb 2019 21:19:03 +0000 (22:19 +0100)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Thu, 21 Feb 2019 06:47:23 +0000 (06:47 +0000)
This fixes and prevents segfaults occurring when settings are needed while the
connection is detached. In that case, the shared client context settings need
to be used rather than the client settings. Before, the attachment of a peer was
assumed for obtaining the settings when it actually could be absent in rare
cases, causing a NULL dereference.

src/lib-http/http-client-connection.c

index 153e476f357e1820811d4751e9ba8eea130572a4..c0fa40a785d5e378e93aeb06ac6b44424215e974 100644 (file)
 static void http_client_connection_ready(struct http_client_connection *conn);
 static void http_client_connection_input(struct connection *_conn);
 
+static inline const struct http_client_settings *
+http_client_connection_get_settings(struct http_client_connection *conn)
+{
+       if (conn->peer != NULL)
+               return &conn->peer->client->set;
+       return &conn->ppool->peer->cctx->set;
+}
+
 static inline void
 http_client_connection_ref_request(struct http_client_connection *conn,
        struct http_client_request *req)
@@ -119,7 +127,8 @@ static void
 http_client_connection_retry_requests(struct http_client_connection *conn,
        unsigned int status, const char *error)
 {
-       const struct http_client_settings *set = &conn->peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        struct http_client_request *req, **req_idx;
 
        if (!array_is_created(&conn->request_wait_list))
@@ -321,7 +330,8 @@ void http_client_connection_handle_output_error(
 
 int http_client_connection_check_ready(struct http_client_connection *conn)
 {
-       const struct http_client_settings *set = &conn->peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        int ret;
 
        if (conn->in_req_callback) {
@@ -415,9 +425,8 @@ http_client_connection_idle_timeout(struct http_client_connection *conn)
 
 void http_client_connection_lost_peer(struct http_client_connection *conn)
 {
-       struct http_client_peer *peer = conn->peer;
-       struct http_client *client = peer->client;
-       const struct http_client_settings *set = &client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        struct http_client_peer_pool *ppool = conn->ppool;
        struct http_client_peer_shared *pshared = ppool->peer;
        unsigned int timeout, count;
@@ -1354,7 +1363,8 @@ http_client_connection_ready(struct http_client_connection *conn)
        struct http_client_peer *peer = conn->peer;
        struct http_client_peer_pool *ppool = conn->ppool;
        struct http_client_peer_shared *pshared = ppool->peer;
-       const struct http_client_settings *set = &peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
 
        e_debug(conn->event, "Ready for requests");
        i_assert(!conn->connect_succeeded);
@@ -1412,9 +1422,9 @@ static int
 http_client_connection_ssl_handshaked(const char **error_r, void *context)
 {
        struct http_client_connection *conn = context;
-       struct http_client_peer *peer = conn->peer;
        struct http_client_peer_shared *pshared = conn->ppool->peer;
-       const struct http_client_settings *set = &peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        const char *error, *host = pshared->addr.a.tcp.https_name;
 
        if (ssl_iostream_check_cert_validity(conn->ssl_iostream, host, &error) == 0)
@@ -1433,10 +1443,10 @@ static int
 http_client_connection_ssl_init(struct http_client_connection *conn,
                                const char **error_r)
 {
-       struct http_client_peer *peer = conn->peer;
        struct http_client_peer_pool *ppool = conn->ppool;
        struct http_client_peer_shared *pshared = ppool->peer;
-       const struct http_client_settings *set = &peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        struct ssl_iostream_settings ssl_set;
        struct ssl_iostream_context *ssl_ctx = ppool->ssl_ctx;
        const char *error;
@@ -1485,9 +1495,9 @@ http_client_connection_connected(struct connection *_conn, bool success)
 {
        struct http_client_connection *conn =
                (struct http_client_connection *)_conn;
-       struct http_client_peer *peer = conn->peer;
        struct http_client_peer_shared *pshared = conn->ppool->peer;
-       const struct http_client_settings *set = &peer->client->set;
+       const struct http_client_settings *set =
+               http_client_connection_get_settings(conn);
        const char *error;
 
        if (!success) {