commit: af3bf8a4628c0b2981d69f624e3be298adc7dfe6
parent 5539fea3bb0d272b4cefc2b72755cb3cd285cc67
Author: Mark Felder <feld@feld.me>
Date: Sun, 15 Sep 2024 13:56:16 -0400
Support implicit TLS connections
Update docs to clarify that the :ssl option is also for modern TLS, but the :tls option is only for STARTTLS
These options may benefit from being renamed but they match upstream terminology.
Diffstat:
3 files changed, 31 insertions(+), 24 deletions(-)
diff --git a/changelog.d/ldaps.fix b/changelog.d/ldaps.fix
@@ -0,0 +1 @@
+LDAPS connections (implicit TLS) are now supported.
diff --git a/docs/configuration/cheatsheet.md b/docs/configuration/cheatsheet.md
@@ -968,9 +968,9 @@ Pleroma account will be created with the same name as the LDAP user name.
* `enabled`: enables LDAP authentication
* `host`: LDAP server hostname
* `port`: LDAP port, e.g. 389 or 636
-* `ssl`: true to use SSL, usually implies the port 636
+* `ssl`: true to use implicit SSL/TLS, usually port 636
* `sslopts`: additional SSL options
-* `tls`: true to start TLS, usually implies the port 389
+* `tls`: true to use explicit TLS (STARTTLS), usually port 389
* `tlsopts`: additional TLS options
* `base`: LDAP base, e.g. "dc=example,dc=com"
* `uid`: LDAP attribute name to authenticate the user, e.g. when "cn", the filter will be "cn=username,base"
diff --git a/lib/pleroma/web/auth/ldap_authenticator.ex b/lib/pleroma/web/auth/ldap_authenticator.ex
@@ -40,34 +40,39 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do
host = Keyword.get(ldap, :host, "localhost")
port = Keyword.get(ldap, :port, 389)
ssl = Keyword.get(ldap, :ssl, false)
- sslopts = Keyword.get(ldap, :sslopts, [])
- tlsopts = Keyword.get(ldap, :tlsopts, [])
+ tls = Keyword.get(ldap, :tls, false)
cacertfile = Keyword.get(ldap, :cacertfile) || CAStore.file_path()
- options =
- [{:port, port}, {:ssl, ssl}, {:timeout, @connection_timeout}] ++
- if sslopts != [], do: [{:sslopts, sslopts}], else: []
+ default_secure_opts = [
+ verify: :verify_peer,
+ cacerts: decode_certfile(cacertfile),
+ customize_hostname_check: [
+ fqdn_fun: fn _ -> to_charlist(host) end
+ ]
+ ]
- cacerts = decode_certfile(cacertfile)
+ sslopts = Keyword.merge(default_secure_opts, Keyword.get(ldap, :sslopts, []))
+ tlsopts = Keyword.merge(default_secure_opts, Keyword.get(ldap, :tlsopts, []))
+
+ # :sslopts can only be included in :eldap.open/2 when {ssl: true}
+ # or the connection will fail
+ options =
+ if ssl do
+ [{:port, port}, {:ssl, ssl}, {:sslopts, sslopts}, {:timeout, @connection_timeout}]
+ else
+ [{:port, port}, {:ssl, ssl}, {:timeout, @connection_timeout}]
+ end
case :eldap.open([to_charlist(host)], options) do
{:ok, connection} ->
- try do
- if Keyword.get(ldap, :tls, false) do
+ cond do
+ ssl ->
:application.ensure_all_started(:ssl)
+ tls ->
case :eldap.start_tls(
connection,
- Keyword.merge(
- [
- verify: :verify_peer,
- cacerts: cacerts,
- customize_hostname_check: [
- fqdn_fun: fn _ -> to_charlist(host) end
- ]
- ],
- tlsopts
- ),
+ tlsopts,
@connection_timeout
) do
:ok ->
@@ -75,14 +80,15 @@ defmodule Pleroma.Web.Auth.LDAPAuthenticator do
error ->
Logger.error("Could not start TLS: #{inspect(error)}")
+ :eldap.close(connection)
end
- end
- bind_user(connection, ldap, name, password)
- after
- :eldap.close(connection)
+ true ->
+ :ok
end
+ bind_user(connection, ldap, name, password)
+
{:error, error} ->
Logger.error("Could not open LDAP connection: #{inspect(error)}")
{:error, {:ldap_connection_error, error}}