[CalendarServer-changes] [3577] CalendarServer/trunk/twistedcaldav

source_changes at macosforge.org source_changes at macosforge.org
Wed Jan 7 14:54:17 PST 2009


Revision: 3577
          http://trac.macosforge.org/projects/calendarserver/changeset/3577
Author:   sagen at apple.com
Date:     2009-01-07 14:54:17 -0800 (Wed, 07 Jan 2009)
Log Message:
-----------
Support for retrieving xmpp and email passwords from system keychain

Modified Paths:
--------------
    CalendarServer/trunk/twistedcaldav/config.py
    CalendarServer/trunk/twistedcaldav/util.py

Modified: CalendarServer/trunk/twistedcaldav/config.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/config.py	2009-01-07 21:51:22 UTC (rev 3576)
+++ CalendarServer/trunk/twistedcaldav/config.py	2009-01-07 22:54:17 UTC (rev 3577)
@@ -34,6 +34,9 @@
 
 from twistedcaldav.log import Logger
 from twistedcaldav.log import clearLogLevels, setLogLevelForNamespace, InvalidLogLevelError
+from twistedcaldav.util import (
+    KeychainAccessError, KeychainPasswordNotFound, getPasswordFromKeychain
+)
 
 log = Logger()
 
@@ -418,6 +421,7 @@
             self.updateDropBox,
             self.updateLogLevels,
             self.updateNotifications,
+            self.updateScheduling,
         ]
 
     def __str__(self):
@@ -638,11 +642,50 @@
                 service["Service"] == "twistedcaldav.notify.XMPPNotifierService" and
                 service["Enabled"]
             ):
+                # Get password from keychain.  If not there, fall back to what
+                # is in the plist.
+                try:
+                    password = getPasswordFromKeychain("icalserver.xmpp")
+                    service["Password"] = password
+                    log.info("XMPP password successfully retreived from keychain")
+                except KeychainAccessError:
+                    # The system doesn't support keychain
+                    pass
+                except KeychainPasswordNotFound:
+                    # The password doesn't exist in the keychain.
+                    log.error("XMPP password not found in keychain")
+
+                # Check for empty fields
                 for key, value in service.iteritems():
                     if not value and key not in ("AllowedJIDs", "HeartbeatMinutes"):
                         raise ConfigurationError("Invalid %s for XMPPNotifierService: %r"
                                                  % (key, value))
 
+    @staticmethod
+    def updateScheduling(self, items):
+        #
+        # Scheduling
+        #
+        service = self.Scheduling["iMIP"]
+
+        if service["Enabled"]:
+            for direction in ("Sending", "Receiving"):
+                # Get password from keychain.  If not there, fall back to what
+                # is in the plist. Keychain account names are icalserver.sending
+                # and icalserver.receiving.
+                try:
+                    account = "icalserver.%s" % (direction.lower(),)
+                    password = getPasswordFromKeychain(account)
+                    service[direction]["Password"] = password
+                    log.info("iMIP %s password successfully retreived from keychain" % (direction,))
+                except KeychainAccessError:
+                    # The system doesn't support keychain
+                    pass
+                except KeychainPasswordNotFound:
+                    # The password doesn't exist in the keychain.
+                    log.info("iMIP %s password not found in keychain" % (direction,))
+
+
 def _mergeData(oldData, newData):
     for key, value in newData.iteritems():
         if isinstance(value, (dict,)):

Modified: CalendarServer/trunk/twistedcaldav/util.py
===================================================================
--- CalendarServer/trunk/twistedcaldav/util.py	2009-01-07 21:51:22 UTC (rev 3576)
+++ CalendarServer/trunk/twistedcaldav/util.py	2009-01-07 22:54:17 UTC (rev 3577)
@@ -14,7 +14,10 @@
 # limitations under the License.
 ##
 
+import os
+import re
 import sys
+from subprocess import Popen, PIPE, STDOUT
 
 ##
 # getNCPU
@@ -117,3 +120,44 @@
     if isinstance(s, unicode):
         s = s.encode("utf-8")
     return s
+
+##
+# Keychain access
+##
+
+class KeychainPasswordNotFound(Exception):
+    """
+    Exception raised when the password does not exist
+    """
+
+class KeychainAccessError(Exception):
+    """
+    Exception raised when not able to access keychain
+    """
+
+passwordRegExp = re.compile(r'password: "(.*)"')
+
+def getPasswordFromKeychain(account):
+    if os.path.isfile("/usr/bin/security"):
+        child = Popen(
+            args=[
+                "/usr/bin/security", "find-generic-password",
+                "-a", account, "-g",
+            ],
+            stdout=PIPE, stderr=STDOUT,
+        )
+        output, error = child.communicate()
+
+        if child.returncode:
+            raise KeychainPasswordNotFound(error)
+        else:
+            match = passwordRegExp.search(output)
+            if not match:
+                error = "Password for %s not found in keychain" % (account,)
+                raise KeychainPasswordNotFound(error)
+            else:
+                return match.group(1)
+
+    else:
+        error = "Keychain access utility ('security') not found"
+        raise KeychainAccessError(error)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20090107/4e70f0e3/attachment-0001.html>


More information about the calendarserver-changes mailing list