jiridanek commented on a change in pull request #744:
URL: https://github.com/apache/qpid-dispatch/pull/744#discussion_r432864967



##########
File path: src/server.c
##########
@@ -17,1657 +17,609 @@
  * under the License.
  */
 
-#include "python_private.h"             // must be first!
-#include "dispatch_private.h"
-#include <qpid/dispatch/python_embedded.h>
-
-#include <qpid/dispatch/ctools.h>
-#include <qpid/dispatch/threading.h>
-#include <qpid/dispatch/log.h>
-#include <qpid/dispatch/amqp.h>
-#include <qpid/dispatch/server.h>
-#include <qpid/dispatch/failoverlist.h>
-#include <qpid/dispatch/alloc.h>
-#include <qpid/dispatch/platform.h>
+// This must be first to work around a Python bug
+//
+// clang-format off
+#include "python_private.h"
+// clang-format on
 
+#include <errno.h>
+#include <inttypes.h>
+#include <proton/condition.h>
 #include <proton/event.h>
 #include <proton/listener.h>
 #include <proton/netaddr.h>
 #include <proton/proactor.h>
 #include <proton/sasl.h>
+#include <qpid/dispatch/alloc.h>
+#include <qpid/dispatch/amqp.h>
+#include <qpid/dispatch/ctools.h>
+#include <qpid/dispatch/failoverlist.h>
+#include <qpid/dispatch/log.h>
+#include <qpid/dispatch/platform.h>
+#include <qpid/dispatch/python_embedded.h>
+#include <qpid/dispatch/server.h>
+#include <qpid/dispatch/threading.h>
+#include <stdio.h>
+#include <string.h>
 
-
+#include "config.h"
+#include "connection.h"
+#include "connector.h"
+#include "dispatch_private.h"
 #include "entity.h"
 #include "entity_cache.h"
-#include "dispatch_private.h"
+#include "listener.h"
 #include "policy.h"
+#include "remote_sasl.h"
 #include "server_private.h"
 #include "timer_private.h"
-#include "config.h"
-#include "remote_sasl.h"
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include <inttypes.h>
-
-struct qd_server_t {
-    qd_dispatch_t            *qd;
-    const int                 thread_count; /* Immutable */
-    const char               *container_name;
-    const char               *sasl_config_path;
-    const char               *sasl_config_name;
-    pn_proactor_t            *proactor;
-    qd_container_t           *container;
-    qd_log_source_t          *log_source;
-    qd_log_source_t          *protocol_log_source; // Log source for the 
PROTOCOL module
-    void                     *start_context;
-    sys_cond_t               *cond;
-    sys_mutex_t              *lock;
-    qd_connection_list_t      conn_list;
-    int                       pause_requests;
-    int                       threads_paused;
-    int                       pause_next_sequence;
-    int                       pause_now_serving;
-    uint64_t                  next_connection_id;
-    void                     *py_displayname_obj;
-    qd_http_server_t         *http;
-    sys_mutex_t              *conn_activation_lock;
-};
 
 #define HEARTBEAT_INTERVAL 1000
 
-ALLOC_DEFINE(qd_listener_t);
-ALLOC_DEFINE(qd_connector_t);
 ALLOC_DEFINE(qd_deferred_call_t);
