changeset 3873:e5a9570d3001

secrets configuration refactored - see the snippet for an example usage
author Thomas Waldmann <tw AT waldmann-edv DOT de>
date Sat, 19 Jul 2008 13:29:16 +0200
parents 9eb4ffbe654d
children 87b63ed39102
files MoinMoin/action/cache.py MoinMoin/config/_tests/test_configs.py MoinMoin/config/multiconfig.py MoinMoin/events/_tests/test_events.py MoinMoin/events/jabbernotify.py MoinMoin/wikiutil.py MoinMoin/xmlrpc/ProcessMail.py MoinMoin/xmlrpc/RemoteScript.py MoinMoin/xmlrpc/__init__.py jabberbot/config.py tests/wikiconfig.py wiki/config/more_samples/mailimportconf.py wiki/config/more_samples/secrets_wikiconfig_snippet wikiconfig.py
diffstat 14 files changed, 69 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/action/cache.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/action/cache.py	Sat Jul 19 13:29:16 2008 +0200
@@ -89,8 +89,10 @@
     @param attachname: the filename of the attachment
     @param content: content data as unicode object (e.g. for page content or
                     parser section content)
+    @param secret: secret for hMAC calculation (default: use secret from cfg)
     """
-    secret = secret or 'nobodyexpectedsuchasecret'
+    if secret is None:
+        secret = request.cfg.secrets['action/cache']
     if content:
         hmac_data = content
     elif itemname is not None and attachname is not None:
--- a/MoinMoin/config/_tests/test_configs.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/config/_tests/test_configs.py	Sat Jul 19 13:29:16 2008 +0200
@@ -9,5 +9,6 @@
     def testConfigs(self):
         for cls in _tests:
             cls.data_dir = self.request.cfg.data_dir
+            cls.secrets = self.request.cfg.secrets
             # quite a bad hack to make _importPlugin succeed
             cls('MoinMoin')
--- a/MoinMoin/config/multiconfig.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/config/multiconfig.py	Sat Jul 19 13:29:16 2008 +0200
@@ -345,14 +345,6 @@
 
         # if we are to use the jabber bot, instantiate a server object for future use
         if self.jabber_enabled:
-
-            errmsg = "You must set a (long) secret string to send notifications!"
-            try:
-                if not self.secret:
-                    raise error.ConfigurationError(errmsg)
-            except AttributeError, err:
-                raise error.ConfigurationError(errmsg)
-
             from xmlrpclib import Server
             self.notification_server = Server(self.notification_bot_uri, )
 
@@ -370,6 +362,31 @@
         if self.url_prefix_local is None:
             self.url_prefix_local = self.url_prefix_static
 
+        secret_key_names = ['action/cache', 'wikiutil/tickets', 'xmlrpc/ProcessMail', 'xmlrpc/RemoteScript', ]
+        if self.jabber_enabled:
+            secret_key_names.append('jabberbot')
+
+        secret_min_length = 10
+        if isinstance(self.secrets, str):
+            if len(self.secrets) < secret_min_length:
+                raise error.ConfigurationError("The secrets = '...' wiki config setting is a way too short string (minimum length is %d chars)!" % (
+                    secret_min_length))
+            # for lazy people: set all required secrets to same value
+            secrets = {}
+            for key in secret_key_names:
+                secrets[key] = self.secrets
+            self.secrets = secrets
+
+        # we check if we have all secrets we need and that they have minimum length
+        for secret_key_name in secret_key_names:
+            try:
+                secret = self.secrets[secret_key_name]
+                if len(secret) < secret_min_length:
+                    raise ValueError
+            except (KeyError, ValueError):
+                raise error.ConfigurationError("You must set a (at least %d chars long) secret string for secrets['%s']!" % (
+                    secret_min_length, secret_key_name))
+
     _meta_dict = None
     def load_meta_dict(self):
         """ The meta_dict contains meta data about the wiki instance. """
@@ -677,6 +694,7 @@
      "list of auth objects, to be called in this order (see HelpOnAuthentication)"),
     ('auth_methods_trusted', ['http', 'xmlrpc_applytoken'],
      'authentication methods for which users should be included in the special "Trusted" ACL group.'),
+    ('secrets', '', 'Either a long shared secret string used for multiple purposes or a dict {"purpose": "longsecretstring", ...} for setting up different shared secrets for different purposes. REQUIRED!'),
     ('DesktopEdition',
      False,
      "if True, give all local users special powers - ''only use this for a local desktop wiki!''"),
@@ -1145,7 +1163,6 @@
       ('smarthost', None, "Address of SMTP server to use for sending mail (None = don't use SMTP server)."),
       ('sendmail', None, "sendmail command to use for sending mail (None = don't use sendmail)"),
 
-      ('import_secret', "", "Shared secret for mail importing"),
       ('import_subpage_template', u"$from-$date-$subject", "Create subpages using this template when importing mail."),
       ('import_pagename_search', ['subject', 'to', ], "Where to look for target pagename specification."),
       ('import_pagename_envelope', u"%s", "Use this to add some fixed prefix/postfix to the generated target pagename."),
--- a/MoinMoin/events/_tests/test_events.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/events/_tests/test_events.py	Sat Jul 19 13:29:16 2008 +0200
@@ -59,7 +59,7 @@
 
     event = events.UserCreatedEvent(request, User(request))
     request.cfg.notification_server = server_dummy()
-    request.cfg.secret = "dummy"
+    request.cfg.secrets = "thisisnotsecret"
 
     jabbernotify.handle_user_created(event)
     assert request.cfg.notification_server.sent is True
--- a/MoinMoin/events/jabbernotify.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/events/jabbernotify.py	Sat Jul 19 13:29:16 2008 +0200
@@ -50,11 +50,12 @@
 
     request = event.request
     server = request.cfg.notification_server
+    secret = request.cfg.secrets['jabberbot']
     try:
         if isinstance(event, ev.JabberIDSetEvent):
-            server.addJIDToRoster(request.cfg.secret, event.jid)
+            server.addJIDToRoster(secret, event.jid)
         else:
-            server.removeJIDFromRoster(request.cfg.secret, event.jid)
+            server.removeJIDFromRoster(secret, event.jid)
     except xmlrpclib.Error, err:
         logging.error("XML RPC error: %s" % str(err))
     except Exception, err:
@@ -197,7 +198,7 @@
         raise ValueError("url_list must be of type list!")
 
     try:
-        server.send_notification(request.cfg.secret, jids, notification)
+        server.send_notification(request.cfg.secrets['jabberbot'], jids, notification)
         return True
     except xmlrpclib.Error, err:
         logging.error("XML RPC error: %s" % str(err))
--- a/MoinMoin/wikiutil.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/wikiutil.py	Sat Jul 19 13:29:16 2008 +0200
@@ -2432,7 +2432,7 @@
 ########################################################################
 
 def createTicket(request, tm=None, action=None):
-    """ Create a ticket using a site-specific secret (the config)
+    """ Create a ticket using a configured secret
 
         @param tm: unix timestamp (optional, uses current time if not given)
         @param action: action name (optional, uses current action if not given)
@@ -2457,20 +2457,12 @@
         except:
             action = 'None'
 
+    secret = request.cfg.secrets['wikiutil/tickets']
+    digest = sha.new(secret)
 
     ticket = "%s.%s.%s" % (tm, pagename, action)
-    digest = sha.new()
     digest.update(ticket)
 
-    varnames = ['data_dir', 'data_underlay_dir', 'language_default',
-                'mail_smarthost', 'mail_from', 'page_front_page',
-                'theme_default', 'sitename', 'logo_string',
-                'interwikiname', 'user_homewiki', 'acl_rights_before', ]
-    for varname in varnames:
-        var = getattr(request.cfg, varname, None)
-        if isinstance(var, (str, unicode)):
-            digest.update(repr(var))
-
     return "%s.%s" % (ticket, digest.hexdigest())
 
 
--- a/MoinMoin/xmlrpc/ProcessMail.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/xmlrpc/ProcessMail.py	Sat Jul 19 13:29:16 2008 +0200
@@ -16,10 +16,7 @@
     secret = xmlrpcobj._instr(secret)
     mail = str(mail)
 
-    if not request.cfg.mail_import_secret:
-        return u"No password set"
-
-    if request.cfg.mail_import_secret != secret:
+    if request.cfg.secrets['xmlrpc/ProcessMail'] != secret:
         return u"Invalid password"
 
     try:
--- a/MoinMoin/xmlrpc/RemoteScript.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/xmlrpc/RemoteScript.py	Sat Jul 19 13:29:16 2008 +0200
@@ -15,9 +15,7 @@
     request = xmlrpcobj.request
     their_secret = xmlrpcobj._instr(their_secret)
 
-    our_secret = request.cfg.remote_script_secret
-    if not our_secret:
-        return u"No password set"
+    our_secret = request.cfg.secrets['xmlrpc/RemoteScript']
 
     if our_secret != their_secret:
         return u"Invalid password"
--- a/MoinMoin/xmlrpc/__init__.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/MoinMoin/xmlrpc/__init__.py	Sat Jul 19 13:29:16 2008 +0200
@@ -702,7 +702,7 @@
 
         @param jid: a bare Jabber ID
         """
