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; }
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; }
static char *test_link_name_lookup(void *context) { // DISPATCH-1011: approval specifications are now CSV concatenated 3-tuples: // (user-subst-code, prefix, suffix) // codes are 'a'bsent, 'p'refix, 's'uffix, 'e'mbedded, '*'wildcard // OLD: 'joe', NEW: 'a,joe,' // Degenerate blank names if (_qd_policy_approve_link_name("a", "a", "")) return "blank proposed name not rejected"; if (_qd_policy_approve_link_name("a", "", "a")) return "blank allowed list not rejected"; // Easy matches if (!_qd_policy_approve_link_name("", "a,joe,", "joe")) return "proposed link 'joe' should match allowed links 'joe' but does not"; if (_qd_policy_approve_link_name("", "a,joe,", "joey")) return "proposed link 'joey' should not match allowed links 'joe' but does"; // Wildcard matches if (!_qd_policy_approve_link_name("", "a,joe*,", "joey")) return "proposed link 'joey' should match allowed links 'joe*' but does not"; if (!_qd_policy_approve_link_name("", "a,joe*,", "joezzzZZZ")) return "proposed link 'joezzzZZZ' should match allowed links 'joe*' but does not"; if (!_qd_policy_approve_link_name("", "a,joe,,*,,", "joey")) return "proposed link 'joey' should match allowed links 'joe,*' but does not"; // Deeper match if (!_qd_policy_approve_link_name("", "a,no1,,a,no2,,a,no3,,a,yes,,a,no4,", "yes")) return "proposed link 'yes' should match allowed links 'no1,no2,no3,yes,no4' but does not"; // Deeeper match - triggers malloc/free internal handler #define BIG_N 512 char * bufp = (char *)malloc(BIG_N * 8 + 6 + 1); if (!bufp) return "failed to allocate buffer for large link name test"; char * wp = bufp; int i; for (i=0; i<BIG_N; i++) { wp += sprintf(wp, "a,n%03d,,", i); } sprintf(wp, "a,yes,"); if (!_qd_policy_approve_link_name("", bufp, "yes")) { free(bufp); return "proposed link 'yes' should match allowed large list but does not"; } free(bufp); // Substitute a user name if (!_qd_policy_approve_link_name("chuck", "e,ab,xyz", "abchuckxyz")) return "proposed link 'abchuckxyz' should match allowed links with ${user} but does not"; if (!_qd_policy_approve_link_name("chuck", "p,,xyz", "chuckxyz")) return "proposed link 'chuckxyz' should match allowed links with ${user} but does not"; if (!_qd_policy_approve_link_name("chuck", "s,ab,", "abchuck")) return "proposed link 'abchuck' should match allowed links with ${user} but does not"; // if (!_qd_policy_approve_link_name("em", "temp-${user}", "temp-em")) // return "proposed link 'temp-em' should match allowed links with ${user} but does not"; // Combine user name and wildcard if (!_qd_policy_approve_link_name("chuck", "e,ab,*", "abchuckzyxw")) return "proposed link 'abchuckzyxw' should match allowed links with ${user}* but does not"; return 0; }