Skip to content

Commit

Permalink
Fixes skupperproject#1398 - prevent force-close of TCP pseudo-connect…
Browse files Browse the repository at this point in the history
…ions via management

TCP adaptor creates special connection instances that are used for
managing the service address subscriptions. A user must not
inadvertantly delete these connections or the router will
malfunction. This patch prevents these connections from being
force-closed via the management interface.

Closes skupperproject#1398
  • Loading branch information
kgiusti committed Feb 6, 2024
1 parent 79c6c36 commit b7e48a4
Show file tree
Hide file tree
Showing 13 changed files with 134 additions and 70 deletions.
4 changes: 2 additions & 2 deletions include/qpid/dispatch/protocol_adaptor.h
Original file line number Diff line number Diff line change
Expand Up @@ -868,7 +868,6 @@ void qdr_link_set_drained(qdr_core_t *core, qdr_link_t *link);
*/
qd_delivery_state_t *qdr_delivery_take_local_delivery_state(qdr_delivery_t *dlv, uint64_t *dispo);


qdr_connection_info_t *qdr_connection_info(bool is_encrypted,
bool is_authenticated,
bool opened,
Expand All @@ -884,7 +883,8 @@ qdr_connection_info_t *qdr_connection_info(bool is_encrypted,
bool ssl,
const char *version,
bool streaming_links,
bool connection_trunking);
bool connection_trunking,
bool allow_delete); // T: can be deleted via mgmt agent

void qdr_connection_info_set_group_correlator(qdr_connection_info_t *info, const char *correlator);

Expand Down
34 changes: 27 additions & 7 deletions src/adaptors/adaptor_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,18 +245,38 @@ int qd_raw_connection_write_buffers(pn_raw_connection_t *pn_raw_conn, qd_adaptor
return num_buffers_written;
}

char *qd_raw_conn_get_address(pn_raw_connection_t *pn_raw_conn)

