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

gmurthy 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 a97dea9  DISPATCH-1434 - Added new attribute saslPasswordFile to the 
connector entity. saslPassword entity has been deprecated. This closes #578.
a97dea9 is described below

commit a97dea9aace6142d58f70caf66710386dc3e1156
Author: Ganesh Murthy <gmur...@apache.org>
AuthorDate: Tue Oct 1 16:34:38 2019 -0400

    DISPATCH-1434 - Added new attribute saslPasswordFile to the connector 
entity. saslPassword entity has been deprecated. This closes #578.
---
 docs/books/user-guide/configuration-reference.adoc |  2 +-
 docs/books/user-guide/configuration-security.adoc  |  4 +-
 ...ing-using-username-password-authentication.adoc |  2 +-
 include/qpid/dispatch/server.h                     |  7 ++
 pom.xml                                            |  1 +
 python/qpid_dispatch/management/qdrouter.json      |  9 ++-
 src/connection_manager.c                           | 75 ++++++++++++++--------
 tests/sasl_password/sasl-password-file.txt         |  1 +
 tests/system_tests_sasl_plain.py                   | 11 +++-
 9 files changed, 77 insertions(+), 35 deletions(-)

diff --git a/docs/books/user-guide/configuration-reference.adoc 
b/docs/books/user-guide/configuration-reference.adoc
index c25cd2c..d3077cb 100644
--- a/docs/books/user-guide/configuration-reference.adoc
+++ b/docs/books/user-guide/configuration-reference.adoc
@@ -144,7 +144,7 @@ Establishes an outgoing connection from the router.
 * *_linkCapacity_* (integer) : The capacity of links within this connection, 
in terms of message deliveries. The capacity is the number of messages that can 
be in-flight concurrently for each link.
 * *_verifyHostname_* (boolean, default=True) : yes: Ensures that when 
initiating a connection (as a client) the hostname in the URL to which this 
connector connects to matches the hostname in the digital certificate that the 
peer sends back as part of the SSL/TLS connection; no: Does not perform 
hostname verification
 * *_saslUsername_* (string) : The username that the connector is using to 
connect to a peer.
-* *_saslPassword_* (string) : The password that the connector is using to 
connect to a peer.
+* *_saslPasswordFile_* (string) : The absolute path to the file that contains 
the password that the connector uses to connect to a peer.
 * *_sslProfile_* (string) : The name of the _sslProfile_ entity to use in 
order to have SSL/TLS configuration.
 
 [id='router-configuration-file-log']
diff --git a/docs/books/user-guide/configuration-security.adoc 
b/docs/books/user-guide/configuration-security.adoc
index d0e4018..b4c97a2 100644
--- a/docs/books/user-guide/configuration-security.adoc
+++ b/docs/books/user-guide/configuration-security.adoc
@@ -370,7 +370,7 @@ connector {
     ...
     saslMechanisms: _MECHANISMS_
     saslUsername: _USERNAME_
-    saslPassword: _PASSWORD_
+    saslPasswordFile: _ABSOLUTE PATH_
 }
 ----
 
@@ -378,7 +378,7 @@ connector {
 +
 For a full list of supported Cyrus SASL authentication mechanisms, see 
link:https://www.cyrusimap.org/sasl/sasl/authentication_mechanisms.html[Authentication
 Mechanisms^].
 `saslUsername`:: If any of the SASL mechanisms uses username/password 
authentication, then provide the username to connect to the external container.
-`saslPassword`:: If any of the SASL mechanisms uses username/password 
authentication, then provide the password to connect to the external container.
+`saslPasswordFile`:: If any of the SASL mechanisms uses username/password 
authentication, then provide the absolute path to the file that contains the 
password to connect to the external container.
 --
 
 [id='integrating-with-kerberos']
diff --git 
a/docs/books/user-guide/modules/connecting-using-username-password-authentication.adoc
 
b/docs/books/user-guide/modules/connecting-using-username-password-authentication.adoc
index cf3f254..f5b40a7 100644
--- 
a/docs/books/user-guide/modules/connecting-using-username-password-authentication.adoc
+++ 
b/docs/books/user-guide/modules/connecting-using-username-password-authentication.adoc
@@ -52,7 +52,7 @@ connector {
     role: route-container
     saslMechanisms: PLAIN
     saslUsername: user
-    saslPassword: password
+    saslPasswordFile: /path/to/file/passwd.txt
     }
 ----
 --
