Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions doc/admin_tls.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Dedicated TLS for the Admin interfaces

ProxySQL can use a dedicated TLS context for its MySQL and PostgreSQL Admin
interfaces. The feature is disabled by default, so existing deployments retain
their previous behavior.

When `admin-ssl_enabled` is enabled, all new connections to either Admin
interface must negotiate TLS. Existing connections are not disconnected.

## Configuration

| Variable | Default | Description |
|---|---|---|
| `admin-ssl_enabled` | `false` | Require TLS and activate the dedicated Admin TLS context. |
| `admin-ssl_key` | empty | PEM private key. Required when enabled. |
| `admin-ssl_cert` | empty | PEM certificate chain. Required when enabled. |
| `admin-ssl_ca` | empty | PEM CA bundle used to verify client certificates. |
| `admin-ssl_capath` | empty | OpenSSL hashed CA directory used to verify client certificates. |
| `admin-ssl_cipher` | empty | OpenSSL TLS 1.2 cipher list. The OpenSSL default is used when empty. |
| `admin-tls_version` | `TLSv1.2` | Minimum accepted version: `TLSv1.2` or `TLSv1.3`. |
| `admin-ssl_curves` | empty | OpenSSL groups/curves list. |
| `admin-ssl_verify_client` | `DISABLED` | Client certificate mode: `DISABLED`, `OPTIONAL`, or `REQUIRED`. Numeric values `0`, `1`, and `2` are also accepted. |
| `admin-ssl_crl` | empty | PEM certificate revocation list. |
| `admin-ssl_crlpath` | empty | OpenSSL hashed CRL directory. |

Relative paths are resolved against ProxySQL's data directory. Client
verification requires `admin-ssl_ca` or `admin-ssl_capath`.

Example using ProxySQL's existing default certificate:

```sql
SELECT Variable_Name, Variable_Value
FROM stats.stats_proxysql_global
WHERE Variable_Name IN
('TLS_Key_File', 'TLS_Server_Cert_File', 'TLS_CA_Cert_File');

SET admin-ssl_key='/var/lib/proxysql/proxysql-key.pem';
SET admin-ssl_cert='/var/lib/proxysql/proxysql-cert.pem';
SET admin-ssl_ca='/var/lib/proxysql/proxysql-ca.pem';
SET admin-ssl_enabled='true';
LOAD ADMIN VARIABLES TO RUNTIME;
SAVE ADMIN VARIABLES TO DISK;
```

To require a trusted client certificate:

```sql
SET admin-ssl_verify_client='REQUIRED';
LOAD ADMIN VARIABLES TO RUNTIME;
```

## Reload behavior

`LOAD ADMIN VARIABLES TO RUNTIME` builds and validates a complete replacement
context before activating it. If validation fails, the previous runtime
configuration and context remain active and the command returns an error.

Certificate files can be re-read without changing variables:

```sql
PROXYSQL RELOAD ADMIN TLS;
```

