Skip to content

Commit 107af3c

Browse files
committed
Merge branch 'maint'
* maint: Update preloaded Test differing cookies with dynamic node names Implement set_cookie/1 and get_cookie/1 Clarify documentation of cookie handling Clean up handshake Cookie handling Test command line -setcookie Node Cookie Read other nodes' cookies from command line Read other nodes' cookies from command line Test differing cookies
2 parents e8851be + 547720e commit 107af3c

File tree

10 files changed

+567
-108
lines changed

10 files changed

+567
-108
lines changed

erts/doc/src/erl_cmd.xml

+8-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<comref>
55
<header>
66
<copyright>
7-
<year>1996</year><year>2020</year>
7+
<year>1996</year><year>2021</year>
88
<holder>Ericsson AB. All Rights Reserved.</holder>
99
</copyright>
1010
<legalnotice>
@@ -629,6 +629,13 @@ $ <input>erl \
629629
<seemfa marker="erlang#set_cookie/2">
630630
<c>erlang:set_cookie/2</c></seemfa>.</p>
631631
</item>
632+
<tag><c><![CDATA[-setcookie Node Cookie]]></c></tag>
633+
<item>
634+
<p>Sets the magic cookie for <c><![CDATA[Node]]></c>
635+
to <c><![CDATA[Cookie]]></c>; see
636+
<seemfa marker="erlang#set_cookie/2">
637+
<c>erlang:set_cookie/2</c></seemfa>.</p>
638+
</item>
632639
<tag><c><![CDATA[-shutdown_time Time]]></c></tag>
633640
<item>
634641
<p>Specifies how long time (in milliseconds) the <c><![CDATA[init]]></c>

erts/doc/src/erlang.xml

+32-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<erlref>
55
<header>
66
<copyright>
7-
<year>1996</year><year>2020</year>
7+
<year>1996</year><year>2021</year>
88
<holder>Ericsson AB. All Rights Reserved.</holder>
99
</copyright>
1010
<legalnotice>
@@ -2521,6 +2521,16 @@ uncompiled code with the same arity are mapped to the same list by
25212521
</desc>
25222522
</func>
25232523

2524+
<func>
2525+
<name name="get_cookie" arity="1" since="OTP @OTP-17538@"/>
2526+
<fsummary>Get the magic cookie for a node.</fsummary>
2527+
<desc>
2528+
<p>Returns the magic cookie for node <c><anno>Node</anno></c>
2529+
if the local node is alive,
2530+
otherwise the atom <c>nocookie</c>.</p>
2531+
</desc>
2532+
</func>
2533+
25242534
<func>
25252535
<name name="get_keys" arity="0" since="OTP 18.0"/>
25262536
<fsummary>Return a list of all keys from the process dictionary.
@@ -6952,14 +6962,31 @@ true</pre>
69526962
</desc>
69536963
</func>
69546964

