static void qd_io_rx_handler(void *context, qd_message_t *msg, int link_id) { IoAdapter *self = (IoAdapter*) context; // // Parse the message through the body and exit if the message is not well formed. // if (!qd_message_check(msg, QD_DEPTH_BODY)) return; // This is called from non-python threads so we need to acquire the GIL to use python APIS. qd_python_lock_state_t lock_state = qd_python_lock(); PyObject *py_msg = PyObject_CallFunction(message_type, NULL); if (!py_msg) { qd_error_py(); qd_python_unlock(lock_state); return; } iter_to_py_attr(qd_message_field_iterator(msg, QD_FIELD_TO), py_iter_copy, py_msg, "address"); iter_to_py_attr(qd_message_field_iterator(msg, QD_FIELD_REPLY_TO), py_iter_copy, py_msg, "reply_to"); // Note: correlation ID requires _typed() iter_to_py_attr(qd_message_field_iterator_typed(msg, QD_FIELD_CORRELATION_ID), py_iter_parse, py_msg, "correlation_id"); iter_to_py_attr(qd_message_field_iterator(msg, QD_FIELD_APPLICATION_PROPERTIES), py_iter_parse, py_msg, "properties"); iter_to_py_attr(qd_message_field_iterator(msg, QD_FIELD_BODY), py_iter_parse, py_msg, "body"); PyObject *value = PyObject_CallFunction(self->handler, "Ol", py_msg, link_id); Py_DECREF(py_msg); Py_XDECREF(value); qd_error_py(); qd_python_unlock(lock_state); }
void qd_policy_socket_close(void *context, const qd_connection_t *conn) { qd_policy_t *policy = (qd_policy_t *)context; n_connections -= 1; assert (n_connections >= 0); if (policy->enableVhostPolicy) { // HACK ALERT: TODO: This should be deferred to a Python thread qd_python_lock_state_t lock_state = qd_python_lock(); PyObject *module = PyImport_ImportModule("qpid_dispatch_internal.policy.policy_manager"); if (module) { PyObject *close_connection = PyObject_GetAttrString(module, "policy_close_connection"); if (close_connection) { PyObject *result = PyObject_CallFunction(close_connection, "(OK)", (PyObject *)policy->py_policy_manager, conn->connection_id); if (result) { Py_XDECREF(result); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: Connection close failed: result"); } Py_XDECREF(close_connection); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: Connection close failed: close_connection"); } Py_XDECREF(module); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: Connection close failed: module"); } qd_python_unlock(lock_state); } const char *hostname = qdpn_connector_name(conn->pn_cxtr); qd_log(policy->log_source, QD_LOG_DEBUG, "Connection '%s' closed with resources n_sessions=%d, n_senders=%d, n_receivers=%d. nConnections= %d.", hostname, conn->n_sessions, conn->n_senders, conn->n_receivers, n_connections); }
void qd_python_initialize(qd_dispatch_t *qd, const char *python_pkgdir) { log_source = qd_log_source("PYTHON"); dispatch = qd; ilock = sys_mutex(); if (python_pkgdir) dispatch_python_pkgdir = PyString_FromString(python_pkgdir); qd_python_lock_state_t ls = qd_python_lock(); Py_Initialize(); qd_python_setup(); qd_python_unlock(ls); }
static void qd_router_link_lost(void *context, int link_mask_bit) { qd_router_t *router = (qd_router_t*) context; PyObject *pArgs; PyObject *pValue; if (pyRemoved && router->router_mode == QD_ROUTER_MODE_INTERIOR) { qd_python_lock_state_t lock_state = qd_python_lock(); pArgs = PyTuple_New(1); PyTuple_SetItem(pArgs, 0, PyInt_FromLong((long) link_mask_bit)); pValue = PyObject_CallObject(pyLinkLost, pArgs); qd_error_py(); Py_DECREF(pArgs); Py_XDECREF(pValue); qd_python_unlock(lock_state); } }
static void qd_router_mobile_removed(void *context, const char *address_hash) { qd_router_t *router = (qd_router_t*) context; PyObject *pArgs; PyObject *pValue; if (pyRemoved && router->router_mode == QD_ROUTER_MODE_INTERIOR) { qd_python_lock_state_t lock_state = qd_python_lock(); pArgs = PyTuple_New(1); PyTuple_SetItem(pArgs, 0, PyString_FromString(address_hash)); pValue = PyObject_CallObject(pyRemoved, pArgs); qd_error_py(); Py_DECREF(pArgs); Py_XDECREF(pValue); qd_python_unlock(lock_state); } }
qd_error_t qd_dispatch_load_config(qd_dispatch_t *qd, const char *config_path) { qd->dl_handle = dlopen(QPID_DISPATCH_LIB, RTLD_LAZY | RTLD_NOLOAD); if (!qd->dl_handle) return qd_error(QD_ERROR_RUNTIME, "Cannot locate library %s", QPID_DISPATCH_LIB); qd_python_lock_state_t lock_state = qd_python_lock(); PyObject *module = PyImport_ImportModule("qpid_dispatch_internal.management.config"); PyObject *configure_dispatch = module ? PyObject_GetAttrString(module, "configure_dispatch") : NULL; Py_XDECREF(module); PyObject *result = configure_dispatch ? PyObject_CallFunction(configure_dispatch, "(lls)", (long)qd, qd->dl_handle, config_path) : NULL; Py_XDECREF(configure_dispatch); if (!result) qd_error_py(); Py_XDECREF(result); qd_python_unlock(lock_state); return qd_error_code(); }
qd_error_t qd_pyrouter_tick(qd_router_t *router) { qd_error_clear(); qd_error_t err = QD_ERROR_NONE; PyObject *pArgs; PyObject *pValue; if (pyTick && router->router_mode == QD_ROUTER_MODE_INTERIOR) { qd_python_lock_state_t lock_state = qd_python_lock(); pArgs = PyTuple_New(0); pValue = PyObject_CallObject(pyTick, pArgs); Py_DECREF(pArgs); Py_XDECREF(pValue); err = qd_error_py(); qd_python_unlock(lock_state); } return err; }
/** Look up user/host/app in python policyRuleset and give the AMQP Open * a go-no_go decision. Return false if the mechanics of calling python * fails. A policy lookup will deny the connection by returning a blank * usergroup name in the name buffer. * Connection and connection denial counting is done in the python code. * @param[in] policy pointer to policy * @param[in] username authenticated user name * @param[in] hostip numeric host ip address * @param[in] app application name received in remote AMQP Open.hostname * @param[in] conn_name connection name for tracking * @param[out] name_buf pointer to settings name buffer * @param[in] name_buf_size size of settings_buf **/ bool qd_policy_open_lookup_user( qd_policy_t *policy, const char *username, const char *hostip, const char *app, const char *conn_name, char *name_buf, int name_buf_size, uint64_t conn_id, qd_policy_settings_t *settings) { // TODO: crolke 2016-03-24 - Workaround for PROTON-1133: Port number is included in Open hostname // Strip the ':NNNN', if any, from the app name so that policy will work with proton 0.12 char appname[HOST_NAME_MAX + 1]; strncpy(appname, app, HOST_NAME_MAX); appname[HOST_NAME_MAX] = 0; char * colonp = strstr(appname, ":"); if (colonp) { *colonp = 0; } // Lookup the user/host/app for allow/deny and to get settings name bool res = false; qd_python_lock_state_t lock_state = qd_python_lock(); PyObject *module = PyImport_ImportModule("qpid_dispatch_internal.policy.policy_manager"); if (module) { PyObject *lookup_user = PyObject_GetAttrString(module, "policy_lookup_user"); if (lookup_user) { PyObject *result = PyObject_CallFunction(lookup_user, "(OssssK)", (PyObject *)policy->py_policy_manager, username, hostip, appname, conn_name, conn_id); if (result) { const char *res_string = PyString_AsString(result); strncpy(name_buf, res_string, name_buf_size); Py_XDECREF(result); res = true; // settings name returned } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: result"); } Py_XDECREF(lookup_user); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: lookup_user"); } } if (!res) { if (module) { Py_XDECREF(module); } qd_python_unlock(lock_state); return false; } // if (name_buf[0]) { // Go get the named settings res = false; PyObject *upolicy = PyDict_New(); if (upolicy) { PyObject *lookup_settings = PyObject_GetAttrString(module, "policy_lookup_settings"); if (lookup_settings) { PyObject *result2 = PyObject_CallFunction(lookup_settings, "(OssO)", (PyObject *)policy->py_policy_manager, appname, name_buf, upolicy); if (result2) { settings->maxFrameSize = qd_entity_opt_long((qd_entity_t*)upolicy, "maxFrameSize", 0); settings->maxMessageSize = qd_entity_opt_long((qd_entity_t*)upolicy, "maxMessageSize", 0); settings->maxSessionWindow = qd_entity_opt_long((qd_entity_t*)upolicy, "maxSessionWindow", 0); settings->maxSessions = qd_entity_opt_long((qd_entity_t*)upolicy, "maxSessions", 0); settings->maxSenders = qd_entity_opt_long((qd_entity_t*)upolicy, "maxSenders", 0); settings->maxReceivers = qd_entity_opt_long((qd_entity_t*)upolicy, "maxReceivers", 0); settings->allowAnonymousSender = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowAnonymousSender", false); settings->allowDynamicSrc = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowDynamicSrc", false); settings->sources = qd_entity_get_string((qd_entity_t*)upolicy, "sources"); settings->targets = qd_entity_get_string((qd_entity_t*)upolicy, "targets"); settings->denialCounts = (qd_policy_denial_counts_t*) qd_entity_get_long((qd_entity_t*)upolicy, "denialCounts"); Py_XDECREF(result2); res = true; // named settings content returned } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: result2"); } Py_XDECREF(lookup_settings); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: lookup_settings"); } Py_XDECREF(upolicy); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: upolicy"); } } Py_XDECREF(module); qd_python_unlock(lock_state); if (name_buf[0]) { qd_log(policy->log_source, QD_LOG_TRACE, "ALLOW AMQP Open lookup_user: %s, hostip: %s, app: %s, connection: %s. Usergroup: '%s'%s", username, hostip, appname, conn_name, name_buf, (res ? "" : " Internal error.")); } else { // Denials are logged in python code } return res; }
/** Look up user/host/vhost in python vhost and give the AMQP Open * a go-no_go decision. Return false if the mechanics of calling python * fails. A policy lookup will deny the connection by returning a blank * usergroup name in the name buffer. * Connection and connection denial counting is done in the python code. * @param[in] policy pointer to policy * @param[in] username authenticated user name * @param[in] hostip numeric host ip address * @param[in] vhost application name received in remote AMQP Open.hostname * @param[in] conn_name connection name for tracking * @param[out] name_buf pointer to settings name buffer * @param[in] name_buf_size size of settings_buf **/ bool qd_policy_open_lookup_user( qd_policy_t *policy, const char *username, const char *hostip, const char *vhost, const char *conn_name, char *name_buf, int name_buf_size, uint64_t conn_id, qd_policy_settings_t *settings) { // Lookup the user/host/vhost for allow/deny and to get settings name bool res = false; qd_python_lock_state_t lock_state = qd_python_lock(); PyObject *module = PyImport_ImportModule("qpid_dispatch_internal.policy.policy_manager"); if (module) { PyObject *lookup_user = PyObject_GetAttrString(module, "policy_lookup_user"); if (lookup_user) { PyObject *result = PyObject_CallFunction(lookup_user, "(OssssK)", (PyObject *)policy->py_policy_manager, username, hostip, vhost, conn_name, conn_id); if (result) { const char *res_string = PyString_AsString(result); strncpy(name_buf, res_string, name_buf_size); Py_XDECREF(result); res = true; // settings name returned } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: result"); } Py_XDECREF(lookup_user); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: lookup_user"); } } if (!res) { if (module) { Py_XDECREF(module); } qd_python_unlock(lock_state); return false; } // if (name_buf[0]) { // Go get the named settings res = false; PyObject *upolicy = PyDict_New(); if (upolicy) { PyObject *lookup_settings = PyObject_GetAttrString(module, "policy_lookup_settings"); if (lookup_settings) { PyObject *result2 = PyObject_CallFunction(lookup_settings, "(OssO)", (PyObject *)policy->py_policy_manager, vhost, name_buf, upolicy); if (result2) { settings->maxFrameSize = qd_entity_opt_long((qd_entity_t*)upolicy, "maxFrameSize", 0); settings->maxMessageSize = qd_entity_opt_long((qd_entity_t*)upolicy, "maxMessageSize", 0); settings->maxSessionWindow = qd_entity_opt_long((qd_entity_t*)upolicy, "maxSessionWindow", 0); settings->maxSessions = qd_entity_opt_long((qd_entity_t*)upolicy, "maxSessions", 0); settings->maxSenders = qd_entity_opt_long((qd_entity_t*)upolicy, "maxSenders", 0); settings->maxReceivers = qd_entity_opt_long((qd_entity_t*)upolicy, "maxReceivers", 0); settings->allowAnonymousSender = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowAnonymousSender", false); settings->allowDynamicSource = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowDynamicSource", false); settings->allowUserIdProxy = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowUserIdProxy", false); settings->sources = qd_entity_get_string((qd_entity_t*)upolicy, "sources"); settings->targets = qd_entity_get_string((qd_entity_t*)upolicy, "targets"); settings->denialCounts = (qd_policy_denial_counts_t*) qd_entity_get_long((qd_entity_t*)upolicy, "denialCounts"); Py_XDECREF(result2); res = true; // named settings content returned } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: result2"); } Py_XDECREF(lookup_settings); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: lookup_settings"); } Py_XDECREF(upolicy); } else { qd_log(policy->log_source, QD_LOG_DEBUG, "Internal: lookup_user: upolicy"); } } Py_XDECREF(module); qd_python_unlock(lock_state); if (name_buf[0]) { qd_log(policy->log_source, QD_LOG_TRACE, "ALLOW AMQP Open lookup_user: %s, rhost: %s, vhost: %s, connection: %s. Usergroup: '%s'%s", username, hostip, vhost, conn_name, name_buf, (res ? "" : " Internal error.")); } else { // Denials are logged in python code } return res; }