You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by tr...@apache.org on 2018/12/18 17:52:36 UTC

[qpid-dispatch] branch master updated: DISPATCH-1227 - Added a policy setting to allow or forbid use of connection-scoped/dynamic link routes.

This is an automated email from the ASF dual-hosted git repository.

tross pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/qpid-dispatch.git


The following commit(s) were added to refs/heads/master by this push:
     new 78f799a  DISPATCH-1227 - Added a policy setting to allow or forbid use of connection-scoped/dynamic link routes.
78f799a is described below

commit 78f799af4ecd4940de181809f35a1abd8fc593ef
Author: Ted Ross <tr...@redhat.com>
AuthorDate: Tue Dec 18 12:52:04 2018 -0500

    DISPATCH-1227 - Added a policy setting to allow or forbid use of connection-scoped/dynamic link routes.
---
 docs/books/user-guide/configuration-security.adoc  |  9 +++++
 include/qpid/dispatch/router_core.h                |  2 ++
 python/qpid_dispatch/management/qdrouter.json      |  7 ++++
 .../qpid_dispatch_internal/policy/policy_local.py  | 38 ++++++++++++----------
 src/policy.c                                       |  5 +--
 src/policy.h                                       |  1 +
 src/router_core/agent_conn_link_route.c            | 12 +++++--
 src/router_core/connections.c                      |  2 ++
 src/router_core/router_core_private.h              |  1 +
 src/router_node.c                                  |  1 +
 10 files changed, 56 insertions(+), 22 deletions(-)

diff --git a/docs/books/user-guide/configuration-security.adoc b/docs/books/user-guide/configuration-security.adoc
index a21c5d6..f8795d6 100644
--- a/docs/books/user-guide/configuration-security.adoc
+++ b/docs/books/user-guide/configuration-security.adoc
@@ -616,6 +616,15 @@ A list of authenticated users for this user group. Use commas to separate multip
 `remoteHosts`::
 A list of remote hosts from which the users may connect. A host can be a hostname, IP address, or IP address range. Use commas to separate multiple hosts. To allow access from all remote hosts, specify a wildcard `*`. To deny access from all remote hosts, leave this attribute blank.
 
+`allowDynamicSource`::
+If true, connections from users in this group are permitted to attach receivers to dynamic sources.  This permits creation of listners to temporary addresses or termporary queues.  If false, use of dynamic sources is forbidden.
+
+`allowWaypointLinks`::
+If true, connections from users in this group are permitted to attach links using waypoint capabilities.  This allows endpoints to act as waypoints (i.e. brokers) without the need for configuring auto-links.  If false, use of waypoint capabilities is forbidden.
+
+`allowDynamicLinkRoutes`::
+If true, connections from users in this group may dynamically create connection-scoped link route destinations.  This allows endpoints to act as link route destinations (i.e. brokers) without the need for configuring link-routes.  If false, creation of dynamic link route destintations is forbidden.
+
 `sources` | `sourcePattern`::
 A list of AMQP source addresses from which users in this group may receive messages.
 +