6965+
<func>
6966+
<name name="set_cookie" arity="1" since="OTP @OTP-17538@"/>
6967+
<fsummary>Set the magic cookie of the local node.</fsummary>
6968+
<desc>
6969+
<p>Sets the magic cookie of the local node to the atom
6970+
<c><anno>Cookie</anno></c>, which is also
6971+
the cookie for all nodes that have no explicit cookie set with
6972+
<seemfa marker="#set_cookie/2"><c>set_cookie/2</c></seemfa>
6973+
<c><anno>Cookie</anno></c> (see section
6974+
<seeguide marker="system/reference_manual:distributed">
6975+
Distributed Erlang</seeguide>
6976+
in the Erlang Reference Manual in System Documentation).</p>
6977+
<p>Failure: <c>function_clause</c> if the local node is not
6978+
alive.</p>
6979+
</desc>
6980+
</func>
6981+
69556982
<func>
69566983
<name name="set_cookie" arity="2" since=""/>
6957-
<fsummary>Set the magic cookie of a node.</fsummary>
6984+
<fsummary>Set the magic cookie for a node.</fsummary>
69586985
<desc>
6959-
<p>Sets the magic cookie of <c><anno>Node</anno></c> to the atom
6986+
<p>Sets the magic cookie for <c><anno>Node</anno></c> to the atom
69606987
<c><anno>Cookie</anno></c>. If <c><anno>Node</anno></c> is the
6961-
local node, the function
6962-
also sets the cookie of all other unknown nodes to
6988+
local node, the function sets the cookie of all other nodes
6989+
(that have no explicit cookie set with this function) to
69636990
<c><anno>Cookie</anno></c> (see section
69646991
<seeguide marker="system/reference_manual:distributed">
69656992
Distributed Erlang</seeguide>

erts/emulator/test/exception_SUITE.erl

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%%
22
%% %CopyrightBegin%
33
%%
4-
%% Copyright Ericsson AB 1997-2020. All Rights Reserved.
4+
%% Copyright Ericsson AB 1997-2021. All Rights Reserved.
55
%%
66
%% Licensed under the Apache License, Version 2.0 (the "License");
77
%% you may not use this file except in compliance with the License.
@@ -888,6 +888,7 @@ error_info(_Config) ->
888888

889889
{gather_gc_info_result, 1}, %Internal BIF.
890890

891+
{get_cookie, [{not_node}]},
891892
{get_keys, [value], [no_fail]},
892893
{get_module_info, 1},
893894
{get_module_info, 2},
@@ -1143,7 +1144,9 @@ error_info(_Config) ->
11431144
{seq_trace_info, 1},
11441145
{seq_trace_print, 1},
11451146
{seq_trace_print, 2},
1146-
{set_cookie, 2},
1147+
{set_cookie, [{not_cookie}]},
1148+
{set_cookie, [{not_node}, {not_cookie}]},
1149+
{set_cookie, [nonode@nohost, {not_cookie}]},
11471150
{set_cpu_topology, 1},
11481151

11491152
{setelement, [a, b, c]},

erts/preloaded/ebin/erlang.beam

460 Bytes
Binary file not shown.

erts/preloaded/src/erlang.erl

+25-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%%
22
%% %CopyrightBegin%
33
%%
4-
%% Copyright Ericsson AB 1996-2020. All Rights Reserved.
4+
%% Copyright Ericsson AB 1996-2021. All Rights Reserved.
55
%%
66
%% Licensed under the Apache License, Version 2.0 (the "License");
77
%% you may not use this file except in compliance with the License.
@@ -35,7 +35,7 @@
3535
-export([min/2, max/2]).
3636
-export([dmonitor_node/3]).
3737
-export([delay_trap/2]).
38-
-export([set_cookie/2, get_cookie/0]).
38+
-export([set_cookie/1, set_cookie/2, get_cookie/0, get_cookie/1]).
3939
-export([nodes/0]).
4040

4141
-export([integer_to_list/2]).
@@ -3781,29 +3781,38 @@ dmonitor_node(Node, Flag, Opts) ->
37813781
delay_trap(Result, 0) -> erlang:yield(), Result;
37823782
delay_trap(Result, Timeout) -> receive after Timeout -> Result end.
37833783

3784-
%%
3785-
%% The business with different in and out cookies represented
3786-
%% everywhere is discarded.
3787-
%% A node has a cookie, connections/messages to that node use that cookie.
3788-
%% Messages to us use our cookie. IF we change our cookie, other nodes
3789-
%% have to reflect that, which we cannot forsee.
3790-
%%
3784+
3785+
-spec erlang:set_cookie(Cookie) -> true when
3786+
Cookie :: atom().
3787+
set_cookie(C) when erlang:is_atom(C) ->
3788+
auth:set_cookie(C);
3789+
set_cookie(C) ->
3790+
badarg_with_info([C]).
3791+
37913792
-spec erlang:set_cookie(Node, Cookie) -> true when
37923793
Node :: node(),
37933794
Cookie :: atom().
3794-
set_cookie(Node, C) when Node =/= nonode@nohost, erlang:is_atom(Node) ->
3795-
case erlang:is_atom(C) of
3796-
true ->
3797-
auth:set_cookie(Node, C);
3798-
false ->
3799-
erlang:error(badarg)
3800-
end.
3795+
set_cookie(Node, C)
3796+
when Node =/= nonode@nohost, erlang:is_atom(Node), erlang:is_atom(C) ->
3797+
auth:set_cookie(Node, C);
3798+
set_cookie(Node, C) ->
3799+
badarg_with_info([Node, C]).
3800+
38013801

38023802
-spec erlang:get_cookie() -> Cookie | nocookie when
38033803
Cookie :: atom().
38043804
get_cookie() ->
38053805
auth:get_cookie().
38063806

3807+
-spec erlang:get_cookie(Node) -> Cookie | nocookie when
3808+
Node :: node(),
3809+
Cookie :: atom().
3810+
get_cookie(Node) when erlang:is_atom(Node) ->
3811+
auth:get_cookie(Node);
3812+
get_cookie(Node) ->
3813+
badarg_with_info([Node]).
3814+
3815+
38073816
-spec integer_to_list(Integer, Base) -> string() when
38083817
Integer :: integer(),
38093818
Base :: 2..36.

lib/kernel/src/auth.erl

+81-26
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%%
22
%% %CopyrightBegin%
33
%%
4-
%% Copyright Ericsson AB 1996-2018. All Rights Reserved.
4+
%% Copyright Ericsson AB 1996-2021. All Rights Reserved.
55
%%
66
%% Licensed under the Apache License, Version 2.0 (the "License");
77
%% you may not use this file except in compliance with the License.
@@ -271,35 +271,90 @@ getnode(P) -> P.
271271
%%%
272272
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
273273

274-
%% Read cookie from $HOME/.erlang.cookie and set it.
274+
%% Read and set cookie from command line or $HOME/.erlang.cookie.
275275
init_cookie() ->
276+
case init:get_argument(setcookie) of
277+
error ->
278+
init_no_setcookie();
279+
{ok, Setcookie} ->
280+
init_setcookie(Setcookie, [], #{})
281+
end.
282+
283+
%% No -setcookie argument
284+
init_no_setcookie() ->
276285
case init:get_argument(nocookie) of
277-
error ->
278-
case init:get_argument(setcookie) of
279-
{ok, [[C0]]} ->
280-
C = list_to_atom(C0),
281-
#state{our_cookie = C,
282-
other_cookies = ets:new(cookies,
283-
[?COOKIE_ETS_PROTECTION])};
284-
_ ->
285-
%% Here is the default
286-
case read_cookie() of
287-
{error, Error} ->
288-
error_logger:error_msg(Error, []),
289-
%% Is this really this serious?
290-
erlang:error(Error);
291-
{ok, Co} ->
292-
#state{our_cookie = list_to_atom(Co),
293-
other_cookies = ets:new(
294-
cookies,
295-
[?COOKIE_ETS_PROTECTION])}
296-
end
297-
end;
298-
_Other ->
299-
#state{our_cookie = nocookie,
300-
other_cookies = ets:new(cookies, [?COOKIE_ETS_PROTECTION])}
286+
error ->
287+
%% Here is the default
288+
%% - no -setcookie nor -nocookie argument
289+
case read_cookie() of
290+
{error, Error} ->
291+
error_logger:error_msg(Error, []),
292+
%% Is this really this serious?
293+
erlang:error(Error);
294+
{ok, Co} ->
295+
#state{our_cookie = list_to_atom(Co),
296+
other_cookies = ets_new_cookies()}
297+
end;
298+
{ok, Nocookie} when is_list(Nocookie) ->
299+
%% Ignore the value
300+
#state{our_cookie = nocookie,
301+
other_cookies = ets_new_cookies()}
301302
end.
302303

