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_access.erl b/apps/emqttd/src/emqttd_access.erl index 7e496698a..01a59d3c0 100644 --- a/apps/emqttd/src/emqttd_access.erl +++ b/apps/emqttd/src/emqttd_access.erl @@ -30,18 +30,41 @@ -export([match/3]). -match(_Who, _Topic, []) -> +-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(_Who, _Topic, [{AllowDeny, all}|_Rules]) -> +match(_User, _Topic, [{AllowDeny, all}|_]) -> AllowDeny; -match(User = #mqtt_user{clientid = ClientId}, Topic, [{AllowDeny, ClientId, Filter}|Rules]) -> - case emqttd_topic:match(Topic, Filter) of +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) -> +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. - - - - diff --git a/apps/emqttd/src/emqttd_acl.erl b/apps/emqttd/src/emqttd_acl.erl index 92fedc9fd..d1b5f235f 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/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. + 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.