@@ -728,6 +728,74 @@ def PipeClient(address):
728
728
WELCOME = b'#WELCOME#'
729
729
FAILURE = b'#FAILURE#'
730
730
731
+ # multiprocessing.connection Authentication Handshake Protocol Description
732
+ # (as documented for reference after reading the existing code)
733
+ # =============================================================================
734
+ #
735
+ # On Windows: native pipes with "overlapped IO" are used to send the bytes,
736
+ # instead of the length prefix SIZE scheme described below. (ie: the OS deals
737
+ # with message sizes for us)
738
+ #
739
+ # Protocol error behaviors:
740
+ #
741
+ # On POSIX, any failure to receive the length prefix into SIZE, for SIZE greater
742
+ # than the requested maxsize to receive, or receiving fewer than SIZE bytes
743
+ # results in the connection being closed and auth to fail.
744
+ #
745
+ # On Windows, receiving too few bytes is never a low level _recv_bytes read
746
+ # error, receiving too many will trigger an error only if receive maxsize
747
+ # value was larger than 128 OR the if the data arrived in smaller pieces.
748
+ #
749
+ # Serving side Client side
750
+ # ------------------------------ ---------------------------------------
751
+ # 0. Open a connection on the pipe.
752
+ # 1. Accept connection.
753
+ # 2. New random 20 bytes -> MESSAGE
754
+ # 3. send 4 byte length (net order)
755
+ # prefix followed by:
756
+ # b'#CHALLENGE#' + MESSAGE
757
+ # 4. Receive 4 bytes, parse as network byte
758
+ # order integer. If it is -1, receive an
759
+ # additional 8 bytes, parse that as network
760
+ # byte order. The result is the length of
761
+ # the data that follows -> SIZE.
762
+ # 5. Receive min(SIZE, 256) bytes -> M1
763
+ # 6. Assert that M1 starts with:
764
+ # b'#CHALLENGE#'
765
+ # 7. Strip that prefix from M1 into -> M2
766
+ # 8. Compute HMAC-MD5 of AUTHKEY, M2 -> C_DIGEST
767
+ # 9. Send 4 byte length prefix (net order)
768
+ # followed by C_DIGEST bytes.
769
+ # 10. Compute HMAC-MD5 of AUTHKEY,
770
+ # MESSAGE into -> M_DIGEST.
771
+ # 11. Receive 4 or 4+8 byte length
772
+ # prefix (#4 dance) -> SIZE.
773
+ # 12. Receive min(SIZE, 256) -> C_D.
774
+ # 13. Compare M_DIGEST == C_D:
775
+ # 14a: Match? Send length prefix &
776
+ # b'#WELCOME#'
777
+ # <- RETURN
778
+ # 14b: Mismatch? Send len prefix &
779
+ # b'#FAILURE#'
780
+ # <- CLOSE & AuthenticationError
781
+ # 15. Receive 4 or 4+8 byte length prefix (net
782
+ # order) again as in #4 into -> SIZE.
783
+ # 16. Receive min(SIZE, 256) bytes -> M3.
784
+ # 17. Compare M3 == b'#WELCOME#':
785
+ # 17a. Match? <- RETURN
786
+ # 17b. Mismatch? <- CLOSE & AuthenticationError
787
+ #
788
+ # If this RETURNed, the connection remains open: it has been authenticated.
789
+ #
790
+ # Length prefixes are used consistently even though every step so far has
791
+ # always been a singular specific fixed length. This may help us evolve
792
+ # the protocol in the future without breaking backwards compatibility.
793
+ #
794
+ # Similarly the initial challenge message from the serving side has always
795
+ # been 20 bytes, but clients can accept a 100+ so using the length of the
796
+ # opening challenge message as an indicator of protocol version may work.
797
+
798
+
731
799
def deliver_challenge (connection , authkey ):
732
800
import hmac
733
801
if not isinstance (authkey , bytes ):
0 commit comments