summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSol Jerome <sol.jerome@gmail.com>2011-08-11 21:03:59 -0500
committerSol Jerome <sol.jerome@gmail.com>2011-08-11 21:05:40 -0500
commit5fe3867a3b75aff04eeb7ba8c910ee6939c1680f (patch)
treec51844648207860428307bdc4b9dcc7e9bce3e1e
parent9ae39f3eff76015a45b30750cacc354d992c66b4 (diff)
downloadbcfg2-5fe3867a3b75aff04eeb7ba8c910ee6939c1680f.tar.gz
bcfg2-5fe3867a3b75aff04eeb7ba8c910ee6939c1680f.tar.bz2
bcfg2-5fe3867a3b75aff04eeb7ba8c910ee6939c1680f.zip
Metadata: Better handling of floating cert-authenticated clients (Ticket #1030)
From the ticket: A floating, cert-authenticated client can be not recognized properly by hostname if it resolves to an arbitrary name in reverse DNS. Background: Metadata.resolve_client, called from @exposed Core's methods, falls back to reverse DNS lookup for client's name, because the name is not preserved thanks to bailing off early from Metadata.AuthenticateConnection. (This issue can be related to #936.) This patch enables caching of client names for cert-based floating clients. Signed-off-by: Sol Jerome <sol.jerome@gmail.com>
-rw-r--r--src/lib/Server/Core.py2
-rw-r--r--src/lib/Server/Plugins/Metadata.py20
2 files changed, 19 insertions, 3 deletions
diff --git a/src/lib/Server/Core.py b/src/lib/Server/Core.py
index 91b6a3555..2d735133b 100644
--- a/src/lib/Server/Core.py
+++ b/src/lib/Server/Core.py
@@ -365,7 +365,7 @@ class Core(Component):
"""Fetch probes for a particular client."""
resp = lxml.etree.Element('probes')
try:
- name = self.metadata.resolve_client(address)
+ name = self.metadata.resolve_client(address, cleanup_cache=True)
meta = self.build_metadata(name)
for plugin in self.plugins_by_type(Bcfg2.Server.Plugin.Probing):
diff --git a/src/lib/Server/Plugins/Metadata.py b/src/lib/Server/Plugins/Metadata.py
index bfe1ac053..c355568cd 100644
--- a/src/lib/Server/Plugins/Metadata.py
+++ b/src/lib/Server/Plugins/Metadata.py
@@ -571,11 +571,24 @@ class Metadata(Bcfg2.Server.Plugin.Plugin,
self.clients[client] = profile
self.clients_xml.write()
- def resolve_client(self, addresspair):
+ def resolve_client(self, addresspair, cleanup_cache=False):
"""Lookup address locally or in DNS to get a hostname."""
if addresspair in self.session_cache:
+ # client _was_ cached, so there can be some expired entries
+ # we need to clean them up to avoid potentially infinite memory swell
+ cache_ttl = 90
+ if cleanup_cache:
+ # remove entries for this client's IP address with _any_ port numbers
+ # - perhaps a priority queue could be faster?
+ curtime = time.time()
+ for addrpair in self.session_cache.keys():
+ if addresspair[0] == addrpair[0]:
+ (stamp, _) = self.session_cache[addrpair]
+ if curtime - stamp > cache_ttl:
+ del self.session_cache[addrpair]
+ # return the cached data
(stamp, uuid) = self.session_cache[addresspair]
- if time.time() - stamp < 90:
+ if time.time() - stamp < cache_ttl:
return self.session_cache[addresspair][1]
address = addresspair[0]
if address in self.addresses:
@@ -741,6 +754,9 @@ class Metadata(Bcfg2.Server.Plugin.Plugin,
return False
if id_method == 'cert' and auth_type != 'cert+password':
+ # remember the cert-derived client name for this connection
+ if client in self.floating:
+ self.session_cache[address] = (time.time(), client)
# we are done if cert+password not required
return True