-ALLOC_DEFINE(qd_connection_t);
-
-const char *MECH_EXTERNAL = "EXTERNAL";
-
-//Allowed uidFormat fields.
-const char CERT_COUNTRY_CODE = 'c';
-const char CERT_STATE = 's';
-const char CERT_CITY_LOCALITY = 'l';
-const char CERT_ORGANIZATION_NAME = 'o';
-const char CERT_ORGANIZATION_UNIT = 'u';
-const char CERT_COMMON_NAME = 'n';
-const char CERT_FINGERPRINT_SHA1 = '1';
-const char CERT_FINGERPRINT_SHA256 = '2';
-const char CERT_FINGERPRINT_SHA512 = '5';
-char *COMPONENT_SEPARATOR = ";";
-
-static const int BACKLOG = 50;  /* Listening backlog */
-
-static void setup_ssl_sasl_and_open(qd_connection_t *ctx);
-static qd_failover_item_t *qd_connector_get_conn_info(qd_connector_t *ct);
-
-/**
- * This function is set as the pn_transport->tracer and is invoked when proton 
tries to write the log message to pn_transport->tracer
- */
-void transport_tracer(pn_transport_t *transport, const char *message)
-{
-    qd_connection_t *ctx = (qd_connection_t*) 
pn_transport_get_context(transport);
-    if (ctx) {
-        // The PROTOCOL module is used exclusively for logging protocol 
related tracing. The protocol could be AMQP, HTTP, TCP etc.
-        qd_log(ctx->server->protocol_log_source, QD_LOG_TRACE, 
"[%"PRIu64"]:%s", ctx->connection_id, message);
-    }
-}
-
-void connection_transport_tracer(pn_transport_t *transport, const char 
*message)
-{
-    qd_connection_t *ctx = (qd_connection_t*) 
pn_transport_get_context(transport);
-    if (ctx) {
-        // Unconditionally write the log at TRACE level to the log file.
-        qd_log_impl_v1(ctx->server->protocol_log_source, QD_LOG_TRACE,  
__FILE__, __LINE__, "[%"PRIu64"]:%s", ctx->connection_id, message);
-    }
-}
 
-/**
- * Save displayNameService object instance and ImportModule address
- * Called with qd_python_lock held
- */
-qd_error_t qd_register_display_name_service(qd_dispatch_t *qd, void 
*displaynameservice)
-{
+// Save displayNameService object instance and ImportModule address.
+// Called with qd_python_lock held.
+//
+// XXX But it doesn't use the _lh convention?
+qd_error_t qd_register_display_name_service(qd_dispatch_t* qd, void* 
displaynameservice) {
     if (displaynameservice) {
         qd->server->py_displayname_obj = displaynameservice;
-        Py_XINCREF((PyObject *)qd->server->py_displayname_obj);
+        Py_XINCREF((PyObject*) qd->server->py_displayname_obj);
         return QD_ERROR_NONE;
-    }
-    else {
+    } else {
         return qd_error(QD_ERROR_VALUE, "displaynameservice is not set");
     }
 }
 
-
-/**
- * Returns a char pointer to a user id which is constructed from components 
specified in the config->ssl_uid_format.
- * Parses through each component and builds a semi-colon delimited string 
which is returned as the user id.
- */
-static const char *transport_get_user(qd_connection_t *conn, pn_transport_t 
*tport)
-{
-    const qd_server_config_t *config =
-            conn->connector ? &conn->connector->config : 
&conn->listener->config;
-
-    if (config->ssl_uid_format) {
-        // The ssl_uid_format length cannot be greater that 7
-        assert(strlen(config->ssl_uid_format) < 8);
-
-        //
-        // The tokens in the uidFormat strings are delimited by comma. Load 
the individual components of the uidFormat
-        // into the components[] array. The maximum number of components that 
are allowed are 7 namely, c, s, l, o, u, n, (1 or 2 or 5)
-        //
-        char components[8];
-
-        //The strcpy() function copies the string pointed to by src, including 
the terminating null byte ('\0'), to the buffer pointed to by dest.
-        strncpy(components, config->ssl_uid_format, 7);
-
-        const char *country_code = 0;
-        const char *state = 0;
-        const char *locality_city = 0;
-        const char *organization = 0;
-        const char *org_unit = 0;
-        const char *common_name = 0;
-        //
-        // SHA1 is 20 octets (40 hex characters); SHA256 is 32 octets (64 hex 
characters).
-        // SHA512 is 64 octets (128 hex characters)
-        //
-        char fingerprint[129] = "\0";
-
-        int uid_length = 0;
-        int semi_colon_count = -1;
-
-        int component_count = strlen(components);
-
-        for (int x = 0; x < component_count ; x++) {
-            // accumulate the length into uid_length on each pass so we 
definitively know the number of octets to malloc.
-            if (components[x] == CERT_COUNTRY_CODE) {
-                country_code =  
pn_ssl_get_remote_subject_subfield(pn_ssl(tport), 
PN_SSL_CERT_SUBJECT_COUNTRY_NAME);
-                if (country_code) {
-                    uid_length += strlen((const char *)country_code);
-                    semi_colon_count++;
-                }
-            }
-            else if (components[x] == CERT_STATE) {
-                state =  pn_ssl_get_remote_subject_subfield(pn_ssl(tport), 
PN_SSL_CERT_SUBJECT_STATE_OR_PROVINCE);
-                if (state) {
-                    uid_length += strlen((const char *)state);
-                    semi_colon_count++;
-                }
-            }
-            else if (components[x] == CERT_CITY_LOCALITY) {
-                locality_city =  
pn_ssl_get_remote_subject_subfield(pn_ssl(tport), 
PN_SSL_CERT_SUBJECT_CITY_OR_LOCALITY);
-                if (locality_city) {
-                    uid_length += strlen((const char *)locality_city);
-                    semi_colon_count++;
-                }
-            }
-            else if (components[x] == CERT_ORGANIZATION_NAME) {
-                organization =  
pn_ssl_get_remote_subject_subfield(pn_ssl(tport), 
PN_SSL_CERT_SUBJECT_ORGANIZATION_NAME);
-                if(organization) {
-                    uid_length += strlen((const char *)organization);
-                    semi_colon_count++;
-                }
-            }
-            else if (components[x] == CERT_ORGANIZATION_UNIT) {
-                org_unit =  pn_ssl_get_remote_subject_subfield(pn_ssl(tport), 
PN_SSL_CERT_SUBJECT_ORGANIZATION_UNIT);
-                if(org_unit) {
-                    uid_length += strlen((const char *)org_unit);
-                    semi_colon_count++;
-                }
-            }
-            else if (components[x] == CERT_COMMON_NAME) {
-                common_name =  
pn_ssl_get_remote_subject_subfield(pn_ssl(tport), 
PN_SSL_CERT_SUBJECT_COMMON_NAME);
-                if(common_name) {
-                    uid_length += strlen((const char *)common_name);
-                    semi_colon_count++;
-                }
-            }
-            else if (components[x] == CERT_FINGERPRINT_SHA1 || components[x] 
== CERT_FINGERPRINT_SHA256 || components[x] == CERT_FINGERPRINT_SHA512) {
-                // Allocate the memory for message digest
-                int out = 0;
-
-                int fingerprint_length = 0;
-                if(components[x] == CERT_FINGERPRINT_SHA1) {
-                    fingerprint_length = 40;
-                    out = pn_ssl_get_cert_fingerprint(pn_ssl(tport), 
fingerprint, fingerprint_length + 1, PN_SSL_SHA1);
-                }
-                else if (components[x] == CERT_FINGERPRINT_SHA256) {
-                    fingerprint_length = 64;
-                    out = pn_ssl_get_cert_fingerprint(pn_ssl(tport), 
fingerprint, fingerprint_length + 1, PN_SSL_SHA256);
-                }
-                else if (components[x] == CERT_FINGERPRINT_SHA512) {
-                    fingerprint_length = 128;
-                    out = pn_ssl_get_cert_fingerprint(pn_ssl(tport), 
fingerprint, fingerprint_length + 1, PN_SSL_SHA512);
-                }
-
-                (void) out;  // avoid 'out unused' compiler warnings if NDEBUG 
undef'ed
-                assert (out != PN_ERR);
-
-                uid_length += fingerprint_length;
-                semi_colon_count++;
-            }
-            else {
-                // This is an unrecognized component. log a critical error
-                qd_log(conn->server->log_source, QD_LOG_CRITICAL, 
"Unrecognized component '%c' in uidFormat ", components[x]);
-                return 0;
-            }
-        }
-
-        if(uid_length > 0) {
-            char *user_id = malloc((uid_length + semi_colon_count + 1) * 
sizeof(char)); // the +1 is for the '\0' character
-            //
-            // We have allocated memory for user_id. We are responsible for 
freeing this memory. Set conn->free_user_id
-            // to true so that we know that we have to free the user_id
-            //
-            conn->free_user_id = true;
-            memset(user_id, 0, uid_length + semi_colon_count + 1);
-
-            // The components in the user id string must appear in the same 
order as it appears in the component string. that is
-            // why we have this loop
-            for (int x=0; x < component_count ; x++) {
-                if (components[x] == CERT_COUNTRY_CODE) {
-                    if (country_code) {
-                        if(*user_id != '\0')
-                            strcat(user_id, COMPONENT_SEPARATOR);
-                        strcat(user_id, (char *) country_code);
-                    }
-                }
-                else if (components[x] == CERT_STATE) {
-                    if (state) {
-                        if(*user_id != '\0')
-                            strcat(user_id, COMPONENT_SEPARATOR);
-                        strcat(user_id, (char *) state);
-                    }
-                }
-                else if (components[x] == CERT_CITY_LOCALITY) {
-                    if (locality_city) {
-                        if(*user_id != '\0')
-                            strcat(user_id, COMPONENT_SEPARATOR);
-                        strcat(user_id, (char *) locality_city);
-                    }
-                }
-                else if (components[x] == CERT_ORGANIZATION_NAME) {
-                    if (organization) {
-                        if(*user_id != '\0')
-                            strcat(user_id, COMPONENT_SEPARATOR);
-                        strcat(user_id, (char *) organization);
-                    }
-                }
-                else if (components[x] == CERT_ORGANIZATION_UNIT) {
-                    if (org_unit) {
-                        if(*user_id != '\0')
-                            strcat(user_id, COMPONENT_SEPARATOR);
-                        strcat(user_id, (char *) org_unit);
-                    }
-                }
-                else if (components[x] == CERT_COMMON_NAME) {
-                    if (common_name) {
-                        if(*user_id != '\0')
-                            strcat(user_id, COMPONENT_SEPARATOR);
-                        strcat(user_id, (char *) common_name);
-                    }
-                }
-                else if (components[x] == CERT_FINGERPRINT_SHA1 || 
components[x] == CERT_FINGERPRINT_SHA256 || components[x] == 
CERT_FINGERPRINT_SHA512) {
-                    if (strlen((char *) fingerprint) > 0) {
-                        if(*user_id != '\0')
-                            strcat(user_id, COMPONENT_SEPARATOR);
-                        strcat(user_id, (char *) fingerprint);
-                    }
-                }
-            }
-            if (config->ssl_uid_name_mapping_file) {
-                // Translate extracted id into display name
-                qd_python_lock_state_t lock_state = qd_python_lock();
-                PyObject *result = PyObject_CallMethod((PyObject 
*)conn->server->py_displayname_obj, "query", "(ss)", config->ssl_profile, 
user_id );
-                if (result) {
-                    free(user_id);
-                    user_id = py_string_2_c(result);
-                    Py_XDECREF(result);
-                } else {
-                    qd_log(conn->server->log_source, QD_LOG_DEBUG, "Internal: 
failed to read displaynameservice query result");
-                }
-                qd_python_unlock(lock_state);
-            }
-            qd_log(conn->server->log_source, QD_LOG_DEBUG, "User id is '%s' ", 
user_id);
-            return user_id;
-        }
-    }
-    else //config->ssl_uid_format not specified, just return the username 
provided by the proton transport.
-        return pn_transport_get_user(tport);
-
-    return 0;
-}
-
-
-void qd_connection_set_user(qd_connection_t *conn)
-{
-    pn_transport_t *tport = pn_connection_transport(conn->pn_conn);
-    pn_sasl_t      *sasl  = pn_sasl(tport);
-    if (sasl) {
-        const char *mech = pn_sasl_get_mech(sasl);
-        conn->user_id = pn_transport_get_user(tport);
-        // We want to set the user name only if it is not already set and the 
selected sasl mechanism is EXTERNAL
-        if (mech && strcmp(mech, MECH_EXTERNAL) == 0) {
-            const char *user_id = transport_get_user(conn, tport);
-            if (user_id)
-                conn->user_id = user_id;
-        }
-    }
-}
-
-
-qd_error_t qd_entity_refresh_sslProfile(qd_entity_t* entity, void *impl)
-{
+qd_error_t qd_entity_refresh_sslProfile(qd_entity_t* entity, void* impl) {
     return QD_ERROR_NONE;
 }
 
-qd_error_t qd_entity_refresh_authServicePlugin(qd_entity_t* entity, void *impl)
-{
+qd_error_t qd_entity_refresh_authServicePlugin(qd_entity_t* entity, void* 
impl) {
     return QD_ERROR_NONE;
 }
 
+qd_server_t* qd_server(qd_dispatch_t* qd, int thread_count, const char* 
container_name, const char* sasl_config_path,
+                       const char* sasl_config_name) {
+    // Initialize const members. Zero initialize all others.
 
-static qd_error_t listener_setup_ssl(qd_connection_t *ctx, const 
qd_server_config_t *config, pn_transport_t *tport)
-{
-    pn_ssl_domain_t *domain = pn_ssl_domain(PN_SSL_MODE_SERVER);
-    if (!domain) return qd_error(QD_ERROR_RUNTIME, "No SSL support");
+    qd_server_t tmp = {.thread_count = thread_count};
+    // XXX This type contructor is different from what I see elsewhere.
+    qd_server_t* server = NEW(qd_server_t);
 
-    // setup my identifying cert:
-    if (pn_ssl_domain_set_credentials(domain,
-                                      config->ssl_certificate_file,
-                                      config->ssl_private_key_file,
-                                      config->ssl_password)) {
-        pn_ssl_domain_free(domain);
-        return qd_error(QD_ERROR_RUNTIME, "Cannot set SSL credentials");
+    if (!server) {
+        return NULL;
     }
 
-    // for peer authentication:
-    if (config->ssl_trusted_certificate_db) {
-        if (pn_ssl_domain_set_trusted_ca_db(domain, 
config->ssl_trusted_certificate_db)) {
-            pn_ssl_domain_free(domain);
-            return qd_error(QD_ERROR_RUNTIME, "Cannot set trusted SSL CA" );
-        }
-    }
+    memcpy(server, &tmp, sizeof(tmp));
 
-    if (config->ssl_ciphers) {
-        if (pn_ssl_domain_set_ciphers(domain, config->ssl_ciphers)) {
-            pn_ssl_domain_free(domain);
-            return qd_error(QD_ERROR_RUNTIME, "Cannot set ciphers. The ciphers 
string might be invalid. Use openssl ciphers -v <ciphers> to validate");
-        }
-    }
+    server->qd                   = qd;
+    server->log_source           = qd_log_source("SERVER");
+    server->protocol_log_source  = qd_log_source("PROTOCOL");
+    server->container_name       = container_name;
+    server->sasl_config_path     = sasl_config_path;
+    server->sasl_config_name     = sasl_config_name;
+    server->proactor             = pn_proactor();
+    server->container            = NULL;
+    server->start_context        = 0;  // XXX Should be NULL?

Review comment:
       Probably, since this is typed as a void pointer.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to