From 6aa724ef31b47a8f2ad684ff8483faef0dac5f21 Mon Sep 17 00:00:00 2001 From: Ery Lee Date: Wed, 25 Mar 2015 22:46:47 +0800 Subject: [PATCH 1/3] acl --- apps/emqttd/src/emqttd_access.erl | 42 ++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/apps/emqttd/src/emqttd_access.erl b/apps/emqttd/src/emqttd_access.erl index 7be0d044c..4fc301fd6 100644 --- a/apps/emqttd/src/emqttd_access.erl +++ b/apps/emqttd/src/emqttd_access.erl @@ -28,8 +28,44 @@ -include("emqttd.hrl"). --export([match/2]). +-export([match/3]). -match({User, Topic}, Rules) -> - ok. +-type who() :: all | + {clientid, binary()} | + {peername, string() | inet:ip_address()} | + {username, binary()}. +-type rule() :: {allow, all} | + {allow, who(), binary()} | + {deny, all} | + {deny, who(), binary()}. + +-spec match(mqtt_user(), binary(), list(rule())) -> allow | deny | nomatch. +match(_User, _Topic, []) -> + nomatch; +match(_User, _Topic, [{AllowDeny, all}|_]) -> + AllowDeny; +match(User, Topic, [{AllowDeny, all, TopicFilter}|Rules]) -> + case emqttd_topic:match(Topic, TopicFilter) of + true -> AllowDeny; + false -> match(User, Topic, Rules) + end; + +match(User = #mqtt_user{clientid = ClientId}, Topic, [{AllowDeny, ClientId, TopicFilter}|Rules]) when is_binary(ClientId) -> + case emqttd_topic:match(Topic, TopicFilter) of + true -> AllowDeny; + false -> match(User, Topic, Rules) + end; +match(User = #mqtt_user{peername = IpAddr}, Topic, [{AllowDeny, {peername, CIDR}, TopicFilter}|Rules]) -> + case {match_cidr(IpAddr, CIDR), emqttd_topic:match(Topic, TopicFilter)} of + {true, true} -> AllowDeny; + _ -> match(User, Topic, Rules) + end; +match(User = #mqtt_user{username = Username}, Topic, [{AllowDeny, {username, Username}, TopicFilter}|Rules]) -> + case emqttd_topic:match(Topic, TopicFilter) of + true -> AllowDeny; + false -> match(User, Topic, Rules) + end. + +match_cidr(IpAddr, CIDR) -> true. + From 5df03ba938fffdcbf92d4e9d235a4bf309621251 Mon Sep 17 00:00:00 2001 From: Ery Lee Date: Wed, 25 Mar 2015 23:03:03 +0800 Subject: [PATCH 2/3] access test --- apps/emqttd/src/emqttd_access.erl | 1 - apps/emqttd/src/emqttd_acl.erl | 2 +- apps/emqttd/src/emqttd_auth_internal.erl | 6 +-- apps/emqttd/src/x.erl | 50 ++++++++++++++++++++++++ apps/emqttd/test/emqttd_access_tests.erl | 45 +++++++++++++++++++++ apps/emqttd/test/emqttd_opts_tests.erl | 12 +++--- 6 files changed, 105 insertions(+), 11 deletions(-) create mode 100644 apps/emqttd/src/x.erl create mode 100644 apps/emqttd/test/emqttd_access_tests.erl diff --git a/apps/emqttd/src/emqttd_access.erl b/apps/emqttd/src/emqttd_access.erl index 4fc301fd6..01a59d3c0 100644 --- a/apps/emqttd/src/emqttd_access.erl +++ b/apps/emqttd/src/emqttd_access.erl @@ -50,7 +50,6 @@ match(User, Topic, [{AllowDeny, all, TopicFilter}|Rules]) -> true -> AllowDeny; false -> match(User, Topic, Rules) end; - match(User = #mqtt_user{clientid = ClientId}, Topic, [{AllowDeny, ClientId, TopicFilter}|Rules]) when is_binary(ClientId) -> case emqttd_topic:match(Topic, TopicFilter) of true -> AllowDeny; diff --git a/apps/emqttd/src/emqttd_acl.erl b/apps/emqttd/src/emqttd_acl.erl index b05688bd0..1503ca20b 100644 --- a/apps/emqttd/src/emqttd_acl.erl +++ b/apps/emqttd/src/emqttd_acl.erl @@ -52,7 +52,7 @@ -type pubsub() :: publish | subscribe. --type who() :: all | +-type who() :: all | binary() | {clientid, binary()} | {peername, string() | inet:ip_address()} | {username, binary()}. diff --git a/apps/emqttd/src/emqttd_auth_internal.erl b/apps/emqttd/src/emqttd_auth_internal.erl index 688fe509a..4745f9e5f 100644 --- a/apps/emqttd/src/emqttd_auth_internal.erl +++ b/apps/emqttd/src/emqttd_auth_internal.erl @@ -48,15 +48,15 @@ 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{passwdhash=PasswdHash}] -> true; + [#mqtt_user{password=PasswdHash}] -> true; _ -> false end. add(Username, Password) when is_binary(Username) and is_binary(Password) -> mnesia:dirty_write( #mqtt_user{ - username=Username, - passwdhash=crypto:hash(md5, Password) + username = Username, + password = crypto:hash(md5, Password) } ). diff --git a/apps/emqttd/src/x.erl b/apps/emqttd/src/x.erl new file mode 100644 index 000000000..06e3e515d --- /dev/null +++ b/apps/emqttd/src/x.erl @@ -0,0 +1,50 @@ +-module(x). +-behaviour(gen_server). +-define(SERVER, ?MODULE). + +%% ------------------------------------------------------------------ +%% API Function Exports +%% ------------------------------------------------------------------ + +-export([start_link/0]). + +%% ------------------------------------------------------------------ +%% gen_server Function Exports +%% ------------------------------------------------------------------ + +-export([init/1, handle_call/3, handle_cast/2, handle_info/2, + terminate/2, code_change/3]). + +%% ------------------------------------------------------------------ +%% API Function Definitions +%% ------------------------------------------------------------------ + +start_link() -> + gen_server:start_link({local, ?SERVER}, ?MODULE, [], []). + +%% ------------------------------------------------------------------ +%% gen_server Function Definitions +%% ------------------------------------------------------------------ + +init(Args) -> + {ok, Args}. + +handle_call(_Request, _From, State) -> + {reply, ok, State}. + +handle_cast(_Msg, State) -> + {noreply, State}. + +handle_info(_Info, State) -> + {noreply, State}. + +terminate(_Reason, _State) -> + ok. + +code_change(_OldVsn, State, _Extra) -> + {ok, State}. + +%% ------------------------------------------------------------------ +%% Internal Function Definitions +%% ------------------------------------------------------------------ + diff --git a/apps/emqttd/test/emqttd_access_tests.erl b/apps/emqttd/test/emqttd_access_tests.erl new file mode 100644 index 000000000..3bb38caab --- /dev/null +++ b/apps/emqttd/test/emqttd_access_tests.erl @@ -0,0 +1,45 @@ +%%%----------------------------------------------------------------------------- +%%% @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_access rules tests. +%%% +%%% @end +%%%----------------------------------------------------------------------------- +-module(emqttd_access_tests). + +-include("emqttd.hrl"). + +-ifdef(TEST). + +-include_lib("eunit/include/eunit.hrl"). + +-define(RULES1, [{allow, all}]). +-define(RULES2, [{deny, all}]). + +match_test() -> + User = #mqtt_user{peername = {127,0,0,1}, clientid = <<"testClient">>, username = <<"TestUser">>}, + ?assertEqual(allow, emqttd_access:match(User, <<"Test/Topic">>, ?RULES1)), + ?assertEqual(deny, emqttd_access:match(User, <<"Test/Topic">>, ?RULES2)). + +-endif. + + diff --git a/apps/emqttd/test/emqttd_opts_tests.erl b/apps/emqttd/test/emqttd_opts_tests.erl index d7cfce02e..50d654327 100644 --- a/apps/emqttd/test/emqttd_opts_tests.erl +++ b/apps/emqttd/test/emqttd_opts_tests.erl @@ -47,12 +47,12 @@ merge_test() -> ?assertEqual(1024, proplists:get_value(backlog, Opts)), ?assertEqual(1024, proplists:get_value(max_clients, Opts)), ?assertEqual(lists:sort(Opts), [binary, raw, - {acceptors,4}, - {backlog,1024}, - {max_clients,1024}, - {nodelay,false}, - {packet,raw}, - {reuseaddr,true}]). + {acceptors, 16}, + {backlog, 1024}, + {max_clients, 1024}, + {nodelay, false}, + {packet, raw}, + {reuseaddr, true}]). -endif. From 1428223a2b1cfbbd85d3e2a1f02dce7c71b6603a Mon Sep 17 00:00:00 2001 From: Ery Lee Date: Wed, 25 Mar 2015 23:23:25 +0800 Subject: [PATCH 3/3] trace --- apps/emqttd/src/emqttd.erl | 8 +++++ apps/emqttd/src/emqttd_trace.erl | 51 ++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 apps/emqttd/src/emqttd_trace.erl diff --git a/apps/emqttd/src/emqttd.erl b/apps/emqttd/src/emqttd.erl index f9d70fc04..578280c42 100644 --- a/apps/emqttd/src/emqttd.erl +++ b/apps/emqttd/src/emqttd.erl @@ -79,4 +79,12 @@ is_running(Node) -> Pid when is_pid(Pid) -> true end. +%% TODO: publish chain... +publish(FromClient, Topic, Message) -> + emqttd_router:route(Message). + +%% TODO: subscribe: subscribe chain... +subscribe(FromClient, Topic) -> + emqttd_pubsub:subscribe(Topic). + diff --git a/apps/emqttd/src/emqttd_trace.erl b/apps/emqttd/src/emqttd_trace.erl new file mode 100644 index 000000000..3c25a2e3c --- /dev/null +++ b/apps/emqttd/src/emqttd_trace.erl @@ -0,0 +1,51 @@ +%%%----------------------------------------------------------------------------- +%%% @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 trace. +%%% +%%% @end +%%%----------------------------------------------------------------------------- +-module(emqttd_trace). + +%% Trace publish messages and write to file.. +%%------------------------------------------------------------------------------ +%% @doc +%% Start to trace client or topic. +%% +%% @end +%%------------------------------------------------------------------------------ +start_trace(client, ClientId) -> + ok; +start_trace(topic, Topic) -> + ok. + +%%------------------------------------------------------------------------------ +%% @doc +%% Stop tracing client or topic. +%% +%% @end +%%------------------------------------------------------------------------------ +stop_trace(client, ClientId) -> + ok; +stop_trace(topic, Topic) -> + ok. +