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 2015/08/11 22:51:02 UTC

svn commit: r1695375 - in /qpid/dispatch/trunk: ./ etc/ include/qpid/dispatch/ python/qpid_dispatch/management/ python/qpid_dispatch_internal/tools/ src/ tests/ tests/config-2/ tools/

Author: tross
Date: Tue Aug 11 20:51:02 2015
New Revision: 1695375

URL: http://svn.apache.org/r1695375
Log:
DISPATCH-152, DISPATCH-153
  - Expose SASL/SSL capabilities via the configuration schema
  - Provide instrumentation on connections to expose security data
  - Updated the tooling (qdstat -c) to display the new data
  - Updated the tests to conform to the security changes
  - Bumped the shared-object major version

Modified:
    qpid/dispatch/trunk/CMakeLists.txt
    qpid/dispatch/trunk/etc/qdrouterd.conf
    qpid/dispatch/trunk/include/qpid/dispatch/server.h
    qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json
    qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py
    qpid/dispatch/trunk/src/connection_manager.c
    qpid/dispatch/trunk/src/server.c
    qpid/dispatch/trunk/src/server_private.h
    qpid/dispatch/trunk/tests/config-2/A-ssl.conf.in
    qpid/dispatch/trunk/tests/config-2/B-ssl.conf.in
    qpid/dispatch/trunk/tests/config-2/gencerts.sh
    qpid/dispatch/trunk/tests/system_test.py
    qpid/dispatch/trunk/tests/system_tests_management.py
    qpid/dispatch/trunk/tests/system_tests_qdmanage.py
    qpid/dispatch/trunk/tests/system_tests_qdstat.py
    qpid/dispatch/trunk/tools/qdstat

Modified: qpid/dispatch/trunk/CMakeLists.txt
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/CMakeLists.txt?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/CMakeLists.txt (original)
+++ qpid/dispatch/trunk/CMakeLists.txt Tue Aug 11 20:51:02 2015
@@ -47,8 +47,8 @@ if (NOT PYTHONLIBS_FOUND)
      message(FATAL_ERROR "Python Development Libraries are needed.")
 endif (NOT PYTHONLIBS_FOUND)
 
-set (SO_VERSION_MAJOR 0)
-set (SO_VERSION_MINOR 1)
+set (SO_VERSION_MAJOR 1)
+set (SO_VERSION_MINOR 0)
 set (SO_VERSION "${SO_VERSION_MAJOR}.${SO_VERSION_MINOR}")
 
 if (NOT DEFINED LIB_SUFFIX)

Modified: qpid/dispatch/trunk/etc/qdrouterd.conf
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/etc/qdrouterd.conf?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/etc/qdrouterd.conf (original)
+++ qpid/dispatch/trunk/etc/qdrouterd.conf Tue Aug 11 20:51:02 2015
@@ -25,23 +25,19 @@ container {
     containerName: Qpid.Dispatch.Router.A
 }
 
