__init__.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. # This file is part of Radicale Server - Calendar Server
  2. # Copyright © 2008 Nicolas Kandel
  3. # Copyright © 2008 Pascal Halter
  4. # Copyright © 2008-2017 Guillaume Ayoub
  5. # Copyright © 2017-2018 Unrud<unrud@outlook.com>
  6. #
  7. # This library is free software: you can redistribute it and/or modify
  8. # it under the terms of the GNU General Public License as published by
  9. # the Free Software Foundation, either version 3 of the License, or
  10. # (at your option) any later version.
  11. #
  12. # This library is distributed in the hope that it will be useful,
  13. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. # GNU General Public License for more details.
  16. #
  17. # You should have received a copy of the GNU General Public License
  18. # along with Radicale. If not, see <http://www.gnu.org/licenses/>.
  19. """
  20. Authentication management.
  21. Default is htpasswd authentication.
  22. Apache's htpasswd command (httpd.apache.org/docs/programs/htpasswd.html)
  23. manages a file for storing user credentials. It can encrypt passwords using
  24. different methods, e.g. BCRYPT, MD5-APR1 (a version of MD5 modified for
  25. Apache), SHA1, or by using the system's CRYPT routine. The CRYPT and SHA1
  26. encryption methods implemented by htpasswd are considered as insecure. MD5-APR1
  27. provides medium security as of 2015. Only BCRYPT can be considered secure by
  28. current standards.
  29. MD5-APR1-encrypted credentials can be written by all versions of htpasswd (it
  30. is the default, in fact), whereas BCRYPT requires htpasswd 2.4.x or newer.
  31. The `is_authenticated(user, password)` function provided by this module
  32. verifies the user-given credentials by parsing the htpasswd credential file
  33. pointed to by the ``htpasswd_filename`` configuration value while assuming
  34. the password encryption method specified via the ``htpasswd_encryption``
  35. configuration value.
  36. The following htpasswd password encrpytion methods are supported by Radicale
  37. out-of-the-box:
  38. - plain-text (created by htpasswd -p...) -- INSECURE
  39. - CRYPT (created by htpasswd -d...) -- INSECURE
  40. - SHA1 (created by htpasswd -s...) -- INSECURE
  41. When passlib (https://pypi.python.org/pypi/passlib) is importable, the
  42. following significantly more secure schemes are parsable by Radicale:
  43. - MD5-APR1 (htpasswd -m...) -- htpasswd's default method
  44. - BCRYPT (htpasswd -B...) -- Requires htpasswd 2.4.x
  45. """
  46. from importlib import import_module
  47. from radicale.log import logger
  48. INTERNAL_TYPES = ("none", "remote_user", "http_x_remote_user", "htpasswd")
  49. def load(configuration):
  50. """Load the authentication manager chosen in configuration."""
  51. auth_type = configuration.get("auth", "type")
  52. if auth_type in INTERNAL_TYPES:
  53. module = "radicale.auth.%s" % auth_type
  54. else:
  55. module = auth_type
  56. try:
  57. class_ = import_module(module).Auth
  58. except Exception as e:
  59. raise RuntimeError("Failed to load authentication module %r: %s" %
  60. (module, e)) from e
  61. logger.info("Authentication type is %r", auth_type)
  62. return class_(configuration)
  63. class BaseAuth:
  64. def __init__(self, configuration):
  65. self.configuration = configuration
  66. def get_external_login(self, environ):
  67. """Optionally provide the login and password externally.
  68. ``environ`` a dict with the WSGI environment
  69. If ``()`` is returned, Radicale handles HTTP authentication.
  70. Otherwise, returns a tuple ``(login, password)``. For anonymous users
  71. ``login`` must be ``""``.
  72. """
  73. return ()
  74. def login(self, login, password):
  75. """Check credentials and map login to internal user
  76. ``login`` the login name
  77. ``password`` the password
  78. Returns the user name or ``""`` for invalid credentials.
  79. """
  80. raise NotImplementedError