From fca6c1a831393e173706a5b5c798c35dc5f7d3e6 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Thu, 3 Sep 2009 20:16:23 +0200 Subject: Thread-Sicherheit verbessert --- Konzept/Klassen.txt | 34 ++++++++++---- src/Common/AuthManager.cpp | 18 +++++--- .../AuthBackendChallengeResponse.cpp | 4 ++ .../AuthBackendChallengeResponse.h | 4 ++ src/modules/AuthProviderFile/AuthProviderFile.cpp | 8 +++- src/modules/AuthProviderFile/AuthProviderFile.h | 4 ++ src/modules/FileLogger/FileLogger.h | 2 +- .../SystemBackendProc/SystemBackendProc.cpp | 8 ++++ src/modules/SystemBackendProc/SystemBackendProc.h | 4 ++ .../UserConfigBackendKrb5.cpp | 53 +++++++++++++++------- .../UserConfigBackendKrb5/UserConfigBackendKrb5.h | 11 +++-- 11 files changed, 112 insertions(+), 38 deletions(-) diff --git a/Konzept/Klassen.txt b/Konzept/Klassen.txt index 67d5c29..37fd93e 100644 --- a/Konzept/Klassen.txt +++ b/Konzept/Klassen.txt @@ -5,8 +5,11 @@ M läuft nur im Main-Thread T Client::Application +T Client::Authenticators::ChallengeResponseAuthenticator +T Client::Authenticators::PasswordAuthenticator M Client::CommandParser T Client::InformationManager +M Client::PasswordReader T Client::Requests::DaemonCommandRequest T Client::Requests::DaemonFSInfoRequest T Client::Requests::DaemonListRequest @@ -14,11 +17,16 @@ T Client::Requests::DaemonStatusRequest M Client::SystemCommands M Client::UserCommands T Common::Application +T Common::AuthBackend +T Common::AuthContext +T Common::AuthManager +T Common::AuthProvider T Common::Backends::NetworkUserBackend T Common::Base64Encoder T Common::ClientConnection ? Common::Connection D Common::GroupInfo +T Common::Hash D Common::HostInfo D Common::Module T Common::ModuleManager @@ -31,6 +39,7 @@ T Common::RequestHandlers::SimpleRequestHandler T Common::RequestHandlers::SimpleRequestHandlerGroup T Common::RequestHandlers::StatusRequestHandler ? Common::RequestManager +T Common::Requests::AuthMethodRequest T Common::Requests::DisconnectRequest T Common::Requests::FSInfoRequest T Common::Requests::IdentifyRequest @@ -38,8 +47,9 @@ T Common::Requests::SimpleRequest T Common::Requests::StatusRequest T Common::SystemBackend T Common::SystemManager -T Common::UserBackend T Common::UserCache +T Common::UserConfigBackend +T Common::UserDBBackend D Common::UserInfo T Common::UserManager D Common::XmlPacket @@ -49,9 +59,7 @@ D Core::ConfigEntry T Core::Configurable D Core::Exception T Core::Logger -T Core::LoggerBase T Core::LogManager -T Core::RemoteLogger T Core::Signals::Connection T Core::Signals::GenericSignal T Core::Signals::Signal0 @@ -64,14 +72,24 @@ T Daemon::Application T Daemon::Backends::NetworkLogger T Daemon::RequestHandlers::CommandRequestHandler T Daemon::Requests::LogRequest -? modules::FileLogger::FileLogger +T modules::AuthBackendChallengeResponse::AuthBackendChallengeResponse +T modules::AuthBackendChallengeResponse::Module +T modules::AuthBackendPassword::AuthBackendPassword +T modules::AuthBackendPassword::Module +T modules::AuthProviderFile::AuthProviderFile +T modules::AuthProviderFile::Module +T modules::FileLogger::FileLogger T modules::FileLogger::Module T modules::SystemBackendPosix::Module -? modules::SystemBackendPosix::SystemBackendPosix +T modules::SystemBackendPosix::SystemBackendPosix T modules::SystemBackendProc::Module -? modules::SystemBackendProc::SystemBackendProc -T modules::UserBackendMysql::Module -T modules::UserBackendMysql::UserBackendMysql +T modules::SystemBackendProc::SystemBackendProc +T modules::UserConfigBackendHome::Module +T modules::UserConfigBackendHome::UserConfigBackendHome +T modules::UserConfigBackendKrb5::Module +T modules::UserConfigBackendKrb5::UserConfigBackendKrb5 +T modules::UserDBBackendMysql::Module +T modules::UserDBBackendMysql::UserDBBackendMysql T Net::ClientConnection T Net::Connection T Net::Listener diff --git a/src/Common/AuthManager.cpp b/src/Common/AuthManager.cpp index c4cace7..38ac9e3 100644 --- a/src/Common/AuthManager.cpp +++ b/src/Common/AuthManager.cpp @@ -77,16 +77,20 @@ std::vector AuthManager::getSubMethods(const std::string &method) t boost::shared_ptr AuthManager::authenticate(const std::string &method, const std::string &subMethod, const std::string &user, const std::vector &data, std::vector &response, boost::shared_ptr context) throw(Core::Exception) { - boost::lock_guard lock(mutex); + std::map >::iterator backend; - response.clear(); + { + boost::lock_guard lock(mutex); - std::map >::iterator backend = backends.find(method); - if(backend == backends.end()) - throw Core::Exception(Core::Exception::NOT_IMPLEMENTED); + response.clear(); - if(!provider) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); + backend = backends.find(method); + if(backend == backends.end()) + throw Core::Exception(Core::Exception::NOT_IMPLEMENTED); + + if(!provider) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + } return backend->second->authenticate(provider, subMethod, user, data, response, context); } diff --git a/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp index 5878362..fc6bd47 100644 --- a/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp +++ b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.cpp @@ -21,6 +21,8 @@ #include +#include + namespace Mad { namespace Modules { namespace AuthBackendChallengeResponse { @@ -30,6 +32,8 @@ const std::string AuthBackendChallengeResponse::methodName = "Challenge-Response AuthBackendChallengeResponse::AuthContextChallengeResponse::AuthContextChallengeResponse(AuthBackendChallengeResponse *backend) : authenticated(false) { challenge.reserve(32); + boost::lock_guard lock(backend->mutex); + for(int i = 0; i < 32; ++i) challenge.push_back(backend->randomGenerator()); } diff --git a/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.h b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.h index a32cc98..dc1b60a 100644 --- a/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.h +++ b/src/modules/AuthBackendChallengeResponse/AuthBackendChallengeResponse.h @@ -33,6 +33,8 @@ #include #include +#include + namespace Mad { namespace Modules { namespace AuthBackendChallengeResponse { @@ -58,6 +60,8 @@ class MAD_MODULE_EXPORT AuthBackendChallengeResponse : public Common::AuthBacken Common::Application *application; + boost::mutex mutex; + boost::mt19937 rng; boost::uniform_int byteDistribution; boost::variate_generator > randomGenerator; diff --git a/src/modules/AuthProviderFile/AuthProviderFile.cpp b/src/modules/AuthProviderFile/AuthProviderFile.cpp index 99af6b6..1756747 100644 --- a/src/modules/AuthProviderFile/AuthProviderFile.cpp +++ b/src/modules/AuthProviderFile/AuthProviderFile.cpp @@ -26,6 +26,7 @@ #include #include +#include namespace Mad { namespace Modules { @@ -56,6 +57,7 @@ void AuthProviderFile::readFile(const std::string &name) { std::string password = match[2].str(); if(filehash.empty()) { + boost::lock_guard lock(mutex); userMap.insert(std::make_pair(match[1].str(), std::vector(password.begin(), password.end()))); } else { @@ -75,8 +77,10 @@ void AuthProviderFile::readFile(const std::string &name) { data.push_back(byte); } - if(!data.empty()) + if(!data.empty()) { + boost::lock_guard lock(mutex); userMap.insert(std::make_pair(match[1].str(), data)); + } } } } @@ -137,6 +141,8 @@ bool AuthProviderFile::checkPassword(const std::string &user, const std::vector< } std::vector AuthProviderFile::getPassword(const std::string &user, const std::string &hash) throw(Core::Exception) { + boost::lock_guard lock(mutex); + std::map >::iterator userIt = userMap.find(user); if(userIt == userMap.end()) return std::vector(); diff --git a/src/modules/AuthProviderFile/AuthProviderFile.h b/src/modules/AuthProviderFile/AuthProviderFile.h index 99deaa0..63f3d28 100644 --- a/src/modules/AuthProviderFile/AuthProviderFile.h +++ b/src/modules/AuthProviderFile/AuthProviderFile.h @@ -28,6 +28,8 @@ #include #include +#include + namespace Mad { namespace Modules { namespace AuthProviderFile { @@ -38,6 +40,8 @@ class MAD_MODULE_EXPORT AuthProviderFile : public Common::AuthProvider, private Common::Application *application; + boost::mutex mutex; + std::map > userMap; std::vector files; diff --git a/src/modules/FileLogger/FileLogger.h b/src/modules/FileLogger/FileLogger.h index c202e4b..edd74a8 100644 --- a/src/modules/FileLogger/FileLogger.h +++ b/src/modules/FileLogger/FileLogger.h @@ -37,7 +37,7 @@ class FileLogger : public Core::Logger { if(source.empty()) file << message << std::endl; else - file << message << " from "<< source << std::endl; + file << message << " from " << source << std::endl; } public: diff --git a/src/modules/SystemBackendProc/SystemBackendProc.cpp b/src/modules/SystemBackendProc/SystemBackendProc.cpp index fb4d4e4..1a8c9c4 100644 --- a/src/modules/SystemBackendProc/SystemBackendProc.cpp +++ b/src/modules/SystemBackendProc/SystemBackendProc.cpp @@ -21,6 +21,8 @@ #include +#include + #include #include @@ -31,6 +33,8 @@ namespace SystemBackendProc { void SystemBackendProc::getUptimeInfo(unsigned long *uptime, unsigned long *idleTime) throw(Core::Exception) { application->getThreadManager()->detach(); + boost::lock_guard lock(uptimeMutex); + uptimeFile.seekg(0, std::ios::beg); if(!uptimeFile.good()) @@ -52,6 +56,8 @@ void SystemBackendProc::getUptimeInfo(unsigned long *uptime, unsigned long *idle void SystemBackendProc::getMemoryInfo(unsigned long *totalMem, unsigned long *freeMem, unsigned long *totalSwap, unsigned long *freeSwap) throw(Core::Exception) { application->getThreadManager()->detach(); + boost::lock_guard lock(meminfoMutex); + if(totalMem) *totalMem = 0; if(freeMem) @@ -94,6 +100,8 @@ void SystemBackendProc::getMemoryInfo(unsigned long *totalMem, unsigned long *fr void SystemBackendProc::getLoadInfo(unsigned long *currentLoad, unsigned long *nProcesses, float *loadAvg1, float *loadAvg5, float *loadAvg15) throw(Core::Exception) { application->getThreadManager()->detach(); + boost::lock_guard lock(loadMutex); + unsigned long currentLoadValue = 0, nProcessesValue = 0; float loadAvg1Value = 0, loadAvg5Value = 0, loadAvg15Value = 0; diff --git a/src/modules/SystemBackendProc/SystemBackendProc.h b/src/modules/SystemBackendProc/SystemBackendProc.h index a6a7835..99cc800 100644 --- a/src/modules/SystemBackendProc/SystemBackendProc.h +++ b/src/modules/SystemBackendProc/SystemBackendProc.h @@ -23,6 +23,8 @@ #include #include +#include + #include namespace Mad { @@ -33,6 +35,8 @@ class SystemBackendProc : public Common::SystemBackend { private: Common::Application *application; + boost::mutex uptimeMutex, meminfoMutex, loadMutex; + std::ifstream uptimeFile; std::ifstream meminfoFile; std::ifstream loadFile; diff --git a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp index 94e3506..b10dbcf 100644 --- a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp +++ b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.cpp @@ -21,13 +21,15 @@ #include #include +#include + #include namespace Mad { namespace Modules { namespace UserConfigBackendKrb5 { -void UserConfigBackendKrb5::connect() { +void UserConfigBackendKrb5::_connect() { if(principal.empty()) { application->log(Core::Logger::LOG_USER, Core::Logger::LOG_ERROR, "UserConfigBackendKrb5: no principal given"); return; @@ -96,6 +98,8 @@ bool UserConfigBackendKrb5::handleConfigEntry(const Core::ConfigEntry &entry, bo if(!entry[1].getKey().matches("Krb5")) return false; + boost::lock_guard lock(mutex); + if(entry[2].getKey().matches("Realm")) { if(entry[3].empty()) realm = entry[2][0]; @@ -122,6 +126,11 @@ bool UserConfigBackendKrb5::handleConfigEntry(const Core::ConfigEntry &entry, bo return true; } +void UserConfigBackendKrb5::configFinished() { + boost::lock_guard lock(mutex); + _connect(); +} + void UserConfigBackendKrb5::checkUserInfo(const Common::UserInfo &userInfo) throw(Core::Exception) { if(std::strcspn(userInfo.getUsername().c_str(), "/@") != userInfo.getUsername().length()) @@ -129,11 +138,13 @@ void UserConfigBackendKrb5::checkUserInfo(const Common::UserInfo &userInfo) thro } void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core::Exception) { + application->getThreadManager()->detach(); + + boost::lock_guard lock(mutex); + if(!context || !handle) throw Core::Exception(Core::Exception::NOT_AVAILABLE); - application->getThreadManager()->detach(); - std::string princStr = userInfo.getUsername() + "@" + realm; kadm5_principal_ent_rec princ; @@ -154,7 +165,7 @@ void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core err = kadm5_create_principal(handle, &princ, KADM5_PRINCIPAL|KADM5_ATTRIBUTES, dummybuf); if(err == KADM5_RPC_ERROR && retryCount > 0) { application->log(Core::Logger::LOG_USER, Core::Logger::LOG_VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); - connect(); + _connect(); --retryCount; } } while(err == KADM5_RPC_ERROR && retryCount >= 0); @@ -167,7 +178,7 @@ void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core err = kadm5_randkey_principal(handle, princ.principal, 0, 0); if(err == KADM5_RPC_ERROR && retryCount > 0) { application->log(Core::Logger::LOG_USER, Core::Logger::LOG_VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); - connect(); + _connect(); --retryCount; } } while(err == KADM5_RPC_ERROR && retryCount >= 0); @@ -181,7 +192,7 @@ void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core err = kadm5_modify_principal(handle, &princ, KADM5_ATTRIBUTES); if(err == KADM5_RPC_ERROR && retryCount > 0) { application->log(Core::Logger::LOG_USER, Core::Logger::LOG_VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); - connect(); + _connect(); --retryCount; } } while(err == KADM5_RPC_ERROR && retryCount >= 0); @@ -193,22 +204,30 @@ void UserConfigBackendKrb5::addUser(const Common::UserInfo &userInfo) throw(Core } void UserConfigBackendKrb5::updateUser(const Common::UserInfo &oldUserInfo, const Common::UserInfo &userInfo) throw(Core::Exception) { - if(!context || !handle) - throw Core::Exception(Core::Exception::NOT_AVAILABLE); + application->getThreadManager()->detach(); - if(oldUserInfo.getUsername() == userInfo.getUsername()) - return; + { + boost::lock_guard lock(mutex); + + if(!context || !handle) + throw Core::Exception(Core::Exception::NOT_AVAILABLE); + + if(oldUserInfo.getUsername() == userInfo.getUsername()) + return; + } deleteUser(oldUserInfo); addUser(userInfo); } void UserConfigBackendKrb5::deleteUser(const Common::UserInfo &userInfo) throw(Core::Exception) { + application->getThreadManager()->detach(); + + boost::lock_guard lock(mutex); + if(!context || !handle) throw Core::Exception(Core::Exception::NOT_AVAILABLE); - application->getThreadManager()->detach(); - std::string princStr = userInfo.getUsername() + "@" + realm; krb5_principal princ; @@ -223,7 +242,7 @@ void UserConfigBackendKrb5::deleteUser(const Common::UserInfo &userInfo) throw(C err = kadm5_delete_principal(handle, princ); if(err == KADM5_RPC_ERROR && retryCount > 0) { application->log(Core::Logger::LOG_USER, Core::Logger::LOG_VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); - connect(); + _connect(); --retryCount; } } while(err == KADM5_RPC_ERROR && retryCount >= 0); @@ -235,11 +254,13 @@ void UserConfigBackendKrb5::deleteUser(const Common::UserInfo &userInfo) throw(C } void UserConfigBackendKrb5::setPassword(const Common::UserInfo &userInfo, const std::string &password) throw(Core::Exception) { + application->getThreadManager()->detach(); + + boost::lock_guard lock(mutex); + if(!context || !handle) throw Core::Exception(Core::Exception::NOT_AVAILABLE); - application->getThreadManager()->detach(); - std::string princStr = userInfo.getUsername() + "@" + realm; krb5_principal princ; @@ -253,7 +274,7 @@ void UserConfigBackendKrb5::setPassword(const Common::UserInfo &userInfo, const err = kadm5_chpass_principal(handle, princ, const_cast(password.c_str())); if(err == KADM5_RPC_ERROR && retryCount > 0) { application->log(Core::Logger::LOG_USER, Core::Logger::LOG_VERBOSE, "Connection to kerberos admin server lost. Reconnecting..."); - connect(); + _connect(); --retryCount; } } while(err == KADM5_RPC_ERROR && retryCount >= 0); diff --git a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h index 11c7187..c2b35fe 100644 --- a/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h +++ b/src/modules/UserConfigBackendKrb5/UserConfigBackendKrb5.h @@ -26,6 +26,8 @@ #include #include +#include + #define USE_KADM5_API_VERSION 2 #include @@ -37,20 +39,19 @@ class UserConfigBackendKrb5 : public Common::UserConfigBackend, private Core::Co private: Common::Application *application; + boost::mutex mutex; + std::string realm, principal, server; std::string password, keytab; krb5_context context; void *handle; - void connect(); + void _connect(); protected: virtual bool handleConfigEntry(const Core::ConfigEntry &entry, bool handled); - - virtual void configFinished() { - connect(); - } + virtual void configFinished(); virtual void checkUserInfo(const Common::UserInfo &userInfo) throw(Core::Exception); -- cgit v1.2.3