-sslProfile {
-    name: sslProfileName
+router {
+    mode: standalone
+    routerId: Router.A
 }
 
 listener {
     addr: 0.0.0.0
     port: amqp
-    allowNoSasl: yes
     saslMechanisms: ANONYMOUS
+    authenticatePeer: no
     maxFrameSize: 16384
 }
 
-router {
-    mode: standalone
-    routerId: Router.A
-}
-
 fixedAddress {
     prefix: /closest/
     fanout: single
@@ -68,20 +64,20 @@ fixedAddress {
 }
 
 fixedAddress {
-	prefix: /unicast
-	fanout: single
-	bias: closest
+    prefix: /unicast
+    fanout: single
+    bias: closest
 }
 
 fixedAddress {
-	prefix: /exclusive
-	fanout: single
-	bias: closest
+    prefix: /exclusive
+    fanout: single
+    bias: closest
 }
 
 fixedAddress {
-	prefix: /broadcast
-	fanout: multiple
+    prefix: /broadcast
+    fanout: multiple
 }
 
 fixedAddress {

Modified: qpid/dispatch/trunk/include/qpid/dispatch/server.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/include/qpid/dispatch/server.h?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/include/qpid/dispatch/server.h (original)
+++ qpid/dispatch/trunk/include/qpid/dispatch/server.h Tue Aug 11 20:51:02 2015
@@ -272,27 +272,29 @@ typedef struct qd_server_config_t {
     int sasl_maxssf;
 
     /**
-     * SSL is enabled for this connection iff non-zero.
+     * SSL is enabled for this connection iff true.
      */
-    int ssl_enabled;
+    bool ssl_enabled;
 
     /**
-     * Connection will take on the role of SSL server iff non-zero.
+     * Iff true, SSL/TLS must be used on the connection.
      */
-    int ssl_server;
+    bool ssl_required;
 
     /**
-     * Iff non-zero AND ssl_enabled is non-zero, this listener will detect the client's use
-     * of SSL or non-SSL and conform to the client's protocol.
-     * (listener only)
+     * Iff true, the client of the connection must authenticate with the server.
      */
-    int ssl_allow_unsecured_client;
+    bool requireAuthentication;
 
     /**
-     * Iff non-zero, this listener will allow clients to connect even if they skip the
-     * SASL authentication protocol.
+     * Iff true, client authentication _may_ be insecure (i.e. PLAIN over plaintext).
      */
-    int allow_no_sasl;
+    bool allowInsecureAuthentication;
+
+    /**
+     * Iff true, the payload of the connection must be encrypted.
+     */
+    bool requireEncryption;
 
     /**
      * Path to the file containing the PEM-formatted public certificate for the local end
@@ -325,16 +327,16 @@ typedef struct qd_server_config_t {
     char *ssl_trusted_certificates;
 
     /**
-     * Iff non-zero, require that the peer's certificate be supplied and that it be authentic
+     * Iff true, require that the peer's certificate be supplied and that it be authentic
      * according to the set of trusted CAs.
      */
-    int ssl_require_peer_authentication;
+    bool ssl_require_peer_authentication;
 
     /**
      * Allow the connection to be redirected by the peer (via CLOSE->Redirect).  This is
      * meaningful for outgoing (connector) connections only.
      */
-    int allow_redirect;
+    bool allow_redirect;
 
     /**
      * The specified role of the connection.  This can be used to control the behavior and

Modified: qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch/management/qdrouter.json Tue Aug 11 20:51:02 2015
@@ -24,19 +24,6 @@
             }
         },
 
-        "saslMechanisms": {
-            "description": "Attribute for a list of SASL mechanisms.",
-            "attributes": {
-                "saslMechanisms": {
-                    "type": "string",
-                    "required": true,
-                    "description": "Comma separated list of accepted SASL authentication mechanisms.",
-                    "create": true
-
-                }
-            }
-        },
-
         "connectionRole": {
             "description": "Attribute for the role of a connection.",
             "attributes": {
@@ -545,17 +532,18 @@
                     "description": "Deprecated - This value is no longer used in the router.",
                     "create": true
                 },
-	        "addrCount": {
+
+                "addrCount": {
                     "type":
                     "integer", "description":"Number of addresses known to the router.",
                     "graph": true
                 },
-	        "linkCount": {
+                "linkCount": {
                     "type": "integer",
                     "description":"Number of links attached to the router node.",
-                     "graph": true
-               },
-	        "nodeCount": {
+                    "graph": true
+                },
+                "nodeCount": {
                     "type": "integer",
                     "description":"Number of known peer router nodes.",
                     "graph": true
@@ -570,31 +558,35 @@
             "annotations": [
                 "addrPort",
                 "connectionRole",
-                "sslProfile",
-                "saslMechanisms"
+                "sslProfile"
             ],
             "attributes": {
-                "requirePeerAuth": {
-                    "type": "boolean",
-                    "default": true,
-                    "description": "Only for listeners using SSL.  If set to 'yes', attached clients will be required to supply a certificate.  If the certificate is not traceable to a CA in the ssl profile's cert-db, authentication fails for the connection.",
+                "saslMechanisms": {
+                    "type": "string",
+                    "description": "Comma separated list of accepted SASL authentication mechanisms.",
                     "create": true
                 },
-                "trustedCerts": {
-                    "type": "path",
-                    "description": "This optional setting can be used to reduce the set of available CAs for client authentication.  If used, this setting must provide a path to a PEM file that contains the trusted certificates.",
+                "authenticatePeer": {
+                    "type": ["yes", "no", "insecureOk"],
+                    "default": "yes",
+                    "description": "['yes', 'no', 'insecureOk'] yes: Require the peer's identity to be authenticated in a secure way; no: Do not require any authentication; insecureOk: Require the peer's identity to be authenticated but allow insecure mechanisms (i.e. PLAIN over clear-text).",
                     "create": true
                 },
-                "allowUnsecured": {
+                "requireEncryption": {
                     "type": "boolean",
                     "default": false,
-                    "description": "For listeners using SSL only.  If set to 'yes' the listener will allow both SSL-secured clients and non-SSL clients to connect.",
+                    "description": "yes: Require the connection to the peer to be encrypted; no: Permit non-encrypted communication with the peer",
                     "create": true
                 },
-                "allowNoSasl": {
+                "requireSsl": {
                     "type": "boolean",
                     "default": false,
-                    "description": "If set to 'yes', this option causes the listener to allow clients to connect even if they skip the SASL authentication protocol.",
+                    "description": "yes: Require the use of SSL or TLS on the connection; no: Allow clients to connect without SSL or TLS.",
+                    "create": true
+                },
+                "trustedCerts": {
+                    "type": "path",
+                    "description": "This optional setting can be used to reduce the set of available CAs for client authentication.  If used, this setting must provide a path to a PEM file that contains the trusted certificates.",
                     "create": true
                 },
                 "maxFrameSize": {
@@ -602,6 +594,22 @@
                     "default": 65536,
                     "description": "Defaults to 65536.  If specified, it is the maximum frame size in octets that will be used in the connection-open negotiation with a connected peer.  The frame size is the largest contiguous set of uninterrupted data that can be sent for a message delivery over the connection. Interleaving of messages on different links is done at frame granularity.",
                     "create": true
+                },
+
+                "requirePeerAuth": {
+                    "type": "boolean",
+                    "create": true,
+                    "description": "Deprecated - This attribute is now controlled by the authenticatePeer attribute."
+                },
+                "allowUnsecured": {
+                    "type": "boolean",
+                    "create": true,
+                    "description": "Deprecated - This attribute is now controlled by the requireEncryption attribute."
+                },
+                "allowNoSasl": {
+                    "type": "boolean",
+                    "create": true,
+                    "description": "Deprecated - This attribute is now controlled by the authenticatePeer attribute."
                 }
             }
         },
@@ -613,10 +621,15 @@
             "annotations": [
                 "addrPort",
                 "connectionRole",
-                "sslProfile",
-                "saslMechanisms"
+                "sslProfile"
             ],
             "attributes": {
+                "saslMechanisms": {
+                    "type": "string",
+                    "required": true,
+                    "description": "Comma separated list of accepted SASL authentication mechanisms.",
+                    "create": true
+                },
                 "allowRedirect": {
                     "type": "boolean",
                     "default": true,
@@ -863,9 +876,41 @@
                     "type": ["in", "out"]
                 },
                 "role": {"type": "string"},
+                "isAuthenticated": {
+                    "description": "Indicates whether the identity of the connection's user is authentic.",
+                    "type": "boolean"
+                },
+                "isEncrypted": {
+                    "description": "Indicates whether the connection content is encrypted.",
+                    "type": "boolean"
+                },
                 "sasl": {
-                    "description": "SASL mechanism used for authentication.",
+                    "description": "SASL mechanism in effect for authentication.",
+                    "type": "string"
+                },
+                "user": {
+                    "description": "Identity of the authenticated user.",
+                    "type": "string"
+                },
+                "ssl": {
+                    "description": "True iff SSL/TLS is in effect for this connection.",
+                    "type": "boolean"
+                },
+                "sslProto": {
+                    "description": "SSL protocol name",
+                    "type": "string"
+                },
+                "sslCipher": {
+                    "description": "SSL cipher name",
                     "type": "string"
+                },
+                "sslSsf": {
+                    "description": "SSL strength factor in effect",
+                    "type": "integer"
+                },
+                "properties": {
+                    "description": "Connection properties supplied by the peer.",
+                    "type": "map"
                 }
             }
         },

Modified: qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py (original)
+++ qpid/dispatch/trunk/python/qpid_dispatch_internal/tools/command.py Tue Aug 11 20:51:02 2015
@@ -93,12 +93,6 @@ def opts_url(opts):
     """Fix up default URL settings based on options"""
     url = Url(opts.bus)
 
-    # Dispatch always allows SASL and requires it unless allow-no-sasl is configured.
-    # Add anonymous@ if no other username is specified to tell proton we want SASL ANONYMOUS.
-    # FIXME aconway 2015-02-17: this may change when proton supports more SASL mechs.
-    if not url.username:
-        url.username = "anonymous"
-
     # If the options indicate SSL, make sure we use the amqps scheme.
     if opts.ssl_certificate or opts.ssl_trustfile:
         url.scheme = "amqps"

Modified: qpid/dispatch/trunk/src/connection_manager.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/connection_manager.c?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/connection_manager.c (original)
+++ qpid/dispatch/trunk/src/connection_manager.c Tue Aug 11 20:51:02 2015
@@ -96,6 +96,14 @@ static void qd_server_config_free(qd_ser
 static qd_error_t load_server_config(qd_dispatch_t *qd, qd_server_config_t *config, qd_entity_t* entity)
 {
     qd_error_clear();
+
+    char *authenticatePeer   = qd_entity_opt_string(entity, "authenticatePeer",  0);     CHECK();
+    bool  requireEncryption  = qd_entity_opt_bool(entity,   "requireEncryption", false); CHECK();
+    bool  requireSsl         = qd_entity_opt_bool(entity,   "requireSsl",        false); CHECK();
+    bool  depRequirePeerAuth = qd_entity_opt_bool(entity,   "requirePeerAuth",   false); CHECK();
+    bool  depAllowUnsecured  = qd_entity_opt_bool(entity,   "allowUnsecured", !requireSsl); CHECK();
+    bool  depAllowNoSasl     = qd_entity_opt_bool(entity,   "allowNoSasl",       false); CHECK();
+
     memset(config, 0, sizeof(*config));
     config->host           = qd_entity_get_string(entity, "addr"); CHECK();
     config->port           = qd_entity_get_string(entity, "port"); CHECK();
@@ -103,12 +111,28 @@ static qd_error_t load_server_config(qd_
     config->max_frame_size = qd_entity_get_long(entity, "maxFrameSize"); CHECK();
     config->sasl_mechanisms = qd_entity_get_string(entity, "saslMechanisms"); CHECK();
     config->ssl_enabled = has_attrs(entity, ssl_attributes, ssl_attributes_count);
-    config->allow_no_sasl =
-        qd_entity_opt_bool(entity, "allowNoSasl", false); CHECK();
+
+    if (authenticatePeer) {
+        if        (strcmp(authenticatePeer, "yes") == 0) {
+            config->requireAuthentication       = true;
+            config->allowInsecureAuthentication = false;
+        } else if (strcmp(authenticatePeer, "insecureOk") == 0) {
+            config->requireAuthentication       = true;
+            config->allowInsecureAuthentication = true;
+        } else {
+            config->requireAuthentication       = false;
+            config->allowInsecureAuthentication = true;
+        }
+    } else {
+        config->requireAuthentication       = !depAllowNoSasl;
+        config->allowInsecureAuthentication = !depRequirePeerAuth;
+    }
+
+    config->requireEncryption = requireEncryption || !depAllowUnsecured;
+
     if (config->ssl_enabled) {
-        config->ssl_server = 1;
-        config->ssl_allow_unsecured_client =
-            qd_entity_opt_bool(entity, "allowUnsecured", false); CHECK();
+        config->ssl_required = requireSsl || !depAllowUnsecured;
+        config->ssl_require_peer_authentication = strstr(config->sasl_mechanisms, "EXTERNAL") != 0;
         config->ssl_certificate_file =
             qd_entity_opt_string(entity, "certFile", 0); CHECK();
         config->ssl_private_key_file =
@@ -119,9 +143,9 @@ static qd_error_t load_server_config(qd_
             qd_entity_opt_string(entity, "certDb", 0); CHECK();
         config->ssl_trusted_certificates =
             qd_entity_opt_string(entity, "trustedCerts", 0); CHECK();
-        config->ssl_require_peer_authentication =
-            qd_entity_opt_bool(entity, "requirePeerAuth", true);
     }
+
+    free(authenticatePeer);
     return QD_ERROR_NONE;
 
   error:

Modified: qpid/dispatch/trunk/src/server.c
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/server.c?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/server.c (original)
+++ qpid/dispatch/trunk/src/server.c Tue Aug 11 20:51:02 2015
@@ -88,63 +88,93 @@ qd_error_t qd_entity_refresh_connection(
     qd_connection_t *conn = (qd_connection_t*)impl;
     const qd_server_config_t *config =
         conn->connector ? conn->connector->config : conn->listener->config;
+    pn_transport_t *tport = 0;
+    pn_sasl_t      *sasl  = 0;
+    pn_ssl_t       *ssl   = 0;
+    const char     *mech  = 0;
+    const char     *user  = 0;
+
+    if (conn->pn_conn) {
+        tport = pn_connection_transport(conn->pn_conn);
+        ssl   = conn->ssl;
+    }
+    if (tport) {
+        sasl = pn_sasl(tport);
+        user = pn_transport_get_user(tport);
+    }
+    if (sasl)
+        mech = pn_sasl_get_mech(sasl);
 
     if (qd_entity_set_string(entity, "state", conn_state_name(conn->state)) == 0 &&
-        qd_entity_set_string(
-            entity, "container",
-            conn->pn_conn ? pn_connection_remote_container(conn->pn_conn) : 0) == 0 &&
+        qd_entity_set_string(entity, "container",
+                             conn->pn_conn ? pn_connection_remote_container(conn->pn_conn) : 0) == 0 &&
         connection_entity_update_host(entity, conn) == 0 &&
-        qd_entity_set_string(entity, "sasl", config->sasl_mechanisms) == 0 &&
+        qd_entity_set_string(entity, "sasl", mech) == 0 &&
         qd_entity_set_string(entity, "role", config->role) == 0 &&
-        qd_entity_set_string(entity, "dir", conn->connector ? "out" : "in") == 0)
+        qd_entity_set_string(entity, "dir", conn->connector ? "out" : "in") == 0 &&
+        qd_entity_set_string(entity, "user", user) == 0 &&
+        qd_entity_set_bool(entity, "isAuthenticated", tport && pn_transport_is_authenticated(tport)) == 0 &&
+        qd_entity_set_bool(entity, "isEncrypted", tport && pn_transport_is_encrypted(tport)) == 0 &&
+        qd_entity_set_bool(entity, "ssl", ssl != 0) == 0) {
+        if (ssl) {
+#define SSL_ATTR_SIZE 50
+            char proto[SSL_ATTR_SIZE];
+            char cipher[SSL_ATTR_SIZE];
+            pn_ssl_get_protocol_name(ssl, proto, SSL_ATTR_SIZE);
+            pn_ssl_get_cipher_name(ssl, cipher, SSL_ATTR_SIZE);
+            qd_entity_set_string(entity, "sslProto", proto);
+            qd_entity_set_string(entity, "sslCipher", cipher);
+            qd_entity_set_long(entity, "sslSsf", pn_ssl_get_ssf(ssl));
+        }
         return QD_ERROR_NONE;
+    }
     return qd_error_code();
 }
 
-static qd_error_t listener_setup_ssl(const qd_server_config_t *config, pn_transport_t *tport) {
-
+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");
 
     // 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");
+                                      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 (config->ssl_allow_unsecured_client) {
-	if (pn_ssl_domain_allow_unsecured_client(domain)) {
-	    pn_ssl_domain_free(domain);
-	    return qd_error(QD_ERROR_RUNTIME, "Cannot allow unsecured client");
-	}
+    if (!config->ssl_required) {
+        if (pn_ssl_domain_allow_unsecured_client(domain)) {
+            pn_ssl_domain_free(domain);
+            return qd_error(QD_ERROR_RUNTIME, "Cannot allow unsecured client");
+        }
     }
 
     // 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 truested SSL CA" );
-	}
+        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" );
+        }
     }
 
     const char *trusted = config->ssl_trusted_certificate_db;
     if (config->ssl_trusted_certificates)
-	trusted = config->ssl_trusted_certificates;
+        trusted = config->ssl_trusted_certificates;
 
     // do we force the peer to send a cert?
     if (config->ssl_require_peer_authentication) {
-	if (!trusted || pn_ssl_domain_set_peer_authentication(domain, PN_SSL_VERIFY_PEER, trusted)) {
-	    pn_ssl_domain_free(domain);
-	    return qd_error(QD_ERROR_RUNTIME, "Cannot set peer authentication");
-	}
+        if (!trusted || pn_ssl_domain_set_peer_authentication(domain, PN_SSL_VERIFY_PEER, trusted)) {
+            pn_ssl_domain_free(domain);
+            return qd_error(QD_ERROR_RUNTIME, "Cannot set peer authentication");
+        }
     }
 
-    pn_ssl_t *ssl = pn_ssl(tport);
-    if (!ssl || pn_ssl_init(ssl, domain, 0)) {
-	pn_ssl_domain_free(domain);
-	return qd_error(QD_ERROR_RUNTIME, "Cannot initialize SSL");
+    ctx->ssl = pn_ssl(tport);
+    if (!ctx->ssl || pn_ssl_init(ctx->ssl, domain, 0)) {
+        pn_ssl_domain_free(domain);
+        return qd_error(QD_ERROR_RUNTIME, "Cannot initialize SSL");
     }
 
     return QD_ERROR_NONE;
@@ -185,6 +215,7 @@ static void thread_process_listeners(qd_
         ctx->enqueued     = 0;
         ctx->pn_cxtr      = cxtr;
         ctx->collector    = 0;
+        ctx->ssl          = 0;
         ctx->listener     = qdpn_listener_context(listener);
         ctx->connector    = 0;
         ctx->context      = ctx->listener->context;
@@ -226,7 +257,7 @@ static void thread_process_listeners(qd_
         if (config->ssl_enabled) {
             qd_log(qd_server->log_source, QD_LOG_TRACE, "Configuring SSL on %s",
                    log_incoming(logbuf, sizeof(logbuf), cxtr));
-            if (listener_setup_ssl(config, tport) != QD_ERROR_NONE) {
+            if (listener_setup_ssl(ctx, config, tport) != QD_ERROR_NONE) {
                 qd_log(qd_server->log_source, QD_LOG_ERROR, "%s on %s",
                        qd_error_message(), log_incoming(logbuf, sizeof(logbuf), cxtr));
                 qdpn_connector_close(cxtr);
@@ -238,8 +269,11 @@ static void thread_process_listeners(qd_
         // Set up SASL
         //
         pn_sasl_t *sasl = pn_sasl(tport);
+        pn_sasl_config_name(sasl, "qdrouterd");
         pn_sasl_allowed_mechs(sasl, config->sasl_mechanisms);
-        pn_transport_require_auth(tport, !config->allow_no_sasl);
+        pn_transport_require_auth(tport, config->requireAuthentication);
+        pn_transport_require_encryption(tport, config->requireEncryption);
+        pn_sasl_set_allow_insecure_mechs(sasl, config->allowInsecureAuthentication);
     }
 }
 
@@ -743,6 +777,7 @@ static void cxtr_try_open(void *context)
     ctx->enqueued     = 0;
     ctx->pn_conn      = 0;
     ctx->collector    = 0;
+    ctx->ssl          = 0;
     ctx->listener     = 0;
     ctx->connector    = ct;
     ctx->context      = ct->context;
@@ -824,8 +859,8 @@ static void cxtr_try_open(void *context)
             }
         }
 
-        pn_ssl_t *ssl = pn_ssl(tport);
-        pn_ssl_init(ssl, domain, 0);
+        ctx->ssl = pn_ssl(tport);
+        pn_ssl_init(ctx->ssl, domain, 0);
         pn_ssl_domain_free(domain);
     }
 
@@ -834,7 +869,6 @@ static void cxtr_try_open(void *context)
     //
     pn_sasl_t *sasl = pn_sasl(tport);
     pn_sasl_allowed_mechs(sasl, config->sasl_mechanisms);
-    pn_transport_require_auth(tport, !config->allow_no_sasl);
 
     ctx->owner_thread = CONTEXT_NO_OWNER;
 }
@@ -1230,6 +1264,7 @@ qd_user_fd_t *qd_user_fd(qd_dispatch_t *
     ctx->enqueued     = 0;
     ctx->pn_conn      = 0;
     ctx->collector    = 0;
+    ctx->ssl          = 0;
     ctx->listener     = 0;
     ctx->connector    = 0;
     ctx->context      = 0;

Modified: qpid/dispatch/trunk/src/server_private.h
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/src/server_private.h?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/src/server_private.h (original)
+++ qpid/dispatch/trunk/src/server_private.h Tue Aug 11 20:51:02 2015
@@ -100,6 +100,7 @@ struct qd_connection_t {
     qdpn_connector_t *pn_cxtr;
     pn_connection_t  *pn_conn;
     pn_collector_t   *collector;
+    pn_ssl_t         *ssl;
     qd_listener_t    *listener;
     qd_connector_t   *connector;
     void             *context; // Copy of context from listener or connector

Modified: qpid/dispatch/trunk/tests/config-2/A-ssl.conf.in
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/config-2/A-ssl.conf.in?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/config-2/A-ssl.conf.in (original)
+++ qpid/dispatch/trunk/tests/config-2/A-ssl.conf.in Tue Aug 11 20:51:02 2015
@@ -68,8 +68,9 @@ listener {
     role: inter-router
     addr: 0.0.0.0
     port: 20102
-    sasl-mechanisms: ANONYMOUS
+    sasl-mechanisms: EXTERNAL
     ssl-profile: ssl-profile-name
+    requirePeerAuth: yes
 }
 
 router {

Modified: qpid/dispatch/trunk/tests/config-2/B-ssl.conf.in
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/config-2/B-ssl.conf.in?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/config-2/B-ssl.conf.in (original)
+++ qpid/dispatch/trunk/tests/config-2/B-ssl.conf.in Tue Aug 11 20:51:02 2015
@@ -63,7 +63,7 @@ connector {
     role: inter-router
     addr: 0.0.0.0
     port: 20102
-    sasl-mechanisms: ANONYMOUS
+    sasl-mechanisms: EXTERNAL
     ssl-profile: ssl-profile-name
 }
 

Modified: qpid/dispatch/trunk/tests/config-2/gencerts.sh
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/config-2/gencerts.sh?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/config-2/gencerts.sh (original)
+++ qpid/dispatch/trunk/tests/config-2/gencerts.sh Tue Aug 11 20:51:02 2015
@@ -1,8 +1,5 @@
 #!/bin/bash -ex
 
-#export SERVER=mrg14.lab.bos.redhat.com
-#export CLIENT=mrg38.lab.bos.redhat.com
-
 export SERVER=A1.Good.Server.domain.com
 export CLIENT=127.0.0.1
 

Modified: qpid/dispatch/trunk/tests/system_test.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_test.py?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_test.py (original)
+++ qpid/dispatch/trunk/tests/system_test.py Tue Aug 11 20:51:02 2015
@@ -305,7 +305,7 @@ class Qdrouterd(Process):
         """
 
         DEFAULTS = {
-            'listener':{'addr':'0.0.0.0', 'saslMechanisms':'ANONYMOUS', 'allowNoSasl': True},
+            'listener':{'addr':'0.0.0.0', 'saslMechanisms':'ANONYMOUS', 'authenticatePeer': 'no'},
             'connector':{'addr':'127.0.0.1', 'saslMechanisms':'ANONYMOUS', 'role':'on-demand'},
             'container':{'debugDump':"qddebug.txt"}
         }
@@ -379,7 +379,7 @@ class Qdrouterd(Process):
     @property
     def addresses(self):
         """Return amqp://host:port addresses for all listeners"""
-        return ["amqp://anonymous@%s:%s"%(l['addr'], l['port']) for l in self.config.sections('listener')]
+        return ["amqp://%s:%s"%(l['addr'], l['port']) for l in self.config.sections('listener')]
 
     @property
     def hostports(self):

Modified: qpid/dispatch/trunk/tests/system_tests_management.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_management.py?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_management.py (original)
+++ qpid/dispatch/trunk/tests/system_tests_management.py Tue Aug 11 20:51:02 2015
@@ -26,6 +26,7 @@ from qpid_dispatch_internal.compat impor
 from system_test import Qdrouterd, message, retry, retry_exception, wait_ports, Process
 from proton import ConnectionException
 from itertools import chain
+from time import sleep
 
 PREFIX = u'org.apache.qpid.dispatch.'
 MANAGEMENT = PREFIX + 'management'
@@ -167,7 +168,7 @@ class ManagementTest(system_test.TestCas
 
         port = self.get_port()
         # Note qdrouter schema defines port as string not int, since it can be a service name.
-        attributes = {'name':'foo', 'port':str(port), 'role':'normal', 'saslMechanisms': 'ANONYMOUS', 'allowNoSasl': True}
+        attributes = {'name':'foo', 'port':str(port), 'role':'normal', 'saslMechanisms': 'ANONYMOUS', 'authenticatePeer': 'no'}
         entity = self.assert_create_ok(LISTENER, 'foo', attributes)
         self.assertEqual(entity['name'], 'foo')
         self.assertEqual(entity['addr'], '127.0.0.1')
@@ -277,6 +278,9 @@ class ManagementTest(system_test.TestCas
             [connector.name, connector.addr, connector.port, connector.role],
             ['wp_connector', '127.0.0.1', str(wp_router.ports[0]), 'on-demand'])
 
+        # Pause to allow the waypoint to settle down
+        sleep(1)
+
         # Send a message through self.router, verify it goes via wp_router
         address=self.router.addresses[0]+"/foo"
         mr = self.messenger()

Modified: qpid/dispatch/trunk/tests/system_tests_qdmanage.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_qdmanage.py?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_qdmanage.py (original)
+++ qpid/dispatch/trunk/tests/system_tests_qdmanage.py Tue Aug 11 20:51:02 2015
@@ -41,9 +41,7 @@ class QdmanageTest(TestCase):
                              'cert-db': cls.ssl_file('ca-certificate.pem'),
                              'cert-file': cls.ssl_file('server-certificate.pem'),
                              'key-file': cls.ssl_file('server-private-key.pem'),
-                             'password': 'server-password',
-                             'allow-unsecured': False,
-                             'require-peer-auth': False}),
+                             'password': 'server-password'}),
             ('listener', {'port': cls.tester.get_port()}),
             ('listener', {'port': cls.tester.get_port(), 'ssl-profile': 'server-ssl'})
         ])

Modified: qpid/dispatch/trunk/tests/system_tests_qdstat.py
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tests/system_tests_qdstat.py?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/tests/system_tests_qdstat.py (original)
+++ qpid/dispatch/trunk/tests/system_tests_qdstat.py Tue Aug 11 20:51:02 2015
@@ -86,31 +86,16 @@ try:
         def setUpClass(cls):
             super(QdstatSslTest, cls).setUpClass()
             config = system_test.Qdrouterd.Config([
-                ('ssl-profile', {'name': 'server-ssl-strict',
+                ('ssl-profile', {'name': 'server-ssl',
                                  'cert-db': cls.ssl_file('ca-certificate.pem'),
                                  'cert-file': cls.ssl_file('server-certificate.pem'),
                                  'key-file': cls.ssl_file('server-private-key.pem'),
-                                 'password': 'server-password',
-                                 'allow-unsecured': False,
-                                 'require-peer-auth': False}),
-                ('ssl-profile', {'name': 'server-ssl-unsecured',
-                                 'cert-db': cls.ssl_file('ca-certificate.pem'),
-                                 'cert-file': cls.ssl_file('server-certificate.pem'),
-                                 'key-file': cls.ssl_file('server-private-key.pem'),
-                                 'password': 'server-password',
-                                 'allow-unsecured': True,
-                                 'require-peer-auth': False}),
-                ('ssl-profile', {'name': 'server-ssl-auth',
-                                 'cert-db': cls.ssl_file('ca-certificate.pem'),
-                                 'cert-file': cls.ssl_file('server-certificate.pem'),
-                                 'key-file': cls.ssl_file('server-private-key.pem'),
-                                 'password': 'server-password',
-                                 'allow-unsecured': False,
-                                 'require-peer-auth': True}),
+                                 'password': 'server-password'}),
                 ('listener', {'port': cls.tester.get_port()}),
-                ('listener', {'port': cls.tester.get_port(), 'ssl-profile': 'server-ssl-strict'}),
-                ('listener', {'port': cls.tester.get_port(), 'ssl-profile': 'server-ssl-unsecured'}),
-                ('listener', {'port': cls.tester.get_port(), 'ssl-profile': 'server-ssl-auth'})
+                ('listener', {'port': cls.tester.get_port(), 'ssl-profile': 'server-ssl', 'authenticatePeer': 'no', 'requireSsl': 'yes'}),
+                ('listener', {'port': cls.tester.get_port(), 'ssl-profile': 'server-ssl', 'authenticatePeer': 'no', 'requireSsl': 'no'}),
+                ('listener', {'port': cls.tester.get_port(), 'ssl-profile': 'server-ssl', 'authenticatePeer': 'yes', 'requireSsl': 'yes',
+                              'saslMechanisms:': 'EXTERNAL'})
             ])
             cls.router = cls.tester.qdrouterd('test-router', config)
 

Modified: qpid/dispatch/trunk/tools/qdstat
URL: http://svn.apache.org/viewvc/qpid/dispatch/trunk/tools/qdstat?rev=1695375&r1=1695374&r2=1695375&view=diff
==============================================================================
--- qpid/dispatch/trunk/tools/qdstat (original)
+++ qpid/dispatch/trunk/tools/qdstat Tue Aug 11 20:51:02 2015
@@ -26,7 +26,6 @@ import locale
 import socket
 import re
 from time import ctime
-from proton import Messenger, Message, Timeout
 import  qpid_dispatch_site
 from qpid_dispatch.management.client import Url, Node, Entity
 from qpid_dispatch_internal.management.qdrouter import QdSchema
@@ -73,15 +72,48 @@ class BusManager(Node):
     def query(self, entity_type):
         return super(BusManager, self).query(entity_type).get_entities()
 
+    def connAuth(self, conn):
+        ##
+        ## Summarize the authentication for a connection:
+        ##   no-auth
+        ##   anonymous-user
+        ##   <user>(PLAIN)
+        ##   <user>(kerberos)
+        ##   <user>(x.509)
+        ##
+        if not conn.isAuthenticated:
+            return "no-auth"
+        sasl = conn.sasl
+        if sasl == "GSSAPI":   sasl = "Kerberos"
+        if sasl == "EXTERNAL": sasl = "x.509"
+        if sasl == "ANONYMOUS":
+            return "anonymous-user"
+        return "%s(%s)" % (conn.user, sasl)
+
+    def connSecurity(self, conn):
+        ##
+        ## Summarize the security of a connection:
+        ##   no-security
+        ##   SSLv3 (cipher)
+        ##   TLS (cipher)
+        ##   Kerberos
+        ##
+        if not conn.isEncrypted:
+            return "no-security"
+        if conn.sasl == "GSSAPI":
+            return "Kerberos"
+        return "%s(%s)" % (conn.sslProto, conn.sslCipher)
+
     def displayConnections(self):
         disp = Display(prefix="  ")
         heads = []
         heads.append(Header("state"))
         heads.append(Header("host"))
         heads.append(Header("container"))
-        heads.append(Header("sasl-mechanisms"))
         heads.append(Header("role"))
         heads.append(Header("dir"))
+        heads.append(Header("security"))
+        heads.append(Header("authentication"))
 
         rows = []
 
@@ -92,9 +124,10 @@ class BusManager(Node):
             row.append(conn.state)
             row.append(conn.host)
             row.append(conn.container)
-            row.append(conn.sasl)
             row.append(conn.role)
             row.append(conn.dir)
+            row.append(self.connSecurity(conn))
+            row.append(self.connAuth(conn))
             rows.append(row)
         title = "Connections"
         dispRows = rows



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