bool qd_policy_approve_amqp_session(pn_session_t *ssn, qd_connection_t *qd_conn) { bool result = true; if (qd_conn->policy_settings) { if (qd_conn->policy_settings->maxSessions) { if (qd_conn->n_sessions == qd_conn->policy_settings->maxSessions) { qd_policy_deny_amqp_session(ssn, qd_conn); result = false; } } } pn_connection_t *conn = qd_connection_pn(qd_conn); qd_dispatch_t *qd = qd_conn->server->qd; qd_policy_t *policy = qd->policy; const char *hostip = qdpn_connector_hostip(qd_conn->pn_cxtr); const char *app = pn_connection_remote_hostname(conn); if (result) { qd_log(policy->log_source, QD_LOG_TRACE, "ALLOW AMQP Begin Session. user: %s, hostip: %s, app: %s", qd_conn->user_id, hostip, app); } else { qd_log(policy->log_source, QD_LOG_INFO, "DENY AMQP Begin Session due to session limit. user: %s, hostip: %s, app: %s", qd_conn->user_id, hostip, app); } return result; }
bool qd_policy_approve_amqp_receiver_link(pn_link_t *pn_link, qd_connection_t *qd_conn) { const char *hostip = qdpn_connector_hostip(qd_conn->pn_cxtr); const char *app = pn_connection_remote_hostname(qd_connection_pn(qd_conn)); if (qd_conn->policy_settings->maxReceivers) { if (qd_conn->n_receivers == qd_conn->policy_settings->maxReceivers) { // Max sender limit specified and violated. qd_log(qd_conn->server->qd->policy->log_source, QD_LOG_INFO, "DENY AMQP Attach receiver for user '%s', host '%s', app '%s' based on maxReceivers limit", qd_conn->user_id, hostip, app); _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } else { // max receiver limit not violated } } else { // max receiver limit not specified } // Approve receiver link based on source bool dynamic_src = pn_terminus_is_dynamic(pn_link_remote_source(pn_link)); if (dynamic_src) { bool lookup = qd_conn->policy_settings->allowDynamicSrc; qd_log(qd_conn->server->qd->policy->log_source, (lookup ? QD_LOG_TRACE : QD_LOG_INFO), "%s AMQP Attach receiver dynamic source for user '%s', host '%s', app '%s',", (lookup ? "ALLOW" : "DENY"), qd_conn->user_id, hostip, app); // Dynamic source policy rendered the decision if (!lookup) { _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); } return lookup; } const char * source = pn_terminus_get_address(pn_link_remote_source(pn_link)); if (source && *source) { // a source is specified bool lookup = _qd_policy_approve_link_name(qd_conn->user_id, qd_conn->policy_settings->sources, source); qd_log(qd_conn->server->qd->policy->log_source, (lookup ? QD_LOG_TRACE : QD_LOG_INFO), "%s AMQP Attach receiver link '%s' for user '%s', host '%s', app '%s' based on link source name", (lookup ? "ALLOW" : "DENY"), source, qd_conn->user_id, hostip, app); if (!lookup) { _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } } else { // A receiver with no remote source. qd_log(qd_conn->server->qd->policy->log_source, QD_LOG_TRACE, "DENY AMQP Attach receiver link '' for user '%s', host '%s', app '%s'", qd_conn->user_id, hostip, app); _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } // Approved return true; }
void qd_policy_amqp_open(void *context, bool discard) { qd_connection_t *qd_conn = (qd_connection_t *)context; if (!discard) { pn_connection_t *conn = qd_connection_pn(qd_conn); qd_dispatch_t *qd = qd_conn->server->qd; qd_policy_t *policy = qd->policy; bool connection_allowed = true; if (policy->enableAccessRules) { // Open connection or not based on policy. pn_transport_t *pn_trans = pn_connection_transport(conn); const char *hostip = qdpn_connector_hostip(qd_conn->pn_cxtr); const char *pcrh = pn_connection_remote_hostname(conn); const char *app = (pcrh ? pcrh : ""); const char *conn_name = qdpn_connector_name(qd_conn->pn_cxtr); #define SETTINGS_NAME_SIZE 256 char settings_name[SETTINGS_NAME_SIZE]; uint32_t conn_id = qd_conn->connection_id; qd_conn->policy_settings = NEW(qd_policy_settings_t); // TODO: memory pool for settings memset(qd_conn->policy_settings, 0, sizeof(qd_policy_settings_t)); if (qd_policy_open_lookup_user(policy, qd_conn->user_id, hostip, app, conn_name, settings_name, SETTINGS_NAME_SIZE, conn_id, qd_conn->policy_settings) && settings_name[0]) { // This connection is allowed by policy. // Apply transport policy settings if (qd_conn->policy_settings->maxFrameSize > 0) pn_transport_set_max_frame(pn_trans, qd_conn->policy_settings->maxFrameSize); if (qd_conn->policy_settings->maxSessions > 0) pn_transport_set_channel_max(pn_trans, qd_conn->policy_settings->maxSessions - 1); } else { // This connection is denied by policy. connection_allowed = false; } } else { // No policy implies automatic policy allow // Note that connections not governed by policy have no policy_settings. } if (connection_allowed) { if (pn_connection_state(conn) & PN_LOCAL_UNINIT) pn_connection_open(conn); policy_notify_opened(qd_conn->open_container, qd_conn, qd_conn->context); } else { qd_policy_private_deny_amqp_connection(conn, RESOURCE_LIMIT_EXCEEDED, CONNECTION_DISALLOWED); } } qd_connection_set_event_stall(qd_conn, false); }
bool qd_policy_approve_amqp_sender_link(pn_link_t *pn_link, qd_connection_t *qd_conn) { const char *hostip = qdpn_connector_hostip(qd_conn->pn_cxtr); const char *app = pn_connection_remote_hostname(qd_connection_pn(qd_conn)); if (qd_conn->policy_settings->maxSenders) { if (qd_conn->n_senders == qd_conn->policy_settings->maxSenders) { // Max sender limit specified and violated. qd_log(qd_conn->server->qd->policy->log_source, QD_LOG_INFO, "DENY AMQP Attach sender for user '%s', host '%s', app '%s' based on maxSenders limit", qd_conn->user_id, hostip, app); _qd_policy_deny_amqp_sender_link(pn_link, qd_conn); return false; } else { // max sender limit not violated } } else { // max sender limit not specified } // Approve sender link based on target const char * target = pn_terminus_get_address(pn_link_remote_target(pn_link)); bool lookup; if (target && *target) { // a target is specified lookup = _qd_policy_approve_link_name(qd_conn->user_id, qd_conn->policy_settings->targets, target); qd_log(qd_conn->server->qd->policy->log_source, (lookup ? QD_LOG_TRACE : QD_LOG_INFO), "%s AMQP Attach sender link '%s' for user '%s', host '%s', app '%s' based on link target name", (lookup ? "ALLOW" : "DENY"), target, qd_conn->user_id, hostip, app); if (!lookup) { _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } } else { // A sender with no remote target. // This happens all the time with anonymous relay lookup = qd_conn->policy_settings->allowAnonymousSender; qd_log(qd_conn->server->qd->policy->log_source, (lookup ? QD_LOG_TRACE : QD_LOG_INFO), "%s AMQP Attach anonymous sender for user '%s', host '%s', app '%s'", (lookup ? "ALLOW" : "DENY"), qd_conn->user_id, hostip, app); if (!lookup) { _qd_policy_deny_amqp_receiver_link(pn_link, qd_conn); return false; } } // Approved return true; }
std::string connection::virtual_host() const { return str(pn_connection_remote_hostname(pn_object())); }