-        if self.cfg.secret != secret:
+        if self.cfg.secrets['jabberbot'] != secret:
             return ""
 
         u = self.request.handle_jid_auth(jid)
--- a/jabberbot/config.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/jabberbot/config.py	Sat Jul 19 13:29:16 2008 +0200
@@ -41,9 +41,8 @@
 
     # A secret shared with Wiki , must be the same in both
     # configs for communication to work.
-    #
-    # CHANGE IT TO A LONG RANDOM STRING, OR YOU WILL HAVE A SECURITY ISSUE!
-    secret = u""
+    secret = "use same string as in secrets setting in wiki config"
+
 
     # Maximum number of items in service discovery cache (XEP-0115)
     disco_cache_size = 100
--- a/tests/wikiconfig.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/tests/wikiconfig.py	Sat Jul 19 13:29:16 2008 +0200
@@ -20,6 +20,9 @@
     data_underlay_dir = os.path.join(_base_dir, "underlay")
 
     show_hosts = 1
+
+    secrets = 'some not secret string just to make tests happy'
+
     # used to check if it is really a wiki we may modify
     is_test_wiki = True
 
--- a/wiki/config/more_samples/mailimportconf.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/wiki/config/more_samples/mailimportconf.py	Sat Jul 19 13:29:16 2008 +0200
@@ -1,7 +1,7 @@
 # This is the configuration file for the mail import client
 
 # This secret has to be known by the wiki server
