From 29569f0b728477bc9d85cb240f18705053cc821e Mon Sep 17 00:00:00 2001 From: Jean-Louis Huynen Date: Mon, 6 Mar 2023 15:11:11 +0100 Subject: [PATCH] add: [lib] initla commit --- .formatter.exs | 4 ++ .gitignore | 26 ++++++++++++ README.md | 20 +++++++++ lib/ex_d4.ex | 98 +++++++++++++++++++++++++++++++++++++++++++ media/text12.png | Bin 0 -> 17341 bytes mix.exs | 40 ++++++++++++++++++ mix.lock | 11 +++++ test/ex_d4_test.exs | 38 +++++++++++++++++ test/test_helper.exs | 1 + 9 files changed, 238 insertions(+) create mode 100644 .formatter.exs create mode 100644 .gitignore create mode 100644 README.md create mode 100644 lib/ex_d4.ex create mode 100644 media/text12.png create mode 100644 mix.exs create mode 100644 mix.lock create mode 100644 test/ex_d4_test.exs create mode 100644 test/test_helper.exs diff --git a/.formatter.exs b/.formatter.exs new file mode 100644 index 0000000..d2cda26 --- /dev/null +++ b/.formatter.exs @@ -0,0 +1,4 @@ +# Used by "mix format" +[ + inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] +] diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..159d1f8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,26 @@ +# The directory Mix will write compiled artifacts to. +/_build/ + +# If you run "mix test --cover", coverage assets end up here. +/cover/ + +# The directory Mix downloads your dependencies sources to. +/deps/ + +# Where third-party dependencies like ExDoc output generated docs. +/doc/ + +# Ignore .fetch files in case you like to edit your project deps locally. +/.fetch + +# If the VM crashes, it generates a dump, let's ignore it too. +erl_crash.dump + +# Also ignore archive artifacts (built via "mix archive.build"). +*.ez + +# Ignore package tarball (built via "mix hex.build"). +exd4-*.tar + +# Temporary files, for example, from tests. +/tmp/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..edd477b --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Ex_d4 + +Ex_d4 allows for communicating with d4-servers in elixir. + +## Installation + +If [available in Hex](https://hex.pm/docs/publish), the package can be installed +by adding `ex_d4` to your list of dependencies in `mix.exs`: + +```elixir +def deps do + [ + {:exd4, "~> 0.1.0"} + ] +end +``` + +Documentation can be generated with [ExDoc](https://github.com/elixir-lang/ex_doc) +and published on [HexDocs](https://hexdocs.pm). Once published, the docs can +be found at . \ No newline at end of file diff --git a/lib/ex_d4.ex b/lib/ex_d4.ex new file mode 100644 index 0000000..053cf65 --- /dev/null +++ b/lib/ex_d4.ex @@ -0,0 +1,98 @@ +defmodule Exd4 do + alias Ecto.UUID + + @moduledoc """ + Module that holds D4 connection struct, and provides encapsulation method. + """ + @moduledoc since: "0.1.0" + + # D4 protocol parameters + # bits + @version_size 8 + # bits + @type_size 8 + # bytes + @uuid_size 16 + # bits + @timestamp_size 64 + # bytes + @hmac_size 32 + # bits + @size_size 32 + + # TODO metaheader implementation + # @metaheader_max_size 100_000 + + @enforce_keys [:destination, :uuid] + + defstruct destination: nil, + uuid: nil, + snaplen: 4096, + port: 4443, + key: "private key to change", + type: 3, + version: 1 + + @typedoc "A d4 connection struct" + @type t() :: %__MODULE__{ + destination: :inet.ip_address(), + uuid: String.t(), + snaplen: non_neg_integer(), + port: non_neg_integer(), + key: String.t(), + type: non_neg_integer(), + version: non_neg_integer() + } + + @doc """ + Encapsultate data to ship to a given D4 server. + + Return a tuple {:ok, [IO data]} + """ + def encapsulate!(d4_connection, data) do + # initialize header + uuid_bytes = + case UUID.dump(d4_connection.uuid) do + {:ok, uuid_bytes} -> + uuid_bytes + + :error -> + raise("Cannot convert UUID #{d4_connection.uuid}") + end + + timestamp = :os.system_time(:second) + hmac_init = :binary.copy(<<0>>, @hmac_size) + + # build header + header = << + d4_connection.version::@version_size, + d4_connection.type::@type_size, + uuid_bytes::@uuid_size-binary, + timestamp::unsigned-integer-size(@timestamp_size)-little, + hmac_init::binary, + byte_size(data)::unsigned-integer-size(@size_size)-little + >> + + # compute HMAC on header + data + hmac = + :crypto.macN( + :hmac, + :sha256, + :unicode.characters_to_binary(d4_connection.key), + header <> data, + 32 + ) + + # update the HMAC in the header + header = << + d4_connection.version::@version_size, + d4_connection.type::@type_size, + uuid_bytes::@uuid_size-binary, + timestamp::integer-size(@timestamp_size)-little, + hmac::binary, + byte_size(data)::unsigned-integer-size(@size_size)-little + >> + + {:ok, [header, data]} + end +end diff --git a/media/text12.png b/media/text12.png new file mode 100644 index 0000000000000000000000000000000000000000..63fe5a0972bdf1db26d88b3a739e17264718427c GIT binary patch literal 17341 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 g9;|d%JimUICMMv%>Ua 1.14", + start_permanent: Mix.env() == :prod, + deps: deps(), + + # Docs + name: "D4 elixir client", + organization: "d4project", + source_url: "https://github.com/d4-project/ex_d4", + homepage_url: "http://d4-project.org", + licence: "MIT", + docs: [ + main: "D4 client", + logo: "media/text12.png", + extras: ["README.md"] + ] + ] + end + + # Run "mix help compile.app" to learn about applications. + def application do + [ + extra_applications: [:logger, :crypto] + ] + end + + # Run "mix help deps" to learn about dependencies. + defp deps do + [ + {:ecto, "~> 3.9.4"}, + {:ex_doc, "~> 0.27", only: :dev, runtime: false} + ] + end +end diff --git a/mix.lock b/mix.lock new file mode 100644 index 0000000..01c4a19 --- /dev/null +++ b/mix.lock @@ -0,0 +1,11 @@ +%{ + "decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"}, + "earmark_parser": {:hex, :earmark_parser, "1.4.31", "a93921cdc6b9b869f519213d5bc79d9e218ba768d7270d46fdcf1c01bacff9e2", [:mix], [], "hexpm", "317d367ee0335ef037a87e46c91a2269fef6306413f731e8ec11fc45a7efd059"}, + "ecto": {:hex, :ecto, "3.9.4", "3ee68e25dbe0c36f980f1ba5dd41ee0d3eb0873bccae8aeaf1a2647242bffa35", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "de5f988c142a3aa4ec18b85a4ec34a2390b65b24f02385c1144252ff6ff8ee75"}, + "ex_doc": {:hex, :ex_doc, "0.29.2", "dfa97532ba66910b2a3016a4bbd796f41a86fc71dd5227e96f4c8581fdf0fdf0", [:mix], [{:earmark_parser, "~> 1.4.19", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "6b5d7139eda18a753e3250e27e4a929f8d2c880dd0d460cb9986305dea3e03af"}, + "makeup": {:hex, :makeup, "1.1.0", "6b67c8bc2882a6b6a445859952a602afc1a41c2e08379ca057c0f525366fc3ca", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "0a45ed501f4a8897f580eabf99a2e5234ea3e75a4373c8a52824f6e873be57a6"}, + "makeup_elixir": {:hex, :makeup_elixir, "0.16.0", "f8c570a0d33f8039513fbccaf7108c5d750f47d8defd44088371191b76492b0b", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "28b2cbdc13960a46ae9a8858c4bebdec3c9a6d7b4b9e7f4ed1502f8159f338e7"}, + "makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"}, + "nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"}, + "telemetry": {:hex, :telemetry, "1.2.1", "68fdfe8d8f05a8428483a97d7aab2f268aaff24b49e0f599faa091f1d4e7f61c", [:rebar3], [], "hexpm", "dad9ce9d8effc621708f99eac538ef1cbe05d6a874dd741de2e689c47feafed5"}, +} diff --git a/test/ex_d4_test.exs b/test/ex_d4_test.exs new file mode 100644 index 0000000..b538d8c --- /dev/null +++ b/test/ex_d4_test.exs @@ -0,0 +1,38 @@ +defmodule Exd4Test do + use ExUnit.Case, async: true + + require Logger + + test "Encapsulating and shiping data to a d4 server" do + options = [ + :binary, + active: false, + verify: :verify_none + ] + + d4_connection = %Exd4{ + destination: {10, 106, 129, 254}, + uuid: "b5062e1f-674e-45a0-9c30-2557d6e70ef5" + } + + :ok = :ssl.start() + + case :ssl.connect(d4_connection.destination, d4_connection.port, options, 5_000) do + {:ok, socket} -> + case Exd4.encapsulate!(d4_connection, "123456789\n") do + {:ok, packet} -> + assert :ssl.send(socket, packet) == :ok + end + + case Exd4.encapsulate!(d4_connection, "Is my D4 client broken??\n") do + {:ok, packet} -> + assert :ssl.send(socket, packet) == :ok + end + + :ok = :ssl.close(socket) + + {:error, reason} -> + Logger.error("Failed to connect to test server #{inspect({:error, reason})}") + end + end +end diff --git a/test/test_helper.exs b/test/test_helper.exs new file mode 100644 index 0000000..869559e --- /dev/null +++ b/test/test_helper.exs @@ -0,0 +1 @@ +ExUnit.start()