CSingletonLDAPConnection.cpp
Go to the documentation of this file.00001
00010 #include "CSingletonLDAPConnection.h"
00011 #include "HttpServerBlacklist.h"
00012 #include "LDAP_URL_Header.h"
00013 #include "CLDAPConnectionInfo.h"
00014 #include "PKIFTime.h"
00015 #include "Duration.h"
00016 #include <cctype>
00017
00018 #include <vector>
00019 #include <string>
00020 #include <map>
00021 using namespace std;
00022
00023
00024
00025 const int g_maxAutoBlacklistEntries = 100;
00026 const int g_numSecondsToLive = 300;
00027 std::vector<std::string> g_blacklistedServers;
00028 std::map<std::string, CPKIFTimePtr> g_autoBlacklistedServers;
00029
00030
00051 void CAC_API PKIFLDAP::AddBlacklistedServer(
00053 std::string& server,
00055 bool bPermanent)
00056 {
00057 if(server == "")
00058 return;
00059 std::string copyOfServer = server;
00060 std::transform(copyOfServer.begin(), copyOfServer.end(), copyOfServer.begin(), (int(*)(int)) std::toupper);
00061 if(bPermanent)
00062 {
00063 if(g_blacklistedServers.end() == find(g_blacklistedServers.begin(), g_blacklistedServers.end(), copyOfServer))
00064 g_blacklistedServers.push_back(copyOfServer);
00065 }
00066 else
00067 {
00068 if(g_maxAutoBlacklistEntries < g_autoBlacklistedServers.size())
00069 {
00070 CPKIFDuration d;
00071 d.setSeconds(g_numSecondsToLive);
00072
00073
00074 CPKIFTimePtr lowerThreshold = CPKIFTime::CurrentTime();
00075 *lowerThreshold -= d;
00076
00077 std::map<std::string, CPKIFTimePtr >::iterator pos;
00078 std::map<std::string, CPKIFTimePtr >::iterator end = g_autoBlacklistedServers.end();
00079 for(pos = g_autoBlacklistedServers.begin(); pos != end; ++pos)
00080 {
00081 if(*lowerThreshold > *(*pos).second)
00082 g_autoBlacklistedServers.erase(pos);
00083 }
00084
00085 if(g_maxAutoBlacklistEntries < g_autoBlacklistedServers.size())
00086 {
00087
00088 int numToRemove = g_maxAutoBlacklistEntries/10;
00089 for(int ii = 0; ii < numToRemove; ++ii)
00090 {
00091 std::string serverToErase = (*g_autoBlacklistedServers.begin()).first;
00092 g_autoBlacklistedServers.erase(serverToErase);
00093 }
00094 }
00095 }
00096
00097
00098 g_autoBlacklistedServers[copyOfServer] = CPKIFTime::CurrentTime();
00099 }
00100 }
00101
00112 void CAC_API PKIFLDAP::RemoveBlacklistedServer(
00114 std::string& server)
00115 {
00116 std::string copyOfServer = server;
00117 std::transform(copyOfServer.begin(), copyOfServer.end(), copyOfServer.begin(), (int(*)(int)) std::toupper);
00118
00119 std::vector<std::string>::iterator found = find(g_blacklistedServers.begin(),g_blacklistedServers.end(),copyOfServer);
00120 if(g_blacklistedServers.end() != found)
00121 g_blacklistedServers.erase(found);
00122
00123 g_autoBlacklistedServers.erase(copyOfServer);
00124 }
00125
00135 bool CAC_API PKIFLDAP::IsBlacklisted(std::string& server)
00136 {
00137 std::string copyOfServer = server;
00138 std::transform(copyOfServer.begin(), copyOfServer.end(), copyOfServer.begin(), (int(*)(int)) std::toupper);
00139
00140 bool bTemporarilyBlacklisted = false;
00141 bool bPermanentlyBlacklisted = g_blacklistedServers.end() != find(g_blacklistedServers.begin(), g_blacklistedServers.end(), copyOfServer);
00142 if(g_autoBlacklistedServers.end() != g_autoBlacklistedServers.find(copyOfServer))
00143 {
00144 CPKIFTimePtr time = g_autoBlacklistedServers[copyOfServer];
00145 CPKIFDuration d;
00146 d.setSeconds(g_numSecondsToLive);
00147
00148 CPKIFTimePtr curTime = CPKIFTime::CurrentTime();
00149 *curTime -= d;
00150 if(*time > *curTime)
00151 bTemporarilyBlacklisted = true;
00152 else
00153 g_autoBlacklistedServers.erase(copyOfServer);
00154 }
00155
00156 std::string host;
00157 GetHostFromUri(copyOfServer.c_str(), host);
00158
00159 if(host == copyOfServer || host.empty())
00160 return bPermanentlyBlacklisted || bTemporarilyBlacklisted;
00161 else
00162 return IsBlacklisted(host);
00163 }
00164
00172 void CAC_API PKIFLDAP::ClearServerBlacklist(void)
00173 {
00174 g_blacklistedServers.clear();
00175 g_autoBlacklistedServers.clear();
00176 }
00177
00185 void CAC_API PKIFLDAP::GetServerBlacklist(std::vector<std::string> & bl)
00186 {
00187 bl = g_blacklistedServers;
00188
00189 CPKIFDuration d;
00190 d.setSeconds(g_numSecondsToLive);
00191
00192 CPKIFTimePtr curTime = CPKIFTime::CurrentTime();
00193 *curTime -= d;
00194
00195 std::map<std::string, CPKIFTimePtr>::iterator pos;
00196 std::map<std::string, CPKIFTimePtr>::iterator end = g_autoBlacklistedServers.end();
00197 for(pos = g_autoBlacklistedServers.begin(); pos != end; ++pos)
00198 {
00199 if((*pos).second != (CPKIFTime*)NULL &&
00200 *(*pos).second > *curTime)
00201 {
00202 if(bl.end() == find(bl.begin(), bl.end(), (*pos).first))
00203 bl.push_back((*pos).first);
00204 }
00205 }
00206 }
00207
00215 CSingletonLDAPConnection::CSingletonLDAPConnection()
00216 {
00217 }
00225 CSingletonLDAPConnection* CSingletonLDAPConnection::Instance()
00226 {
00227 if(!m_instance)
00228 {
00229 m_instance = new CSingletonLDAPConnection();
00230 }
00231
00232 return m_instance;
00233 }
00241 CSingletonLDAPConnection::~CSingletonLDAPConnection()
00242 {
00243 std::vector<CLDAPConnectionInfo*>::iterator pos;
00244 std::vector<CLDAPConnectionInfo*>::iterator end = m_ldaps.end();
00245
00246 for(pos = m_ldaps.begin(); pos != end; ++pos)
00247 {
00248 if(NULL != (*pos)->m_connection)
00249 ldap_unbind((*pos)->m_connection);
00250 delete *pos;
00251 }
00252
00253 }
00261 void CSingletonLDAPConnection::PushConnection(
00263 std::string& host,
00265 int port,
00267 LDAP* ldap)
00268 {
00269 std::vector<CLDAPConnectionInfo*>::iterator pos;
00270 std::vector<CLDAPConnectionInfo*>::iterator end = m_ldaps.end();
00271
00272 for(pos = m_ldaps.begin(); pos != end; ++pos)
00273 {
00274 if(host == (*pos)->m_host && port == (*pos)->m_port)
00275 return;
00276 }
00277
00278 CLDAPConnectionInfo* p = new CLDAPConnectionInfo();
00279 p->m_host = host;
00280 p->m_port = port;
00281 p->m_connection = ldap;
00282 m_ldaps.push_back(p);
00283 }
00284
00292 LDAP* CSingletonLDAPConnection::GetConnection(
00294 std::string& host,
00296 int port)
00297 {
00298 std::vector<CLDAPConnectionInfo*>::iterator pos;
00299 std::vector<CLDAPConnectionInfo*>::iterator end = m_ldaps.end();
00300 for(pos = m_ldaps.begin(); pos != end; ++pos)
00301 {
00302 if(host == (*pos)->m_host && port == (*pos)->m_port)
00303 return (*pos)->m_connection;
00304 }
00305 return NULL;
00306 }
00314 void CSingletonLDAPConnection::CSingletonLDAPConnectionDestructor()
00315 {
00316 if(m_instance) {
00317 delete m_instance;
00318 m_instance = 0;
00319 }
00320 }
00321
00331 class CSingletonLDAPConnectionCleaner
00332 {
00333 public:
00334 ~CSingletonLDAPConnectionCleaner()
00335 {
00336 CSingletonLDAPConnection::CSingletonLDAPConnectionDestructor();
00337 }
00338 } CSingletonLDAPConnectionCleanerInstance;