-mail_import_secret = u"foo"
+mail_import_secret = "use same string as in secrets setting in wiki config"
 
 # The target wiki URL
 mail_import_url = u"http://localhost/?action=xmlrpc2"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/wiki/config/more_samples/secrets_wikiconfig_snippet	Sat Jul 19 13:29:16 2008 +0200
@@ -0,0 +1,21 @@
+    # MoinMoin uses (shared) secrets in some subsystems. These secrets are NOT passwords, you
+    # will never have to enter them as a moin wiki user. Don't re-use some of your passwords
+    # as a secret, just use some long random string.
+    # For example, the 'action/cache' secret is used to calculate unpredictable cache access keys.
+    # The 'mailimport' secret is a shared secret for importing e-mail via xmlrpc (you will have
+    # to copy it to the mailimporter script).
+    #
+    # IMPORTANT: Don't use the strings below, they are NOT secret as they are part of the moin
+    #            distribution archive's config samples.
+
+    # For low security requirements (all subsystems will use this same secret then):
+    secrets = 'I&TNny^UVBUasdK^NN&T^^RyyujB^UN^B^UNBasrgrttdNFU^BFNasad'
+
+    # For higher security requirements, you can use different secrets for different subsystems:
+    secrets = {
+            'action/cache':'35gnb35h8g0835hgnbe035g85b8',
+            'wikiutil/tickets': 'asdasdvarebtbertbaetbtrbetgrergfqe3r',
+            'jabberbot': 'asasegs5hg5h64he56h5e6j5e6uhgsewhye56h5jne56hj56',
+            'xmlrpc/ProcessMail': '324tgw2g3q3gw3g3wg3353ehb',
+            'xmlrpc/RemoteScript': 'kuIUYBO85jtf932l:-0aGf',
+    }
--- a/wikiconfig.py	Sat Jul 19 10:26:47 2008 +0200
+++ b/wikiconfig.py	Sat Jul 19 13:29:16 2008 +0200
@@ -23,9 +23,8 @@
     page_front_page = u'FrontPage' # change to some better value
     # ^^^ DON'T TOUCH THIS EXCEPT IF YOU KNOW WHAT YOU DO ^^^
 
-
     # Add your configuration items here.
-
+    secrets = 'This string is NOT a secret, please make up your own, long, random secret string!'
 
 
 # DEVELOPERS! Do not add your configuration items there,