Esempio n. 1
0
class HandshakesTest(unittest.TestCase):
    USERNAME = 123456789
    KEYPAIR = KeyPair.generate()
    PHONE_ID = uuid.uuid4().__str__()
    CONFIG = ClientConfig(username=USERNAME,
                          passive=True,
                          useragent=VBoxUserAgentConfig(
                              app_version="2.19.51",
                              phone_id=PHONE_ID,
                              mcc="000",
                              mnc="000",
                          ),
                          pushname="consonance",
                          short_connect=True)
    ENDPOINT = ("e1.whatsapp.net", 443)
    HEADER = b"WA\x02\x01"

    def test_xx_handshake(self):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect(self.ENDPOINT)
        # send WA header indicating protocol version
        s.send(self.HEADER)
        # use WASegmentedStream for sending/receiving in frames
        stream = WASegmentedStream(SocketArbitraryStream(s))
        # initialize WANoiseProtocol 2.1
        wa_noiseprotocol = WANoiseProtocol(2, 1)
        # start the protocol, this should a XX handshake since
        # we are not passing the remote static public key
        self.assertTrue(
            wa_noiseprotocol.start(stream, self.CONFIG, self.KEYPAIR))
        # we are now in transport phase, first incoming data
        # will indicate whether we are authenticated
        first_transport_data = wa_noiseprotocol.receive()
        # fourth byte is status, 172 is success, 52 is failure
        self.assertEqual(52, first_transport_data[3])
class HandshakesTest(unittest.TestCase):
    KEYPAIR = KeyPair.from_bytes(
        base64.b64decode(
            b"YJa8Vd9pG0KV2tDYi5V+DMOtSvCEFzRGCzOlGZkvBHzJvBE5C3oC2Fruniw0GBGo7HHgR4TjvjI3C9AihStsVg=="
        ))
    PHONE_ID = uuid.uuid4().__str__()
    CONFIG = ClientConfig(username=1,
                          passive=True,
                          useragent=VBoxUserAgentConfig(
                              app_version="2.19.51",
                              phone_id=PHONE_ID,
                              mcc="000",
                              mnc="000",
                          ),
                          pushname="consonance",
                          short_connect=True)

    def test_xx_handshake_offline(self):
        stream = DummySegmentedStream([
            base64.b64decode(
                b"GvoBCiCiMwovEL8pYkUdcxCz6w5lvzvyxgAgHiNm4LnOwO8KQxIwt+dvmTcTMcE12jCC"
                b"rbnLcFY+H2/QuKr4/h4BCHy0rDS9rKp63yqRfFX5vEPY0/UGGqMBCfYtpYzsdsU3cN0Bq4ui5Dm0MY/+Yur2cCFb"
                b"tLRgBa858hWFuCIuWKrkE89GrF0uo+wJsolq4miiqMOdXJfuZ2YBZ4paFS2mWjVmQSINRo8J3LzXncUDMeQBO/KkC"
                b"ARw5BTcVkj2gwI6FG+yB/qI8BUJIxxswJc6q+H+HWkNro+Xl6urn5aOwK7bgBSPNctncZGY72NlJByEQCB6Bra7U"
                b"ykzQA==")
        ])
        ephemeral = KeyPair.from_bytes(
            base64.b64decode(
                b"qLt+l8Jh9mUF/QciIRjd7Z0qKyhN//46Xawk5jdL4WF4tFaszfGgyodH3ErvqU5lV4GnOccdy9zj39GU6AAPVQ=="
            ))
        # initialize WANoiseProtocol 2.1
        wa_handshake = WAHandshake(2, 1)
        # this should do a XX handshake since we are not passing the remote static public key
        wa_handshake.perform(self.CONFIG, stream, self.KEYPAIR, e=ephemeral)
Esempio n. 3
0
    def on_auth(self, event):
        logger.debug("Received auth event")
        credentials = event.getArg("credentials")
        self._username, local_static = int(credentials[0]), credentials[1]
        config = self._config_manager.load(
            self._username)  # type: yowsup.config.v1.config.Config
        # event's keypair will override config's keypair
        local_static = local_static or config.client_static_keypair
        if type(local_static) is bytes:
            local_static = KeyPair.from_bytes(local_static)
        assert type(local_static) is KeyPair
        passive = event.getArg('passive')

        self.setProp(YowNoiseSegmentsLayer.PROP_ENABLED, False)

        if config.edge_routing_info:
            self.toLower(self.EDGE_HEADER)
            self.setProp(YowNoiseSegmentsLayer.PROP_ENABLED, True)
            self.toLower(config.edge_routing_info)
            self.setProp(YowNoiseSegmentsLayer.PROP_ENABLED, False)

        self.toLower(self.HEADER)
        self.setProp(YowNoiseSegmentsLayer.PROP_ENABLED, True)

        remote_static = config.server_static_public

        self._rs = remote_static
        yowsupenv = YowsupEnv.getCurrent()
        client_config = ClientConfig(
            username=self._username,
            passive=passive,
            useragent=UserAgentConfig(platform=0,
                                      app_version="2.19.51",
                                      mcc=config.mcc,
                                      mnc=config.mnc,
                                      os_version=yowsupenv.getOSVersion(),
                                      manufacturer=yowsupenv.getManufacturer(),
                                      device=yowsupenv.getDeviceName(),
                                      os_build_number=yowsupenv.getOSVersion(),
                                      phone_id=config.fdid,
                                      locale_lang="en",
                                      locale_country="US"),
            pushname=config.pushname or self.DEFAULT_PUSHNAME,
            short_connect=True)
        if not self._in_handshake():
            logger.debug("Performing handshake [username= %d, passive=%s]" %
                         (self._username, passive))
            self._handshake_worker = WANoiseProtocolHandshakeWorker(
                self._wa_noiseprotocol,
                self._stream,
                client_config,
                local_static,
                remote_static,
            )
            logger.debug("Starting handshake worker")
            self._stream.set_events_callback(self._handle_stream_event)
            self._handshake_worker.start()
