diff --git a/apps/emqttd/include/emqttd.hrl b/apps/emqttd/include/emqttd.hrl index ed74dff13..0727d3291 100644 --- a/apps/emqttd/include/emqttd.hrl +++ b/apps/emqttd/include/emqttd.hrl @@ -63,10 +63,9 @@ %% MQTT User Management %%------------------------------------------------------------------------------ -record(mqtt_user, { - clientid :: binary(), - ipaddr :: inet:ip_address(), username :: binary(), - password :: binary() + ipaddr :: inet:ip_address(), + clientid :: binary() }). -type mqtt_user() :: #mqtt_user{}. diff --git a/apps/emqttd/src/emqttd_auth.erl b/apps/emqttd/src/emqttd_auth.erl index 3a8a7c914..139236547 100644 --- a/apps/emqttd/src/emqttd_auth.erl +++ b/apps/emqttd/src/emqttd_auth.erl @@ -30,47 +30,22 @@ -include("emqttd.hrl"). --export([start_link/0, - add/2, - check/1, check/2, - delete/1]). +-export([start_link/1, check/2]). -behavior(gen_server). --export([init/1, - handle_call/3, - handle_cast/2, - handle_info/2, - terminate/2, - code_change/3]). +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, terminate/2, code_change/3]). --define(TAB, ?MODULE). +-define(AUTH_TABLE, mqtt_auth). -start_link() -> - gen_server:start_link({local, ?MODULE}, ?MODULE, [], []). +start_link(AuthOpts) -> + gen_server:start_link({local, ?MODULE}, ?MODULE, [AuthOpts], []). --spec check({Usename :: binary(), Password :: binary()}) -> true | false. -check({Username, Password}) -> - execute(check, [Username, Password]). +-spec check(mqtt_user(), binary()) -> true | false. +check(User, Password) when is_record(User, mqtt_user) -> + [{_, }] = ets:lookup(?AUTH_TABLE, auth_modules), --spec check(Usename :: binary(), Password :: binary()) -> true | false. -check(Username, Password) -> - execute(check, [Username, Password]). - --spec add(Usename :: binary(), Password :: binary()) -> ok. -add(Username, Password) -> - execute(add, [Username, Password]). - --spec delete(Username :: binary()) -> ok. -delete(Username) -> - execute(delete, [Username]). - -execute(F, Args) -> - [{_, M}] = ets:lookup(?TAB, mod), - apply(M, F, Args). - -init([]) -> - {ok, {Name, Opts}} = application:get_env(auth), +init([AuthOpts]) -> AuthMod = authmod(Name), ok = AuthMod:init(Opts), ets:new(?TAB, [named_table, protected]), diff --git a/apps/emqttd/src/emqttd_auth_anonymous.erl b/apps/emqttd/src/emqttd_auth_anonymous.erl index f99ef861e..257e5c539 100644 --- a/apps/emqttd/src/emqttd_auth_anonymous.erl +++ b/apps/emqttd/src/emqttd_auth_anonymous.erl @@ -28,13 +28,16 @@ -author('feng@emqtt.io'). --export([init/1, add/2, check/2, delete/1]). +-export([init/1, add_user/2, check_login/2, del_user/1]). init(_Opts) -> ok. -check(_, _) -> true. +check_login(_, _) -> true. + +add_user(_, _) -> ok. + +del_user(_Username) -> ok. + -add(_, _) -> ok. -delete(_Username) -> ok. diff --git a/apps/emqttd/src/emqttd_auth_clientid.erl b/apps/emqttd/src/emqttd_auth_clientid.erl new file mode 100644 index 000000000..45403ae9d --- /dev/null +++ b/apps/emqttd/src/emqttd_auth_clientid.erl @@ -0,0 +1,43 @@ +%%%----------------------------------------------------------------------------- +%%% @Copyright (C) 2012-2015, Feng Lee +%%% +%%% 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 +%%% emqttd authentication with clientid. +%%% +%%% @end +%%%----------------------------------------------------------------------------- +-module(emqttd_auth_clientid). + +-author('feng@emqtt.io'). + +-include("emqttd.hrl"). + +-export([init/1]). + +-define(AUTH_CLIENTID_TABLE, mqtt_auth_clientid). + +init(Opts) -> + mnesia:create_table(?AUTH_CLIENTID_TABLE, [ + {disc_copies, [node()]}, + {attributes, record_info(fields, mqtt_user)}]), + mnesia:add_table_copy(?AUTH_CLIENTID_TABLE, node(), ram_copies), + {ok, Opts}. + diff --git a/apps/emqttd/src/emqttd_auth_internal.erl b/apps/emqttd/src/emqttd_auth_username.erl similarity index 78% rename from apps/emqttd/src/emqttd_auth_internal.erl rename to apps/emqttd/src/emqttd_auth_username.erl index 4745f9e5f..dc7137f8f 100644 --- a/apps/emqttd/src/emqttd_auth_internal.erl +++ b/apps/emqttd/src/emqttd_auth_username.erl @@ -20,11 +20,11 @@ %%% SOFTWARE. %%%----------------------------------------------------------------------------- %%% @doc -%%% emqttd internal authentication. +%%% emqttd authentication with username and password. %%% %%% @end %%%----------------------------------------------------------------------------- --module(emqttd_auth_internal). +-module(emqttd_auth_username). -author('feng@emqtt.io'). @@ -32,13 +32,15 @@ -export([init/1, add/2, check/2, delete/1]). --define(USER_TAB, mqtt_user). +-define(AUTH_USER_TABLE, mqtt_auth_username). + +-record(mqtt_auth_username, {username, password}). init(_Opts) -> - mnesia:create_table(?USER_TAB, [ - {ram_copies, [node()]}, + mnesia:create_table(?AUTH_USER_TABLE, [ + {ram_copies, [node()]}, {attributes, record_info(fields, mqtt_user)}]), - mnesia:add_table_copy(?USER_TAB, node(), ram_copies), + mnesia:add_table_copy(?AUTH_USER_TABLE, node(), ram_copies), ok. check(undefined, _) -> false; @@ -47,19 +49,19 @@ check(_, undefined) -> false; check(Username, Password) when is_binary(Username), is_binary(Password) -> PasswdHash = crypto:hash(md5, Password), - case mnesia:dirty_read(?USER_TAB, Username) of - [#mqtt_user{password=PasswdHash}] -> true; + case mnesia:dirty_read(?AUTH_USER_TABLE, Username) of + [#mqtt_user{}] -> true; %password=PasswdHash} _ -> false end. add(Username, Password) when is_binary(Username) and is_binary(Password) -> mnesia:dirty_write( #mqtt_user{ - username = Username, - password = crypto:hash(md5, Password) + username = Username + %password = crypto:hash(md5, Password) } ). delete(Username) when is_binary(Username) -> - mnesia:dirty_delete(?USER_TAB, Username). + mnesia:dirty_delete(?AUTH_USER_TABLE, Username). diff --git a/rel/files/app.config b/rel/files/app.config index 1ed23e875..3fb6493e5 100644 --- a/rel/files/app.config +++ b/rel/files/app.config @@ -39,7 +39,7 @@ ]}, {emqttd, [ %Authetication. Internal, Anonymous Default - {auth, {anonymous, []}}, + {auth, [{anonymous, []}]}, %ACL config {acl, [{file, "etc/acl.config"}]}, {packet, [ @@ -85,6 +85,11 @@ {max_clients, 512}, {access, [{allow, "127.0.0.1"}]} ]} + ]}, + % Plugins + {plugins, [ + {emqttd_auth_ldap, [ldap_params]}, + {emqttd_auth_mysql, [mysql_params]}, ]} ]} ]. diff --git a/rel/reltool.config b/rel/reltool.config index c5757d859..30249feb9 100644 --- a/rel/reltool.config +++ b/rel/reltool.config @@ -2,7 +2,7 @@ {lib_dirs, ["../apps", "../deps", "../plugins"]}, {erts, [{mod_cond, derived}, {app_file, strip}]}, {app_file, strip}, - {rel, "emqttd", "0.5.0", + {rel, "emqttd", "0.5.4", [ kernel, stdlib, @@ -58,6 +58,7 @@ {mkdir, "log/"}, {mkdir, "etc/"}, {mkdir, "data/"}, + {mkdir, "plugins/"}, {copy, "files/erl", "\{\{erts_vsn\}\}/bin/erl"}, {template, "files/nodetool", "\{\{erts_vsn\}\}/bin/nodetool"}, {template, "files/emqttd", "bin/emqttd"},