304+
%% Process -setcookie options
305+
init_setcookie([SetCo | Setcookie], OurCookies, OtherCookies) ->
306+
case SetCo of
307+
%% Collect arity 0 and 1 options as our cookie
308+
[] ->
309+
init_setcookie(Setcookie, [SetCo | OurCookies], OtherCookies);
310+
[_] ->
311+
init_setcookie(Setcookie, [SetCo | OurCookies], OtherCookies);
312+
[Node, Co] ->
313+
%% Collect arity 2 options as other nodes' cookies
314+
init_setcookie(
315+
Setcookie, OurCookies,
316+
case OtherCookies of
317+
#{Node := _} ->
318+
%% If a node's cookie is set more than once
319+
%% we pretend it was not set, a'la how
320+
%% setting our own cookie is handled
321+
OtherCookies#{Node := undefined};
322+
#{} ->
323+
OtherCookies#{Node => Co}
324+
end);
325+
_ when is_list(SetCo) ->
326+
%% Ignore options of arity 3 or more, which changes
327+
%% legacy behaviour which was to ignore our own
328+
%% cookie due to invalid arity (only valid was 1)
329+
init_setcookie(Setcookie, OurCookies, OtherCookies)
330+
end;
331+
init_setcookie([], OurCookies, OtherCookies) ->
332+
%% Options collected - handle them
333+
State =
334+
case OurCookies of
335+
[[Co]] ->
336+
%% We have no arity 0 and exactly one arity 1
337+
%% option i.e our cookie
338+
#state{
339+
our_cookie = list_to_atom(Co),
340+
other_cookies = ets_new_cookies()};
341+
_ when is_list(OurCookies) ->
342+
%% Any other combination of arity 0 and 1 options
343+
%% makes us pretend they were not there;
344+
%% legacy behaviour - we have no set cookie
345+
init_no_setcookie()
346+
end,
347+
%% Register all other node's cookies (arity 2 options)
348+
ets:insert(
349+
State#state.other_cookies,
350+
[{list_to_atom(Node), list_to_atom(Co)} ||
351+
{Node, Co} <- maps:to_list(OtherCookies),
352+
Co =/= undefined]),
353+
State.
354+
355+
ets_new_cookies() ->
356+
ets:new(cookies, [?COOKIE_ETS_PROTECTION]).
357+
303358
read_cookie() ->
304359
case init:get_argument(home) of
305360
{ok, [[Home]]} ->

