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             //first try removing old entries
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                 //failing that, simply remove 10% of the store
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         //If the server isn't in the map, add it.  If it is, update the time
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;

Generated on Mon Nov 15 11:15:50 2010 for PublicKeyInfrastructureFramework(PKIF) by  doxygen 1.5.6