From 4c4d861792d79ac7773548c089b7a93bc2c72a51 Mon Sep 17 00:00:00 2001 From: Raimo Niskanen Date: Fri, 20 Apr 2018 16:52:15 +0200 Subject: Open for host and node allow list --- lib/kernel/src/dist_util.erl | 81 +++++++++++++++++++++++++++++++------------ lib/ssl/src/inet_tls_dist.erl | 55 +++++++++++------------------ 2 files changed, 79 insertions(+), 57 deletions(-) diff --git a/lib/kernel/src/dist_util.erl b/lib/kernel/src/dist_util.erl index b325fc5456..402d474c6d 100644 --- a/lib/kernel/src/dist_util.erl +++ b/lib/kernel/src/dist_util.erl @@ -30,7 +30,7 @@ strict_order_flags/0, start_timer/1, setup_timer/2, reset_timer/1, cancel_timer/1, - is_allowed/2, + is_node_name/1, split_node/1, is_allowed/2, shutdown/3, shutdown/4]). -import(error_logger,[error_msg/2]). @@ -632,7 +632,7 @@ recv_name(#hs_data{socket = Socket, f_recv = Recv} = HSData) -> {ok, [$n,VersionA, VersionB, Flag1, Flag2, Flag3, Flag4 | OtherNode] = Data} -> - case is_valid_name(OtherNode) of + case is_node_name(OtherNode) of true -> Flags = ?u32(Flag1, Flag2, Flag3, Flag4), Version = ?u16(VersionA,VersionB), @@ -644,6 +644,31 @@ recv_name(#hs_data{socket = Socket, f_recv = Recv} = HSData) -> ?shutdown(no_node) end. +is_node_name(OtherNodeName) -> + case string:split(OtherNodeName, "@") of + [Name,Host] -> + (not string:is_empty(Name)) + andalso (not string:is_empty(Host)); + _ -> + false + end. + +split_node(Node) -> + case string:split(listify_node(Node), "@") of + [Name,Host] = Split -> + case + (not string:is_empty(Name)) + andalso (not string:is_empty(Host)) + of + true -> + {Name,Host}; + false -> + Split + end; + Split -> + Split + end. + %% %% check if connecting node is allowed to connect %% with allow-node-scheme @@ -661,32 +686,44 @@ is_allowed(#hs_data{allowed = Allowed} = HSData, Flags, Node, Version) -> ?shutdown2(Node, {is_allowed, not_allowed}) end. +%% Allow Node on Allowed node list, and also if host part +%% of Node matches Allowed list item. The Allowed list +%% contains node names or host names. +%% is_allowed(_Node, []) -> false; +is_allowed(Node, [Node|_Allowed]) when is_atom(Node) -> + true; is_allowed(Node, [AllowedNode|Allowed]) -> - case is_nodename_equal(Node, AllowedNode) of - true -> - true; - false -> + case split_node(AllowedNode) of + {AllowedName,AllowedHost} -> + %% Allowed node name + case split_node(Node) of + {AllowedName,AllowedHost} -> + true; + _ -> + is_allowed(Node, Allowed) + end; + [AllowedHost] -> + %% Allowed host name + case split_node(Node) of + {_,AllowedHost} -> + %% Matching Host part + true; + [AllowedHost] -> + %% Host matches Host + true; + _ -> + is_allowed(Node, Allowed) + end; + _ -> is_allowed(Node, Allowed) end. -is_nodename_equal(A, B) when is_atom(A), is_atom(B) -> - A =:= B; -is_nodename_equal(A, B) when is_atom(A) -> - is_nodename_equal(atom_to_list(A), B); -is_nodename_equal(A, B) when is_atom(B) -> - is_nodename_equal(A, atom_to_list(B)); -is_nodename_equal(A, B) when is_list(A), is_list(B) -> - A =:= B. - -is_valid_name(OtherNodeName) -> - case string:lexemes(OtherNodeName,"@") of - [_OtherNodeName,_OtherNodeHost] -> - true; - _else -> - false - end. +listify_node(Atom) when is_atom(Atom) -> + atom_to_list(Atom); +listify_node(Node) when is_list(Node) -> + Node. publish_type(Flags) -> case Flags band ?DFLAG_PUBLISHED of diff --git a/lib/ssl/src/inet_tls_dist.erl b/lib/ssl/src/inet_tls_dist.erl index 3257e3a6c2..d4215c8f83 100644 --- a/lib/ssl/src/inet_tls_dist.erl +++ b/lib/ssl/src/inet_tls_dist.erl @@ -29,7 +29,7 @@ -export([gen_listen/2, gen_accept/2, gen_accept_connection/6, gen_setup/6, gen_close/2, gen_select/2]). --export([split_node/1, nodelay/0]). +-export([nodelay/0]). -export([verify_client/3, verify_server/3, cert_nodes/1]). @@ -52,25 +52,20 @@ select(Node) -> gen_select(inet_tcp, Node). gen_select(Driver, Node) -> - case split_node(Node) of - false -> - false; - Host -> + case dist_util:split_node(Node) of + {_,Host} -> case Driver:getaddr(Host) of {ok, _} -> true; _ -> false - end + end; + _ -> + false end. %% ------------------------------------------------------------------------- is_node_name(Node) -> - case split_node(Node) of - false -> - false; - _Host -> - true - end. + dist_util:is_node_name(Node). %% ------------------------------------------------------------------------- @@ -145,13 +140,13 @@ f_getll(DistCtrl) -> f_address(SslSocket, Node) -> case ssl:peername(SslSocket) of {ok, Address} -> - case split_node(Node) of - false -> - {error, no_node}; - Host -> + case dist_util:split_node(Node) of + {_,Host} -> #net_address{ address=Address, host=Host, - protocol=tls, family=inet} + protocol=tls, family=inet}; + _ -> + {error, no_node} end end. @@ -429,7 +424,7 @@ gen_setup(Driver, Node, Type, MyNode, LongOrShortNames, SetupTime) -> [link, {priority, max}])). do_setup(Driver, Kernel, Node, Type, MyNode, LongOrShortNames, SetupTime) -> - [Name, Address] = splitnode(Driver, Node, LongOrShortNames), + {Name, Address} = split_node(Driver, Node, LongOrShortNames), case Driver:getaddr(Address) of {ok, Ip} -> Timer = trace(dist_util:start_timer(SetupTime)), @@ -654,9 +649,9 @@ parse_rdn([_|Rdn]) -> %% If Node is illegal terminate the connection setup!! -splitnode(Driver, Node, LongOrShortNames) -> - case string:split(atom_to_list(Node), "@") of - [Name, Host] when Host =/= [] -> +split_node(Driver, Node, LongOrShortNames) -> + case dist_util:split_node(Node) of + {Name, Host} -> check_node(Driver, Name, Node, Host, LongOrShortNames); [_] -> error_logger:error_msg( @@ -671,10 +666,10 @@ splitnode(Driver, Node, LongOrShortNames) -> check_node(Driver, Name, Node, Host, LongOrShortNames) -> case string:split(Host, ".") of - [_] when LongOrShortNames == longnames -> + [_] when LongOrShortNames =:= longnames -> case Driver:parse_address(Host) of {ok, _} -> - [Name, Host]; + {Name, Host}; _ -> error_logger:error_msg( "** System running to use " @@ -683,7 +678,7 @@ check_node(Driver, Name, Node, Host, LongOrShortNames) -> [Host]), ?shutdown2(Node, trace({not_longnames, Host})) end; - [_, _] when LongOrShortNames == shortnames -> + [_,_|_] when LongOrShortNames =:= shortnames -> error_logger:error_msg( "** System NOT running to use " "fully qualified hostnames **~n" @@ -691,19 +686,9 @@ check_node(Driver, Name, Node, Host, LongOrShortNames) -> [Host]), ?shutdown2(Node, trace({not_shortnames, Host})); _ -> - [Name, Host] + {Name, Host} end. -split_node(Node) when is_atom(Node) -> - case string:split(atom_to_list(Node), "@") of - [Name, Host] when Name =/= [], Host =/= [] -> - Host; - _ -> - false - end; -split_node(_) -> - false. - %% ------------------------------------------------------------------------- connect_options(Opts) -> -- cgit v1.2.3