lib/kernel/src/dist_util.erl

+9-22
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
%%
22
%% %CopyrightBegin%
33
%%
4-
%% Copyright Ericsson AB 1999-2020. All Rights Reserved.
4+
%% Copyright Ericsson AB 1999-2021. All Rights Reserved.
55
%%
66
%% Licensed under the Apache License, Version 2.0 (the "License");
77
%% you may not use this file except in compliance with the License.
@@ -222,7 +222,7 @@ handshake_other_started(#hs_data{request_type=ReqType,
222222
?debug({"MD5 connection from ~p~n", [NodeOrHost]}),
223223
HSData2 = mark_pending(HSData1),
224224
Node = HSData2#hs_data.other_node,
225-
{MyCookie,HisCookie} = get_cookies(Node),
225+
Cookie = auth:get_cookie(Node),
226226
ChallengeA = gen_challenge(),
227227
send_challenge(HSData2, ChallengeA),
228228
reset_timer(HSData2#hs_data.timer),
@@ -232,8 +232,8 @@ handshake_other_started(#hs_data{request_type=ReqType,
232232
HSData3#hs_data.other_flags),
233233
HSData4 = HSData3#hs_data{this_flags = ChosenFlags,
234234
other_flags = ChosenFlags},
235-
ChallengeB = recv_challenge_reply(HSData4, ChallengeA, MyCookie),
236-
send_challenge_ack(HSData4, gen_digest(ChallengeB, HisCookie)),
235+
ChallengeB = recv_challenge_reply(HSData4, ChallengeA, Cookie),
236+
send_challenge_ack(HSData4, gen_digest(ChallengeB, Cookie)),
237237
?debug({dist_util, self(), accept_connection, Node}),
238238
connection(HSData4);
239239

@@ -441,13 +441,13 @@ handshake_we_started(#hs_data{request_type=ReqType,
441441
other_version = flags_to_version(PreOtherFlags),
442442
other_creation = Creation},
443443
check_dflags(HSData2, EDF),
444-
MyChallenge = gen_challenge(),
445-
{MyCookie,HisCookie} = get_cookies(Node),
444+
ChallengeB = gen_challenge(),
445+
Cookie = auth:get_cookie(Node),
446446
send_complement(HSData2, SendNameVersion),
447-
send_challenge_reply(HSData2,MyChallenge,
448-
gen_digest(ChallengeA,HisCookie)),
447+
send_challenge_reply(HSData2, ChallengeB,
448+
gen_digest(ChallengeA, Cookie)),
449449
reset_timer(HSData2#hs_data.timer),
450-
recv_challenge_ack(HSData2, MyChallenge, MyCookie),
450+
recv_challenge_ack(HSData2, ChallengeB, Cookie),
451451
connection(HSData2);
452452

453453
handshake_we_started(OldHsData) when element(1,OldHsData) =:= hs_data ->
@@ -535,19 +535,6 @@ gen_challenge() ->
535535
(B + (C bsl 16)) bxor
536536
(D + (H bsl 16)) ) band 16#ffffffff.
537537

538-
%%
539-
%% Get the cookies for a node from auth
540-
%%
541-
get_cookies(Node) ->
542-
case auth:get_cookie(Node) of
543-
X when is_atom(X) ->
544-
{X,X}
545-
% {Y,Z} when is_atom(Y), is_atom(Z) ->
546-
% {Y,Z};
547-
% _ ->
548-
% erlang:error("Corrupt cookie database")
549-
end.
550-
551538
%% No error return; either succeeds or terminates the process.
552539
do_setnode(#hs_data{other_node = Node, socket = Socket,
553540
this_node = MyNode,

0 commit comments

Comments
 (0)