Просмотр исходного кода

Merge pull request #1733 from pbiering/auth-default-denyall

Auth default type changed to denyall
Peter Bieringer 11 месяцев назад
Родитель
Сommit
a3880480a9
7 измененных файлов с 125 добавлено и 21 удалено
  1. 1 0
      CHANGELOG.md
  2. 116 19
      DOCUMENTATION.md
  3. 1 1
      config
  4. 1 1
      radicale/config.py
  5. 2 0
      radicale/tests/test_base.py
  6. 3 0
      radicale/tests/test_rights.py
  7. 1 0
      radicale/tests/test_storage.py

+ 1 - 0
CHANGELOG.md

@@ -18,6 +18,7 @@
 * Improve: catch htpasswd hash verification errors
 * Improve: add support for more bcrypt algos on autodetection, extend logging for autodetection fallback to PLAIN in case of hash length is not matching
 * Add: warning in case of started standalone and not listen on loopback interface but trusting external authentication
+* Adjust: Change default [auth] type from "none" to "denyall" for secure-by-default
 
 ## 3.4.1
 * Add: option [auth] dovecot_connection_type / dovecot_host / dovecot_port

+ 116 - 19
DOCUMENTATION.md

@@ -135,6 +135,8 @@ Note: some OS contain unpatched `htpasswd` (< 2.4.59) without supporting SHA-256
 (e.g. Ubuntu LTS 22), in this case use '-B' for "bcrypt" hash method or stay with
 insecure MD5 (default) or SHA-1 ('-s').
 
+Note that support of SHA-256 or SHA-512 was introduced with 3.1.9
+
 ```bash
 # Create a new htpasswd file with the user "user1" using SHA-512 as hash method
 $ htpasswd -5 -c /path/to/users user1
@@ -763,10 +765,12 @@ to secure TCP traffic between Radicale and a reverse proxy. If you want to
 authenticate users with client-side certificates, you also have to write an
 authentication plugin that extracts the username from the certificate.
 
-Default:
+Default: (unset)
 
 ##### protocol
 
+_(>= 3.3.1)_
+
 Accepted SSL protocol (maybe not all supported by underlying OpenSSL version)
 Example for secure configuration: ALL -SSLv3 -TLSv1 -TLSv1.1
 Format: Apache SSLProtocol list (from "mod_ssl")
@@ -775,6 +779,8 @@ Default: (system default)
 
 ##### ciphersuite
 
+_(>= 3.3.1)_
+
 Accepted SSL ciphersuite (maybe not all supported by underlying OpenSSL version)
 Example for secure configuration: DHE:ECDHE:-NULL:-SHA
 Format: OpenSSL cipher list (see also "man openssl-ciphers")
@@ -783,6 +789,8 @@ Default: (system-default)
 
 ##### script_name
 
+_(>= 3.5.0)_
+
 Strip script name from URI if called by reverse proxy
 
 Default: (taken from HTTP_X_SCRIPT_NAME or SCRIPT_NAME)
@@ -812,6 +820,9 @@ Available backends:
 `none`
 : Just allows all usernames and passwords.
 
+`denyall`  _(>= 3.2.2)_
+: Just denies all usernames and passwords.
+
 `htpasswd`
 : Use an
   [Apache htpasswd file](https://httpd.apache.org/docs/current/programs/htpasswd.html)
@@ -827,26 +838,27 @@ Available backends:
   authentication. This can be used to provide the username from a reverse
   proxy.
 
-`ldap`
+`ldap` _(>= 3.3.0)_
 : Use a LDAP or AD server to authenticate users.
 
-`dovecot`
+`dovecot` _(>= 3.3.1)_
 : Use a Dovecot server to authenticate users.
 
-`imap`
+`imap` _(>= 3.4.1)_
 : Use an IMAP server to authenticate users.
 
-`oauth2`
+`oauth2` _(>= 3.5.0)_
 : Use an OAuth2 server to authenticate users.
 
-`pam`
+`pam` _(>= 3.5.0)_
 : Use local PAM to authenticate users.
 
-
-Default: `none`
+Default: `none` _(< 3.5.0)_ `denyall` _(>= 3.5.0)_
 
 ##### cache_logins
 
+_(>= 3.4.0)_
+
 Cache successful/failed logins until expiration time. Enable this to avoid
 overload of authentication backends.
 
@@ -854,12 +866,16 @@ Default: `false`
 
 ##### cache_successful_logins_expiry
 
+_(>= 3.4.0)_
+
 Expiration time of caching successful logins in seconds
 
 Default: `15`
 
 ##### cache_failed_logins_expiry
 
+_(>= 3.4.0)_
+
 Expiration time of caching failed logins in seconds
 
 Default: `90`
@@ -894,19 +910,21 @@ Available methods:
 `md5`
 : This uses an iterated MD5 digest of the password with a salt (nowadays insecure).
 
-`sha256`
+`sha256` _(>= 3.1.9)_
 : This uses an iterated SHA-256 digest of the password with a salt.
 
-`sha512`
+`sha512` _(>= 3.1.9)_
 : This uses an iterated SHA-512 digest of the password with a salt.
 
-`autodetect`
+`autodetect` _(>= 3.1.9)_
 : This selects autodetection of method per entry.
 
-Default: `autodetect`
+Default: `md5` _(< 3.3.0)_ `autodetect` _(>= 3.3.0)_
 
 ##### htpasswd_cache
 
+_(>= 3.4.0)_
+
 Enable caching of htpasswd file based on size and mtime_ns
 
 Default: `False`
@@ -925,48 +943,64 @@ Default: `Radicale - Password Required`
 
 ##### ldap_uri
 
+_(>= 3.3.0)_
+
 The URI to the ldap server
 
 Default: `ldap://localhost`
 
 ##### ldap_base
 
