diff options
| author | Justin Ross <jross@apache.org> | 2014-11-06 14:36:10 +0000 |
|---|---|---|
| committer | Justin Ross <jross@apache.org> | 2014-11-06 14:36:10 +0000 |
| commit | 01092981d8c8acb2c67b5379b8626777577bc383 (patch) | |
| tree | 2a95369ee3c31c333002b59b2c1d940eb0347882 /qpid/cpp/src | |
| parent | 2f4bf9476f38bee374f2e164d8455bd62c2b6bcb (diff) | |
| download | qpid-python-01092981d8c8acb2c67b5379b8626777577bc383.tar.gz | |
QPID-6203: Prevent broker startup when invalid directory is passed to --sasl-config; this is a patch from Ernie Allen
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1637122 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/cpp/src')
| -rw-r--r-- | qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp index 55a10063f8..41b56e1d82 100644 --- a/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp +++ b/qpid/cpp/src/qpid/broker/SaslAuthenticator.cpp @@ -35,6 +35,7 @@ #if HAVE_SASL #include <sys/stat.h> #include <sasl/sasl.h> +#include <sasl/saslplug.h> #include "qpid/sys/cyrus/CyrusSecurityLayer.h" using qpid::sys::cyrus::CyrusSecurityLayer; #endif @@ -97,6 +98,37 @@ bool SaslAuthenticator::available(void) { return true; } +// Called by sasl_server_init() when config file name is constructed to allow clients to verify file +// Returning SASL_FAIL here will cause sasl_server_init() to fail and an exception will be thrown +int _sasl_verifyfile_callback(void *, const char *configFileName, sasl_verify_type_t type) +{ + if (type == SASL_VRFY_CONF) { + struct stat st; + // verify the file exists + if ( ::stat ( configFileName, & st) ) { + QPID_LOG(error, "SASL: config file doesn't exist: " << configFileName); + return SASL_FAIL; + } + // verify the file can be read by the broker + if ( ::access ( configFileName, R_OK ) ) { + QPID_LOG(error, "SASL: broker unable to read the config file. Check file permissions: " << configFileName); + return SASL_FAIL; + } + } + return SASL_OK; +} + +#ifndef sasl_callback_ft +typedef int (*sasl_callback_ft)(void); +#endif + +// passed to sasl_server_init() +static sasl_callback_t callbacks[] = +{ + { SASL_CB_VERIFYFILE, (sasl_callback_ft)&_sasl_verifyfile_callback, NULL }, + { SASL_CB_LIST_END, NULL, NULL } +}; + // Initialize the SASL mechanism; throw if it fails. void SaslAuthenticator::init(const std::string& saslName, std::string const & saslConfigPath ) { @@ -120,6 +152,11 @@ void SaslAuthenticator::init(const std::string& saslName, std::string const & sa throw Exception ( QPID_MSG ( "SASL: sasl_set_path failed: cannot stat: " << saslConfigPath ) ); } + // Make sure that saslConfigPath is a directory. + if (!S_ISDIR(st.st_mode)) { + throw Exception ( QPID_MSG ( "SASL: not a directory: " << saslConfigPath ) ); + } + // Make sure the directory is readable. if ( ::access ( saslConfigPath.c_str(), R_OK ) ) { throw Exception ( QPID_MSG ( "SASL: sasl_set_path failed: directory not readable:" << saslConfigPath ) ); @@ -134,11 +171,11 @@ void SaslAuthenticator::init(const std::string& saslName, std::string const & sa } #endif - int code = sasl_server_init(NULL, saslName.c_str()); + int code = sasl_server_init(callbacks, saslName.c_str()); if (code != SASL_OK) { // TODO: Figure out who owns the char* returned by // sasl_errstring, though it probably does not matter much - throw Exception(QPID_MSG("SASL: failed to parse SASL configuration file, error: " << sasl_errstring(code, NULL, NULL))); + throw Exception(QPID_MSG("SASL: failed to parse SASL configuration file in (" << saslConfigPath << "), error: " << sasl_errstring(code, NULL, NULL))); } } |
