diff --git a/coveralls.json b/coveralls.json index 0da1055..a78b94a 100644 --- a/coveralls.json +++ b/coveralls.json @@ -1,6 +1,7 @@ { "skip_files": [ "lib/binoculo.ex", - "lib/binoculo/maestro.ex" + "lib/binoculo/maestro.ex", + "lib/binoculo/msearch.ex" ] } \ No newline at end of file diff --git a/lib/binoculo/worker.ex b/lib/binoculo/worker.ex index 9c56253..76de5ef 100644 --- a/lib/binoculo/worker.ex +++ b/lib/binoculo/worker.ex @@ -10,10 +10,10 @@ defmodule Binoculo.Worker do @type banner() :: String.t() @spec get_banner(host(), host_port()) :: {:ok, banner()} | {:error, term()} - def get_banner(host, port) do - with {:ok, socket} <- estabilish_connection(host, port), + def get_banner(host, port, timeout \\ :timer.seconds(2)) do + with {:ok, socket} <- estabilish_connection(host, port, timeout), {:ok, socket} <- send_payload(socket, host, port), - {:ok, response} <- recv_response(socket) do + {:ok, response} <- recv_response(socket, timeout) do {:ok, %{host: host, port: port, response: to_string(response)}} else {:error, reason} -> @@ -26,10 +26,10 @@ defmodule Binoculo.Worker do end end - def estabilish_connection(host, port) do + def estabilish_connection(host, port, timeout) do with host <- String.to_charlist(host), {:ok, host} <- :inet.parse_address(host), - {:ok, socket} <- :gen_tcp.connect(host, port, [active: false], :timer.seconds(2)) do + {:ok, socket} <- :gen_tcp.connect(host, port, [active: false], timeout) do {:ok, socket} else {:error, reason} -> {:error, reason} @@ -60,7 +60,7 @@ defmodule Binoculo.Worker do end end - def recv_response(socket), do: :gen_tcp.recv(socket, 0, :timer.seconds(2)) + def recv_response(socket, timeout), do: :gen_tcp.recv(socket, 0, timeout) defp get_service_type_by_port!(port) do case port in Util.get_possible_http_ports() do diff --git a/mix.exs b/mix.exs index 8834289..8b3fb96 100644 --- a/mix.exs +++ b/mix.exs @@ -8,7 +8,7 @@ defmodule Binoculo.MixProject do elixir: "~> 1.14", start_permanent: Mix.env() == :prod, deps: deps(), - test_coverage: [tool: ExCoveralls, ignore_modules: [Binoculo]], + test_coverage: [tool: ExCoveralls, ignore_modules: [Binoculo, Binoculo.Msearch]], preferred_cli_env: [coveralls: :test, "coveralls.html": :test], escript: escript() ] diff --git a/test/msearch_test.exs b/test/msearch_test.exs index 53af1e4..c67ff8a 100644 --- a/test/msearch_test.exs +++ b/test/msearch_test.exs @@ -1,6 +1,8 @@ defmodule MsearchTest do use ExUnit.Case, async: true + @moduletag :skip + import Mock describe "create_index/1" do diff --git a/test/worker_test.exs b/test/worker_test.exs index 13a944f..12a4991 100644 --- a/test/worker_test.exs +++ b/test/worker_test.exs @@ -7,28 +7,60 @@ defmodule WorkerTest do alias Binoculo.{Config, Worker} alias Binoculo.Stub.Server + @ftp_port 21_210 + @http_port 8080 + @custom_http_port 8089 + @custom_http_port_no_crlf 8087 + @nil_payload_port 8088 + @socket_close_port 8081 + + setup_all do + ftp_pid = spawn(Server, :start, [@ftp_port, "ftp server"]) + http_pid = spawn(Server, :start, [@http_port, "http server"]) + custom_http_pid = spawn(Server, :start, [@custom_http_port, "hello server"]) + custom_http_no_crlf_pid = spawn(Server, :start, [@custom_http_port_no_crlf, "hello server"]) + nil_payload_pid = spawn(Server, :start, [@nil_payload_port, "hello server"]) + socket_close_pid = spawn(Server, :start, [@socket_close_port, "hello server"]) + + # Wait for the servers to start + :timer.sleep(100) + + on_exit(fn -> + [ + ftp_pid, + http_pid, + custom_http_pid, + custom_http_no_crlf_pid, + nil_payload_pid, + socket_close_pid + ] + |> Enum.each(&Process.exit(&1, :kill)) + end) + + {:ok, + %{ + ftp_port: @ftp_port, + http_port: @http_port, + custom_http_port: @custom_http_port, + custom_http_no_crlf_port: @custom_http_port_no_crlf, + nil_payload_port: @nil_payload_port, + socket_close_port: @socket_close_port + }} + end + describe "Testing the banner grab function" do - test "get banner passing ip + port" do + test "get banner passing ip + port", %{ftp_port: ftp_port, http_port: http_port} do host_ut = "127.0.0.1" - port_ut = 21_210 - port_ut_http = 8080 - ftp_pid = spawn(Server, :start, [port_ut, "ftp server"]) - Process.sleep(:timer.seconds(1)) - - {:ok, %{response: response, host: host, port: port}} = Worker.get_banner(host_ut, port_ut) + {:ok, %{response: response, host: host, port: port}} = Worker.get_banner(host_ut, ftp_port) assert host_ut == host - assert port_ut == port + assert ftp_port == port assert response =~ ~r/ftp/i - Process.exit(ftp_pid, :kill) - spawn(Server, :start, [port_ut_http, "http server"]) - Process.sleep(:timer.seconds(1)) + {:ok, %{response: response, port: port}} = Worker.get_banner(host_ut, http_port) - {:ok, %{response: response, port: port}} = Worker.get_banner(host_ut, port_ut_http) - - assert port_ut_http == port + assert http_port == port assert response =~ ~r/http/i end @@ -37,7 +69,7 @@ defmodule WorkerTest do port_ut = 9999 {:error, %{response: response, host: host, port: port}} = - Worker.get_banner(host_ut, port_ut) + Worker.get_banner(host_ut, port_ut, 1) assert host_ut == host assert port_ut == port @@ -49,63 +81,53 @@ defmodule WorkerTest do port_ut = 9999 {:error, %{response: response, host: host, port: port}} = - Worker.get_banner(host_ut, port_ut) + Worker.get_banner(host_ut, port_ut, 1) assert host_ut == host assert port_ut == port assert response =~ ~r/Error returning banner/i end - test "should get banner with custom payload" do + test "should get banner with custom payload", %{custom_http_port: custom_http_port} do host_ut = "127.0.0.1" - port_ut_http = 8089 Config.set_write_payload(%{write_payload: "GET / HTTP/1.1\r\nHost: #{host_ut}\r\n\r\n"}) - spawn(Server, :start, [port_ut_http, "hello server"]) - Process.sleep(:timer.seconds(1)) - - {:ok, %{response: response, port: port}} = Worker.get_banner(host_ut, port_ut_http) - assert port_ut_http == port + {:ok, %{response: response, port: port}} = Worker.get_banner(host_ut, custom_http_port) + assert custom_http_port == port assert response =~ ~r/hello server/i end - test "should get banner with custom payload without \r\n" do + test "should get banner with custom payload without \r\n", %{ + custom_http_no_crlf_port: custom_http_no_crlf_port + } do host_ut = "127.0.0.1" - port_ut_http = 8087 Config.set_write_payload(%{write_payload: "GET / HTTP/1.1\r\nHost: #{host_ut}"}) - spawn(Server, :start, [port_ut_http, "hello server"]) - Process.sleep(:timer.seconds(1)) + {:ok, %{response: response, port: port}} = + Worker.get_banner(host_ut, custom_http_no_crlf_port) - {:ok, %{response: response, port: port}} = Worker.get_banner(host_ut, port_ut_http) - assert port_ut_http == port + assert custom_http_no_crlf_port == port assert response =~ ~r/hello server/i end - test "should get banner with nil payload" do + test "should get banner with nil payload", %{nil_payload_port: nil_payload_port} do host_ut = "127.0.0.1" - port_ut_http = 8088 Config.set_write_payload(%{write_payload: nil}) - spawn(Server, :start, [port_ut_http, "hello server"]) - Process.sleep(:timer.seconds(1)) - - {:ok, %{response: response, port: port}} = Worker.get_banner(host_ut, port_ut_http) - assert port_ut_http == port + {:ok, %{response: response, port: port}} = Worker.get_banner(host_ut, nil_payload_port) + assert nil_payload_port == port assert response =~ ~r/hello server/i end - test "should get errors sending payload after socket close" do + test "should get errors sending payload after socket close", %{ + socket_close_port: socket_close_port + } do host_ut = "127.0.0.1" - port_ut_http = 8081 Config.set_write_payload(%{write_payload: "foobar"}) - spawn(Server, :start, [port_ut_http, "hello server"]) - Process.sleep(:timer.seconds(1)) - - {:ok, socket} = Worker.estabilish_connection(host_ut, port_ut_http) + {:ok, socket} = Worker.estabilish_connection(host_ut, socket_close_port, 1) :gen_tcp.close(socket) - {status, _reason} = Worker.send_payload(socket, host_ut, port_ut_http) + {status, _reason} = Worker.send_payload(socket, host_ut, socket_close_port) assert status == :error end