Exemplo n.º 1
0
    def connect_to_icloud(
            self, config: Dict[str, Union[str, bool,
                                          None]]) -> PyiCloudService:
        self.logger.info("Connecting to iCloud…")
        if config["password"] == "":
            api = PyiCloudService(config["username"])
        else:
            api = PyiCloudService(config["username"], config["password"])

        if api.requires_2sa:
            print("Two-step authentication required.")

            if click.confirm(
                    "Have you received authentication request on any of your devices?"
            ):
                verification_function = lambda code: api.validate_2fa_code(code
                                                                           )
            else:
                print("Fallback to SMS verification.")
                print("Your trusted devices are:")
                devices = api.trusted_devices
                for i, device in enumerate(devices):
                    print("  {}: {}".format(
                        i,
                        device.get(
                            "deviceName",
                            "SMS to {}".format(device.get("phoneNumber")),
                        ),
                    ))
                device = click.prompt("Which device would you like to use?",
                                      default=0)
                device = devices[device]
                if not api.send_verification_code(device):
                    raise Exception("Failed to send verification code")
                verification_function = lambda code: api.validate_verification_code(
                    device, code)

            verified = False
            while not verified:
                code = click.prompt("Please enter validation code")
                verified = verification_function(code)
                self.logger.debug("Verification result: %s", verified)
                if verified:
                    print("Succeed")
                else:
                    print(
                        "Failed to verify verification code, retry (Ctrl-C to cancel)"
                    )

        return api
Exemplo n.º 2
0
def authenticate(username, password):
    """attempt to authenticate user using provided credentials"""

    api = PyiCloudService(username, password)

    if api.requires_2fa:
        print("Two-factor authentication required.")
        code = input(
            "Enter the code you received of one of your approved devices: ")
        result = api.validate_2fa_code(code)
        print("Code validation result: %s" % result)

        if not result:
            print("Failed to verify security code")
            sys.exit(1)

        if not api.is_trusted_session:
            print("Session is not trusted. Requesting trust...")
            result = api.trust_session()
            print("Session trust result %s" % result)

            if not result:
                print(
                    "Failed to request trust. You will likely be prompted for the code again in the coming weeks"
                )
    elif api.requires_2sa:
        import click
        print("Two-step authentication required. Your trusted devices are:")

        devices = api.trusted_devices
        for i, device in enumerate(devices):
            print("  %s: %s" %
                  (i,
                   device.get('deviceName',
                              "SMS to %s" % device.get('phoneNumber'))))

        device = click.prompt('Which device would you like to use?', default=0)
        device = devices[device]
        if not api.send_verification_code(device):
            print("Failed to send verification code")
            sys.exit(1)

        code = click.prompt('Please enter validation code')
        if not api.validate_verification_code(device, code):
            print("Failed to verify verification code")
            sys.exit(1)

    return api
Exemplo n.º 3
0
    def login(self, username, password):
        api = PyiCloudService(username, password)
        if api.requires_2fa:
            logging.info(
                f"ICloud with mail {username} required Two-factor authentication!"
            )
            result = api.validate_2fa_code(self.__get_2fa_code())

            if not result:
                logging.critical(
                    f"Failed to verify security code of ICloud-Account with mail {username}"
                )
                self.connected = False

            if not api.is_trusted_session:
                logging.info(
                    f"Session for mail, {username} is not trusted. Requesting trust..."
                )
                result = api.trust_session()
                print(f"Session trust for mail {username} result '{result}'")

                if not result:
                    logging.critical(
                        "Failed to request trust. You will likely be prompted for the code again in the coming weeks!"
                    )
                    self.connected = False
        elif api.requires_2sa:
            import click
            devices = api.trusted_devices
            for i, device in enumerate(devices):
                print("  %s: %s" %
                      (i,
                       device.get('deviceName',
                                  "SMS to %s" % device.get('phoneNumber'))))

            device = click.prompt('Which device would you like to use?',
                                  default=0)
            device = devices[device]
            if not api.send_verification_code(device):
                logging.critical("Failed to send verification code")
            code = click.prompt('Please enter validation code')

            if not api.validate_verification_code(device, code):
                logging.critical("Failed to verify verification code!")
                self.connected = False

        return api