+_(>= 3.3.0)_
+
 LDAP base DN of the ldap server. This parameter must be provided if auth type is ldap.
 
 Default:
 
 ##### ldap_reader_dn
 
+_(>= 3.3.0)_
+
 The DN of a ldap user with read access to get the user accounts. This parameter must be provided if auth type is ldap.
 
 Default:
 
 ##### ldap_secret
 
+_(>= 3.3.0)_
+
 The password of the ldap_reader_dn. Either this parameter or `ldap_secret_file` must be provided if auth type is ldap.
 
 Default:
 
 ##### ldap_secret_file
 
+_(>= 3.3.0)_
+
 Path of the file containing the password of the ldap_reader_dn. Either this parameter or `ldap_secret` must be provided if auth type is ldap.
 
 Default:
 
 ##### ldap_filter
 
+_(>= 3.3.0)_
+
 The search filter to find the user DN to authenticate by the username. User '{0}' as placeholder for the user name.
 
 Default: `(cn={0})`
 
 ##### ldap_user_attribute
 
+_(>= 3.4.0)_
+
 The LDAP attribute whose value shall be used as the user name after successful authentication
 
 Default: not set, i.e. the login name given is used directly.
 
 ##### ldap_groups_attribute
 
+_(>= 3.4.0)_
+
 The LDAP attribute to read the group memberships from in the authenticated user's LDAP entry.
 
 If set, load the LDAP group memberships from the attribute given
@@ -978,28 +1012,36 @@ This also gives you access to the group calendars, if they exist.
 
 Use 'memberOf' if you want to load groups on Active Directory and alikes, 'groupMembership' on Novell eDirectory, ...
 
-Default: unset
+Default: (unset)
 
 ##### ldap_use_ssl
 
+_(>= 3.3.0)_
+
 Use ssl on the ldap connection
 
 Default: False
 
 ##### ldap_ssl_verify_mode
 
+_(>= 3.3.0)_
+
 The certificate verification mode. NONE, OPTIONAL or REQUIRED
 
 Default: REQUIRED
 
 ##### ldap_ssl_ca_file
 
+_(>= 3.3.0)_
+
 The path to the CA file in pem format which is used to certificate the server certificate
 
 Default:
 
 ##### dovecot_connection_type = AF_UNIX
 
+_(>= 3.4.1)_
+
 Connection type for dovecot authentication (AF_UNIX|AF_INET|AF_INET6)
 
 Note: credentials are transmitted in cleartext
@@ -1008,48 +1050,64 @@ Default: `AF_UNIX`
 
 ##### dovecot_socket
 
+_(>= 3.3.1)_
+
 The path to the Dovecot client authentication socket (eg. /run/dovecot/auth-client on Fedora). Radicale must have read / write access to the socket.
 
 Default: `/var/run/dovecot/auth-client`
 
 ##### dovecot_host
 
+_(>= 3.4.1)_
+
 Host of via network exposed dovecot socket
 
 Default: `localhost`
 
 ##### dovecot_port
 
+_(>= 3.4.1)_
+
 Port of via network exposed dovecot socket
 
 Default: `12345`
 
 ##### imap_host
 
+_(>= 3.4.1)_
+
 IMAP server hostname: address | address:port | [address]:port | imap.server.tld
 
 Default: `localhost`
 
 ##### imap_security
 
+_(>= 3.4.1)_
+
 Secure the IMAP connection: tls | starttls | none
 
 Default: `tls`
 
 ##### oauth2_token_endpoint
 
+_(>= 3.5.0)_
+
 OAuth2 token endpoint URL
 
 Default:
 
 ##### pam_service
 
+_(>= 3.5.0)_
+
 PAM service
 
 Default: radicale
 
 ##### pam_group_membership
 