The reload is atomic for new connections. Connections that are already using
TLS continue with the context under which they were established.
2 changes: 1 addition & 1 deletion include/MySQL_Protocol.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ class MySQL_Protocol {
// - a pointer to unsigned int, used to return the size of the packet if not NULL
// for now, they all return true
bool generate_pkt_OK(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, unsigned int affected_rows, uint64_t last_insert_id, uint16_t status, uint16_t warnings, char *msg, bool eof_identifier=false);
bool generate_pkt_ERR(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, uint16_t error_code, char *sql_state, const char *sql_message, bool track=false);
bool generate_pkt_ERR(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, uint16_t error_code, const char *sql_state, const char *sql_message, bool track=false);
bool generate_pkt_EOF(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, uint16_t warnings, uint16_t status, MySQL_ResultSet *myrs=NULL);
// bool generate_COM_INIT_DB(bool send, void **ptr, unsigned int *len, char *schema);
//bool generate_COM_PING(bool send, void **ptr, unsigned int *len);
Expand Down
26 changes: 25 additions & 1 deletion include/proxysql_admin.h
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ struct FlushVariableStats {
int updated = 0;
int rejected = 0;
int unknown = 0;
std::string error;
};

class ProxySQL_Admin {
Expand Down Expand Up @@ -360,6 +361,7 @@ class ProxySQL_Admin {

void wrlock();
void wrunlock();
int reload_admin_tls_unlocked(std::string& msg);

struct {
char *admin_credentials;
Expand All @@ -370,6 +372,25 @@ class ProxySQL_Admin {
char *telnet_admin_ifaces;
char *telnet_stats_ifaces;
bool admin_read_only;
/**
* Require TLS and use the dedicated Admin TLS context for MySQL and
* PostgreSQL Admin interface connections.
*/
bool admin_ssl_enabled;
char *admin_ssl_key;
char *admin_ssl_cert;
char *admin_ssl_ca;
char *admin_ssl_capath;
char *admin_ssl_cipher;
char *admin_tls_version;
char *admin_ssl_curves;
/**
* Client certificate verification: 0=DISABLED, 1=OPTIONAL,
* 2=REQUIRED.
*/
int admin_ssl_verify_client;
char *admin_ssl_crl;
char *admin_ssl_crlpath;
// bool hash_passwords;
bool vacuum_stats;
char * admin_version;
Expand Down Expand Up @@ -644,6 +665,7 @@ class ProxySQL_Admin {
void load_restapi_server();
bool get_read_only() { return variables.admin_read_only; }
bool set_read_only(bool ro) { variables.admin_read_only=ro; return variables.admin_read_only; }
int reload_admin_tls(std::string& msg);
bool has_variable(const char *name);
void init_users(std::unique_ptr<SQLite3_result>&& mysql_users_resultset = nullptr, const std::string& checksum = "", const time_t epoch = 0);
void init_mysql_servers();
Expand Down Expand Up @@ -748,7 +770,9 @@ class ProxySQL_Admin {
void load_scheduler_to_runtime();
void save_scheduler_runtime_to_database(bool);

void load_admin_variables_to_runtime(const std::string& checksum = "", const time_t epoch = 0, bool lock = true) { flush_admin_variables___database_to_runtime(admindb, true, checksum, epoch, lock); }
FlushVariableStats load_admin_variables_to_runtime(const std::string& checksum = "", const time_t epoch = 0, bool lock = true) {
return flush_admin_variables___database_to_runtime(admindb, true, checksum, epoch, lock);
}
void save_admin_variables_from_runtime() { flush_admin_variables___runtime_to_database(admindb, true, true, false); }

#ifdef PROXYSQLTSDB
Expand Down
6 changes: 6 additions & 0 deletions include/proxysql_glovars.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,9 @@ class ProxySQL_GlobalVariables {
#endif /* PROXYSQL40 */
SSL_CTX *get_SSL_ctx();
SSL *get_SSL_new();
SSL *get_admin_SSL_new();
bool is_admin_SSL_enabled();
void set_admin_SSL_ctx(SSL_CTX *ctx, bool enabled);
void get_SSL_pem_mem(char **key, char **cert);
std::shared_ptr<prometheus::Registry> prometheus_registry { nullptr };
struct {
Expand Down Expand Up @@ -138,6 +141,9 @@ class ProxySQL_GlobalVariables {
std::mutex ssl_mutex;
SSL_CTX *ssl_ctx;
SSL_CTX *tmp_ssl_ctx;
std::mutex admin_ssl_mutex;
SSL_CTX *admin_ssl_ctx;
bool admin_ssl_enabled;
// these two buffers are used for the web interface
char * ssl_key_pem_mem;
char * ssl_cert_pem_mem;
Expand Down
7 changes: 6 additions & 1 deletion lib/Admin_Bootstrap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,12 @@ bool ProxySQL_Admin::init(const bootstrap_info_t& bootstrap_info) {
// TODO-NOTE: This MUST go away; 'admin-hash_passwords' will be deprecated
admindb->execute("UPDATE global_variables SET variable_value='false' WHERE variable_name='admin-hash_passwords'");
}
flush_admin_variables___database_to_runtime(admindb,true);
const FlushVariableStats admin_stats =
flush_admin_variables___database_to_runtime(admindb, true);
if (!admin_stats.error.empty()) {
proxy_error("Unable to load admin variables: %s\n", admin_stats.error.c_str());
return false;
}

if (GloVars.global.gr_bootstrap_mode) {
flush_admin_variables___runtime_to_database(configdb, false, true, false);
Expand Down
48 changes: 48 additions & 0 deletions lib/Admin_FlushVariables.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,57 @@ FlushVariableStats ProxySQL_Admin::flush_admin_variables___database_to_runtime(
SQLite3_result *resultset=NULL;
if (flush_GENERIC_variables__retrieve__database_to_runtime("admin", error, cols, affected_rows, resultset) == true) {
wrlock();
const bool old_ssl_enabled = variables.admin_ssl_enabled;
const int old_ssl_verify_client = variables.admin_ssl_verify_client;
const std::string old_ssl_key = variables.admin_ssl_key;
const std::string old_ssl_cert = variables.admin_ssl_cert;
const std::string old_ssl_ca = variables.admin_ssl_ca;
const std::string old_ssl_capath = variables.admin_ssl_capath;
const std::string old_ssl_cipher = variables.admin_ssl_cipher;
const std::string old_tls_version = variables.admin_tls_version;
const std::string old_ssl_curves = variables.admin_ssl_curves;
const std::string old_ssl_crl = variables.admin_ssl_crl;
const std::string old_ssl_crlpath = variables.admin_ssl_crlpath;

FlushVariableStats stats = flush_GENERIC_variables__process__database_to_runtime("admin", db, resultset, lock, replace, {"version"}, {"debug"}, {}, {});
//commit(); NOT IMPLEMENTED

const bool admin_tls_changed =
old_ssl_enabled != variables.admin_ssl_enabled
|| old_ssl_verify_client != variables.admin_ssl_verify_client
|| old_ssl_key != variables.admin_ssl_key
|| old_ssl_cert != variables.admin_ssl_cert
|| old_ssl_ca != variables.admin_ssl_ca
|| old_ssl_capath != variables.admin_ssl_capath
|| old_ssl_cipher != variables.admin_ssl_cipher
|| old_tls_version != variables.admin_tls_version
|| old_ssl_curves != variables.admin_ssl_curves
|| old_ssl_crl != variables.admin_ssl_crl
|| old_ssl_crlpath != variables.admin_ssl_crlpath;

if (admin_tls_changed || variables.admin_ssl_enabled != GloVars.is_admin_SSL_enabled()) {
std::string tls_error;
if (reload_admin_tls_unlocked(tls_error) != 0) {
auto restore_string = [](char **target, const std::string& value) {
free_null(*target);
*target = strdup(value.c_str());
};
variables.admin_ssl_enabled = old_ssl_enabled;
variables.admin_ssl_verify_client = old_ssl_verify_client;
restore_string(&variables.admin_ssl_key, old_ssl_key);
restore_string(&variables.admin_ssl_cert, old_ssl_cert);
restore_string(&variables.admin_ssl_ca, old_ssl_ca);
restore_string(&variables.admin_ssl_capath, old_ssl_capath);
restore_string(&variables.admin_ssl_cipher, old_ssl_cipher);
restore_string(&variables.admin_tls_version, old_tls_version);
restore_string(&variables.admin_ssl_curves, old_ssl_curves);
restore_string(&variables.admin_ssl_crl, old_ssl_crl);
restore_string(&variables.admin_ssl_crlpath, old_ssl_crlpath);
stats.error = tls_error;
proxy_error("Rejected Admin TLS configuration: %s\n", tls_error.c_str());
}
}

// Checksums are always generated - 'admin-checksum_*' deprecated

{
Expand Down
29 changes: 26 additions & 3 deletions lib/Admin_Handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1149,6 +1149,21 @@ bool admin_handler_command_proxysql(char *query_no_space, unsigned int query_no_
return false;
}

if (strcasecmp("PROXYSQL RELOAD ADMIN TLS", query_no_space) == 0) {
proxy_info("Received %s command\n", query_no_space);
ProxySQL_Admin *SPA = (ProxySQL_Admin *)pa;
std::string msg;
const int rc = SPA->reload_admin_tls(msg);
if (rc == 0) {
SPA->send_ok_msg_to_client(sess, msg.empty() ? NULL : msg.c_str(), 0, query_no_space);
} else {
SPA->send_error_msg_to_client(
sess, msg.empty() ? "RELOAD ADMIN TLS failed" : msg.c_str()
);
}
return false;
}

if (strncasecmp("PROXYSQL SET CONFIG FILE ", query_no_space, 25) == 0) {
proxy_info("Received %s command\n", query_no_space);
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
Expand Down Expand Up @@ -2752,9 +2767,17 @@ bool admin_handler_command_load_or_save(char *query_no_space, unsigned int query

if ( is_admin_command_or_alias(LOAD_ADMIN_VARIABLES_FROM_MEMORY, query_no_space, query_no_space_length) ) {
ProxySQL_Admin *SPA=(ProxySQL_Admin *)pa;
SPA->load_admin_variables_to_runtime();
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Loaded admin variables to RUNTIME\n");
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
const FlushVariableStats stats = SPA->load_admin_variables_to_runtime();
if (stats.error.empty()) {
proxy_debug(PROXY_DEBUG_ADMIN, 4, "Loaded admin variables to RUNTIME\n");
SPA->send_ok_msg_to_client(sess, NULL, 0, query_no_space);
} else {
const std::string error =
"Admin variables loaded, but Admin TLS was rejected and rolled back: "
+ stats.error;
proxy_error("%s\n", error.c_str());
SPA->send_error_msg_to_client(sess, error.c_str());
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
return false;
}

Expand Down
9 changes: 7 additions & 2 deletions lib/MySQL_Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ bool MySQL_Protocol::generate_pkt_EOF(bool send, void **ptr, unsigned int *len,
return true;
}

bool MySQL_Protocol::generate_pkt_ERR(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, uint16_t error_code, char *sql_state, const char *sql_message, bool track) {
bool MySQL_Protocol::generate_pkt_ERR(bool send, void **ptr, unsigned int *len, uint8_t sequence_id, uint16_t error_code, const char *sql_state, const char *sql_message, bool track) {
if ((*myds)->sess->mirror==true) {
return true;
}
Expand Down Expand Up @@ -1080,7 +1080,12 @@ bool MySQL_Protocol::generate_pkt_initial_handshake(bool send, void **ptr, unsig
mysql_thread___server_capabilities &= ~CLIENT_COMPRESS;
mysql_thread___server_capabilities &= ~CLIENT_ZSTD_COMPRESSION_ALGORITHM;
}
if (mysql_thread___have_ssl==true || mysql_thread___default_authentication_plugin_int==2) {
const bool admin_tls_enabled =
(*myds)->sess != NULL
&& ((*myds)->sess->session_type == PROXYSQL_SESSION_ADMIN
|| (*myds)->sess->session_type == PROXYSQL_SESSION_STATS)
&& GloVars.is_admin_SSL_enabled();
if (mysql_thread___have_ssl==true || mysql_thread___default_authentication_plugin_int==2 || admin_tls_enabled) {
// we enable SSL for client connections for either of these 2 conditions:
// - have_ssl is enabled
// - default_authentication_plugin=caching_sha2_password
Expand Down
67 changes: 65 additions & 2 deletions lib/MySQL_Session.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6529,6 +6529,35 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE_

void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(PtrSize_t *pkt, bool *wrong_pass) {
bool is_encrypted = client_myds->encrypted;
const bool admin_tls_required =
(session_type == PROXYSQL_SESSION_ADMIN || session_type == PROXYSQL_SESSION_STATS)
&& GloVars.is_admin_SSL_enabled();

// A plaintext MySQL HandshakeResponse starts with the client capability
// flags after the four-byte packet header. Reject it before credentials
// are parsed when the dedicated Admin TLS context is active.
if (
admin_tls_required && is_encrypted == false && client_myds->DSS == STATE_SERVER_HANDSHAKE
&& pkt->size >= 8
) {
const unsigned char *payload = (const unsigned char *)pkt->ptr + 4;
const uint32_t capabilities =
(uint32_t)payload[0] | ((uint32_t)payload[1] << 8)
| ((uint32_t)payload[2] << 16) | ((uint32_t)payload[3] << 24);
if ((capabilities & CLIENT_SSL) == 0) {
l_free(pkt->size, pkt->ptr);
*wrong_pass = true;
client_myds->setDSS_STATE_QUERY_SENT_NET();
uint8_t packet_id = client_myds->pkt_sid;
packet_id++;
client_myds->myprot.generate_pkt_ERR(
true, NULL, NULL, packet_id, 1045, "28000",
"ProxySQL Admin interface requires SSL", true
);
return;
}
Comment on lines +6539 to +6558

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Where is pkt_sid assigned? Confirm it is only updated during handshake-response parsing.
rg -nP --type=cpp -C3 '\bpkt_sid\s*=' lib/ include/

Repository: sysown/proxysql

Length of output: 4553


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "MySQL_Session.cpp around lines 6480-6625 and 6700-6845:"
sed -n '6480,6845p' lib/MySQL_Session.cpp | nl -ba -v6480

echo
echo "Relevant MySQL_Protocol generate_pkt_ERR signatures/sequence handling:"
sed -n '220,430p' lib/MySQL_Protocol.cpp | nl -ba -v220

echo
echo "mysql_hdr definition and myprot uses:"
rg -n --type=cpp -C3 '\bstruct\s+mysql_hdr\b|\btypedef\s+\(.*\)mysql_hdr\b|pkt_sid|generate_pkt_ERR\s*\(' lib include

Repository: sysown/proxysql

Length of output: 249


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "MySQL_Session.cpp around lines 6480-6625 and 6700-6845:"
sed -n '6480,6845p' lib/MySQL_Session.cpp | awk '{printf "%4d  %s\n", NR+6479, $0}'

echo
echo "Relevant MySQL_Protocol generate_pkt_ERR signatures/sequence handling:"
sed -n '220,430p' lib/MySQL_Protocol.cpp | awk '{printf "%4d  %s\n", NR+219, $0}'

echo
echo "mysql_hdr definition and myprot uses:"
rg -n --type=cpp -C3 '\bstruct\s+mysql_hdr\b|\btypedef\s+\(.*\)mysql_hdr\b|pkt_sid|generate_pkt_ERR\s*\(' lib include

Repository: sysown/proxysql

Length of output: 50371


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "mysql_data_stream.cpp packet reads around pkt_sid:"
sed -n '1220,1390p' lib/mysql_data_stream.cpp | awk '{printf "%4d  %s\n", NR+1219, $0}'

echo
echo "MySQL_Data_Stream state transition methods:"
rg -n --type=cpp -C4 'setDSS_STATE_(HANDSHAKE|QUERY_SENT_NET|SSL_INIT|ERROR|WAITING|AUTH)' lib include

echo
echo "process_pkt_handshake_response sequence-id effects:"
rg -n --type=cpp -C8 '\bprocess_pkt_handshake_response\b|process_pkt_(handshake|SSL)' lib include

Repository: sysown/proxysql

Length of output: 50371


Use the incoming packet id for this pre-parse SSL ERR.

process_pkt_handshake_response() runs after the pre-parse check, so the later post-parse path already uses an incremented seq id, but this branch still derives packet_id from the previous outbound packet and can send an ERR with the wrong seq id. Derive it from pkt->ptr before freeing, e.g. const unsigned char *h = (const unsigned char*)pkt->ptr; uint8_t packet_id = h[3];.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@lib/MySQL_Session.cpp` around lines 6539 - 6558, Update the pre-parse SSL
rejection branch in process_pkt_handshake_response() to derive packet_id from
the incoming packet header at pkt->ptr[3] before freeing the packet, instead of
incrementing client_myds->pkt_sid; preserve the existing ERR generation and
cleanup behavior.

}

bool handshake_response_return = client_myds->myprot.process_pkt_handshake_response((unsigned char *)pkt->ptr,pkt->size);
bool handshake_err = true;

Expand All @@ -6548,16 +6577,50 @@ void MySQL_Session::handler___status_CONNECTING_CLIENT___STATE_SERVER_HANDSHAKE(
client_myds->DSS=STATE_SSL_INIT;
client_myds->rbio_ssl = BIO_new(BIO_s_mem());
client_myds->wbio_ssl = BIO_new(BIO_s_mem());
client_myds->ssl = GloVars.get_SSL_new();
const bool admin_session =
session_type == PROXYSQL_SESSION_ADMIN || session_type == PROXYSQL_SESSION_STATS;
client_myds->ssl =
admin_session ? GloVars.get_admin_SSL_new() : GloVars.get_SSL_new();
if (client_myds->ssl == NULL) {
proxy_error(
"Unable to create %s TLS connection: SSL_new() failed\n",
admin_session ? "MySQL Admin" : "MySQL frontend"
);
BIO_free(client_myds->rbio_ssl);
BIO_free(client_myds->wbio_ssl);
client_myds->rbio_ssl = NULL;
client_myds->wbio_ssl = NULL;
l_free(pkt->size, pkt->ptr);
*wrong_pass = true;
client_myds->setDSS_STATE_QUERY_SENT_NET();
return;
}
SSL_set_fd(client_myds->ssl, client_myds->fd);
SSL_set_accept_state(client_myds->ssl);
SSL_set_bio(client_myds->ssl, client_myds->rbio_ssl, client_myds->wbio_ssl);
l_free(pkt->size,pkt->ptr);
proxysql_keylog_attach_callback(GloVars.get_SSL_ctx());
proxysql_keylog_attach_callback(SSL_get_SSL_CTX(client_myds->ssl));
return;
}
}

if (
handshake_response_return == true
&& admin_tls_required
&& is_encrypted == false
) {
l_free(pkt->size, pkt->ptr);
*wrong_pass = true;
client_myds->setDSS_STATE_QUERY_SENT_NET();
uint8_t packet_id = client_myds->pkt_sid;
packet_id++;
client_myds->myprot.generate_pkt_ERR(
true, NULL, NULL, packet_id, 1045, "28000",
"ProxySQL Admin interface requires SSL", true
);
return;
}

if (
//(client_myds->myprot.process_pkt_handshake_response((unsigned char *)pkt->ptr,pkt->size)==true)
(handshake_response_return == true)
Expand Down
7 changes: 6 additions & 1 deletion lib/PgSQL_Protocol.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,12 @@ bool PgSQL_Protocol::process_startup_packet(unsigned char* pkt, unsigned int len
}

if (hdr.type == PG_PKT_SSLREQ) {
const bool have_ssl = pgsql_thread___have_ssl;
const bool admin_tls_enabled =
(*myds)->sess != NULL
&& ((*myds)->sess->session_type == PROXYSQL_SESSION_ADMIN
|| (*myds)->sess->session_type == PROXYSQL_SESSION_STATS)
&& GloVars.is_admin_SSL_enabled();
const bool have_ssl = pgsql_thread___have_ssl || admin_tls_enabled;
char* ssl_supported = (char*)malloc(1);
*ssl_supported = have_ssl ? 'S' : 'N';
(*myds)->PSarrayOUT->add((void*)ssl_supported, 1);
Expand Down
Loading