Exemplo n.º 4
0
class iCloud:
    def __init__(self):
        creds = self.__load_creds(os.getcwd() + "/Secrets.txt")
        self.api = PyiCloudService(creds[0], creds[1])
        self.__two_factor_routine()
        self.phone = self.Phone()
        self.update_phone()

        self.lats, self.longs = self.__load_location()

    def __load_location(self):
        with open("location.txt", "r") as f:
            temp = f.readlines()
        out = []
        for i in temp:
            i = i.strip()
            i = i.split(",")
            out.append([float(j) for j in i])
        return out[0], out[1]

    def update_phone(self):
        _phone = self.api.devices[1]
        status = _phone.status()
        self.phone.update(_phone.content, status)

    def __load_creds(self, path):
        with open(path, "r") as f:
            creds = f.readlines()
        return [i.strip() for i in creds]

    # Not my code. This was ripped from pycloud docs.
    def __two_factor_routine(self):
        if self.api.requires_2fa:
            print("Two-factor authentication required.")
            code = input(
                "Enter the code you received of one of your approved devices: "
            )
            result = self.api.validate_2fa_code(code)
            print("Code validation result: %s" % result)

            if not result:
                print("Failed to verify security code")
                sys.exit(1)

            if not self.api.is_trusted_session:
                print("Session is not trusted. Requesting trust...")
                result = self.api.trust_session()
                print("Session trust result %s" % result)

                if not result:
                    print(
                        "Failed to request trust. You will likely be prompted for the code again in the coming weeks"
                    )
        elif self.api.requires_2sa:
            import click
            print(
                "Two-step authentication required. Your trusted devices are:")

            devices = self.api.trusted_devices
            for i, device in enumerate(devices):
                print("  %s: %s" %
                      (i,
                       device.get('deviceName',
                                  "SMS to %s" % device.get('phoneNumber'))))

            device = click.prompt('Which device would you like to use?',
                                  default=0)
            device = devices[device]
            if not self.api.send_verification_code(device):
                print("Failed to send verification code")
                sys.exit(1)

            code = click.prompt('Please enter validation code')
            if not self.api.validate_verification_code(device, code):
                print("Failed to verify verification code")
                sys.exit(1)

    def is_charging(self):
        first = self.api.devices[1].status()["batteryLevel"]
        count = 0

        while True:
            time.sleep(20)
            second = self.api.devices[1].status()["batteryLevel"]
            print("First {} --> Second {}".format(first, second))
            if second != first:
                break
            count += 1
        if second - first > 0.0:
            return True
        else:
            return False

    def is_home(self):
        lat_fence = self.lats
        long_fence = self.longs

        lat_check = self.phone.location[0] > lat_fence[
            0] and self.phone.location[0] < lat_fence[1]
        long_check = self.phone.location[1] < long_fence[
            0] and self.phone.location[1] > long_fence[1]
        return lat_check and long_check

    class Phone:
        def __init__(self):
            self.battery = 0.0
            self.location = []
            self.id = ""
            self.timestamp = None

        def update(self, content, status):
            self.timestamp = datetime.datetime.now()
            self.battery = status["batteryLevel"]
            self.id = content["id"]
            lat = content["location"]["latitude"]
            long = content["location"]["longitude"]
            self.location = [lat, long]
