@@ -7,18 +7,14 @@ defmodule NervesHubWeb.DeviceSocket do
77 alias NervesHub.Devices
88 alias NervesHub.Devices.Connections
99 alias NervesHub.Devices.DeviceConnection
10- alias NervesHub.Products
1110 alias NervesHub.Tracker
1211
13- alias Plug.Crypto
12+ alias NervesHub.RPC.DeviceAuth
1413
1514 channel ( "console" , NervesHubWeb.ConsoleChannel )
1615 channel ( "device" , NervesHubWeb.DeviceChannel )
1716 channel ( "extensions" , NervesHubWeb.ExtensionsChannel )
1817
19- # Default 90 seconds max age for the signature
20- @ default_max_hmac_age 90
21-
2218 defoverridable init: 1 , handle_in: 2 , terminate: 2
2319
2420 @ impl Phoenix.Socket.Transport
@@ -96,14 +92,10 @@ defmodule NervesHubWeb.DeviceSocket do
9692 when is_list ( x_headers ) and length ( x_headers ) > 0 do
9793 headers = Map . new ( x_headers )
9894
99- with :ok <- check_shared_secret_enabled ( ) ,
100- { :ok , key , salt , verification_opts } <- decode_from_headers ( headers ) ,
101- { :ok , auth } <- get_shared_secret_auth ( key ) ,
102- { :ok , signature } <- Map . fetch ( headers , "x-nh-signature" ) ,
103- { :ok , identifier } <- Crypto . verify ( auth . secret , salt , signature , verification_opts ) ,
104- { :ok , device } <- get_or_maybe_create_device ( auth , identifier ) do
105- socket_and_assigns ( socket , device )
106- else
95+ case DeviceAuth . connect_device ( { :shared_secrets , x_headers } ) do
96+ { :ok , device } ->
97+ socket_and_assigns ( socket , Devices . preload_product ( device ) )
98+
10799 error ->
108100 :telemetry . execute ( [ :nerves_hub , :devices , :invalid_auth ] , % { count: 1 } , % {
109101 auth: :shared_secrets ,
@@ -133,61 +125,6 @@ defmodule NervesHubWeb.DeviceSocket do
133125 ]
134126 end
135127
136- defp decode_from_headers ( % { "x-nh-alg" => "NH1-HMAC-" <> alg } = headers ) do
137- with [ digest_str , iter_str , klen_str ] <- String . split ( alg , "-" ) ,
138- digest <- String . to_existing_atom ( String . downcase ( digest_str ) ) ,
139- { iterations , "" } <- Integer . parse ( iter_str ) ,
140- { key_length , "" } <- Integer . parse ( klen_str ) ,
141- { signed_at , "" } <- Integer . parse ( headers [ "x-nh-time" ] ) ,
142- { :ok , key } <- Map . fetch ( headers , "x-nh-key" ) do
143- expected_salt = """
144- NH1:device-socket:shared-secret:connect
145-
146- x-nh-alg=NH1-HMAC-#{ alg }
147- x-nh-key=#{ key }
148- x-nh-time=#{ signed_at }
149- """
150-
151- opts = [
152- key_length: key_length ,
153- key_iterations: iterations ,
154- key_digest: digest ,
155- signed_at: signed_at ,
156- max_age: max_hmac_age ( )
157- ]
158-
159- { :ok , key , expected_salt , opts }
160- end
161- end
162-
163- defp decode_from_headers ( _headers ) , do: { :error , :headers_decode_failed }
164-
165- defp get_shared_secret_auth ( "nhp_" <> _ = key ) , do: Products . get_shared_secret_auth ( key )
166- defp get_shared_secret_auth ( key ) , do: Devices . get_shared_secret_auth ( key )
167-
168- defp get_or_maybe_create_device ( % Products.SharedSecretAuth { } = auth , identifier ) do
169- # TODO: Support JITP profile here to decide if enabled or what tags to use
170- Devices . get_or_create_device ( auth , identifier )
171- end
172-
173- defp get_or_maybe_create_device ( % { device: % { identifier: identifier } = device } , identifier ) ,
174- do: { :ok , device }
175-
176- defp get_or_maybe_create_device ( _auth , _identifier ) , do: { :error , :bad_identifier }
177-
178- defp max_hmac_age ( ) do
179- Application . get_env ( :nerves_hub , __MODULE__ , [ ] )
180- |> Keyword . get ( :max_age , @ default_max_hmac_age )
181- end
182-
183- defp check_shared_secret_enabled ( ) do
184- if shared_secrets_enabled? ( ) do
185- :ok
186- else
187- { :error , :shared_secrets_not_enabled }
188- end
189- end
190-
191128 defp socket_and_assigns ( socket , device ) do
192129 # disconnect devices using the same identifier
193130 _ = socket . endpoint . broadcast_from ( self ( ) , "device_socket:#{ device . id } " , "disconnect" , % { } )
@@ -273,10 +210,4 @@ defmodule NervesHubWeb.DeviceSocket do
273210 defp last_seen_update_interval ( ) do
274211 Application . get_env ( :nerves_hub , :device_last_seen_update_interval_minutes )
275212 end
276-
277- def shared_secrets_enabled? ( ) do
278- Application . get_env ( :nerves_hub , __MODULE__ , [ ] )
279- |> Keyword . get ( :shared_secrets , [ ] )
280- |> Keyword . get ( :enabled , false )
281- end
282213end
0 commit comments