Esempio n. 4
0
dissononce.logger.setLevel(logging.DEBUG)

# username is phone number
USERNAME = 123456789
# on Android fetch client_static_keypair from /data/data/com.whatsapp/shared_prefs/keystore.xml
KEYPAIR = KeyPair.from_bytes(
    base64.b64decode(
        b"YJa8Vd9pG0KV2tDYi5V+DMOtSvCEFzRGCzOlGZkvBHzJvBE5C3oC2Fruniw0GBGo7HHgR4TjvjI3C9AihStsVg=="
    ))
# same phone_id/fdid used at registration.
# on Android it's phoneid_id under /data/data/com.whatsapp/shared_prefs/com.whatsapp_preferences.xml
PHONE_ID = uuid.uuid4().__str__()
# create full configuration which will translate later into a protobuf payload
CONFIG = ClientConfig(username=USERNAME,
                      passive=True,
                      useragent=SamsungS9PUserAgentConfig(
                          app_version="2.21.21.18", phone_id=PHONE_ID),
                      pushname="consonance",
                      short_connect=True)
PROTOCOL_VERSION = (4, 0)
ENDPOINT = ("e1.whatsapp.net", 443)
HEADER = b"WA" + bytes(PROTOCOL_VERSION)

if __name__ == "__main__":
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.connect(ENDPOINT)
    # send WA header indicating protocol version
    s.send(HEADER)
    # use WASegmentedStream for sending/receiving in frames
    stream = WASegmentedStream(SocketArbitraryStream(s))
    # initialize WANoiseProtocol
    wa_noiseprotocol = WANoiseProtocol(*PROTOCOL_VERSION)
Esempio n. 5
0
    def on_auth(self, event):
        logger.debug("Received auth event")
        self._profile = self.getProp("profile")
        config = self._profile.config  # type: yowsup.config.v1.config.Config
        # event's keypair will override config's keypair
        local_static = config.client_static_keypair
        username = int(self._profile.username)

        if local_static is None:
            logger.error(
                "client_static_keypair is not defined in specified config, disconnecting"
            )
            self.broadcastEvent(
                YowLayerEvent(
                    YowNetworkLayer.EVENT_STATE_DISCONNECT,
                    reason=
                    "client_static_keypair is not defined in specified config")
            )
        else:
            if type(local_static) is bytes:
                local_static = KeyPair.from_bytes(local_static)
            assert type(local_static) is KeyPair, type(local_static)
            passive = event.getArg('passive')

            self.setProp(YowNoiseSegmentsLayer.PROP_ENABLED, False)

            if config.edge_routing_info:
                self.toLower(self.EDGE_HEADER)
                self.setProp(YowNoiseSegmentsLayer.PROP_ENABLED, True)
                self.toLower(config.edge_routing_info)
                self.setProp(YowNoiseSegmentsLayer.PROP_ENABLED, False)

            self.toLower(self.HEADER)
            self.setProp(YowNoiseSegmentsLayer.PROP_ENABLED, True)

            remote_static = config.server_static_public

            self._rs = remote_static
            yowsupenv = YowsupEnv.getCurrent()
            client_config = ClientConfig(
                username=username,
                passive=passive,
                useragent=UserAgentConfig(
                    platform=0,
                    app_version=yowsupenv.getVersion(),
                    mcc=config.mcc or "000",
                    mnc=config.mnc or "000",
                    os_version=yowsupenv.getOSVersion(),
                    manufacturer=yowsupenv.getManufacturer(),
                    device=yowsupenv.getDeviceName(),
                    os_build_number=yowsupenv.getOSVersion(),
                    phone_id=config.fdid or "",
                    locale_lang="en",
                    locale_country="US"),
                pushname=config.pushname or self.DEFAULT_PUSHNAME,
                short_connect=True)
            if not self._in_handshake():
                logger.debug(
                    "Performing handshake [username= %d, passive=%s]" %
                    (username, passive))
                self._handshake_worker = WANoiseProtocolHandshakeWorker(
                    self._wa_noiseprotocol, self._stream, client_config,
                    local_static, remote_static, self.on_handshake_finished)
                logger.debug("Starting handshake worker")
                self._stream.set_events_callback(self._handle_stream_event)
                self._handshake_worker.start()