From c1576c90f439b51dad59a00caf9618f8946ed6d3 Mon Sep 17 00:00:00 2001 From: Feng Lee Date: Mon, 11 May 2015 16:36:57 +0800 Subject: [PATCH] ldap plugin --- plugins/emqttd_auth_ldap/README.md | 9 ++ plugins/emqttd_auth_ldap/etc/app.config | 12 +++ .../src/emqttd_auth_ldap.app.src | 12 +++ .../emqttd_auth_ldap/src/emqttd_auth_ldap.erl | 89 +++++++++++++++++++ .../src/emqttd_auth_ldap_app.erl | 58 ++++++++++++ 5 files changed, 180 insertions(+) create mode 100644 plugins/emqttd_auth_ldap/README.md create mode 100644 plugins/emqttd_auth_ldap/etc/app.config create mode 100644 plugins/emqttd_auth_ldap/src/emqttd_auth_ldap.app.src create mode 100644 plugins/emqttd_auth_ldap/src/emqttd_auth_ldap.erl create mode 100644 plugins/emqttd_auth_ldap/src/emqttd_auth_ldap_app.erl diff --git a/plugins/emqttd_auth_ldap/README.md b/plugins/emqttd_auth_ldap/README.md new file mode 100644 index 000000000..d4bc562e6 --- /dev/null +++ b/plugins/emqttd_auth_ldap/README.md @@ -0,0 +1,9 @@ +# emqttd_auth_ldap + +LDAP Authentication Plugin. + +## Plugin config + +``` + +``` diff --git a/plugins/emqttd_auth_ldap/etc/app.config b/plugins/emqttd_auth_ldap/etc/app.config new file mode 100644 index 000000000..ac582d7d4 --- /dev/null +++ b/plugins/emqttd_auth_ldap/etc/app.config @@ -0,0 +1,12 @@ +[ + {emqttd_auth_ldap, [ + {servers, ["localhost"]}, + {port, 389}, + {timeout, 30}, + {user_dn, "uid=$u,ou=People,dc=example,dc=com"}, + {ssl, fasle}, + {sslopts, [ + {"certfile", "ssl.crt"}, + {"keyfile", "ssl.key"}]} + ]} +]. diff --git a/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap.app.src b/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap.app.src new file mode 100644 index 000000000..61aca3ac0 --- /dev/null +++ b/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap.app.src @@ -0,0 +1,12 @@ +{application, emqttd_auth_ldap, + [ + {description, "emqttd LDA Authentication Plugin"}, + {vsn, "1.0"}, + {registered, []}, + {applications, [ + kernel, + stdlib + ]}, + {mod, {emqttd_auth_ldap_app, []}}, + {env, []} +]}. diff --git a/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap.erl b/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap.erl new file mode 100644 index 000000000..02fb4d121 --- /dev/null +++ b/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap.erl @@ -0,0 +1,89 @@ +%%%----------------------------------------------------------------------------- +%%% Copyright (c) 2012-2015 eMQTT.IO, All Rights Reserved. +%%% +%%% Permission is hereby granted, free of charge, to any person obtaining a copy +%%% of this software and associated documentation files (the "Software"), to deal +%%% in the Software without restriction, including without limitation the rights +%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%%% copies of the Software, and to permit persons to whom the Software is +%%% furnished to do so, subject to the following conditions: +%%% +%%% The above copyright notice and this permission notice shall be included in all +%%% copies or substantial portions of the Software. +%%% +%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +%%% SOFTWARE. +%%%----------------------------------------------------------------------------- +%%% @doc +%%% LDAP Authentication Module. +%%% +%%% @end +%%%----------------------------------------------------------------------------- +-module(emqttd_auth_ldap). + +-author("Feng Lee "). + +-include_lib("emqttd/include/emqttd.hrl"). + +-behaviour(emqttd_auth_mod). + +-export([init/1, check/3, description/0]). + +-record(state, {servers, user_dn, options}). + +init(Opts) -> + Servers = proplists:get_value(servers, Opts, ["localhost"]), + Port = proplists:get_value(port, Opts, 389), + Timeout = proplists:get_value(timeout, Opts, 30), + UserDn = proplists:get_value(user_dn, Opts), + LdapOpts = + case proplists:get_value(ssl, Opts, false) of + true -> + SslOpts = proplists:get_value(sslopts, Opts), + [{port, Port}, {timeout, Timeout}, {sslopts, SslOpts}]; + false -> + [{port, Port}, {timeout, Timeout}] + end, + {ok, #state{servers = Servers, user_dn = UserDn, options = LdapOpts}}. + +check(#mqtt_client{username = undefined}, _Password, _State) -> + {error, "Username undefined"}; +check(_Client, undefined, _State) -> + {error, "Password undefined"}; +check(_Client, <<>>, _State) -> + {error, "Password undefined"}; +check(#mqtt_client{username = Username}, Password, + #state{servers = Servers, user_dn = UserDn, options = Options}) -> + case eldap:open(Servers, Options) of + {ok, LDAP} -> + UserDn1 = fill(binary_to_list(Username), UserDn), + ldap_bind(LDAP, UserDn1, binary_to_list(Password)); + {error, Reason} -> + {error, Reason} + end. + +description() -> "LDAP Authentication Module". + +ldap_bind(LDAP, UserDn, Password) -> + case catch eldap:simple_bind(LDAP, UserDn, Password) of + ok -> + ok; + {error, invalidCredentials} -> + {error, "LDAP Invalid Credentials"}; + {error, Error} -> + {error, Error}; + {'EXIT', Reason} -> + {error, Reason} + end. + +fill(Username, UserDn) -> + lists:append(lists:map( + fun("$u") -> Username; + (S) -> S + end, string:tokens(UserDn, ",="))). + diff --git a/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap_app.erl b/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap_app.erl new file mode 100644 index 000000000..c3d09b62f --- /dev/null +++ b/plugins/emqttd_auth_ldap/src/emqttd_auth_ldap_app.erl @@ -0,0 +1,58 @@ +%%%----------------------------------------------------------------------------- +%%% Copyright (c) 2012-2015 eMQTT.IO, All Rights Reserved. +%%% +%%% Permission is hereby granted, free of charge, to any person obtaining a copy +%%% of this software and associated documentation files (the "Software"), to deal +%%% in the Software without restriction, including without limitation the rights +%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +%%% copies of the Software, and to permit persons to whom the Software is +%%% furnished to do so, subject to the following conditions: +%%% +%%% The above copyright notice and this permission notice shall be included in all +%%% copies or substantial portions of the Software. +%%% +%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +%%% SOFTWARE. +%%%----------------------------------------------------------------------------- +%%% @doc +%%% ldap authentication app. +%%% +%%% @end +%%%----------------------------------------------------------------------------- +-module(emqttd_auth_ldap_app). + +-behaviour(application). +%% Application callbacks +-export([start/2, prep_stop/1, stop/1]). + +-behaviour(supervisor). +%% Supervisor callbacks +-export([init/1]). + +%%%============================================================================= +%%% Application callbacks +%%%============================================================================= + +start(_StartType, _StartArgs) -> + Opts = application:get_all_env(emqttd_auth_ldap, ldap), + emqttd_access_control:register_mod(auth, emqttd_auth_ldap, Opts), + supervisor:start_link({local, ?MODULE}, ?MODULE, []). + +prep_stop(State) -> + emqttd_access_control:unregister_mod(auth, emqttd_auth_ldap), State. + +stop(_State) -> + ok. + +%%%============================================================================= +%%% Supervisor callbacks +%%%============================================================================= + +init([]) -> + {ok, { {one_for_one, 5, 10}, []} }. +