Skip to content

Commit

Permalink
Merge v0.13.14
Browse files Browse the repository at this point in the history
  • Loading branch information
cleverfox committed Nov 16, 2022
2 parents 59bd2a7 + 6ce1a0b commit c40e807
Show file tree
Hide file tree
Showing 6 changed files with 237 additions and 3 deletions.
7 changes: 5 additions & 2 deletions apps/tpic2/src/tpic2_tls.erl
Original file line number Diff line number Diff line change
Expand Up @@ -164,8 +164,11 @@ loop(State=#{parent:=Parent, socket:=Socket, transport:=Transport, opts:=_Opts,
?LOG_ERROR("Received stray message ~p.~n", [Msg]),
?MODULE:loop(State)
after 10000 -> %to avoid killing on code change
ok=send_msg(#{null=><<"KA">>},State),
?MODULE:loop(State)
case send_msg(#{null=><<"KA">>},State) of
ok -> ?MODULE:loop(State);
{error, closed} ->
exit(normal)
end
end.

system_continue(_PID,_,{State}) ->
Expand Down
1 change: 1 addition & 0 deletions apps/tpnode/src/tpnode.app.src
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
tinymq,
jsx,
cowboy,
certifi,
rocksdb,
gb_merkle_trees,
msgpack,
Expand Down
195 changes: 195 additions & 0 deletions apps/tpnode/src/tpnode_hotfix.erl
Original file line number Diff line number Diff line change
@@ -0,0 +1,195 @@
-module(tpnode_hotfix).
-export([install/1, autoload/0, unpack/1, load/1, load1/2, validkey/1]).

-define(STD_KEYS,[
"302A300506032B65700321002B3A6C9A401865F65004665336A9CA3E33D029D7AE2B5204EBFBC0A4910CFA1E",
"032FB1B9DF699380904A803E579AB7392B7DF26881DA07D1ABC9DB198919B03782"
]).

validkey(PubKey) ->
ValidKeys=lists:foldl(
fun(HexKey,A) ->
maps:put(tpecdsa:cmp_pubkey(hex:decode(HexKey)),1,A)
end, #{},
application:get_env(tpnode, hotfix_keys, ?STD_KEYS)
),
PK=tpecdsa:cmp_pubkey(PubKey),
maps:is_key(PK,ValidKeys).


versig({true,#{extra := SigXD}}=Any) ->
case proplists:get_value(pubkey,SigXD) of
undefined ->
logger:notice("Versig failed to find pubkey: ~p",[Any]),
false;
PubKey ->
validkey(PubKey)
end;

versig(Any) ->
logger:notice("Versig failed: ~p",[Any]),
false.

autoload() ->
ok.

install(Fix) ->
Host=application:get_env(tpnode,hotfix_host,"https://hotfix.thepower.io"),

case get(Host, "/thepower/hotfix/tpnode/"++Fix) of
{200, Bin} ->
{ok, Files, Sig} = unpack(Bin),
case versig(Sig) of
true ->
code:delete(hotfix_compatible),
code:purge(hotfix_compatible),
code:delete(hotfix_compatible),
case proplists:get_value("hotfix_compatible.beam",Files) of
undefined -> {error, that_is_not_hotfix};
Beam ->
load1("hotfix_compatible.beam",Beam),
{file,_} = code:is_loaded(hotfix_compatible),
ok = hotfix_compatible:check(Files),
{ok,load(Files)}
end;
false ->
{error,badsig}
end;
{Code,_} ->
{error,{http,Code}}
end.


load1(Filename, Bin) ->
N=filename:basename(Filename),
case string:split(N,".") of
[Module,"beam"] ->
ModName=list_to_atom(Module),
{Filename,case code:load_binary(ModName,Filename,Bin) of
{error, R} ->
R;
{module, _} ->
ok
end};
_ ->
false
end.

load([]) -> [];

load([{"hotfix_compatible.beam",_}|Files]) ->
load(Files);

load([{Filename,<<"FOR1",_/binary>> = Bin}|Files]) ->
case load1(Filename,Bin) of
false ->
load(Files);
{_,_} = E ->
[E|load(Files)]
end;

load([_|Files]) ->
load(Files).

split_bin(<<HL:16/big,0,Signatures:(HL-1)/binary,ZIP/binary>>) ->
{Signatures,ZIP}.

unpack(Bin) ->
{Sig,Zip}=split_bin(Bin),
{ok,Files}=zip:extract(Zip,[memory]),
Hash=crypto:hash(sha256,Zip),
CheckSig=bsig:checksig1(Hash,Sig),
{ok, Files, CheckSig}.

get(Node, Path) ->
application:ensure_all_started(gun),
{ok, ConnPid} = connect(Node),
StreamRef = gun:get(ConnPid, Path, []),
{response, Fin, Code, _Headers} = gun:await(ConnPid, StreamRef),
case Code of
200 ->
Body=case Fin of
fin -> <<>>;
nofin ->
{ok, Body2} = gun:await_body(ConnPid, StreamRef),
Body2
end,
gun:close(ConnPid),
{Code,Body};
Code ->
gun:close(ConnPid),
logger:error("Can't fetch ~s: code ~w",[Path,Code]),
{Code,<<>>}
end.

connect(Node) ->
{Host, Port, Opts,_} = parse_url(Node),
{ok, ConnPid} = gun:open(Host,Port,Opts),
case gun:await_up(ConnPid) of
{ok, _} ->
{ok, ConnPid};
{error,Other} ->
throw(Other)
end.

parse_url(Node) when is_binary(Node) ->
parse_url(binary_to_list(Node));

parse_url(Node) when is_list(Node) ->
CaCerts = certifi:cacerts(),
CHC=[
{match_fun, public_key:pkix_verify_hostname_match_fun(https)}
],
#{scheme:=Sch,
path:=Path,
host:=Host}=P = uri_string:parse(Node),
{Opts,Port}=case Sch of
"httpsi" ->
case get(warned) of
undefined ->
logger:notice("-=-=-= [ connection is insecure ] =-=-=-~n",[]),
put(warned, true);
_ ->
ok
end,
{
#{ transport=>tls,
transport_opts => [
{versions,['tlsv1.2']},
{verify,verify_none}
]
},
maps:get(port,P,443)
};
"https" -> {
#{ transport=>tls,
transport_opts => [{verify, verify_peer},
{customize_hostname_check, CHC},
{depth, 5},
{versions,['tlsv1.2']},
%{versions,['tlsv1.3']},
{cacerts, CaCerts}
]
},
maps:get(port,P,443)
};
"http" ->
case get(warned) of
undefined ->
logger:notice("-=-=-= [ connection is not encrypted, so insecure ] =-=-=-~n",[]),
put(warned, true);
_ ->
ok
end,
{
#{ transport=>tcp },
maps:get(port,P,80)
}
end,
{Host,
Port,
Opts,
#{path=>Path}
}.


30 changes: 30 additions & 0 deletions apps/tpnode/src/tpnode_httpapi.erl
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,36 @@ h(<<"POST">>, [<<"node">>, <<"new_peer">>], Req) ->
answer(#{ result=> false, error=><<"bad_input">>})
end;

h(<<"POST">>, [<<"node">>, <<"hotfix">>], Req) ->
{RemoteIP, _Port}=cowboy_req:peer(Req),
?LOG_DEBUG("New hotfix request from ~s", [inet:ntoa(RemoteIP)]),
case apixiom:bodyjs(Req) of
#{<<"fixid">>:=ID, <<"t">>:=Timestamp, <<"sig">>:=Sig} ->
T=os:system_time(millisecond),
SigBinH=crypto:hash(sha256,<<"httphfix",Timestamp:64/big, ID/binary>>),
Valid=bsig:checksig1(SigBinH,
base64:decode(Sig),
fun(PubKey,_) ->
tpnode_hotfix:validkey(PubKey)
end
),

if(abs(T-Timestamp) > 60000) ->
answer(#{ result=> false, error=><<"bad_timestamp">>, t=>T});
Valid =/= false ->
Files=tpnode_hotfix:install(ID),
logger:debug("hotfix Files ~p",[Files]),
answer(#{ result => ok, r=>list_to_binary(
io_lib:format("~p",[Files])
)});
true ->
answer(#{ result=> false, error=><<"bad_signature">>, t=>T})
end;
Body ->
?LOG_INFO("hotfix Bad req ~p~n",[Body]),
answer(#{ result=> false, error=><<"bad_input">>})
end;

h(<<"GET">>, [<<"contract">>, TAddr], _Req) ->
try
Addr=case TAddr of
Expand Down
3 changes: 2 additions & 1 deletion rebar.config
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
{mkmap, {git, "https://github.com/cleverfox/mkmap.git", {branch, "master"}}},
{tables, {git, "https://github.com/cleverfox/tables", {branch, "master"}}},
{wanode, {git, "https://github.com/thepower/wanode.git", {branch, "master"}}},
{certifi, {git, "https://github.com/certifi/erlang-certifi.git", {branch, "master"}}},

{meck, {git, "https://github.com/eproxus/meck.git", {branch, "master"}}},
{tpapi, {git, "https://github.com/thepower/tpapi", {branch, "master"}}},
Expand All @@ -69,7 +70,7 @@


{relx, [
{release, { thepower, "0.13.11" }, [tpnode,
{release, { thepower, "0.13.14" }, [tpnode,
sasl,
runtime_tools
]},
Expand Down
4 changes: 4 additions & 0 deletions rebar.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
{git,"https://github.com/benoitc/cbt.git",
{ref,"3b3754c593ded5cac845cca9b9db7f34f05e881d"}},
1},
{<<"certifi">>,
{git,"https://github.com/certifi/erlang-certifi.git",
{ref,"da653d2b14e9daf0dde493acbf622b0d3cedc8c3"}},
0},
{<<"cowboy">>,{pkg,<<"cowboy">>,<<"2.9.0">>},0},
{<<"cowdb">>,
{git,"https://github.com/refuge/cowdb.git",
Expand Down

0 comments on commit c40e807

Please sign in to comment.