ruby_home 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +13 -14
- data/README.md +1 -1
- data/bin/rubyhome +1 -1
- data/lib/ruby_home/accessory_info.rb +33 -72
- data/lib/ruby_home/device_id.rb +0 -2
- data/lib/ruby_home/dns/service.rb +1 -6
- data/lib/ruby_home/dns/text_record.rb +0 -2
- data/lib/ruby_home/factories/accessory_factory.rb +0 -5
- data/lib/ruby_home/factories/characteristic_factory.rb +0 -3
- data/lib/ruby_home/factories/templates/characteristic_template.rb +0 -1
- data/lib/ruby_home/factories/templates/service_template.rb +0 -2
- data/lib/ruby_home/hap/accessory.rb +2 -2
- data/lib/ruby_home/hap/characteristic.rb +2 -2
- data/lib/ruby_home/hap/crypto/chacha20poly1305.rb +0 -4
- data/lib/ruby_home/hap/crypto/hkdf.rb +0 -2
- data/lib/ruby_home/hap/http_decryption.rb +5 -6
- data/lib/ruby_home/hap/http_encryption.rb +21 -11
- data/lib/ruby_home/hap/service.rb +0 -3
- data/lib/ruby_home/hap/tlv.rb +28 -21
- data/lib/ruby_home/hex_helper.rb +15 -0
- data/lib/ruby_home/http/application.rb +24 -19
- data/lib/ruby_home/http/controllers/accessories_controller.rb +1 -2
- data/lib/ruby_home/http/controllers/application_controller.rb +60 -13
- data/lib/ruby_home/http/controllers/characteristics_controller.rb +2 -3
- data/lib/ruby_home/http/controllers/pair_setups_controller.rb +41 -78
- data/lib/ruby_home/http/controllers/pair_verifies_controller.rb +22 -24
- data/lib/ruby_home/http/controllers/pairings_controller.rb +8 -8
- data/lib/ruby_home/http/hap_request.rb +2 -6
- data/lib/ruby_home/http/hap_response.rb +2 -8
- data/lib/ruby_home/http/hap_server.rb +7 -12
- data/lib/ruby_home/http/serializers/object_serializer.rb +0 -2
- data/lib/ruby_home/http/services/start_srp_service.rb +46 -0
- data/lib/ruby_home/http/services/verify_srp_service.rb +55 -0
- data/lib/ruby_home/rack/handler/hap_server.rb +2 -7
- data/lib/ruby_home/version.rb +1 -1
- data/lib/ruby_home/yaml_record.rb +440 -0
- data/lib/ruby_home.rb +45 -6
- data/rubyhome.gemspec +4 -4
- metadata +44 -49
- data/lib/ruby_home/broadcast.rb +0 -31
- data/lib/ruby_home/hap/hex_pad.rb +0 -13
- data/lib/ruby_home/http/cache.rb +0 -30
@@ -1,10 +1,9 @@
|
|
1
1
|
require_relative 'application_controller'
|
2
|
-
require_relative '../serializers/characteristic_value_serializer'
|
3
2
|
|
4
3
|
module RubyHome
|
5
4
|
module HTTP
|
6
5
|
class CharacteristicsController < ApplicationController
|
7
|
-
get '/
|
6
|
+
get '/' do
|
8
7
|
content_type 'application/hap+json'
|
9
8
|
|
10
9
|
if cache[:controller_to_accessory_key] && cache[:accessory_to_controller_key]
|
@@ -21,7 +20,7 @@ module RubyHome
|
|
21
20
|
end
|
22
21
|
end
|
23
22
|
|
24
|
-
put '/
|
23
|
+
put '/' do
|
25
24
|
content_type 'application/hap+json'
|
26
25
|
|
27
26
|
if cache[:controller_to_accessory_key] && cache[:accessory_to_controller_key]
|
@@ -1,81 +1,75 @@
|
|
1
|
-
require 'hkdf'
|
2
|
-
require 'openssl'
|
3
|
-
require 'rbnacl/libsodium'
|
4
|
-
require 'ruby_home-srp'
|
5
|
-
require_relative '../../hap/hex_pad'
|
6
|
-
require_relative '../../hap/tlv'
|
7
1
|
require_relative 'application_controller'
|
8
2
|
|
9
3
|
module RubyHome
|
10
4
|
module HTTP
|
11
5
|
class PairSetupsController < ApplicationController
|
12
|
-
post '/
|
6
|
+
post '/' do
|
13
7
|
content_type 'application/pairing+tlv8'
|
14
8
|
|
15
|
-
case unpack_request[
|
9
|
+
case unpack_request[:state]
|
16
10
|
when 1
|
17
|
-
|
11
|
+
start
|
18
12
|
when 3
|
19
|
-
|
13
|
+
verify
|
20
14
|
when 5
|
21
|
-
|
15
|
+
exchange
|
22
16
|
end
|
23
17
|
end
|
24
18
|
|
25
19
|
private
|
26
20
|
|
27
|
-
def
|
28
|
-
|
29
|
-
password = '031-45-154'
|
21
|
+
def pairing_failed
|
22
|
+
clear_cache
|
30
23
|
|
31
|
-
|
24
|
+
tlv state: 4, error: 2
|
25
|
+
end
|
32
26
|
|
33
|
-
|
34
|
-
|
27
|
+
def start
|
28
|
+
start_srp = StartSRPService.new(
|
29
|
+
username: accessory_info.username,
|
30
|
+
password: accessory_info.password
|
31
|
+
)
|
35
32
|
|
36
|
-
|
37
|
-
store_proof(challenge_and_proof[:proof])
|
33
|
+
cache[:srp_session] = start_srp.proof
|
38
34
|
|
39
|
-
|
40
|
-
'kTLVType_Salt' => [challenge_and_proof[:challenge][:salt]].pack('H*'),
|
41
|
-
'kTLVType_PublicKey' => [challenge_and_proof[:challenge][:B]].pack('H*'),
|
42
|
-
'kTLVType_State' => 2
|
43
|
-
})
|
35
|
+
tlv salt: start_srp.salt_bytes, public_key: start_srp.public_key_bytes, state: 2
|
44
36
|
end
|
45
37
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
38
|
+
def verify
|
39
|
+
verify_srp = VerifySRPService.new(
|
40
|
+
device_proof: unpack_request[:proof],
|
41
|
+
srp_session: cache[:srp_session],
|
42
|
+
public_key: unpack_request[:public_key],
|
43
|
+
)
|
51
44
|
|
52
|
-
|
53
|
-
|
45
|
+
if verify_srp.valid?
|
46
|
+
cache[:session_key] = verify_srp.session_key
|
47
|
+
cache.delete(:srp_session)
|
54
48
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
49
|
+
tlv state: 4, proof: verify_srp.server_proof
|
50
|
+
else
|
51
|
+
pairing_failed
|
52
|
+
end
|
59
53
|
end
|
60
54
|
|
61
|
-
def
|
62
|
-
encrypted_data = unpack_request[
|
55
|
+
def exchange
|
56
|
+
encrypted_data = unpack_request[:encrypted_data]
|
63
57
|
|
64
58
|
hkdf = HAP::Crypto::HKDF.new(info: 'Pair-Setup-Encrypt-Info', salt: 'Pair-Setup-Encrypt-Salt')
|
65
|
-
key = hkdf.encrypt(session_key)
|
59
|
+
key = hkdf.encrypt(cache[:session_key])
|
66
60
|
|
67
61
|
chacha20poly1305ietf = HAP::Crypto::ChaCha20Poly1305.new(key)
|
68
62
|
|
69
|
-
nonce =
|
63
|
+
nonce = HexHelper.pad('PS-Msg05')
|
70
64
|
decrypted_data = chacha20poly1305ietf.decrypt(nonce, encrypted_data)
|
71
65
|
unpacked_decrypted_data = HAP::TLV.read(decrypted_data)
|
72
66
|
|
73
|
-
iosdevicepairingid = unpacked_decrypted_data[
|
74
|
-
iosdevicesignature = unpacked_decrypted_data[
|
75
|
-
iosdeviceltpk = unpacked_decrypted_data[
|
67
|
+
iosdevicepairingid = unpacked_decrypted_data[:identifier]
|
68
|
+
iosdevicesignature = unpacked_decrypted_data[:signature]
|
69
|
+
iosdeviceltpk = unpacked_decrypted_data[:public_key]
|
76
70
|
|
77
71
|
hkdf = HAP::Crypto::HKDF.new(info: 'Pair-Setup-Controller-Sign-Info', salt: 'Pair-Setup-Controller-Sign-Salt')
|
78
|
-
iosdevicex = hkdf.encrypt(session_key)
|
72
|
+
iosdevicex = hkdf.encrypt(cache[:session_key])
|
79
73
|
|
80
74
|
iosdeviceinfo = [
|
81
75
|
iosdevicex.unpack1('H*'),
|
@@ -86,7 +80,7 @@ module RubyHome
|
|
86
80
|
|
87
81
|
if verify_key.verify(iosdevicesignature, [iosdeviceinfo].pack('H*'))
|
88
82
|
hkdf = HAP::Crypto::HKDF.new(info: 'Pair-Setup-Accessory-Sign-Info', salt: 'Pair-Setup-Accessory-Sign-Salt')
|
89
|
-
accessory_x = hkdf.encrypt(session_key)
|
83
|
+
accessory_x = hkdf.encrypt(cache[:session_key])
|
90
84
|
|
91
85
|
signing_key = accessory_info.signing_key
|
92
86
|
accessoryltpk = signing_key.verify_key.to_bytes
|
@@ -98,48 +92,17 @@ module RubyHome
|
|
98
92
|
|
99
93
|
accessorysignature = signing_key.sign([accessoryinfo].pack('H*'))
|
100
94
|
|
101
|
-
subtlv =
|
102
|
-
'kTLVType_Identifier' => accessory_info.device_id,
|
103
|
-
'kTLVType_PublicKey' => accessoryltpk,
|
104
|
-
'kTLVType_Signature' => accessorysignature
|
105
|
-
})
|
95
|
+
subtlv = tlv(identifier: accessory_info.device_id, public_key: accessoryltpk, signature: accessorysignature)
|
106
96
|
|
107
|
-
nonce =
|
97
|
+
nonce = HexHelper.pad('PS-Msg06')
|
108
98
|
encrypted_data = chacha20poly1305ietf.encrypt(nonce, subtlv)
|
109
99
|
|
110
100
|
pairing_params = { admin: true, identifier: iosdevicepairingid, public_key: iosdeviceltpk.unpack1('H*') }
|
111
101
|
accessory_info.add_paired_client pairing_params
|
112
102
|
|
113
|
-
|
114
|
-
'kTLVType_State' => 6,
|
115
|
-
'kTLVType_EncryptedData' => encrypted_data
|
116
|
-
})
|
103
|
+
tlv state: 6, encrypted_data: encrypted_data
|
117
104
|
end
|
118
105
|
end
|
119
|
-
|
120
|
-
def srp_verifier
|
121
|
-
@_verifier ||= RubyHome::SRP::Verifier.new
|
122
|
-
end
|
123
|
-
|
124
|
-
def store_proof(proof)
|
125
|
-
cache[:proof] = proof
|
126
|
-
end
|
127
|
-
|
128
|
-
def retrieve_proof
|
129
|
-
cache[:proof]
|
130
|
-
end
|
131
|
-
|
132
|
-
def forget_proof!
|
133
|
-
cache[:proof] = nil
|
134
|
-
end
|
135
|
-
|
136
|
-
def store_session_key(key)
|
137
|
-
cache[:session_key] = key
|
138
|
-
end
|
139
|
-
|
140
|
-
def session_key
|
141
|
-
cache[:session_key]
|
142
|
-
end
|
143
106
|
end
|
144
107
|
end
|
145
108
|
end
|
@@ -1,16 +1,14 @@
|
|
1
|
-
require 'x25519'
|
2
|
-
require_relative '../../hap/crypto/hkdf'
|
3
|
-
require_relative '../../hap/hex_pad'
|
4
|
-
require_relative '../../hap/tlv'
|
5
1
|
require_relative 'application_controller'
|
6
2
|
|
7
3
|
module RubyHome
|
8
4
|
module HTTP
|
9
5
|
class PairVerifiesController < ApplicationController
|
10
|
-
post '/
|
6
|
+
post '/' do
|
11
7
|
content_type 'application/pairing+tlv8'
|
12
8
|
|
13
|
-
|
9
|
+
verify_accessory_paired
|
10
|
+
|
11
|
+
case unpack_request[:state]
|
14
12
|
when 1
|
15
13
|
verify_start_response
|
16
14
|
when 3
|
@@ -21,10 +19,10 @@ module RubyHome
|
|
21
19
|
private
|
22
20
|
|
23
21
|
def verify_start_response
|
24
|
-
secret_key =
|
22
|
+
secret_key = RbNaCl::PrivateKey.generate
|
25
23
|
public_key = secret_key.public_key.to_bytes
|
26
|
-
client_public_key =
|
27
|
-
shared_secret =
|
24
|
+
client_public_key = RbNaCl::PublicKey.new(unpack_request[:public_key])
|
25
|
+
shared_secret = RbNaCl::GroupElement.new(client_public_key).mult(secret_key).to_bytes
|
28
26
|
cache[:shared_secret] = shared_secret
|
29
27
|
|
30
28
|
accessoryinfo = [
|
@@ -36,46 +34,46 @@ module RubyHome
|
|
36
34
|
signing_key = accessory_info.signing_key
|
37
35
|
accessorysignature = signing_key.sign([accessoryinfo].pack('H*'))
|
38
36
|
|
39
|
-
subtlv =
|
40
|
-
'kTLVType_Identifier' => accessory_info.device_id,
|
41
|
-
'kTLVType_Signature' => accessorysignature
|
42
|
-
})
|
37
|
+
subtlv = tlv(identifier: accessory_info.device_id, signature: accessorysignature)
|
43
38
|
|
44
39
|
hkdf = HAP::Crypto::HKDF.new(info: 'Pair-Verify-Encrypt-Info', salt: 'Pair-Verify-Encrypt-Salt')
|
45
40
|
session_key = hkdf.encrypt(shared_secret)
|
46
41
|
cache[:session_key] = session_key
|
47
42
|
|
48
43
|
chacha20poly1305ietf = HAP::Crypto::ChaCha20Poly1305.new(session_key)
|
49
|
-
nonce =
|
44
|
+
nonce = HexHelper.pad('PV-Msg02')
|
50
45
|
encrypted_data = chacha20poly1305ietf.encrypt(nonce, subtlv)
|
51
46
|
|
52
|
-
|
53
|
-
'kTLVType_State' => 2,
|
54
|
-
'kTLVType_PublicKey' => public_key,
|
55
|
-
'kTLVType_EncryptedData' => encrypted_data
|
56
|
-
})
|
47
|
+
tlv state: 2, public_key: public_key, encrypted_data: encrypted_data
|
57
48
|
end
|
58
49
|
|
59
50
|
def verify_finish_response
|
60
|
-
encrypted_data = unpack_request[
|
51
|
+
encrypted_data = unpack_request[:encrypted_data]
|
61
52
|
|
62
53
|
chacha20poly1305ietf = HAP::Crypto::ChaCha20Poly1305.new(cache[:session_key])
|
63
|
-
nonce =
|
54
|
+
nonce = HexHelper.pad('PV-Msg03')
|
64
55
|
decrypted_data = chacha20poly1305ietf.decrypt(nonce, encrypted_data)
|
65
56
|
unpacked_decrypted_data = HAP::TLV.read(decrypted_data)
|
66
57
|
|
67
|
-
if accessory_info.paired_clients.any? {|h| h[:identifier] == unpacked_decrypted_data[
|
58
|
+
if accessory_info.paired_clients.any? {|h| h[:identifier] == unpacked_decrypted_data[:identifier]}
|
68
59
|
hkdf = HAP::Crypto::HKDF.new(info: 'Control-Write-Encryption-Key', salt: 'Control-Salt')
|
69
60
|
cache[:controller_to_accessory_key] = hkdf.encrypt(cache[:shared_secret])
|
70
61
|
|
71
62
|
hkdf = HAP::Crypto::HKDF.new(info: 'Control-Read-Encryption-Key', salt: 'Control-Salt')
|
72
63
|
cache[:accessory_to_controller_key] = hkdf.encrypt(cache[:shared_secret])
|
73
64
|
|
74
|
-
|
65
|
+
cache.delete(:session_key)
|
66
|
+
cache.delete(:shared_secret)
|
67
|
+
|
68
|
+
tlv state: 4
|
75
69
|
else
|
76
|
-
|
70
|
+
tlv state: 4, error: 2
|
77
71
|
end
|
78
72
|
end
|
73
|
+
|
74
|
+
def verify_accessory_paired
|
75
|
+
halt 403 unless accessory_info.paired?
|
76
|
+
end
|
79
77
|
end
|
80
78
|
end
|
81
79
|
end
|
@@ -3,10 +3,10 @@ require_relative 'application_controller'
|
|
3
3
|
module RubyHome
|
4
4
|
module HTTP
|
5
5
|
class PairingsController < ApplicationController
|
6
|
-
post '/
|
6
|
+
post '/' do
|
7
7
|
content_type 'application/pairing+tlv8'
|
8
8
|
|
9
|
-
case unpack_request[
|
9
|
+
case unpack_request[:method]
|
10
10
|
when 3
|
11
11
|
add_pairing
|
12
12
|
when 4
|
@@ -18,20 +18,20 @@ module RubyHome
|
|
18
18
|
|
19
19
|
def add_pairing
|
20
20
|
pairing_params = {
|
21
|
-
admin: !!unpack_request[
|
22
|
-
identifier: unpack_request[
|
23
|
-
public_key: unpack_request[
|
21
|
+
admin: !!unpack_request[:permissions],
|
22
|
+
identifier: unpack_request[:identifier],
|
23
|
+
public_key: unpack_request[:public_key].unpack1('H*')
|
24
24
|
}
|
25
25
|
accessory_info.add_paired_client pairing_params
|
26
26
|
|
27
|
-
|
27
|
+
tlv state: 2
|
28
28
|
end
|
29
29
|
|
30
30
|
def remove_pairing
|
31
|
-
accessory_info.remove_paired_client(unpack_request[
|
31
|
+
accessory_info.remove_paired_client(unpack_request[:identifier])
|
32
32
|
|
33
33
|
response['connection'] = 'close'
|
34
|
-
|
34
|
+
tlv state: 2
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|
@@ -1,11 +1,7 @@
|
|
1
|
-
require 'webrick/httprequest'
|
2
|
-
require_relative '../hap/http_decryption'
|
3
|
-
|
4
1
|
module RubyHome
|
5
2
|
module HTTP
|
6
3
|
class HAPRequest < WEBrick::HTTPRequest
|
7
|
-
def initialize(*args
|
8
|
-
@_request_id = request_id
|
4
|
+
def initialize(*args)
|
9
5
|
cache[:controller_to_accessory_count] ||= 0
|
10
6
|
|
11
7
|
super(*args)
|
@@ -49,7 +45,7 @@ module RubyHome
|
|
49
45
|
end
|
50
46
|
|
51
47
|
def cache
|
52
|
-
|
48
|
+
RequestStore.store
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
@@ -1,11 +1,7 @@
|
|
1
|
-
require 'webrick/httpresponse'
|
2
|
-
require_relative '../hap/http_encryption'
|
3
|
-
|
4
1
|
module RubyHome
|
5
2
|
module HTTP
|
6
3
|
class HAPResponse < WEBrick::HTTPResponse
|
7
|
-
def initialize(*args
|
8
|
-
@_request_id = request_id
|
4
|
+
def initialize(*args)
|
9
5
|
cache[:accessory_to_controller_count] ||= 0
|
10
6
|
|
11
7
|
super(*args)
|
@@ -48,10 +44,8 @@ module RubyHome
|
|
48
44
|
end
|
49
45
|
|
50
46
|
def cache
|
51
|
-
|
47
|
+
RequestStore.store
|
52
48
|
end
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
56
|
-
|
57
|
-
|
@@ -1,26 +1,21 @@
|
|
1
|
-
require 'webrick/httpserver'
|
2
|
-
require 'webrick/httpstatus'
|
3
|
-
require_relative 'hap_request'
|
4
|
-
require_relative 'hap_response'
|
5
|
-
|
6
1
|
module RubyHome
|
7
2
|
module HTTP
|
8
3
|
class HAPServer < WEBrick::HTTPServer
|
9
|
-
def run(
|
4
|
+
def run(socket)
|
10
5
|
while true
|
11
|
-
res = RubyHome::HTTP::HAPResponse.new(@config
|
12
|
-
req = RubyHome::HTTP::HAPRequest.new(@config
|
6
|
+
res = RubyHome::HTTP::HAPResponse.new(@config)
|
7
|
+
req = RubyHome::HTTP::HAPRequest.new(@config)
|
13
8
|
server = self
|
14
9
|
begin
|
15
10
|
timeout = @config[:RequestTimeout]
|
16
11
|
while timeout > 0
|
17
|
-
break if
|
12
|
+
break if socket.to_io.wait_readable(0.5)
|
18
13
|
break if @status != :Running
|
19
14
|
timeout -= 0.5
|
20
15
|
end
|
21
16
|
raise WEBrick::HTTPStatus::EOFError if timeout <= 0 || @status != :Running
|
22
|
-
raise WEBrick::HTTPStatus::EOFError if
|
23
|
-
req.parse(
|
17
|
+
raise WEBrick::HTTPStatus::EOFError if socket.eof?
|
18
|
+
req.parse(socket)
|
24
19
|
res.received_encrypted_request = req.received_encrypted_request?
|
25
20
|
res.request_method = req.request_method
|
26
21
|
res.request_uri = req.request_uri
|
@@ -50,7 +45,7 @@ module RubyHome
|
|
50
45
|
if req.keep_alive? && res.keep_alive?
|
51
46
|
req.fixup()
|
52
47
|
end
|
53
|
-
res.send_response(
|
48
|
+
res.send_response(socket)
|
54
49
|
server.access_log(@config, req, res)
|
55
50
|
end
|
56
51
|
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
class StartSRPService
|
2
|
+
def initialize(username: , password:)
|
3
|
+
@username = username
|
4
|
+
@password = password
|
5
|
+
end
|
6
|
+
|
7
|
+
def salt_bytes
|
8
|
+
[salt].pack('H*')
|
9
|
+
end
|
10
|
+
|
11
|
+
def public_key_bytes
|
12
|
+
[public_key].pack('H*')
|
13
|
+
end
|
14
|
+
|
15
|
+
def proof
|
16
|
+
challenge_and_proof[:proof]
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def salt
|
22
|
+
user_auth[:salt]
|
23
|
+
end
|
24
|
+
|
25
|
+
def public_key
|
26
|
+
challenge[:B]
|
27
|
+
end
|
28
|
+
|
29
|
+
def challenge
|
30
|
+
challenge_and_proof[:challenge]
|
31
|
+
end
|
32
|
+
|
33
|
+
def challenge_and_proof
|
34
|
+
srp_verifier.get_challenge_and_proof(username, user_auth[:verifier], user_auth[:salt])
|
35
|
+
end
|
36
|
+
|
37
|
+
def user_auth
|
38
|
+
@_user_auth ||= srp_verifier.generate_userauth(username, password)
|
39
|
+
end
|
40
|
+
|
41
|
+
def srp_verifier
|
42
|
+
@_verifier ||= RubyHome::SRP::Verifier.new
|
43
|
+
end
|
44
|
+
|
45
|
+
attr_reader :username, :password
|
46
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
class VerifySRPService
|
2
|
+
def initialize(public_key: , device_proof: , srp_session: )
|
3
|
+
@device_proof = device_proof
|
4
|
+
@srp_session = srp_session
|
5
|
+
@public_key = public_key
|
6
|
+
end
|
7
|
+
|
8
|
+
def valid?
|
9
|
+
return false unless public_key
|
10
|
+
return false unless device_proof
|
11
|
+
return false unless srp_session
|
12
|
+
return false unless valid_session?
|
13
|
+
|
14
|
+
true
|
15
|
+
end
|
16
|
+
|
17
|
+
def session_key
|
18
|
+
srp_verifier.K
|
19
|
+
end
|
20
|
+
|
21
|
+
def server_proof
|
22
|
+
verify_session_bytes
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def valid_session?
|
28
|
+
!!verify_session
|
29
|
+
end
|
30
|
+
|
31
|
+
def verify_session_bytes
|
32
|
+
[verify_session].pack('H*')
|
33
|
+
end
|
34
|
+
|
35
|
+
def verify_session
|
36
|
+
@_verify_session ||= srp_verifier.verify_session(
|
37
|
+
srp_session.merge({A: public_key_bytes}),
|
38
|
+
device_proof_bytes
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def public_key_bytes
|
43
|
+
public_key.unpack1('H*')
|
44
|
+
end
|
45
|
+
|
46
|
+
def device_proof_bytes
|
47
|
+
device_proof.unpack1('H*')
|
48
|
+
end
|
49
|
+
|
50
|
+
def srp_verifier
|
51
|
+
@_verifier ||= RubyHome::SRP::Verifier.new
|
52
|
+
end
|
53
|
+
|
54
|
+
attr_reader :public_key, :device_proof, :srp_session
|
55
|
+
end
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'webrick'
|
2
|
-
require_relative '../../http/hap_server'
|
3
|
-
|
4
1
|
module RubyHome
|
5
2
|
module Rack
|
6
3
|
module Handler
|
@@ -11,10 +8,8 @@ module RubyHome
|
|
11
8
|
|
12
9
|
options[:BindAddress] = options.delete(:Host) || default_host
|
13
10
|
options[:Port] ||= 8080
|
14
|
-
|
15
|
-
|
16
|
-
options[:AccessLog] = []
|
17
|
-
end
|
11
|
+
options[:Logger] = WEBrick::Log.new("/dev/null")
|
12
|
+
options[:AccessLog] = []
|
18
13
|
@server = HTTP::HAPServer.new(options)
|
19
14
|
@server.mount '/', Handler::HAPServer, app
|
20
15
|
yield @server if block_given?
|
data/lib/ruby_home/version.rb
CHANGED