Exemplo n.º 5
0
def main(args=None):
    """Main commandline entrypoint."""
    if args is None:
        args = sys.argv[1:]

    parser = argparse.ArgumentParser(description="Find My iPhone CommandLine Tool")

    parser.add_argument(
        "--username",
        action="store",
        dest="username",
        default="",
        help="Apple ID to Use",
    )
    parser.add_argument(
        "--password",
        action="store",
        dest="password",
        default="",
        help=(
            "Apple ID Password to Use; if unspecified, password will be "
            "fetched from the system keyring."
        ),
    )
    parser.add_argument(
        "-n",
        "--non-interactive",
        action="store_false",
        dest="interactive",
        default=True,
        help="Disable interactive prompts.",
    )
    parser.add_argument(
        "--delete-from-keyring",
        action="store_true",
        dest="delete_from_keyring",
        default=False,
        help="Delete stored password in system keyring for this username.",
    )
    parser.add_argument(
        "--list",
        action="store_true",
        dest="list",
        default=False,
        help="Short Listings for Device(s) associated with account",
    )
    parser.add_argument(
        "--llist",
        action="store_true",
        dest="longlist",
        default=False,
        help="Detailed Listings for Device(s) associated with account",
    )
    parser.add_argument(
        "--locate",
        action="store_true",
        dest="locate",
        default=False,
        help="Retrieve Location for the iDevice (non-exclusive).",
    )

    # Restrict actions to a specific devices UID / DID
    parser.add_argument(
        "--device",
        action="store",
        dest="device_id",
        default=False,
        help="Only effect this device",
    )

    # Trigger Sound Alert
    parser.add_argument(
        "--sound",
        action="store_true",
        dest="sound",
        default=False,
        help="Play a sound on the device",
    )

    # Trigger Message w/Sound Alert
    parser.add_argument(
        "--message",
        action="store",
        dest="message",
        default=False,
        help="Optional Text Message to display with a sound",
    )

    # Trigger Message (without Sound) Alert
    parser.add_argument(
        "--silentmessage",
        action="store",
        dest="silentmessage",
        default=False,
        help="Optional Text Message to display with no sounds",
    )

    # Lost Mode
    parser.add_argument(
        "--lostmode",
        action="store_true",
        dest="lostmode",
        default=False,
        help="Enable Lost mode for the device",
    )
    parser.add_argument(
        "--lostphone",
        action="store",
        dest="lost_phone",
        default=False,
        help="Phone Number allowed to call when lost mode is enabled",
    )
    parser.add_argument(
        "--lostpassword",
        action="store",
        dest="lost_password",
        default=False,
        help="Forcibly active this passcode on the idevice",
    )
    parser.add_argument(
        "--lostmessage",
        action="store",
        dest="lost_message",
        default="",
        help="Forcibly display this message when activating lost mode.",
    )

    # Output device data to an pickle file
    parser.add_argument(
        "--outputfile",
        action="store_true",
        dest="output_to_file",
        default="",
        help="Save device data to a file in the current directory.",
    )

    command_line = parser.parse_args(args)

    username = command_line.username
    password = command_line.password

    if username and command_line.delete_from_keyring:
        utils.delete_password_in_keyring(username)

    failure_count = 0
    while True:
        # Which password we use is determined by your username, so we
        # do need to check for this first and separately.
        if not username:
            parser.error("No username supplied")

        if not password:
            password = utils.get_password(
                username, interactive=command_line.interactive
            )

        if not password:
            parser.error("No password supplied")

        try:
            api = PyiCloudService(username.strip(), password.strip())
            if (
                not utils.password_exists_in_keyring(username)
                and command_line.interactive
                and confirm("Save password in keyring?")
            ):
                utils.store_password_in_keyring(username, password)

            if api.requires_2fa:
                # fmt: off
                print(
                    "\nTwo-step authentication required.",
                    "\nPlease enter validation code"
                )
                # fmt: on

                code = input("(string) --> ")
                if not api.validate_2fa_code(code):
                    print("Failed to verify verification code")
                    sys.exit(1)

                print("")

            elif api.requires_2sa:
                # fmt: off
                print(
                    "\nTwo-step authentication required.",
                    "\nYour trusted devices are:"
                )
                # fmt: on

                devices = api.trusted_devices
                for i, device in enumerate(devices):
                    print(
                        "    %s: %s"
                        % (
                            i,
                            device.get(
                                "deviceName", "SMS to %s" % device.get("phoneNumber")
                            ),
                        )
                    )

                print("\nWhich device would you like to use?")
                device = int(input("(number) --> "))
                device = devices[device]
                if not api.send_verification_code(device):
                    print("Failed to send verification code")
                    sys.exit(1)

                print("\nPlease enter validation code")
                code = input("(string) --> ")
                if not api.validate_verification_code(device, code):
                    print("Failed to verify verification code")
                    sys.exit(1)

                print("")
            break
        except PyiCloudFailedLoginException:
            # If they have a stored password; we just used it and
            # it did not work; let's delete it if there is one.
            if utils.password_exists_in_keyring(username):
                utils.delete_password_in_keyring(username)

            message = "Bad username or password for {username}".format(
                username=username,
            )
            password = None

            failure_count += 1
            if failure_count >= 3:
                raise RuntimeError(message)

            print(message, file=sys.stderr)

    for dev in api.devices:
        if not command_line.device_id or (
            command_line.device_id.strip().lower() == dev.content["id"].strip().lower()
        ):
            # List device(s)
            if command_line.locate:
                dev.location()

            if command_line.output_to_file:
                create_pickled_data(
                    dev,
                    filename=(dev.content["name"].strip().lower() + ".fmip_snapshot"),
                )

            contents = dev.content
            if command_line.longlist:
                print("-" * 30)
                print(contents["name"])
                for key in contents:
                    print("%20s - %s" % (key, contents[key]))
            elif command_line.list:
                print("-" * 30)
                print("Name - %s" % contents["name"])
                print("Display Name  - %s" % contents["deviceDisplayName"])
                print("Location      - %s" % contents["location"])
                print("Battery Level - %s" % contents["batteryLevel"])
                print("Battery Status- %s" % contents["batteryStatus"])
                print("Device Class  - %s" % contents["deviceClass"])
                print("Device Model  - %s" % contents["deviceModel"])

            # Play a Sound on a device
            if command_line.sound:
                if command_line.device_id:
                    dev.play_sound()
                else:
                    raise RuntimeError(
                        "\n\n\t\t%s %s\n\n"
                        % (
                            "Sounds can only be played on a singular device.",
                            DEVICE_ERROR,
                        )
                    )

            # Display a Message on the device
            if command_line.message:
                if command_line.device_id:
                    dev.display_message(
                        subject="A Message", message=command_line.message, sounds=True
                    )
                else:
                    raise RuntimeError(
                        "%s %s"
                        % (
                            "Messages can only be played on a singular device.",
                            DEVICE_ERROR,
                        )
                    )

            # Display a Silent Message on the device
            if command_line.silentmessage:
                if command_line.device_id:
                    dev.display_message(
                        subject="A Silent Message",
                        message=command_line.silentmessage,
                        sounds=False,
                    )
                else:
                    raise RuntimeError(
                        "%s %s"
                        % (
                            "Silent Messages can only be played "
                            "on a singular device.",
                            DEVICE_ERROR,
                        )
                    )

            # Enable Lost mode
            if command_line.lostmode:
                if command_line.device_id:
                    dev.lost_device(
                        number=command_line.lost_phone.strip(),
                        text=command_line.lost_message.strip(),
                        newpasscode=command_line.lost_password.strip(),
                    )
                else:
                    raise RuntimeError(
                        "%s %s"
                        % (
                            "Lost Mode can only be activated on a singular device.",
                            DEVICE_ERROR,
                        )
                    )
    sys.exit(0)
Exemplo n.º 6
0
appleid_email = ''
appleid_password = ''
lostmode_phonenumber = ''
lostmode_message = ''

from pyicloud import PyiCloudService
#api = PyiCloudService(appleid_email, appleid_password)
api = PyiCloudService(appleid_email, appleid_password)

if api.requires_2fa:
    print("Two-factor authentication required.")
    code = input(
        "Enter the code you received of one of your approved devices: ")
    result = api.validate_2fa_code(code)
    print("Code validation result: %s" % result)

    if not result:
        print("Failed to verify security code")
        sys.exit(1)

    if not api.is_trusted_session:
        print("Session is not trusted. Requesting trust...")
        result = api.trust_session()
        print("Session trust result %s" % result)

        if not result:
            print(
                "Failed to request trust. You will likely be prompted for the code again in the coming weeks"
            )
elif api.requires_2sa:
    import click