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