diff --git a/include/qpid/dispatch/router_core.h b/include/qpid/dispatch/router_core.h
index a86428a..11275d3 100644
--- a/include/qpid/dispatch/router_core.h
+++ b/include/qpid/dispatch/router_core.h
@@ -173,6 +173,7 @@ typedef void (*qdr_connection_bind_context_t) (qdr_connection_t *context, void*
  *        correlate the connection with waypoints and link-route destinations that use the connection.
  * @param strip_annotations_in True if configured to remove annotations on inbound messages.
  * @param strip_annotations_out True if configured to remove annotations on outbound messages.
+ * @param policy_allow_dynamic_link_routes True if this connection is allowed by policy to create link route destinations.
  * @param link_capacity The capacity, in deliveries, for links in this connection.
  * @param vhost If non-null, this is the vhost of the connection to be used for multi-tenancy.
  * @return Pointer to a connection object that can be used to refer to this connection over its lifetime.
@@ -186,6 +187,7 @@ qdr_connection_t *qdr_connection_opened(qdr_core_t            *core,
                                         const char            *remote_container_id,
                                         bool                   strip_annotations_in,
                                         bool                   strip_annotations_out,
+                                        bool                   policy_allow_dynamic_link_routes,
                                         int                    link_capacity,
                                         const char            *vhost,
                                         qdr_connection_info_t *connection_info,
diff --git a/python/qpid_dispatch/management/qdrouter.json b/python/qpid_dispatch/management/qdrouter.json
index 180a0e0..861d620 100644
--- a/python/qpid_dispatch/management/qdrouter.json
+++ b/python/qpid_dispatch/management/qdrouter.json
@@ -1875,6 +1875,13 @@
                     "required": false,
                     "create": true
                 },
+                "allowDynamicLinkRoutes": {
+                    "type": "boolean",
+                    "description": "Whether this connection is allowed to dynamically create connection-scoped link route destinations.",
+                    "default": true,
+                    "required": false,
+                    "create": true
+                },
                 "sources": {
                     "type": "string",
                     "description": "A list of source addresses from which users in this group may receive messages. To specify multiple addresses, separate the addresses with either a comma or a space. If you do not specify any addresses, users in this group are not allowed to receive messages from any addresses. You can use the substitution token '${user}' to specify an address that contains a user's authenticated user name. You can use an asterisk ('*') wildcard to match one or more ch [...]
diff --git a/python/qpid_dispatch_internal/policy/policy_local.py b/python/qpid_dispatch_internal/policy/policy_local.py
index 2f3cfb4..b62e8d4 100644
--- a/python/qpid_dispatch_internal/policy/policy_local.py
+++ b/python/qpid_dispatch_internal/policy/policy_local.py
@@ -59,22 +59,23 @@ class PolicyKeys(object):
     KW_GROUPS                      = "groups"
 
     # Policy settings key words
-    KW_USERS                    = "users"
-    KW_REMOTE_HOSTS             = "remoteHosts"
-    KW_MAX_FRAME_SIZE           = "maxFrameSize"
-    KW_MAX_MESSAGE_SIZE         = "maxMessageSize"
-    KW_MAX_SESSION_WINDOW       = "maxSessionWindow"
-    KW_MAX_SESSIONS             = "maxSessions"
-    KW_MAX_SENDERS              = "maxSenders"
-    KW_MAX_RECEIVERS            = "maxReceivers"
-    KW_ALLOW_DYNAMIC_SRC        = "allowDynamicSource"
-    KW_ALLOW_ANONYMOUS_SENDER   = "allowAnonymousSender"
-    KW_ALLOW_USERID_PROXY       = "allowUserIdProxy"
-    KW_ALLOW_WAYPOINT_LINKS     = "allowWaypointLinks"
-    KW_SOURCES                  = "sources"
-    KW_TARGETS                  = "targets"
-    KW_SOURCE_PATTERN           = "sourcePattern"
-    KW_TARGET_PATTERN           = "targetPattern"
+    KW_USERS                     = "users"
+    KW_REMOTE_HOSTS              = "remoteHosts"
+    KW_MAX_FRAME_SIZE            = "maxFrameSize"
+    KW_MAX_MESSAGE_SIZE          = "maxMessageSize"
+    KW_MAX_SESSION_WINDOW        = "maxSessionWindow"
+    KW_MAX_SESSIONS              = "maxSessions"
+    KW_MAX_SENDERS               = "maxSenders"
+    KW_MAX_RECEIVERS             = "maxReceivers"
+    KW_ALLOW_DYNAMIC_SRC         = "allowDynamicSource"
+    KW_ALLOW_ANONYMOUS_SENDER    = "allowAnonymousSender"
+    KW_ALLOW_USERID_PROXY        = "allowUserIdProxy"
+    KW_ALLOW_WAYPOINT_LINKS      = "allowWaypointLinks"
+    KW_ALLOW_DYNAMIC_LINK_ROUTES = "allowDynamicLinkRoutes"
+    KW_SOURCES                   = "sources"
+    KW_TARGETS                   = "targets"
+    KW_SOURCE_PATTERN            = "sourcePattern"
+    KW_TARGET_PATTERN            = "targetPattern"
 
     # Policy stats key words
     KW_CONNECTIONS_APPROVED     = "connectionsApproved"
@@ -145,6 +146,7 @@ class PolicyCompiler(object):
         PolicyKeys.KW_ALLOW_ANONYMOUS_SENDER,
         PolicyKeys.KW_ALLOW_USERID_PROXY,
         PolicyKeys.KW_ALLOW_WAYPOINT_LINKS,
+        PolicyKeys.KW_ALLOW_DYNAMIC_LINK_ROUTES,
         PolicyKeys.KW_SOURCES,
         PolicyKeys.KW_TARGETS,
         PolicyKeys.KW_SOURCE_PATTERN,
@@ -246,6 +248,7 @@ class PolicyCompiler(object):
         policy_out[PolicyKeys.KW_ALLOW_ANONYMOUS_SENDER] = False
         policy_out[PolicyKeys.KW_ALLOW_USERID_PROXY] = False
         policy_out[PolicyKeys.KW_ALLOW_WAYPOINT_LINKS] = True
+        policy_out[PolicyKeys.KW_ALLOW_DYNAMIC_LINK_ROUTES] = True
         policy_out[PolicyKeys.KW_SOURCES] = ''
         policy_out[PolicyKeys.KW_TARGETS] = ''
         policy_out[PolicyKeys.KW_SOURCE_PATTERN] = ''
@@ -282,7 +285,8 @@ class PolicyCompiler(object):
             elif key in [PolicyKeys.KW_ALLOW_ANONYMOUS_SENDER,
                          PolicyKeys.KW_ALLOW_DYNAMIC_SRC,
                          PolicyKeys.KW_ALLOW_USERID_PROXY,
-                         PolicyKeys.KW_ALLOW_WAYPOINT_LINKS
+                         PolicyKeys.KW_ALLOW_WAYPOINT_LINKS,
+                         PolicyKeys.KW_ALLOW_DYNAMIC_LINK_ROUTES
                          ]:
                 if isinstance(val, (PY_STRING_TYPE, PY_TEXT_TYPE)) and val.lower() in ['true', 'false']:
                     val = True if val == 'true' else False
diff --git a/src/policy.c b/src/policy.c
index 910a93b..d9ecddc 100644
--- a/src/policy.c
+++ b/src/policy.c
@@ -436,8 +436,9 @@ bool qd_policy_open_lookup_user(
                     if (!settings->allowDynamicSource) { //don't override if enabled by authz plugin
                         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->allowWaypointLinks   = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowWaypointLinks", true);
+                    settings->allowUserIdProxy       = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowUserIdProxy", false);
+                    settings->allowWaypointLinks     = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowWaypointLinks", true);
+                    settings->allowDynamicLinkRoutes = qd_entity_opt_bool((qd_entity_t*)upolicy, "allowDynamicLinkRoutes", true);
                     if (settings->sources == 0) { //don't override if configured by authz plugin
                         settings->sources              = qd_entity_get_string((qd_entity_t*)upolicy, "sources");
                     }
diff --git a/src/policy.h b/src/policy.h
index 5f7af74..0b9fc0d 100644
--- a/src/policy.h
+++ b/src/policy.h
@@ -52,6 +52,7 @@ struct qd_policy__settings_s {
     bool allowAnonymousSender;
     bool allowUserIdProxy;
     bool allowWaypointLinks;
+    bool allowDynamicLinkRoutes;
     char *sources;
     char *targets;
     char *sourcePattern;
diff --git a/src/router_core/agent_conn_link_route.c b/src/router_core/agent_conn_link_route.c
index c093780..a671bf3 100644
--- a/src/router_core/agent_conn_link_route.c
+++ b/src/router_core/agent_conn_link_route.c
@@ -158,9 +158,9 @@ static qdr_link_route_t *_find_link_route_CT(qdr_connection_t *conn,
 
 
 void qdra_conn_link_route_create_CT(qdr_core_t         *core,
-                                        qd_iterator_t      *name,
-                                        qdr_query_t        *query,
-                                        qd_parsed_field_t  *in_body)
+                                    qd_iterator_t      *name,
+                                    qdr_query_t        *query,
+                                    qd_parsed_field_t  *in_body)
 {
     char *pattern = NULL;
 
@@ -179,6 +179,12 @@ void qdra_conn_link_route_create_CT(qdr_core_t         *core,
         goto exit;
     }
 
+    // fail if forbidden by policy
+    if (!conn->policy_allow_dynamic_link_routes) {
+        query->status = QD_AMQP_FORBIDDEN;
+        goto exit;
+    }
+
     if (!qd_parse_is_map(in_body)) {
         query->status.description = "Body of request must be a map";
         goto exit;
diff --git a/src/router_core/connections.c b/src/router_core/connections.c
index d6ced98..a1717a8 100644
--- a/src/router_core/connections.c
+++ b/src/router_core/connections.c
@@ -70,6 +70,7 @@ qdr_connection_t *qdr_connection_opened(qdr_core_t            *core,
                                         const char            *remote_container_id,
                                         bool                   strip_annotations_in,
                                         bool                   strip_annotations_out,
+                                        bool                   policy_allow_dynamic_link_routes,
                                         int                    link_capacity,
                                         const char            *vhost,
                                         qdr_connection_info_t *connection_info,
@@ -89,6 +90,7 @@ qdr_connection_t *qdr_connection_opened(qdr_core_t            *core,
     conn->inter_router_cost     = cost;
     conn->strip_annotations_in  = strip_annotations_in;
     conn->strip_annotations_out = strip_annotations_out;
+    conn->policy_allow_dynamic_link_routes = policy_allow_dynamic_link_routes;
     conn->link_capacity         = link_capacity;
     conn->mask_bit              = -1;
     DEQ_INIT(conn->links);
diff --git a/src/router_core/router_core_private.h b/src/router_core/router_core_private.h
index a2ebc8e..7d6f2a3 100644
--- a/src/router_core/router_core_private.h
+++ b/src/router_core/router_core_private.h
@@ -614,6 +614,7 @@ struct qdr_connection_t {
     qdr_conn_identifier_t      *conn_id;
     bool                        strip_annotations_in;
     bool                        strip_annotations_out;
+    bool                        policy_allow_dynamic_link_routes;
     int                         link_capacity;
     int                         mask_bit;
     qdr_connection_work_list_t  work_list;
diff --git a/src/router_node.c b/src/router_node.c
index 7ab9d0a..8c44264 100644
--- a/src/router_node.c
+++ b/src/router_node.c
@@ -1152,6 +1152,7 @@ static void AMQP_opened_handler(qd_router_t *router, qd_connection_t *conn, bool
                           pn_connection_remote_container(pn_conn),
                           conn->strip_annotations_in,
                           conn->strip_annotations_out,
+                          conn->policy_settings ? conn->policy_settings->allowDynamicLinkRoutes : true,
                           link_capacity,
                           vhost,
                           connection_info,


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org