size_t qd_raw_conn_get_address_buf(pn_raw_connection_t *pn_raw_conn, char *buf, size_t buflen)
{
assert(pn_raw_conn);
assert(buflen);

buf[0] = '\0';

const pn_netaddr_t *netaddr = pn_raw_connection_remote_addr(pn_raw_conn);
char buffer[1024];
int len = pn_netaddr_str(netaddr, buffer, 1024);
if (len <= 1024) {
return strdup(buffer);
} else {
return strndup(buffer, 1024);
if (!netaddr)
return 0;

int len = pn_netaddr_str(netaddr, buf, buflen);
if (len < 0)
return 0;
if (len >= buflen) { // truncated
len = buflen - 1;
buf[len] = '\0';
}

return (size_t) len;
}


char *qd_raw_conn_get_address(pn_raw_connection_t *pn_raw_conn)
{
char result[1024];
qd_raw_conn_get_address_buf(pn_raw_conn, result, sizeof(result));
return strdup(result);
}


int qd_raw_connection_drain_write_buffers(pn_raw_connection_t *pn_raw_conn)
{
pn_raw_buffer_t buffs[RAW_BUFFER_BATCH];
Expand Down
7 changes: 7 additions & 0 deletions src/adaptors/adaptor_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ int qd_raw_connection_write_buffers(pn_raw_connection_t *pn_raw_conn, qd_adaptor
*/
char *qd_raw_conn_get_address(pn_raw_connection_t *pn_raw_conn);

/**
* Get the raw connections remote address.
* Like qd_raw_conn_get_address(), but address buffer is supplied by caller.
* @return number of bytes written, zero if no address available (buf is set to the null string).
*/
size_t qd_raw_conn_get_address_buf(pn_raw_connection_t *pn_raw_conn, char *buf, size_t buflen);

/**
* Drains write buffers held by proton raw connection.
* @param raw_conn - The pn_raw_connection_t to which the write buffers were granted.
Expand Down
3 changes: 2 additions & 1 deletion src/adaptors/http1/http1_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,8 @@ static void _setup_client_connection(qdr_http1_connection_t *hconn)
false, //bool ssl,
"", // peer router version,
false, // streaming links
false); // connection trunking
false, // connection trunking
true); // allow mgmt agent DELETE operation

hconn->qdr_conn = qdr_connection_opened(qdr_http1_adaptor->core,
qdr_http1_adaptor->adaptor,
Expand Down
3 changes: 2 additions & 1 deletion src/adaptors/http1/http1_server.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ static qdr_http1_connection_t *_create_server_connection(qd_http_connector_t *co
false, //bool ssl,
"", // peer router version,
false, // streaming links
false); // connection trunking
false, // connection trunking
true); // allow mgmt agent DELETE operation

hconn->qdr_conn = qdr_connection_opened(qdr_http1_adaptor->core,
qdr_http1_adaptor->adaptor,
Expand Down
35 changes: 19 additions & 16 deletions src/adaptors/http2/http2_adaptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -2760,22 +2760,24 @@ static int handle_incoming_http(qdr_http2_connection_t *conn)
qdr_http2_connection_t *qdr_http_connection_ingress_accept(qdr_http2_connection_t* ingress_http_conn)
{
ingress_http_conn->remote_address = qd_raw_conn_get_address(ingress_http_conn->pn_raw_conn);
qdr_connection_info_t *info = qdr_connection_info(false, //bool is_encrypted,
false, //bool is_authenticated,
true, //bool opened,
"", //char *sasl_mechanisms,
qdr_connection_info_t *info = qdr_connection_info(false, //bool is_encrypted,
false, //bool is_authenticated,
true, //bool opened,
"", //char *sasl_mechanisms,
QD_INCOMING, //qd_direction_t dir,
ingress_http_conn->remote_address, //const char *host,
"", //const char *ssl_proto,
"", //const char *ssl_cipher,
"", //const char *user,
"", //const char *ssl_proto,
"", //const char *ssl_cipher,
"", //const char *user,
"HttpAdaptor", //const char *container,
0, //pn_data_t *connection_properties,
0, //int ssl_ssf,
false, //bool ssl,
"", // peer router version,
false, // streaming links
false); // connection trunking
0, //pn_data_t *connection_properties,
0, //int ssl_ssf,
false, //bool ssl,
"", // peer router version,
false, // streaming links
false, // connection trunking
true); // allow mgmt agent DELETE operation


qdr_connection_t *conn = qdr_connection_opened(http2_adaptor->core,
http2_adaptor->adaptor,
Expand Down Expand Up @@ -3106,9 +3108,10 @@ qdr_http2_connection_t *qdr_http_connection_egress(qd_http_connector_t *connecto
0, //pn_data_t *connection_properties,
0, //int ssl_ssf,
false, //bool ssl,
"", // peer router version,
false, // streaming links
false); // connection trunking
"", // peer router version,
false, // streaming links
false, // connection trunking
true); // allow mgmt agent DELETE operation

qdr_connection_t *conn = qdr_connection_opened(http2_adaptor->core,
http2_adaptor->adaptor,
Expand Down
3 changes: 2 additions & 1 deletion src/adaptors/reference_adaptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,8 @@ static void on_startup(void *context)
false, //bool ssl,
"", // peer router version,
false, // streaming links
false); // connection trunking
false, // connection trunking
true); // allow mgmt agent DELETE operation

adaptor->conn = qdr_connection_opened(adaptor->core, // core
adaptor->adaptor, // protocol_adaptor
Expand Down
40 changes: 23 additions & 17 deletions src/adaptors/tcp/tcp_adaptor.c
Original file line number Diff line number Diff line change
Expand Up @@ -921,22 +921,23 @@ static void qdr_tcp_connection_ingress_accept(qdr_tcp_connection_t* tc)
// So, we need to call pn_data_free(tcp_conn_properties).
//
pn_data_t *tcp_conn_properties = qdr_tcp_conn_properties();
qdr_connection_info_t *info = qdr_connection_info(tc->require_tls, // is_encrypted,
false, // is_authenticated,
true, // opened,
"", // *sasl_mechanisms,
QD_INCOMING, // dir,
tc->remote_address, // *host,
"", // *ssl_proto,
"", // *ssl_cipher,
"", // *user,
"TcpAdaptor", // *container,
tcp_conn_properties, // *connection_properties,
0, // ssl_ssf,
false, // ssl,
"", // peer router version,
false, // streaming links
false); // connection trunking
qdr_connection_info_t *info = qdr_connection_info(tc->require_tls, // is_encrypted,
false, // is_authenticated,
true, // opened,
"", // *sasl_mechanisms,
QD_INCOMING, // dir,
tc->remote_address, // *host,
"", // *ssl_proto,
"", // *ssl_cipher,
"", // *user,
"TcpAdaptor", // *container,
tcp_conn_properties, // *connection_properties,
0, // ssl_ssf,
false, // ssl,
"", // peer router version,
false, // streaming links
false, // connection trunking
true); // allow mgmt agent DELETE operation
pn_data_free(tcp_conn_properties);

qdr_connection_t *conn = qdr_connection_opened(tcp_adaptor->core,
Expand Down Expand Up @@ -1351,6 +1352,10 @@ static void qdr_tcp_create_server_side_connection(qdr_tcp_connection_t* tc)
qd_log(LOG_TCP_ADAPTOR, QD_LOG_DEBUG, "[C%" PRIu64 "] Opening server-side core connection %s", tc->conn_id,
host);

// ISSUE-1225: cannot allow user to delete tcp dispatch connections via management. The must delete the
// parent tcpConnector instead.
const bool allow_delete = !tc->is_egress_dispatcher_conn;

//
// The qdr_connection_info() function makes its own copy of the passed in tcp_conn_properties.
// So, we need to call pn_data_free(tcp_conn_properties)
Expand All @@ -1371,7 +1376,8 @@ static void qdr_tcp_create_server_side_connection(qdr_tcp_connection_t* tc)
false, // bool ssl,
"", // peer router version,
false, // streaming links
false); // connection trunking
false, // connection trunking
allow_delete);
pn_data_free(tcp_conn_properties);

qdr_connection_t *conn = qdr_connection_opened(tcp_adaptor->core,
Expand Down
Loading

0 comments on commit b7e48a4

Please sign in to comment.