From 085cdb1910ded5e6fcf9b56da595e9f4609f95b8 Mon Sep 17 00:00:00 2001 From: Michael Goulish Date: Thu, 13 Oct 2011 21:50:56 +0000 Subject: QPID-3528 sasl_set_path() does no check on the given directory, so when you get bad behavior later it can be hard to track down. Especially bad is its policy of defaulting to an alternate standard location if yours fails. That's a potential security bug. So this patch checks that your dir exists, and is readable, before calling sasl_set_path(). Either you get the sasl config dir you were expecting, git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1183121 13f79535-47bb-0310-9956-ffa450edef68 --- cpp/src/qpid/broker/SaslAuthenticator.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'cpp/src/qpid') diff --git a/cpp/src/qpid/broker/SaslAuthenticator.cpp b/cpp/src/qpid/broker/SaslAuthenticator.cpp index befe7eef25..d7adbd68ab 100644 --- a/cpp/src/qpid/broker/SaslAuthenticator.cpp +++ b/cpp/src/qpid/broker/SaslAuthenticator.cpp @@ -30,6 +30,7 @@ #include #if HAVE_SASL +#include #include #include "qpid/sys/cyrus/CyrusSecurityLayer.h" using qpid::sys::cyrus::CyrusSecurityLayer; @@ -98,11 +99,33 @@ void SaslAuthenticator::init(const std::string& saslName, std::string const & sa // Check if we have a version of SASL that supports sasl_set_path() #if (SASL_VERSION_FULL >= ((2<<16)|(1<<8)|22)) // If we are not given a sasl path, do nothing and allow the default to be used. - if ( ! saslConfigPath.empty() ) { - int code = sasl_set_path(SASL_PATH_TYPE_CONFIG, - const_cast(saslConfigPath.c_str())); + if ( saslConfigPath.empty() ) { + QPID_LOG ( info, "SASL: no config path set - using default." ); + } + else { + struct stat st; + + // Make sure the directory exists and we can read up to it. + if ( ::stat ( saslConfigPath.c_str(), & st) ) { + // Note: not using strerror() here because I think its messages are a little too hazy. + if ( errno == ENOENT ) + throw Exception ( QPID_MSG ( "SASL: sasl_set_path failed: no such directory: " << saslConfigPath ) ); + if ( errno == EACCES ) + throw Exception ( QPID_MSG ( "SASL: sasl_set_path failed: cannot read parent of: " << saslConfigPath ) ); + // catch-all stat failure + throw Exception ( QPID_MSG ( "SASL: sasl_set_path failed: cannot stat: " << 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 ) ); + } + + // This shouldn't fail now, but check anyway. + int code = sasl_set_path(SASL_PATH_TYPE_CONFIG, const_cast(saslConfigPath.c_str())); if(SASL_OK != code) throw Exception(QPID_MSG("SASL: sasl_set_path failed [" << code << "] " )); + QPID_LOG(info, "SASL: config path set to " << saslConfigPath ); } #endif -- cgit v1.2.1