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 | d05027f9a18766d5a10aa05a84b587e2247b6f0a (patch) | |
| tree | 3b30cb72389df9ff3ba897342862a3e8b92c368f /cpp | |
| parent | a1bc2a199f1c5f4f03d002ebcb7e0bb3818651bf (diff) | |
| download | qpid-python-d05027f9a18766d5a10aa05a84b587e2247b6f0a.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/qpid@1637122 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'cpp')
| -rw-r--r-- | cpp/src/qpid/broker/SaslAuthenticator.cpp | 41 |
1 files changed, 39 insertions, 2 deletions
diff --git a/cpp/src/qpid/broker/SaslAuthenticator.cpp b/cpp/src/qpid/broker/SaslAuthenticator.cpp index 55a10063f8..41b56e1d82 100644 --- a/cpp/src/qpid/broker/SaslAuthenticator.cpp +++ b/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))); } } |