+_(>= 3.5.0)_
+
 PAM group user should be member of
 
 Default:
@@ -1065,6 +1123,8 @@ Note: cannot be enabled together with `uc_username`
 
 ##### uc_username
 
+_(>= 3.3.2)_
+
 Сonvert username to uppercase, must be true for case-insensitive auth
 providers like ldap, kerberos
 
@@ -1074,6 +1134,8 @@ Note: cannot be enabled together with `lc_username`
 
 ##### strip_domain
 
+_(>= 3.2.3)_
+
 Strip domain from username
 
 Default: `False`
@@ -1115,7 +1177,7 @@ File for the rights backend `from_file`.  See the
 
 ##### permit_delete_collection
 
-(New since 3.1.9)
+_(>= 3.1.9)_
 
 Global control of permission to delete complete collection (default: True)
 
@@ -1124,7 +1186,7 @@ If True it can be forbidden by permissions per section with: d
 
 ##### permit_overwrite_collection
 
-(New since 3.3.0)
+_(>= 3.3.0)_
 
 Global control of permission to overwrite complete collection (default: True)
 
@@ -1156,6 +1218,8 @@ Default: `/var/lib/radicale/collections`
 
 ##### filesystem_cache_folder
 
+_(>= 3.3.2)_
+
 Folder for storing cache of local collections, created if not present
 
 Default: (filesystem_folder)
