Пример #1
0
 def __init__(self, config_class):
     super(ConfigSerialize, self).__init__(
         transforms=(
             ConfigDictTransform(config_class),
             FilterTransform(
                 transform_filter=lambda key, val: val is not None,
                 reverse_filter=lambda key, val: key != "version"
             ),
             MapTransform(transform_map=lambda key, val: (key[1:], val)),
             PropsTransform(
                 transform_map={
                     "server_static_public": lambda key, val: (key, base64.b64encode(val.data).decode()),
                     "client_static_keypair": lambda key, val: (key, base64.b64encode(val.private.data + val.public.data).decode()),
                     "id": lambda key, val: (key, base64.b64encode(val).decode()),
                     "expid": lambda key, val: (key, base64.b64encode(val).decode()),
                     "edge_routing_info": lambda key, val: (key, base64.b64encode(val).decode())
                 },
                 reverse_map={
                     "server_static_public": lambda key, val: (key, PublicKey(base64.b64decode(val))),
                     "client_static_keypair": lambda key, val: (key, KeyPair.from_bytes(base64.b64decode(val))),
                     "id": lambda key, val: (key, base64.b64decode(val)),
                     "expid": lambda key, val: (key, base64.b64decode(val)),
                     "edge_routing_info": lambda key, val: (key, base64.b64decode(val))
                 }
             ),
             MetaPropsTransform(meta_props=("version", )),
         )
     )
Пример #2
0
def run(wttQueue, ttwQueue, config):
    logger.info("Starting Whatsapp Self-Bot")

    keypair = KeyPair.from_bytes(
        base64.b64decode(config["client_static_keypair"]))

    credentials = (config["phone"], keypair)

    layers = (
        WhatsappLayer(wttQueue, ttwQueue),
        YowParallelLayer([
            YowAuthenticationProtocolLayer, YowMessagesProtocolLayer,
            YowReceiptProtocolLayer, YowAckProtocolLayer, YowIqProtocolLayer,
            YowGroupsProtocolLayer, YowMediaProtocolLayer
        ]),
        AxolotlControlLayer,
        YowParallelLayer((AxolotlSendLayer, AxolotlReceivelayer)),
    ) + YOWSUP_CORE_LAYERS

    stack = YowStack(layers)
    stack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS,
                  credentials)  # setting credentials
    stack.setProp(YowNetworkLayer.PROP_ENDPOINT,
                  YowConstants.ENDPOINTS[0])  # whatsapp server address
    # stack.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)
    # stack.setProp(YowCoderLayer.PROP_RESOURCE, YowsupEnv.getCurrent().getResource()) #info about us as WhatsApp client

    stack.broadcastEvent(YowLayerEvent(
        YowNetworkLayer.EVENT_STATE_CONNECT))  # sending the connect signal

    stack.loop()
Пример #3
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)
Пример #5
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()
Пример #6
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=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]" % (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()
 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)
Пример #8
0
 def __init__(self, config_class):
     super(ConfigSerialize, self).__init__(transforms=(
         ConfigDictTransform(config_class),
         FilterTransform(transform_filter=lambda key, val: val is not None,
                         reverse_filter=lambda key, val: key != "version"),
         MapTransform(transform_map=lambda key, val: (key[1:], val)),
         PropsTransform(transform_map={
             "server_static_public":
             lambda key, val: (key, base64.b64encode(val.data).decode()),
             "client_static_keypair":
             lambda key, val:
             (key, base64.b64encode(val.private.data + val.public.data).
              decode()),
             "id":
             lambda key, val: (key, base64.b64encode(val).decode()),
             "expid":
             lambda key, val: (key, base64.b64encode(val).decode()),
             "edge_routing_info":
             lambda key, val: (key, base64.b64encode(val).decode())
         },
                        reverse_map={
                            "server_static_public":
                            lambda key, val:
                            (key, PublicKey(base64.b64decode(val))),
                            "client_static_keypair":
                            lambda key, val:
                            (key, KeyPair.from_bytes(base64.b64decode(val))
                             ),
                            "id":
                            lambda key, val: (key, base64.b64decode(val)),
                            "expid":
                            lambda key, val: (key, base64.b64decode(val)),
                            "edge_routing_info":
                            lambda key, val: (key, base64.b64decode(val))
                        }),
         MetaPropsTransform(meta_props=("version", )),
     ))
Пример #9
0
import consonance
import uuid
import dissononce
import socket
import logging
import sys
import base64

consonance.logger.setLevel(logging.DEBUG)
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)
Пример #10
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()
Пример #11
0
 def generateKeyPair(cls):
     """
     :return:
     :rtype: KeyPair
     """
     return KeyPair.generate()
Пример #12
0
from yowsup.layers.network import YowNetworkLayer
from consonance.structs.keypair import KeyPair
import base64

from app.layer import MacLayer

import threading
from flask import Flask, request, g
from app.utils import helper
import json

# Uncomment to log
#logging.basicConfig(level=logging.DEBUG)

# Config
credentials = config.credentials['phone'], KeyPair.from_bytes(base64.b64decode(config.credentials['password']))
encryption = True

class WS(object):
    def __init__(self):
        self.app = Flask(__name__)

        @self.app.route("/send", methods=['POST'])
        def send():            
            body = request.json
            MacLayer.send_message(body['text'].replace("\n", "\n"), body['conversation'])
            return helper.json_response(status=201)

        thread = threading.Thread(target=self.run, args=())
        thread.daemon = True                            
        thread.start() 
Пример #13
0
from yowsup.stacks import YowStackBuilder
from layer import EchoLayer
from yowsup.layers import YowLayerEvent
from yowsup.layers.network import YowNetworkLayer
from yowsup.env import YowsupEnv
from yowsup.layers.axolotl.props import PROP_IDENTITY_AUTOTRUST
from consonance.structs.keypair import KeyPair
import base64
import sys
import config


credentials = (config.credentials["PHONE"], KeyPair.from_bytes(base64.b64decode(config.credentials["CLIENT_STATIC_KEYPAIR"])))


if __name__==  "__main__":
  stackBuilder = YowStackBuilder()

  try:
    stack = stackBuilder\
      .pushDefaultLayers()\
      .push(EchoLayer)\
      .build()

    stack.setCredentials(credentials)
    stack.setProp(PROP_IDENTITY_AUTOTRUST, True)
    stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT)) # sending the connect signal
    stack.loop()
  except KeyboardInterrupt:
    sys.exit(0)
  except: