@@ -59,6 +59,7 @@ class HAP_SERVER_STATUS:
59
59
OPERATION_TIMED_OUT = - 70408
60
60
RESOURCE_DOES_NOT_EXIST = - 70409
61
61
INVALID_VALUE_IN_REQUEST = - 70410
62
+ INSUFFICIENT_AUTHORIZATION = - 70411
62
63
63
64
64
65
# Error codes and the like, guessed by packet inspection
@@ -91,6 +92,10 @@ def hap_hkdf(key, salt, info):
91
92
return hkdf .derive (key )
92
93
93
94
95
+ class TimeoutException (Exception ):
96
+ pass
97
+
98
+
94
99
class UnprivilegedRequestException (Exception ):
95
100
pass
96
101
@@ -269,14 +274,20 @@ def dispatch(self):
269
274
try :
270
275
getattr (self , self .HANDLERS [self .command ][path ])()
271
276
except NotAllowedInStateException :
272
- self .send_response (403 )
273
- self .end_response (b'' )
277
+ self .send_response_with_status (403 , HAP_SERVER_STATUS .INSUFFICIENT_AUTHORIZATION )
274
278
except UnprivilegedRequestException :
275
- response = {"status" : HAP_SERVER_STATUS .INSUFFICIENT_PRIVILEGES }
276
- data = json .dumps (response ).encode ("utf-8" )
277
- self .send_response (401 )
278
- self .send_header ("Content-Type" , self .JSON_RESPONSE_TYPE )
279
- self .end_response (data )
279
+ self .send_response_with_status (401 , HAP_SERVER_STATUS .INSUFFICIENT_PRIVILEGES )
280
+ except TimeoutException :
281
+ self .send_response_with_status (500 , HAP_SERVER_STATUS .OPERATION_TIMED_OUT )
282
+ except Exception : # pylint: disable=broad-except
283
+ logger .exception ("Failed to process request for: %s" , path )
284
+ self .send_response_with_status (500 , HAP_SERVER_STATUS .SERVICE_COMMUNICATION_FAILURE )
285
+
286
+ def send_response_with_status (self , http_code , hap_server_status ):
287
+ """Send a generic HAP status response."""
288
+ self .send_response (http_code )
289
+ self .send_header ("Content-Type" , self .JSON_RESPONSE_TYPE )
290
+ self .end_response (json .dumps ({"status" : hap_server_status }).encode ("utf-8" ))
280
291
281
292
def handle_pairing (self ):
282
293
"""Handles arbitrary step of the pairing process."""
@@ -430,8 +441,7 @@ def _pairing_five(self, client_username, client_ltpk, encryption_key):
430
441
should_confirm = self .accessory_handler .pair (client_uuid , client_ltpk )
431
442
432
443
if not should_confirm :
433
- self .send_response (500 )
434
- self .end_response (b'' )
444
+ self .send_response_with_status (500 , HAP_SERVER_STATUS .INVALID_VALUE_IN_REQUEST )
435
445
return
436
446
437
447
tlv_data = tlv .encode (HAP_TLV_TAGS .SEQUENCE_NUM , b'\x06 ' ,
@@ -456,7 +466,7 @@ def handle_pair_verify(self):
456
466
elif sequence == b'\x03 ' :
457
467
self ._pair_verify_two (tlv_objects )
458
468
else :
459
- raise ValueError
469
+ raise ValueError ( "Unknown pairing sequence of %s during pair verify" % ( sequence ))
460
470
461
471
def _pair_verify_one (self , tlv_objects ):
462
472
"""Generate new session key pair and send a proof to the client.
@@ -610,7 +620,7 @@ def handle_pairings(self):
610
620
elif request_type == 4 :
611
621
self ._handle_remove_pairing (tlv_objects )
612
622
else :
613
- raise ValueError
623
+ raise ValueError ( "Unknown pairing request type of %s during pair verify" % ( request_type ))
614
624
615
625
def _handle_add_pairing (self , tlv_objects ):
616
626
"""Update client information."""
@@ -621,8 +631,7 @@ def _handle_add_pairing(self, tlv_objects):
621
631
should_confirm = self .accessory_handler .pair (
622
632
client_uuid , client_public )
623
633
if not should_confirm :
624
- self .send_response (500 )
625
- self .end_response (b'' )
634
+ self .send_response_with_status (500 , HAP_SERVER_STATUS .INVALID_VALUE_IN_REQUEST )
626
635
return
627
636
628
637
data = tlv .encode (HAP_TLV_TAGS .SEQUENCE_NUM , b"\x02 " )
@@ -765,7 +774,13 @@ def recv(self, buflen=1042, flags=0):
765
774
The received full cipher blocks are decrypted and returned and partial cipher
766
775
blocks are buffered locally.
767
776
"""
768
- assert not flags and buflen
777
+ assert not flags
778
+
779
+ if buflen == 0 :
780
+ # If the reads get aligned just right, it possible that we
781
+ # could be asked to read zero bytes. Since we do not want to block
782
+ # we return an empty bytes string.
783
+ return b""
769
784
770
785
result = self .curr_decrypted
771
786
0 commit comments