diff --git a/include/qpid/dispatch/server.h b/include/qpid/dispatch/server.h
index 043baa5..992ded6 100644
--- a/include/qpid/dispatch/server.h
+++ b/include/qpid/dispatch/server.h
@@ -205,8 +205,15 @@ typedef struct qd_server_config_t {
     char *sasl_username;
 
     /**
+     * The full path of the file that contains the sasl password. Use this 
instead of sasl_password.
+     */
+    char *sasl_password_file;
+
+    /**
      * If appropriate for the mechanism, the password for authentication
      * (connector only)
+     *
+     * Deprecated - Use sasl_password_file instead.
      */
     char *sasl_password;
 
diff --git a/pom.xml b/pom.xml
index 3769861..74d7bf8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -104,6 +104,7 @@
                       <exclude>**/VERSION.txt</exclude>
                       <exclude>**/v3_ca.ext</exclude>
                       <exclude>**/system_test.dir/**</exclude>
+                     <exclude>**/sasl-password-file.txt</exclude>
                       <exclude>**/server-password-file.txt</exclude>
                       <exclude>**/server-password-file-bad.txt</exclude>
                       <exclude>**/client-password-file.txt</exclude>
diff --git a/python/qpid_dispatch/management/qdrouter.json 
b/python/qpid_dispatch/management/qdrouter.json
index 707ae46..5d1f4d9 100644
--- a/python/qpid_dispatch/management/qdrouter.json
+++ b/python/qpid_dispatch/management/qdrouter.json
@@ -1002,10 +1002,17 @@
                 "saslPassword": {
                     "type": "string",
                     "required": false,
-                    "description": "The password that the connector is using 
to connect to a peer.",
+                    "description": "(DEPRECATED) The password that the 
connector is using to connect to a peer. This takes precedence over the 
saslPasswordFile if both are specified. This attribute has been deprecated 
because it is unsafe to store plain text passwords in config files. Use the 
saslPasswordFile instead",
                     "create": true,
+                    "deprecated": true,
                     "hidden": true
                 },
+                "saslPasswordFile": {
+                    "type": "string",
+                    "required": false,
+                    "description": "The absolute path to the file that 
contains the password that the connector uses to connect to a peer. This file 
should be permission protected to limit access",
+                    "create": true
+                },
                 "messageLoggingComponents": {
                     "type": "string",
                     "default": "none",
diff --git a/src/connection_manager.c b/src/connection_manager.c
index b571555..5df28d8 100644
--- a/src/connection_manager.c
+++ b/src/connection_manager.c
@@ -89,6 +89,38 @@ const char *ALL = "all";
 const char *NONE = "none";
 
 /**
+ * Reads the password from the password_file and populates the contents of the 
file in password_field.
+ */
+static void set_password_from_file(char *password_file, char **password_field)
+{
+    if (password_file) {
+        FILE *file = fopen(password_file, "r");
+
+        if (file) {
+            char buffer[200];
+
+            int c;
+            int i=0;
+
+            while (i < 200 - 1) {
+                c = fgetc(file);
+                if (c == EOF || c == '\n')
+                    break;
+                buffer[i++] = c;
+            }
+
+            if (i != 0) {
+                buffer[i] = '\0';
+                free(*password_field);
+                *password_field = strdup(buffer);
+            }
+            fclose(file);
+        }
+    }
+}
+
+
+/**
  * Search the list of config_ssl_profiles for an ssl-profile that matches the 
passed in name
  */
 static qd_config_ssl_profile_t *qd_find_ssl_profile(qd_connection_manager_t 
*cm, char *name)
@@ -299,6 +331,8 @@ static qd_error_t load_server_config(qd_dispatch_t *qd, 
qd_server_config_t *conf
 {
     qd_error_clear();
 
+    qd_connection_manager_t *cm = qd->connection_manager;
+
     bool authenticatePeer   = qd_entity_opt_bool(entity, "authenticatePeer",  
false);    CHECK();
     bool verifyHostName     = qd_entity_opt_bool(entity, "verifyHostname",    
true);     CHECK();
     bool requireEncryption  = qd_entity_opt_bool(entity, "requireEncryption", 
false);    CHECK();
@@ -327,6 +361,17 @@ static qd_error_t load_server_config(qd_dispatch_t *qd, 
qd_server_config_t *conf
     }
     config->sasl_username        = qd_entity_opt_string(entity, 
"saslUsername", 0);   CHECK();
     config->sasl_password        = qd_entity_opt_string(entity, 
"saslPassword", 0);   CHECK();
+
+    if (config->sasl_password) {
+        qd_log(cm->log_source, QD_LOG_WARNING, "Attribute saslPassword of 
entity connector has been deprecated. Use saslPasswordFile instead.");
+    }
+    else {
+        // saslPassword not provided. Check if saslPasswordFile property is 
specified.
+        char *password_file = qd_entity_opt_string(entity, "saslPasswordFile", 
0); CHECK();
+        set_password_from_file(password_file, &config->sasl_password);
+        free(password_file);
+    }
+
     config->sasl_mechanisms      = qd_entity_opt_string(entity, 
"saslMechanisms", 0); CHECK();
     config->ssl_profile          = qd_entity_opt_string(entity, "sslProfile", 
0);     CHECK();
     config->sasl_plugin          = qd_entity_opt_string(entity, "saslPlugin", 
0);   CHECK();
@@ -512,36 +557,10 @@ qd_config_ssl_profile_t 
*qd_dispatch_configure_ssl_profile(qd_dispatch_t *qd, qd
     if (ssl_profile->ssl_password) {
         qd_log(cm->log_source, QD_LOG_WARNING, "Attribute password of entity 
sslProfile has been deprecated. Use passwordFile instead.");
     }
-
-
-    if (!ssl_profile->ssl_password) {
+    else {
         // SSL password not provided. Check if passwordFile property is 
specified.
         char *password_file = qd_entity_opt_string(entity, "passwordFile", 0); 
CHECK();
-
-        if (password_file) {
-            FILE *file = fopen(password_file, "r");
-
-            if (file) {
-                char buffer[200];
-
-                int c;
-                int i=0;
-
-                while (i < 200 - 1) {
-                    c = fgetc(file);
-                    if (c == EOF || c == '\n')
-                        break;
-                    buffer[i++] = c;
-                }
-
-                if (i != 0) {
-                    buffer[i] = '\0';
-                    free(ssl_profile->ssl_password);
-                    ssl_profile->ssl_password = strdup(buffer);
-                }
-                fclose(file);
-            }
-        }
+        set_password_from_file(password_file, &ssl_profile->ssl_password);
         free(password_file);
     }
     ssl_profile->ssl_ciphers   = qd_entity_opt_string(entity, "ciphers", 0);   
                CHECK();
diff --git a/tests/sasl_password/sasl-password-file.txt 
b/tests/sasl_password/sasl-password-file.txt
new file mode 100644
index 0000000..f3097ab
--- /dev/null
+++ b/tests/sasl_password/sasl-password-file.txt
@@ -0,0 +1 @@
+password
diff --git a/tests/system_tests_sasl_plain.py b/tests/system_tests_sasl_plain.py
index 95b1ecd..6a6749f 100644
--- a/tests/system_tests_sasl_plain.py
+++ b/tests/system_tests_sasl_plain.py
@@ -58,6 +58,9 @@ sql_select: dummy select
 """)
 
 class RouterTestPlainSasl(RouterTestPlainSaslCommon):
+    @staticmethod
+    def sasl_password_file(name):
+        return os.path.join(DIR, 'sasl_password', name)
 
     @classmethod
     def setUpClass(cls):
@@ -101,7 +104,7 @@ class RouterTestPlainSasl(RouterTestPlainSaslCommon):
                                     # Provide a sasl user name and password to 
connect to QDR.X
                                    'saslMechanisms': 'PLAIN',
                                     'saslUsername': 't...@domain.com',
-                                    'saslPassword': 'password'}),
+                                    'saslPasswordFile': 
cls.sasl_password_file('sasl-password-file.txt')}),
                      ('router', {'workerThreads': 1,
                                  'mode': 'interior',
                                  'id': 'QDR.Y'}),
@@ -194,6 +197,10 @@ class 
RouterTestPlainSaslOverSsl(RouterTestPlainSaslCommon):
     def ssl_file(name):
         return os.path.join(DIR, 'ssl_certs', name)
 
+    @staticmethod
+    def sasl_password_file(name):
+        return os.path.join(DIR, 'sasl_password', name)
+
     @classmethod
     def setUpClass(cls):
         """
@@ -248,7 +255,7 @@ class RouterTestPlainSaslOverSsl(RouterTestPlainSaslCommon):
                                     # Provide a sasl user name and password to 
connect to QDR.X
                                     'saslMechanisms': 'PLAIN',
                                     'saslUsername': 't...@domain.com',
-                                    'saslPassword': 'password'}),
+                                    'saslPasswordFile': 
cls.sasl_password_file('sasl-password-file.txt')}),
                      ('router', {'workerThreads': 1,
                                  'mode': 'interior',
                                  'id': 'QDR.Y'}),


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

Reply via email to