@@ -1166,6 +1230,8 @@ Note: can be used on multi-instance setup to cache files on local node (see belo
 
 ##### use_cache_subfolder_for_item
 
+_(>= 3.3.2)_
+
 Use subfolder `collection-cache` for cache file structure of 'item' instead of inside collection folders, created if not present
 
 Default: `False`
@@ -1174,6 +1240,8 @@ Note: can be used on multi-instance setup to cache 'item' on local node
 
 ##### use_cache_subfolder_for_history
 
+_(>= 3.3.2)_
+
 Use subfolder `collection-cache` for cache file structure of 'history' instead of inside collection folders, created if not present
 
 Default: `False`
@@ -1182,6 +1250,8 @@ Note: use only on single-instance setup, will break consistency with client in m
 
 ##### use_cache_subfolder_for_synctoken
 
+_(>= 3.3.2)_
+
 Use subfolder `collection-cache` for cache file structure of 'sync-token' instead of inside collection folders, created if not present
 
 Default: `False`
@@ -1190,6 +1260,8 @@ Note: use only on single-instance setup, will break consistency with client in m
 
 ##### use_mtime_and_size_for_item_cache
 
+_(>= 3.3.2)_
+
 Use last modifiction time (nanoseconds) and size (bytes) for 'item' cache instead of SHA256 (improves speed)
 
 Default: `False`
@@ -1200,6 +1272,8 @@ Note: conversion is done on access, bulk conversion can be done offline using st
 
 ##### folder_umask
 
+_(>= 3.3.2)_
+
 Use configured umask for folder creation (not applicable for OS Windows)
 
 Default: (system-default, usual `0022`)
@@ -1214,6 +1288,8 @@ Default: `2592000`
 
 ##### skip_broken_item
 
+_(>= 3.2.2)_
+
 Skip broken item instead of triggering an exception
 
 Default: `True`
@@ -1274,7 +1350,7 @@ Set the logging level.
 
 Available levels: **debug**, **info**, **warning**, **error**, **critical**
 
-Default: `warning`
+Default: `warning` _(< 3.2.0)_ `info` _(>= 3.2.0)_
 
 ##### mask_passwords
 
@@ -1284,30 +1360,40 @@ Default: `True`
 
 ##### bad_put_request_content
 
+_(>= 3.2.1)_
+
 Log bad PUT request content (for further diagnostics)
 
 Default: `False`
 
 ##### backtrace_on_debug
 
+_(>= 3.2.2)_
+
 Log backtrace on level=debug
 
 Default: `False`
 
 ##### request_header_on_debug
 
+_(>= 3.2.2)_
+
 Log request on level=debug
 
 Default: `False`
 
 ##### request_content_on_debug
 
+_(>= 3.2.2)_
+
 Log request on level=debug
 
 Default: `False`
 
 ##### response_content_on_debug
 
+_(>= 3.2.2)_
+
 Log response on level=debug
 
 Default: `False`
@@ -1320,6 +1406,8 @@ Default: `False`
 
 ##### storage_cache_actions_on_debug
 
+_(>= 3.3.2)_
+
 Log storage cache actions on level=debug
 
 Default: `False`
@@ -1345,13 +1433,15 @@ Available types:
 `none`
 : Disabled. Nothing will be notified.
 
-`rabbitmq`
+`rabbitmq` _(>= 3.2.0)_
 : Push the message to the rabbitmq server.
 
 Default: `none`
 
 ##### rabbitmq_endpoint
 
+_(>= 3.2.0)_
+
 End-point address for rabbitmq server.
 Ex: amqp://user:password@localhost:5672/
 
@@ -1359,19 +1449,26 @@ Default:
 
 ##### rabbitmq_topic
 
+_(>= 3.2.0)_
+
 RabbitMQ topic to publish message.
 
 Default:
 
 ##### rabbitmq_queue_type
 
+_(>= 3.2.0)_
+
 RabbitMQ queue type for the topic.
 
 Default: classic
 
 #### reporting
+
 ##### max_freebusy_occurrence
 
+_(>= 3.2.3)_
+
 When returning a free-busy report, a list of busy time occurrences are
 generated based on a given time frame. Large time frames could
 generate a lot of occurrences based on the time frame supplied. This
@@ -1586,8 +1683,8 @@ The following `permissions` are recognized:
   (CalDAV/CardDAV is susceptible to expensive search requests)
 * **W:** write collections (excluding address books and calendars)
 * **w:** write address book and calendar collections
-* **D:** permit delete of collection in case permit_delete_collection=False
-* **d:** forbid delete of collection in case permit_delete_collection=True
+* **D:** permit delete of collection in case permit_delete_collection=False _(>= 3.3.0)_
+* **d:** forbid delete of collection in case permit_delete_collection=True _(>= 3.3.0)_
 * **O:** permit overwrite of collection in case permit_overwrite_collection=False
 * **o:** forbid overwrite of collection in case permit_overwrite_collection=True
 

+ 1 - 1
config

@@ -63,7 +63,7 @@
 
 # Authentication method
 # Value: none | htpasswd | remote_user | http_x_remote_user | dovecot | ldap | oauth2 | pam | denyall
-#type = none
+#type = denyall
 
 # Cache logins for until expiration time
 #cache_logins = false

+ 1 - 1
radicale/config.py

@@ -206,7 +206,7 @@ DEFAULT_CONFIG_SCHEMA: types.CONFIG_SCHEMA = OrderedDict([
             "type": str})])),
     ("auth", OrderedDict([
         ("type", {
-            "value": "none",
+            "value": "denyall",
             "help": "authentication method (" + "|".join(auth.INTERNAL_TYPES) + ")",
             "type": str_or_callable,
             "internal": auth.INTERNAL_TYPES}),

+ 2 - 0
radicale/tests/test_base.py

@@ -1714,6 +1714,7 @@ permissions: RrWw""")
         assert status == 200 and prop.text == "text/vcard;charset=utf-8"
 
     def test_authorization(self) -> None:
+        self.configure({"auth": {"type": "none"}})
         _, responses = self.propfind("/", """\
 <?xml version="1.0" encoding="utf-8"?>
 <propfind xmlns="DAV:">
@@ -1740,6 +1741,7 @@ permissions: RrWw""")
 
     def test_principal_collection_creation(self) -> None:
         """Verify existence of the principal collection."""
+        self.configure({"auth": {"type": "none"}})
         self.propfind("/user/", login="user:")
 
     def test_authentication_current_user_principal_hack(self) -> None:

+ 3 - 0
radicale/tests/test_rights.py

@@ -143,6 +143,7 @@ collection: public/[^/]*
 permissions: i""")
         self.configure({"rights": {"type": "from_file",
                                    "file": rights_file_path}})
+        self.configure({"auth": {"type": "none"}})
         self.mkcalendar("/tmp/calendar", login="tmp:bepo")
         self.mkcol("/public", login="tmp:bepo")
         self.mkcalendar("/public/calendar", login="tmp:bepo")
@@ -165,6 +166,7 @@ permissions: i""")
         Items are allowed at "/.../.../...".
 
         """
+        self.configure({"auth": {"type": "none"}})
         self.mkcalendar("/", check=401)
         self.mkcalendar("/user/", check=401)
         self.mkcol("/user/")
@@ -175,6 +177,7 @@ permissions: i""")
 
     def test_put_collections_and_items(self) -> None:
         """Test rights for creation of calendars and items with PUT."""
+        self.configure({"auth": {"type": "none"}})
         self.put("/user/", "BEGIN:VCALENDAR\r\nEND:VCALENDAR", check=401)
         self.mkcol("/user/")
         self.put("/user/calendar/", "BEGIN:VCALENDAR\r\nEND:VCALENDAR")

+ 1 - 0
radicale/tests/test_storage.py

@@ -77,6 +77,7 @@ class TestMultiFileSystem(BaseTest):
         """Verify that the hooks runs when a new user is created."""
         self.configure({"storage": {"hook": "mkdir %s" % os.path.join(
             "collection-root", "created_by_hook")}})
+        self.configure({"auth": {"type": "none"}})
         self.propfind("/", login="user:")
         self.propfind("/created_by_hook/")