[Checkins] SVN: cipher.googlepam/trunk/ Fix unpickling errors in MemCache.

Marius Gedminas cvs-admin at zope.org
Thu Oct 11 13:20:15 UTC 2012


Log message for revision 127966:
  Fix unpickling errors in MemCache.

Changed:
  U   cipher.googlepam/trunk/CHANGES.txt
  U   cipher.googlepam/trunk/src/cipher/googlepam/pam_google.py
  U   cipher.googlepam/trunk/src/cipher/googlepam/tests/test_doc.py

-=-
Modified: cipher.googlepam/trunk/CHANGES.txt
===================================================================
--- cipher.googlepam/trunk/CHANGES.txt	2012-10-11 12:38:31 UTC (rev 127965)
+++ cipher.googlepam/trunk/CHANGES.txt	2012-10-11 13:20:11 UTC (rev 127966)
@@ -12,6 +12,12 @@
     using their own passwords -- but the first user could now use her password
     to log in as anyone else.
 
+  + Do not store custom classes in memcached so we don't get unpickling
+    errors caused by the special execution environment set up by
+    pam_python.so.  Previously the cached value was a subclass of tuple,
+    now it's a plain tuple, so old caches will continue to work with the
+    new code.
+
 - FileCache reliability fixes:
 
   + Avoid incorrect cache lookups (or invalidations) when a username is a

Modified: cipher.googlepam/trunk/src/cipher/googlepam/pam_google.py
===================================================================
--- cipher.googlepam/trunk/src/cipher/googlepam/pam_google.py	2012-10-11 12:38:31 UTC (rev 127965)
+++ cipher.googlepam/trunk/src/cipher/googlepam/pam_google.py	2012-10-11 13:20:11 UTC (rev 127966)
@@ -144,12 +144,15 @@
         return self.pam.config.get(self.SECTION_NAME, 'key-prefix') + username
 
     def _get_user_info(self, username):
-        return self._client.get(self._get_key(username))
+        cached = self._client.get(self._get_key(username))
+        if cached is None:
+            return None
+        return UserInfo(*cached)
 
     def _add_user_info(self, username, password):
         self._client.set(
             self._get_key(username),
-            UserInfo(time.time(), bcrypt.hashpw(password, bcrypt.gensalt())))
+            (time.time(), bcrypt.hashpw(password, bcrypt.gensalt())))
 
     def _del_user_info(self, username):
         self._client.delete(self._get_key(username))

Modified: cipher.googlepam/trunk/src/cipher/googlepam/tests/test_doc.py
===================================================================
--- cipher.googlepam/trunk/src/cipher/googlepam/tests/test_doc.py	2012-10-11 12:38:31 UTC (rev 127965)
+++ cipher.googlepam/trunk/src/cipher/googlepam/tests/test_doc.py	2012-10-11 13:20:11 UTC (rev 127966)
@@ -14,6 +14,7 @@
 """Google PAM Tests
 """
 import doctest
+import sys
 import os
 import tempfile
 import ConfigParser
@@ -452,12 +453,27 @@
 def doctest_MemcacheCache():
     """class MemcacheCache
 
+    This is a bit tricky: when pam_python.so loads the module, its name
+    ends up being simply 'pam_google' instead of 'cipher.googlepam.pam_google'.
+    This can break unpickling of classes defined in that module, since
+    pam_python.so doesn't add the directory containing pam_google.py to
+    sys.path, and it doesn't add pam_google itself to sys.modules.
+
+      >>> sys.path.insert(0, os.path.dirname(pam_google.__file__))
+      >>> import pam_google
+      >>> pam_google.__name__
+      'pam_google'
+      >>> del sys.path[0]
+      >>> del sys.modules['pam_google']
+
+    Now that we have an approximation of that environment, let's go on
+
       >>> pam = pam_google.GooglePAM(
       ...     FakePamHandle(), 0,
       ...     ['script', '-c', os.path.join(HERE, 'mem-cache.conf')])
 
       >>> pam._cache
-      <cipher.googlepam.pam_google.MemcacheCache object at ...>
+      <pam_google.MemcacheCache object at ...>
 
       >>> pam._cache.authenticate('user', 'pwd')
 



More information about the checkins mailing list