Process server, port, error and warning records
This commit is contained in:
parent
ec308c1fd4
commit
28f1a91ebf
|
@ -11,6 +11,7 @@ defmodule Chronoscope.NTS do
|
||||||
case :ssl.connect(host, port, tls_options, @timeout_in_milliseconds) do
|
case :ssl.connect(host, port, tls_options, @timeout_in_milliseconds) do
|
||||||
{:ok, socket} -> perform_key_establishment(socket)
|
{:ok, socket} -> perform_key_establishment(socket)
|
||||||
{:error, {:tls_alert, {:handshake_failure, error}}} -> {:error, to_string(error)}
|
{:error, {:tls_alert, {:handshake_failure, error}}} -> {:error, to_string(error)}
|
||||||
|
{:error, :timeout} -> {:error, :timeout}
|
||||||
{:error, error} -> {:error, inspect(error)}
|
{:error, error} -> {:error, inspect(error)}
|
||||||
error -> {:error, inspect(error)}
|
error -> {:error, inspect(error)}
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,24 +10,37 @@ defmodule Chronoscope.NTS.KeyEstablishment do
|
||||||
30 => "AEAD_AES_128_GCM_SIV"
|
30 => "AEAD_AES_128_GCM_SIV"
|
||||||
}
|
}
|
||||||
|
|
||||||
@next_protocols %{0 => "NTPv4"}
|
@next_protocols %{
|
||||||
|
0 => "NTPv4"
|
||||||
|
}
|
||||||
|
|
||||||
|
@errors %{
|
||||||
|
0 => "Unrecognized Critical Record",
|
||||||
|
1 => "Bad Request",
|
||||||
|
2 => "Internal Server Error"
|
||||||
|
}
|
||||||
|
|
||||||
def request() do
|
def request() do
|
||||||
@next_protocol_negotiation <> @aead_algorithm_negotiation <> @end_of_message
|
@next_protocol_negotiation <> @aead_algorithm_negotiation <> @end_of_message
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_response(response) do
|
def parse_response(response) do
|
||||||
{:ok, Map.update(do_parse_response(response, %{}), :cookies, 0, &length/1)}
|
response
|
||||||
|
|> do_parse_response(%{})
|
||||||
|
|> Map.update(:cookies, 0, &length/1)
|
||||||
|
|> then(&{:ok, &1})
|
||||||
end
|
end
|
||||||
|
|
||||||
defp do_parse_response([], acc) do
|
defp do_parse_response([], acc) do
|
||||||
acc
|
acc
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# End of Message
|
||||||
defp do_parse_response([0x80, 0x00, 0x00, 0x00], acc) do
|
defp do_parse_response([0x80, 0x00, 0x00, 0x00], acc) do
|
||||||
acc
|
acc
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# NTS Next Protocol Negotiation
|
||||||
defp do_parse_response([0x80, 0x01, length_high, length_low | rest], acc) do
|
defp do_parse_response([0x80, 0x01, length_high, length_low | rest], acc) do
|
||||||
length = combine_octets(length_high, length_low)
|
length = combine_octets(length_high, length_low)
|
||||||
{next_protocols, remaining} = Enum.split(rest, length)
|
{next_protocols, remaining} = Enum.split(rest, length)
|
||||||
|
@ -38,6 +51,24 @@ defmodule Chronoscope.NTS.KeyEstablishment do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Error
|
||||||
|
defp do_parse_response([0x80, 0x02, 0x00, 0x02, error_high, error_low | rest], acc) do
|
||||||
|
error = combine_octets(error_high, error_low)
|
||||||
|
|
||||||
|
do_parse_response(
|
||||||
|
rest,
|
||||||
|
Map.put(acc, :error, Map.get(@errors, error, error))
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Warning
|
||||||
|
defp do_parse_response([0x80, 0x03, 0x00, 0x02, warning_high, warning_low | rest], acc) do
|
||||||
|
warning = combine_octets(warning_high, warning_low)
|
||||||
|
|
||||||
|
do_parse_response(rest, Map.put(acc, :warning, warning))
|
||||||
|
end
|
||||||
|
|
||||||
|
# AEAD Algorithm Negotiation
|
||||||
defp do_parse_response([first, 0x04, length_high, length_low | rest], acc)
|
defp do_parse_response([first, 0x04, length_high, length_low | rest], acc)
|
||||||
when first == 0x00 or first == 0x80 do
|
when first == 0x00 or first == 0x80 do
|
||||||
length = combine_octets(length_high, length_low)
|
length = combine_octets(length_high, length_low)
|
||||||
|
@ -49,6 +80,7 @@ defmodule Chronoscope.NTS.KeyEstablishment do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# New Cookie for NTPv4
|
||||||
defp do_parse_response([first, 0x05, length_high, length_low | rest], acc)
|
defp do_parse_response([first, 0x05, length_high, length_low | rest], acc)
|
||||||
when first == 0x00 or first == 0x80 do
|
when first == 0x00 or first == 0x80 do
|
||||||
length = combine_octets(length_high, length_low)
|
length = combine_octets(length_high, length_low)
|
||||||
|
@ -62,6 +94,23 @@ defmodule Chronoscope.NTS.KeyEstablishment do
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# NTPv4 Server Negotiation
|
||||||
|
defp do_parse_response([first, 0x06, length_high, length_low | rest], acc)
|
||||||
|
when first == 0x00 or first == 0x80 do
|
||||||
|
length = combine_octets(length_high, length_low)
|
||||||
|
{server, remaining} = Enum.split(rest, length)
|
||||||
|
|
||||||
|
do_parse_response(remaining, Map.put(acc, :server, to_string(server)))
|
||||||
|
end
|
||||||
|
|
||||||
|
# NTPv4 Port Negotiation
|
||||||
|
defp do_parse_response([first, 0x07, 0x00, 0x02, port_high, port_low | rest], acc)
|
||||||
|
when first == 0x00 or first == 0x80 do
|
||||||
|
port = combine_octets(port_high, port_low)
|
||||||
|
|
||||||
|
do_parse_response(rest, Map.put(acc, :port, port))
|
||||||
|
end
|
||||||
|
|
||||||
defp do_parse_response([_, _, length_high, length_low | rest], acc) do
|
defp do_parse_response([_, _, length_high, length_low | rest], acc) do
|
||||||
length = combine_octets(length_high, length_low)
|
length = combine_octets(length_high, length_low)
|
||||||
{_, remaining} = Enum.split(rest, length)
|
{_, remaining} = Enum.split(rest, length)
|
||||||
|
@ -97,8 +146,6 @@ defmodule Chronoscope.NTS.KeyEstablishment do
|
||||||
|> then(&do_parse_aead_algorithm_list(rest, [&1 | acc]))
|
|> then(&do_parse_aead_algorithm_list(rest, [&1 | acc]))
|
||||||
end
|
end
|
||||||
|
|
||||||
# todo parse server/port information
|
|
||||||
|
|
||||||
defp combine_octets(high, low) do
|
defp combine_octets(high, low) do
|
||||||
high <<< 8 ||| low
|
high <<< 8 ||| low
|
||||||
end
|
end
|
||||||
|
|
|
@ -16,7 +16,7 @@ defmodule ChronoscopeWeb.API.V1.NTS.KeyEstablishmentController do
|
||||||
ok_response(conn, %{status: :ok, configuration: configuration})
|
ok_response(conn, %{status: :ok, configuration: configuration})
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
ok_response(conn, %{status: :error, reason: inspect(error)})
|
ok_response(conn, %{status: :error, reason: to_string(error)})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue