Skip to content

Commit aaf9f77

Browse files
authored
Validate USERNAME in binding requests (#17)
1 parent b05bb9c commit aaf9f77

File tree

5 files changed

+57
-26
lines changed

5 files changed

+57
-26
lines changed

.credo.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@
104104
{Credo.Check.Readability.ParenthesesInCondition, []},
105105
{Credo.Check.Readability.ParenthesesOnZeroArityDefs, []},
106106
{Credo.Check.Readability.PipeIntoAnonymousFunctions, []},
107-
{Credo.Check.Readability.PredicateFunctionNames, []},
107+
{Credo.Check.Readability.PredicateFunctionNames, [exit_status: 0]},
108108
{Credo.Check.Readability.PreferImplicitTry, []},
109109
{Credo.Check.Readability.RedundantBlankLines, []},
110110
{Credo.Check.Readability.Semicolons, []},

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ as WebRTC multiplexes traffic on a single socket but PRs are welcomed
2727
```elixir
2828
def deps do
2929
[
30-
{:ex_ice, "~> 0.4.0"}
30+
{:ex_ice, "~> 0.5.0"}
3131
]
3232
end
3333
```

lib/ice_agent.ex

Lines changed: 44 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,7 @@ defmodule ExICE.ICEAgent do
509509
{true, state}
510510

511511
nil ->
512+
# credo:disable-for-lines:3 Credo.Check.Refactor.Nesting
512513
case get_next_gathering_transaction(state.gathering_transactions) do
513514
{_t_id, transaction} ->
514515
case handle_gathering_transaction(transaction, state) do
@@ -761,11 +762,9 @@ defmodule ExICE.ICEAgent do
761762
end
762763

763764
## BINDING REQUEST HANDLING ##
764-
765765
defp handle_binding_request(socket, src_ip, src_port, msg, state) do
766-
# username = state.local_ufrag <> ":" <> state.remote_ufrag
767-
# TODO check username
768-
with {:ok, key} <- authenticate_msg(msg, state.local_pwd),
766+
with :ok <- check_username(msg, state.local_ufrag),
767+
{:ok, key} <- authenticate_msg(msg, state.local_pwd),
769768
{:ok, prio_attr} <- get_prio_attribute(msg),
770769
{:ok, role_attr} <- get_role_attribute(msg),
771770
use_cand_attr when use_cand_attr in [nil, %UseCandidate{}] <-
@@ -805,12 +804,21 @@ defmodule ExICE.ICEAgent do
805804
# we should add message-integrity
806805
Logger.debug("""
807806
Invalid binding request, reason: #{reason}. \
808-
Sending bad request error response"\
807+
Sending bad request error response\
809808
""")
810809

811810
send_bad_request_error_response(socket, src_ip, src_port, msg)
812811
state
813812

813+
{:error, reason} when reason in [:missing_username, :invalid_username] ->
814+
Logger.debug("""
815+
Invalid binding request, reason: #{reason}. \
816+
Sending unauthenticated error response\
817+
""")
818+
819+
send_unauthenticated_error_response(socket, src_ip, src_port, msg)
820+
state
821+
814822
{:error, reason} ->
815823
Logger.debug("Ignoring binding request, reason: #{reason}")
816824
state
@@ -898,6 +906,19 @@ defmodule ExICE.ICEAgent do
898906

899907
defp check_req_role_conflict(_role_attr, state), do: {:ok, state}
900908

909+
defp check_username(msg, local_ufrag) do
910+
# See RFC 8445, sec. 7.3.
911+
case Message.get_attribute(msg, Username) do
912+
{:ok, %Username{value: username}} ->
913+
if String.starts_with?(username, local_ufrag <> ":"),
914+
do: :ok,
915+
else: {:error, :invalid_username}
916+
917+
nil ->
918+
{:error, :missing_username}
919+
end
920+
end
921+
901922
## BINDING RESPONSE HANDLING ##
902923

903924
defp handle_conn_check_response(socket, src_ip, src_port, msg, state) do
@@ -1219,14 +1240,6 @@ defmodule ExICE.ICEAgent do
12191240
send_binding_success_response(pair.local_cand.socket, src_ip, src_port, msg, key)
12201241
end
12211242

1222-
@doc false
1223-
@spec send_bad_request_error_response(CandidatePair.t(), Message.t()) :: :ok
1224-
def send_bad_request_error_response(pair, msg) do
1225-
src_ip = pair.remote_cand.address
1226-
src_port = pair.remote_cand.port
1227-
send_bad_request_error_response(pair.local_cand.socket, src_ip, src_port, msg)
1228-
end
1229-
12301243
defp send_binding_success_response(socket, src_ip, src_port, req, key) do
12311244
type = %Type{class: :success_response, method: :binding}
12321245

@@ -1239,6 +1252,14 @@ defmodule ExICE.ICEAgent do
12391252
do_send(socket, {src_ip, src_port}, resp)
12401253
end
12411254

1255+
@doc false
1256+
@spec send_bad_request_error_response(CandidatePair.t(), Message.t()) :: :ok
1257+
def send_bad_request_error_response(pair, msg) do
1258+
src_ip = pair.remote_cand.address
1259+
src_port = pair.remote_cand.port
1260+
send_bad_request_error_response(pair.local_cand.socket, src_ip, src_port, msg)
1261+
end
1262+
12421263
defp send_bad_request_error_response(socket, src_ip, src_port, req) do
12431264
type = %Type{class: :error_response, method: :binding}
12441265

@@ -1249,6 +1270,16 @@ defmodule ExICE.ICEAgent do
12491270
do_send(socket, {src_ip, src_port}, response)
12501271
end
12511272

1273+
defp send_unauthenticated_error_response(socket, src_ip, src_port, req) do
1274+
type = %Type{class: :error_response, method: :binding}
1275+
1276+
response =
1277+
Message.new(req.transaction_id, type, [%ErrorCode{code: 401}])
1278+
|> Message.encode()
1279+
1280+
do_send(socket, {src_ip, src_port}, response)
1281+
end
1282+
12521283
defp send_role_conflict_error_response(socket, src_ip, src_port, req, key) do
12531284
type = %Type{class: :error_response, method: :binding}
12541285

mix.exs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
defmodule ExICE.MixProject do
22
use Mix.Project
33

4-
@version "0.4.0"
4+
@version "0.5.0"
55
@source_url "https://github.com/elixir-webrtc/ex_ice"
66

77
def project do

mix.lock

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,21 @@
11
%{
2-
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
2+
"bunt": {:hex, :bunt, "1.0.0", "081c2c665f086849e6d57900292b3a161727ab40431219529f13c4ddcf3e7a44", [:mix], [], "hexpm", "dc5f86aa08a5f6fa6b8096f0735c4e76d54ae5c9fa2c143e5a1fc7c1cd9bb6b5"},
33
"certifi": {:hex, :certifi, "2.9.0", "6f2a475689dd47f19fb74334859d460a2dc4e3252a3324bd2111b8f0429e7e21", [:rebar3], [], "hexpm", "266da46bdb06d6c6d35fde799bcb28d36d985d424ad7c08b5bb48f5b5cdd4641"},
4-
"credo": {:hex, :credo, "1.6.5", "330ca591c12244ab95498d8f47994c493064b2689febf1236d43d596b4f2261d", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "101de53e6907397c3246ccd2cc9b9f0d3fc0b7805b8e1c1c3d818471fc85bafd"},
5-
"earmark_parser": {:hex, :earmark_parser, "1.4.26", "f4291134583f373c7d8755566122908eb9662df4c4b63caa66a0eabe06569b0a", [:mix], [], "hexpm", "48d460899f8a0c52c5470676611c01f64f3337bad0b26ddab43648428d94aabc"},
6-
"ex_doc": {:hex, :ex_doc, "0.28.4", "001a0ea6beac2f810f1abc3dbf4b123e9593eaa5f00dd13ded024eae7c523298", [: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", "bf85d003dd34911d89c8ddb8bda1a958af3471a274a4c2150a9c01c78ac3f8ed"},
4+
"credo": {:hex, :credo, "1.7.3", "05bb11eaf2f2b8db370ecaa6a6bda2ec49b2acd5e0418bc106b73b07128c0436", [:mix], [{:bunt, "~> 0.2.1 or ~> 1.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2 or ~> 1.0", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "35ea675a094c934c22fb1dca3696f3c31f2728ae6ef5a53b5d648c11180a4535"},
5+
"earmark_parser": {:hex, :earmark_parser, "1.4.39", "424642f8335b05bb9eb611aa1564c148a8ee35c9c8a8bba6e129d51a3e3c6769", [:mix], [], "hexpm", "06553a88d1f1846da9ef066b87b57c6f605552cfbe40d20bd8d59cc6bde41944"},
6+
"ex_doc": {:hex, :ex_doc, "0.31.1", "8a2355ac42b1cc7b2379da9e40243f2670143721dd50748bf6c3b1184dae2089", [:mix], [{:earmark_parser, "~> 1.4.39", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_c, ">= 0.1.1", [hex: :makeup_c, repo: "hexpm", optional: true]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "3178c3a407c557d8343479e1ff117a96fd31bafe52a039079593fb0524ef61b0"},
77
"ex_stun": {:hex, :ex_stun, "0.1.0", "252474bf4c8519fbf4bc0fbfc6a1b846a634b1478c65dbbfb4b6ab4e33c2a95a", [:mix], [], "hexpm", "629fc8be45b624a92522f81d85ba001877b1f0745889a2419bdb678790d7480c"},
8-
"excoveralls": {:hex, :excoveralls, "0.17.0", "279f124dba347903bb654bc40745c493ae265d45040001b4899ea1edf88078c7", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "08b638d114387a888f9cb8d65f2a0021ec04c3e447b793efa7c1e734aba93004"},
9-
"file_system": {:hex, :file_system, "0.2.10", "fb082005a9cd1711c05b5248710f8826b02d7d1784e7c3451f9c1231d4fc162d", [:mix], [], "hexpm", "41195edbfb562a593726eda3b3e8b103a309b733ad25f3d642ba49696bf715dc"},
8+
"excoveralls": {:hex, :excoveralls, "0.18.0", "b92497e69465dc51bc37a6422226ee690ab437e4c06877e836f1c18daeb35da9", [:mix], [{:castore, "~> 1.0", [hex: :castore, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1109bb911f3cb583401760be49c02cbbd16aed66ea9509fc5479335d284da60b"},
9+
"file_system": {:hex, :file_system, "1.0.0", "b689cc7dcee665f774de94b5a832e578bd7963c8e637ef940cd44327db7de2cd", [:mix], [], "hexpm", "6752092d66aec5a10e662aefeed8ddb9531d79db0bc145bb8c40325ca1d8536d"},
1010
"hackney": {:hex, :hackney, "1.18.1", "f48bf88f521f2a229fc7bae88cf4f85adc9cd9bcf23b5dc8eb6a1788c662c4f6", [:rebar3], [{:certifi, "~>2.9.0", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a4ecdaff44297e9b5894ae499e9a070ea1888c84afdd1fd9b7b2bc384950128e"},
1111
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
1212
"jason": {:hex, :jason, "1.4.1", "af1504e35f629ddcdd6addb3513c3853991f694921b1b9368b0bd32beb9f1b63", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "fbb01ecdfd565b56261302f7e1fcc27c4fb8f32d56eab74db621fc154604a7a1"},
13-
"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"},
14-
"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"},
15-
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
13+
"makeup": {:hex, :makeup, "1.1.1", "fa0bc768698053b2b3869fa8a62616501ff9d11a562f3ce39580d60860c3a55e", [:mix], [{:nimble_parsec, "~> 1.2.2 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "5dc62fbdd0de44de194898b6710692490be74baa02d9d108bc29f007783b0b48"},
14+
"makeup_elixir": {:hex, :makeup_elixir, "0.16.1", "cc9e3ca312f1cfeccc572b37a09980287e243648108384b97ff2b76e505c3555", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.2.3 or ~> 1.3", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "e127a341ad1b209bd80f7bd1620a15693a9908ed780c3b763bccf7d200c767c6"},
15+
"makeup_erlang": {:hex, :makeup_erlang, "0.1.3", "d684f4bac8690e70b06eb52dad65d26de2eefa44cd19d64a8095e1417df7c8fd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "b78dc853d2e670ff6390b605d807263bf606da3c82be37f9d7f68635bd886fc9"},
1616
"metrics": {:hex, :metrics, "1.0.1", "25f094dea2cda98213cecc3aeff09e940299d950904393b2a29d191c346a8486", [:rebar3], [], "hexpm", "69b09adddc4f74a40716ae54d140f93beb0fb8978d8636eaded0c31b6f099f16"},
1717
"mimerl": {:hex, :mimerl, "1.2.0", "67e2d3f571088d5cfd3e550c383094b47159f3eee8ffa08e64106cdf5e981be3", [:rebar3], [], "hexpm", "f278585650aa581986264638ebf698f8bb19df297f66ad91b18910dfc6e19323"},
18-
"nimble_parsec": {:hex, :nimble_parsec, "1.2.3", "244836e6e3f1200c7f30cb56733fd808744eca61fd182f731eac4af635cc6d0b", [:mix], [], "hexpm", "c8d789e39b9131acf7b99291e93dae60ab48ef14a7ee9d58c6964f59efb570b0"},
18+
"nimble_parsec": {:hex, :nimble_parsec, "1.4.0", "51f9b613ea62cfa97b25ccc2c1b4216e81df970acd8e16e8d1bdc58fef21370d", [:mix], [], "hexpm", "9c565862810fb383e9838c1dd2d7d2c437b3d13b267414ba6af33e50d2d1cf28"},
1919
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
2020
"ssl_verify_fun": {:hex, :ssl_verify_fun, "1.1.6", "cf344f5692c82d2cd7554f5ec8fd961548d4fd09e7d22f5b62482e5aeaebd4b0", [:make, :mix, :rebar3], [], "hexpm", "bdb0d2471f453c88ff3908e7686f86f9be327d065cc1ec16fa4540197ea04680"},
2121
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},

0 commit comments

Comments
 (0)