Esempio n. 1
0
    def process(self):
        self.args = vars(self.parse_args())

        if self.args["debug"]:
            logger.setLevel(logging.DEBUG)
            yowlogger.setLevel(level=logging.DEBUG)
        else:
            logger.setLevel(logging.INFO)
            yowlogger.setLevel(level=logging.INFO)

        YowsupEnv.setEnv("android")

        config_manager = ConfigManager()
        profile_name = None
        config_loaded_from_profile = True
        if self.args["config"]:
            config = config_manager.load(self.args["config"])
            if not os.path.isfile(self.args["config"]):
                profile_name = self.args["config"]
            elif not self.args["config"].startswith(
                    StorageTools.getStorageForProfile(config.phone)):
                config_loaded_from_profile = False
        else:
            raise ValueError("Must specify --config")

        if config is None:
            config = Config()

        if not config_loaded_from_profile:
            # config file was explicitly specified and is not that of profile,
            # load profile config and override values
            internal_config = config_manager.load(config.phone,
                                                  profile_only=True)
            if internal_config is not None:
                for property in config.keys():
                    if property != "version" and config[property] is not None:
                        internal_config[property] = config[property]
                config = internal_config

        if self._profile is None or self._profile.config is None:
            self._profile = YowProfile(profile_name or config.phone, config)

        if self._profile.config.phone is None:
            print("Invalid config")
            sys.exit(1)
Esempio n. 2
0
class YowProfile(object):
    def __init__(self, profile_name, config=None):
        # type: (str, Config) -> None
        """
        :param profile_name:  profile name
        :param config: A supplied config will disable loading configs using the Config manager and provide that config
        instead
        """
        logger.info("Constructed Profile(profile_name=%s)" % profile_name)
        self._profile_name = profile_name
        self._config = config
        self._config_manager = ConfigManager()
        self._axolotl_manager = None

    def __str__(self):
        return "YowProfile(profile_name=%s)" % self._profile_name

    def _load_config(self):
        # type: () -> Config
        logger.debug("load_config for %s" % self._profile_name)
        return self._config_manager.load(self._profile_name)

    def _load_axolotl_manager(self):
        # type: () -> AxolotlManager
        return AxolotlManagerFactory().get_manager(self._profile_name,
                                                   self.username)

    def write_config(self, config):
        # type: (Config) -> None
        logger.debug("write_config for %s" % self._profile_name)
        self._config_manager.save(self._profile_name, config)

    @property
    def config(self):
        if self._config is None:
            self._config = self._load_config()
        return self._config

    @property
    def axolotl_manager(self):
        if self._axolotl_manager is None:
            self._axolotl_manager = self._load_axolotl_manager()
        return self._axolotl_manager

    @property
    def username(self):
        config = self.config
        return config.login or config.phone or self._profile_name
Esempio n. 3
0
class YowNoiseLayer(YowLayer):
    DEFAULT_PUSHNAME = "yowsup"
    HEADER = b'WA\x02\x01'
    EDGE_HEADER = b'ED\x00\x01'

    def __init__(self):
        super(YowNoiseLayer, self).__init__()
        self._wa_noiseprotocol = WANoiseProtocol(
            2, 1, protocol_state_callbacks=self._on_protocol_state_changed
        )  # type: WANoiseProtocol

        self._handshake_worker = None
        self._stream = BlockingQueueSegmentedStream()  # type: BlockingQueueSegmentedStream
        self._read_buffer = bytearray()
        self._flush_lock = threading.Lock()
        self._incoming_segments_queue = Queue.Queue()
        self._config_manager = ConfigManager()
        self._username = None
        self._rs = None

    def __str__(self):
        return "Noise Layer"

    @EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECTED)
    def on_disconnected(self, event):
        self._wa_noiseprotocol.reset()

    @EventCallback(YowAuthenticationProtocolLayer.EVENT_AUTH)
    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 _in_handshake(self):
        """
        :return:
        :rtype: bool
        """
        return self._wa_noiseprotocol.state == WANoiseProtocol.STATE_HANDSHAKE

    def _on_protocol_state_changed(self, state):
        if state == WANoiseProtocol.STATE_TRANSPORT:
            if self._rs != self._wa_noiseprotocol.rs:
                config = self._config_manager.load(self._username)
                config.server_static_public = self._wa_noiseprotocol.rs
                self._config_manager.save(config)
                self._rs = self._wa_noiseprotocol.rs
            self._flush_incoming_buffer()

    def _handle_stream_event(self, event):
        if event == BlockingQueueSegmentedStream.EVENT_WRITE:
            self.toLower(self._stream.get_write_segment())
        elif event == BlockingQueueSegmentedStream.EVENT_READ:
            self._stream.put_read_segment(self._incoming_segments_queue.get(block=True))

    def send(self, data):
        """
        :param data:
        :type data: bytearray | bytes
        :return:
        :rtype:
        """
        data = bytes(data) if type(data) is not bytes else data
        self._wa_noiseprotocol.send(data)

    def _flush_incoming_buffer(self):
        self._flush_lock.acquire()
        while self._incoming_segments_queue.qsize():
            self.toUpper(self._wa_noiseprotocol.receive())
        self._flush_lock.release()

    def receive(self, data):
        """
        :param data:
        :type data: bytes
        :return:
        :rtype:
        """
        self._incoming_segments_queue.put(data)
        if not self._in_handshake():
            self._flush_incoming_buffer()
Esempio n. 4
0
from yowsup.stacks import YowStackBuilder
from layer import MqttLayer
from layer import EchoLayer
from yowsup.layers import YowLayerEvent
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.auth import YowAuthenticationProtocolLayer
from yowsup.common import YowConstants
from yowsup.profile.profile import YowProfile
from yowsup.config.manager import ConfigManager
from yowsup.config.v1.config import Config

stackBuilder = YowStackBuilder()

stack = stackBuilder\
        .pushDefaultLayers()\
        .push(MqttLayer())\
        .build()
config_manager = ConfigManager()
config = config_manager.load("36309040975")
profile = YowProfile(config.login,config)
stack.setProfile(profile)

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

stack.loop() #this is the program mainloop`
Esempio n. 5
0
class YowNoiseLayer(YowLayer):
    DEFAULT_PUSHNAME = "yowsup"
    HEADER = b'WA\x02\x01'
    EDGE_HEADER = b'ED\x00\x01'

    def __init__(self):
        super(YowNoiseLayer, self).__init__()
        self._wa_noiseprotocol = WANoiseProtocol(
            2, 1, protocol_state_callbacks=self._on_protocol_state_changed
        )  # type: WANoiseProtocol

        self._handshake_worker = None
        self._stream = BlockingQueueSegmentedStream(
        )  # type: BlockingQueueSegmentedStream
        self._read_buffer = bytearray()
        self._flush_lock = threading.Lock()
        self._incoming_segments_queue = Queue.Queue()
        self._config_manager = ConfigManager()
        self._username = None
        self._rs = None

    def __str__(self):
        return "Noise Layer"

    @EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECTED)
    def on_disconnected(self, event):
        self._wa_noiseprotocol.reset()

    @EventCallback(YowAuthenticationProtocolLayer.EVENT_AUTH)
    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()

    def _in_handshake(self):
        """
        :return:
        :rtype: bool
        """
        return self._wa_noiseprotocol.state == WANoiseProtocol.STATE_HANDSHAKE

    def _on_protocol_state_changed(self, state):
        if state == WANoiseProtocol.STATE_TRANSPORT:
            if self._rs != self._wa_noiseprotocol.rs:
                config = self._config_manager.load(self._username)
                config.server_static_public = self._wa_noiseprotocol.rs
                self._config_manager.save(config)
                self._rs = self._wa_noiseprotocol.rs
            self._flush_incoming_buffer()

    def _handle_stream_event(self, event):
        if event == BlockingQueueSegmentedStream.EVENT_WRITE:
            self.toLower(self._stream.get_write_segment())
        elif event == BlockingQueueSegmentedStream.EVENT_READ:
            self._stream.put_read_segment(
                self._incoming_segments_queue.get(block=True))

    def send(self, data):
        """
        :param data:
        :type data: bytearray | bytes
        :return:
        :rtype:
        """
        data = bytes(data) if type(data) is not bytes else data
        self._wa_noiseprotocol.send(data)

    def _flush_incoming_buffer(self):
        self._flush_lock.acquire()
        while self._incoming_segments_queue.qsize():
            self.toUpper(self._wa_noiseprotocol.receive())
        self._flush_lock.release()

    def receive(self, data):
        """
        :param data:
        :type data: bytes
        :return:
        :rtype:
        """
        self._incoming_segments_queue.put(data)
        if not self._in_handshake():
            self._flush_incoming_buffer()