diff options
Diffstat (limited to 'lib/diameter/src/base/diameter_types.erl')
-rw-r--r-- | lib/diameter/src/base/diameter_types.erl | 29 |
1 files changed, 16 insertions, 13 deletions
diff --git a/lib/diameter/src/base/diameter_types.erl b/lib/diameter/src/base/diameter_types.erl index fe7613541c..87a0f0663d 100644 --- a/lib/diameter/src/base/diameter_types.erl +++ b/lib/diameter/src/base/diameter_types.erl @@ -93,7 +93,7 @@ case diameter_codec:getopt(string_decode) of true -> binary_to_list(Bin); - _ -> + false -> Bin end; @@ -565,18 +565,29 @@ msb(false) -> ?TIME_2036. scan_uri(Bin) -> RE = "^(aaas?)://" - "([-a-zA-Z0-9.]+)" - "(:([0-9]+))?" + "([-a-zA-Z0-9.]{1,255})" + "(:0{0,5}([0-9]{1,5}))?" "(;transport=(tcp|sctp|udp))?" "(;protocol=(diameter|radius|tacacs\\+))?$", + %% A port number is 16-bit, so an arbitrary number of digits is + %% just a vulnerability, but provide a little slack with leading + %% zeros in a port number just because the regexp was previously + %% [0-9]+ and it's not inconceivable that a value might be padded. + %% Don't fantasize about this padding being more than the number + %% of digits in the port number proper. + %% + %% Similarly, a FQDN can't be arbitrarily long: at most 255 + %% octets. {match, [A, DN, PN, T, P]} = re:run(Bin, RE, [{capture, [1,2,4,6,8], binary}]), Type = to_atom(A), {PN0, T0} = defaults(diameter_codec:getopt(rfc), Type), + PortNr = to_int(PN, PN0), + 0 = PortNr bsr 16, %% assert #diameter_uri{type = Type, - fqdn = from_bin(DN), - port = to_int(PN, PN0), + fqdn = 'OctetString'(decode, DN), + port = PortNr, transport = to_atom(T, T0), protocol = to_atom(P, diameter)}. @@ -588,14 +599,6 @@ defaults(6733, aaa) -> defaults(6733, aaas) -> {5658, tcp}. -from_bin(B) -> - case diameter_codec:getopt(string_decode) of - true -> - binary_to_list(B); - false -> - B - end. - to_int(<<>>, N) -> N; to_int(B, _) -> |