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
	
	Block a user