[CalendarServer-changes] [7322] CalendarServer/trunk/contrib

source_changes at macosforge.org source_changes at macosforge.org
Mon Apr 18 14:18:51 PDT 2011


Revision: 7322
          http://trac.macosforge.org/projects/calendarserver/changeset/7322
Author:   sagen at apple.com
Date:     2011-04-18 14:18:50 -0700 (Mon, 18 Apr 2011)
Log Message:
-----------
Adds a cert-update handler for calendar/addressbook service.  9281505

Added Paths:
-----------
    CalendarServer/trunk/contrib/certupdate/
    CalendarServer/trunk/contrib/certupdate/__init__.py
    CalendarServer/trunk/contrib/certupdate/calendarcertupdate.py
    CalendarServer/trunk/contrib/certupdate/test/
    CalendarServer/trunk/contrib/certupdate/test/__init__.py
    CalendarServer/trunk/contrib/certupdate/test/test_certupdate.py

Added: CalendarServer/trunk/contrib/certupdate/__init__.py
===================================================================
--- CalendarServer/trunk/contrib/certupdate/__init__.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/certupdate/__init__.py	2011-04-18 21:18:50 UTC (rev 7322)
@@ -0,0 +1,15 @@
+##
+# Copyright (c) 2011 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##

Added: CalendarServer/trunk/contrib/certupdate/calendarcertupdate.py
===================================================================
--- CalendarServer/trunk/contrib/certupdate/calendarcertupdate.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/certupdate/calendarcertupdate.py	2011-04-18 21:18:50 UTC (rev 7322)
@@ -0,0 +1,135 @@
+#!/usr/bin/env python
+#
+# CertUpdate script for calendar / addresbook service.
+#
+# This script will be called with the path to the cert file in
+# /etc/certificates and also the keychain persistent reference if
+# we have one available. For the remove command, the handler
+# returns 0 = don't care, 1 = please keep, 2 = an error occurred.
+# For the replace command the handler returns
+# 0 = don't care/ cert replaced, 2 = an error occurred.
+#
+# Copyright (c) 2011 Apple Inc.  All Rights Reserved.
+#
+# IMPORTANT NOTE:  This file is licensed only for use on Apple-labeled
+# computers and is subject to the terms and conditions of the Apple
+# Software License Agreement accompanying the package this file is a
+# part of.  You may not port this file to another platform without
+# Apple's written consent.
+
+import datetime
+import os
+import subprocess
+import sys
+
+from plistlib import readPlist, readPlistFromString, writePlist
+
+LOG = "/var/log/caldavd/certupdate.log"
+SERVICE_NAME = "calendar"
+CALDAVD_PLIST = "/etc/caldavd/caldavd.plist"
+SERVER_ADMIN = "/usr/sbin/serveradmin"
+
+def main():
+
+    log(sys.argv)
+    numArgs = len(sys.argv) - 1
+    if numArgs == 3:
+        if sys.argv[1] != "remove":
+            die("Bad command line; 'remove' expected", 2)
+        if isThisMyCert(CALDAVD_PLIST, sys.argv[2]):
+            die("%s is in use by calendar" % (sys.argv[2],), 1)
+        else:
+            die("%s is not in use by calendar" % (sys.argv[2],), 0)
+
+    elif numArgs == 5:
+        if sys.argv[1] != "replace":
+            die("Bad command line; 'replace' expected", 2)
+        if isThisMyCert(CALDAVD_PLIST, sys.argv[2]):
+            try:
+                replaceCert(CALDAVD_PLIST, sys.argv[4])
+                restartService()
+                die("Replaced calendar cert with %s" % (sys.argv[4],), 0)
+            except Exception, e:
+                die("Error replacing calendar cert with %s: %s" % (sys.argv[4], e), 2)
+
+        else:
+            die("%s is not in use by calendar" % (sys.argv[2],), 0)
+
+    else:
+        # Wrong number of args
+        die("Bad command line; incorrect number of arguments", 2)
+
+
+def getMyCert(plistPath):
+    """
+    Return SSLCertificate from the plist at plistPath
+    """
+    plist = readPlist(plistPath)
+    return plist.get("SSLCertificate", None)
+
+
+def isThisMyCert(plistPath, otherCert):
+    """
+    Compare otherCert against SSLCertificate from the plist at plistPath
+    """
+    myCert = getMyCert(plistPath)
+    return otherCert == myCert
+
+
+def replaceCert(plistPath, otherCert):
+    """
+    Replace SSL settings in plist at plistPath based on otherCert path
+    """
+    log("Reading plist %s" % (plistPath,))
+    plist = readPlist(plistPath)
+    log("Read in plist %s" % (plistPath,))
+
+    basePath = otherCert[:-len("cert.pem")]
+    log("Base path is %s" % (basePath,))
+
+    log("Setting SSLCertificate to %s" % (otherCert,))
+    plist["SSLCertificate"] = otherCert
+
+    otherChain = basePath + "chain.pem"
+    log("Setting SSLAuthorityChain to %s" % (otherChain,))
+    plist["SSLAuthorityChain"] = otherChain
+
+    otherKey = basePath + "key.pem"
+    log("Setting SSLPrivateKey to %s" % (otherKey,))
+    plist["SSLPrivateKey"] = otherKey
+
+    log("Writing plist %s" % (plistPath,))
+    writePlist(plist, plistPath)
+
+
+def restartService():
+    """
+    Use serveradmin to restart the service.
+    """
+
+    log("Starting service via serveradmin")
+    ret = subprocess.call([SERVER_ADMIN, "restart", "calendar"])
+    log("serveradmin exited with %d" % (ret,))
+
+
+def log(msg):
+    try:
+        timestamp = datetime.datetime.now().strftime("%b %d %H:%M:%S")
+        msg = "calendarcertupdate: %s %s" % (timestamp, msg)
+        with open(LOG, 'a') as output:
+            output.write("%s\n" % (msg,)) # so it appears in our log
+    except IOError:
+        # Could not write to log
+        pass
+
+
+def die(msg, exitCode):
+    """
+    Log msg and exit with exitCode
+    """
+    log(msg)
+    sys.exit(exitCode)
+
+
+if __name__ == '__main__':
+    main()


Property changes on: CalendarServer/trunk/contrib/certupdate/calendarcertupdate.py
___________________________________________________________________
Added: svn:executable
   + *

Added: CalendarServer/trunk/contrib/certupdate/test/__init__.py
===================================================================
--- CalendarServer/trunk/contrib/certupdate/test/__init__.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/certupdate/test/__init__.py	2011-04-18 21:18:50 UTC (rev 7322)
@@ -0,0 +1,15 @@
+##
+# Copyright (c) 2011 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##

Added: CalendarServer/trunk/contrib/certupdate/test/test_certupdate.py
===================================================================
--- CalendarServer/trunk/contrib/certupdate/test/test_certupdate.py	                        (rev 0)
+++ CalendarServer/trunk/contrib/certupdate/test/test_certupdate.py	2011-04-18 21:18:50 UTC (rev 7322)
@@ -0,0 +1,65 @@
+##
+# Copyright (c) 2011 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
+
+from tempfile import mkstemp
+import os
+import twistedcaldav.test.util
+from plistlib import readPlist
+from contrib.certupdate.calendarcertupdate import (
+    getMyCert, isThisMyCert, replaceCert
+)
+
+samplePlist = """<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+    <key>SSLAuthorityChain</key>
+    <string>/etc/certificates/original.chain.pem</string>
+    <key>SSLCertificate</key>
+    <string>/etc/certificates/original.cert.pem</string>
+    <key>SSLPrivateKey</key>
+    <string>/etc/certificates/original.key.pem</string>
+</dict>
+</plist>
+"""
+
+class CertUpdateTests(twistedcaldav.test.util.TestCase):
+    """
+    Calendar Server Certificate Update Tests
+    """
+
+    def setUp(self):
+        self.fd, self.path = mkstemp(suffix=".plist")
+        out = os.fdopen(self.fd, "w")
+        out.write(samplePlist)
+        out.close()
+
+    def tearDown(self):
+        os.remove(self.path)
+
+    def test_getMyCert(self):
+        self.assertEquals("/etc/certificates/original.cert.pem", getMyCert(self.path))
+
+    def test_isThisMyCert(self):
+        self.assertTrue(isThisMyCert(self.path, "/etc/certificates/original.cert.pem"))
+        self.assertFalse(isThisMyCert(self.path, "/etc/certificates/not.cert.pem"))
+
+    def test_replaceCert(self):
+        replaceCert(self.path, "/etc/certificates/new.cert.pem")
+        plist = readPlist(self.path)
+        self.assertEquals(plist["SSLAuthorityChain"], "/etc/certificates/new.chain.pem")
+        self.assertEquals(plist["SSLCertificate"], "/etc/certificates/new.cert.pem")
+        self.assertEquals(plist["SSLPrivateKey"], "/etc/certificates/new.key.pem")
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110418/aaf4a47a/attachment.html>


More information about the calendarserver-changes mailing list