Пример #1
0
    def OneRow(cursor, rowtransform, print_transform=False, printer=StatusPrinter()):

        row = cursor.fetchone()

        next_row = cursor.fetchone()
        if next_row:
            raise Exception("OneRow feedback strategy saw at least two rows: {} and {}".format(row, next_row))
            # this function refuses to break ties for you
            # if you expected multiple rows, use the ManyRows feedback strategy and break them yourself


        # exit early if response is empty
        if not row:
            printer("...got empty result")
            return None

        printer('[Row]')
        with Indent(printer):
            printer(shorten(row))

        # exit early if transform is trivial
        if is_identity(rowtransform):
            return row

        row = rowtransform(row)

        if print_transform:
            printer('[Transformed Row]')
            with Indent(printer):
                printer(pretty_shorten(row))

        return row
Пример #2
0
def print_or_warn(string, max_length=500, printer=StatusPrinter()):

    if len(string) > max_length and sys.stdout.isatty():

        validJson = False
        try:
            json.loads(string)
            validJson = True
        except ValueError:
            pass

        if validJson:
            printer("Output is {} chars (json) and stdout is a tty.".format(
                len(string)))
        else:
            printer("Output is {} chars and stdout is a tty.".format(
                len(string)))

        with Indent(printer):
            printer(
                "\nIf you really want that much garbage in your terminal, write to a pipe, like so:"
            )
            with Indent(printer):
                printer(clistring() + " | cat")
            if validJson:
                printer(
                    "Or better yet, use `jq` to query it:"
                )  # because humans shouldn't have to read non-pretty json
                with Indent(printer):
                    printer(clistring() + " | jq '.someKey[3]'")
        sys.exit(15)
    else:
        print(string)
Пример #3
0
    def execute(self, feedback, rowtransform=lambda x : x, print_transform=False, printer=StatusPrinter()):
        # open an ssh tunnel
        with PossibleSshTunnel(self.ssh_config, printer) as tun:
            with Indent(printer):

                host = Query.get_mysql_host(tun.mysql().host)

                # open a mysql connection
                db = MySQLdb.connect(user=self.mysql_user,
                                    host=host,
                                    port=tun.mysql().port,
                                    db=tun.mysql().db,
                                    passwd=self.mysql_pass,
                                    autocommit=True,
                                    cursorclass=MySQLdb.cursors.DictCursor)
                c = db.cursor()

                # show the query then run it
                printer("[Query]")
                with Indent(printer):
                    printer(dedent(self.sql).strip())
                c.execute(self.sql)

                # do what the caller wanted
                return feedback(c, rowtransform, print_transform=print_transform, printer=printer)
Пример #4
0
    def ManyRows(cursor, rowtransform, print_transform=False, printer=StatusPrinter()):

        # exit early if response is empty
        rows = cursor.fetchall()
        if not rows:
            printer("...got empty result")
            return None

        printer('[Rows]')
        with Indent(printer):
            printer(shorten(rows))

        # exit early if transform is trivial
        if is_identity(rowtransform):
            return rows


        rows = list(map(rowtransform, rows))

        if print_transform:
            printer('[Transformed Rows]')
            with Indent(printer):
                printer(pretty_shorten(rows))

        return rows
Пример #5
0
def master_clear():
    printer = StatusPrinter(indent=0)
    printer("Clearing Device")
    with Indent(printer):
        with Indent(printer):
            d = get_connected_device(printer=printer)
        cmd = ['shell', 'am', 'broadcast', '-a', 'android.intent.action.MASTER_CLEAR', '-n', 'android/com.android.server.MasterClearReceiver']
        printer('\'' + ' '.join(cmd) + '\'')
        adb(cmd)
    sleep(d.get_shutdown_delay())
Пример #6
0
def print_request(printer, endpoint, headers, data):

    printer("[Request] " + endpoint)
    with Indent(printer):
        printer("headers:")
        with Indent(printer):
            printer(pp.pformat(headers, indent=2))
        printer("data:")
        with Indent(printer):
            printer(pretty_shorten(data))
Пример #7
0
def print_response(printer, response):

    printer("[Response]")
    with Indent(printer):
        printer("code:", end='')
        printer(response.status_code)
        printer("reason:", end='')
        printer(response.reason)
        printer("content:")
        with Indent(printer):
            printer(pretty_shorten_maybe_json(response))
Пример #8
0
def set_target():
    parsed_args = parse(Parseable.target_type, Parseable.server)

    printer = StatusPrinter(indent=0)
    printer("Targeting attached device to {} {}".format(parsed_args.targettype, parsed_args.server))
    with Indent(printer):
        get_connected_device(printer=printer).set_target(parsed_args.targettype, parsed_args.server)
Пример #9
0
def deprovision():
    args = parse_serial_ssh()

    printer = StatusPrinter(indent=0)
    printer("Deprovisioning Device")
    with Indent(printer):

        auth_token = get_auth_token(
            args.ssh_config,
            '/v3/partner/pp/merchants/{mId}/devices/{serialNumber}/deprovision'
        )

        mid = get_merchant(args.serial_num, args.ssh_config,
                           printer=printer).uuid

        endpoint = 'https://{}/v3/partner/pp/merchants/{}/devices/{}/deprovision'.format(
            args.ssh_config.hostname, mid, args.serial_num)

        headers = {'Authorization': 'Bearer ' + auth_token}

        print_request(printer, endpoint, headers, {})
        response = requests.put(endpoint, headers=headers)
        print_response(printer, response)

    # TODO: server/scripts/disassociate_device.py also DELETEs '/v3/resellers/{rId}/devices/{serial}'
    # maybe this function should do that also?

    if response.status_code == 200:
        printer('OK')
    else:
        printer('Error')
        sys.exit(10)
Пример #10
0
def provision():
    args = parse_serial_ssh_merch()

    printer = StatusPrinter(indent=0)
    printer("Provisioning Device")

    with Indent(printer):

        endpoint = 'https://{}/v3/partner/pp/merchants/{}/devices/{}/provision'.format(
            args.ssh_config.hostname, args.merchant, args.serial_num)

        auth_token = get_auth_token(
            args.ssh_config,
            '/v3/partner/pp/merchants/{mId}/devices/{serialNumber}/provision')

        headers = {'Authorization': 'Bearer ' + auth_token}

        data = {
            'mId': get_mid(args.ssh_config, args.merchant),
            'merchantUuid': args.merchant,
            'serial': args.serial_num,
            'chipUid': args.cpuid
        }

        print_request(printer, endpoint, headers, data)

        response = requests.put(endpoint, headers=headers, data=data)

        print_response(printer, response)

    if response.status_code == 200:
        printer('OK')
    else:
        printer('Error')
        sys.exit(20)
Пример #11
0
def print_local_ip():

    printer = StatusPrinter(indent=0)
    printer("Seeking local IP accessable by device")

    with Indent(printer):
        local_ip = probe_network(selector = lambda x : x['local_ip'], printer=printer)
    print(local_ip)
Пример #12
0
def print_device_ip():

    printer = StatusPrinter(indent=0)
    printer("Seeking accessable device IP")

    with Indent(printer):
        device_ip = probe_network(selector = lambda x : x['device_ip'], printer=printer)
    print(device_ip)
Пример #13
0
def print_activation_code():
    args = parse_serial_ssh()
    printer = StatusPrinter(indent=0)
    printer("Getting Activation Code")
    with Indent(printer):
        print(
            get_activation_code(args.ssh_config,
                                args.serial_num,
                                printer=printer))
Пример #14
0
    def execute(self, then=lambda db: None, printer=StatusPrinter()):
        # open an ssh tunnel
        with SshTunnel(self.ssh_config, printer) as tun:
            with Indent(printer):
                # open a mysql connection
                db = _mysql.connect(user=self.mysql_user,
                                    host='127.0.0.1',
                                    port=tun.mysql_port,
                                    db='meta',
                                    passwd=self.mysql_pass)

                # show the query then run it
                printer("[Query]")
                with Indent(printer):
                    printer(dedent(self.sql).strip())
                db.query(self.sql)

                # do what the caller wanted
                return then(db)
Пример #15
0
def probe_network(selector=lambda x : x, printer=StatusPrinter()):

    with Indent(printer):
        local_remote = get_local_remote_ip()

    if local_remote:
        return selector({ "local_ip" : local_remote[0],
                   "device_ip" : local_remote[1] })
    else:
        printer("No connectivity between local machine and device")
        sys.exit(40)
Пример #16
0
    def ChangeCount(cursor, rowtransform, print_transform=False, printer=StatusPrinter()):

        if not is_identity(rowtransform):
            printer("ChangeCount got nontrivial row transform.  It will be ignored.")

        change_ct = cursor.rowcount

        printer('[Rows Changed]')
        with Indent(printer):
            printer(change_ct)

        return change_ct
Пример #17
0
def internal_auth(target,
                  creds = {'username' : 'joe.blow',
                           'password' : 'letmein' },
                  printer=StatusPrinter()):

    endpoint = '{}://{}/cos/v1/dashboard/internal/login'.format(
                target.get_hypertext_protocol(),
                target.get_hostname() + ":" + str(target.get_http_port()))

    headers = { 'Content-Type' : 'application/json ',
                      'Accept' : 'application/json, text/javascript, */*; q=0.01',
                  'Connection' : 'keep-alive' }

    data = creds

    # first try with with a nonsense user
    printer("Attempting cloverDevAuth")
    with Indent(printer):
        response = post(endpoint, headers, data, obfuscate_pass=True, printer=printer)

    if response.status_code == 200:
        return response.headers['set-cookie']

    # if that fails, use a real one
    elif response.status_code == 401:
        printer("{} has cloverDevAuth unset or false, looking for real credentials".format(target.get_name()))

        creds = get_creds(printer=printer)
        data = {'username' : creds.user,
                'password' : creds.passwd}

        with Indent(printer):
            response = post(endpoint, headers, data, obfuscate_pass=True, printer=printer)

            if response.status_code == 200:
                return response.headers['set-cookie']
            else:
                raise Exception("Unexpected response from login endpoint")
Пример #18
0
    def can_talk(local, remote, printer):

        printer("Pinging {} -> {}".format(remote, local))
        with Indent(printer):
            printer('''adb shell 'ping -c 4 {} && echo SUCCESS || echo FAIL' '''.format(local))
            with Indent(printer):
                remote2local = str(adb(['shell', 'ping -c 4 {} && echo SUCCESS || echo FAIL'.format(local)]))
                printer(remote2local)

        if 'SUCCESS' in remote2local:
            printer("Pinging {} -> {}".format(local, remote))
            with Indent(printer):
                printer('ping -c 4 {}'.format(local))
                with Indent(printer):
                    try:
                        local2remote = ping(['-c', '4', remote])
                    except sh.ErrorReturnCode as err:
                        local2remote = err
                    printer(local2remote)

            if local2remote.exit_code == 0:
                return True
        return False
Пример #19
0
def get_creds(printer=StatusPrinter()):

    user_exists = False
    user_var='LDAP_USER'
    if user_var in os.environ:
        user = os.environ[user_var]
        user_exists = True
    # else: warn later so we can warn for both

    passwd_exists=False
    passwd_var='LDAP_PASSWORD'
    if passwd_var in os.environ:
        passwd = os.environ[passwd_var]
        passwd_exists = True
    # else: warn later so we can warn for both

    try:
        return UserPass(user, passwd)
    except NameError:
        with Indent(printer):
            printer("Please set environment variables:")
            with Indent(printer):

                if not user_exists:
                    printer(user_var)
                    with Indent(printer):
                        printer("(try typing: 'export {}=<your_username>' and rerunning the command)".format(
                            user_var))

                if not passwd_exists:
                    printer(passwd_var)
                    with Indent(printer):
                        printer("(try typing: \'read -s {} && export {}\', ".format(passwd_var, passwd_var),
                                "typing your password, and rerunning the command)")
                if not (user_exists and passwd_exists):
                    sys.exit(100)
Пример #20
0
def print_merchant():
    args = parse_serial_ssh()

    printer = StatusPrinter(indent=0)
    printer("Finding {}'s merchant according to {}".format(
        args.serial_num, args.ssh_config.ssh_host))

    try:
        with Indent(printer):
            merchant = get_merchant(args.serial_num,
                                    args.ssh_config,
                                    printer=printer)
        print(json.dumps(merchant._asdict()))
    except ValueError as ex:
        printer(str(ex))
        sys.exit(30)
Пример #21
0
def screenshot(device, printer=StatusPrinter()):
    printer("Dumping screenshot for Device: {}".format(device.serial))
    with Indent(printer):

        # make way for new file
        outfile_name = "{}_{}.png".format(device.serial,
                                          datetime.now().strftime("%Y-%m-%d_%H%M%S"))
        outfile_path = os.path.join(os.getcwd(), outfile_name)
        rm('-f', outfile_path)

        # get the screencap
        tempfile_path = '/sdcard/{}'.format(outfile_name)
        adb.shell('screencap', '-p', tempfile_path)
        adb.pull(tempfile_path)
        adb.shell('rm', tempfile_path)

        printer("Wrote " + outfile_path)
Пример #22
0
def _do_request(verb, endpoint, headers, data, print_data=None, printer=StatusPrinter()):

    # for obfuscating passwords
    if not print_data:
        print_data = data

    printer("[Http]")
    with Indent(printer):
        print_request(printer, endpoint, headers, print_data)
        if data:
            if 'json' in ''.join(headers.values()).lower():
                response = verb(endpoint, headers=headers, json=data)
            else:
                response = verb(endpoint, headers=headers, data=data)
        else:
            response = verb(endpoint, headers=headers)
        print_response(printer, response)
    return response
Пример #23
0
    def set_target(self, target, url, printer=StatusPrinter()):
        self.wait_ready()

        if re.match('http://.*', url):
            url = url[7:]

        printer("Targeting device to: " + url)
        with Indent(printer):

            cmd = ['su', '1000', 'content', 'call', '--uri', 'content://com.clover.service.provider',
                '--method', 'changeTarget', '--extra', 'target:s:{}:{}'.format(target, url)]

            printer('\'' + ' '.join(cmd) + '\'')
            adb.shell(cmd)

        # the above call causes a reset
        # wait until the adb connection is lost
        printer("Waiting {} seconds for device to begin reboot..."
                .format(self.get_shutdown_delay()))
        sleep(self.get_shutdown_delay())
Пример #24
0
 def get_row_val(db):
     row = db.store_result().fetch_row(how=1)
     if not row:
         printer("...got empty result")
         raise ValueError(self._empty_message)
     else:
         printer("[Result]")
         with Indent(printer):
             try:
                 # if we're selecting rows directly
                 if isinstance(row, tuple):
                     printer(row[0])
                     return getter(row[0])
                 # if we're selecting the output of a mysql builtin
                 else:
                     printer(row)
                     return getter(row)
             except:
                 printer(row[0])
                 raise
Пример #25
0
def print_info():
    printer = StatusPrinter(indent=0)
    printer("Getting device info")
    with Indent(printer):
        info = json.dumps(get_connected_device(printer=printer).get_info())
    print(info)
Пример #26
0
def print_serial():
    printer = StatusPrinter(indent=0)
    printer("Getting device serial")
    with Indent(printer):
        serial = get_connected_device(printer=printer).serial
    print(serial)
Пример #27
0
def get_local_remote_ip(printer=StatusPrinter()):

    printer("Probing Network From Both Sides")

    Address = namedtuple("Address",  "ip_str int")

    def read_ip(msg, ip_str, printer):
        if '127.0.0.1' not in ip_str:
            printer("{:>10}:  {}".format(msg, ip_str))
            return Address(ip_str, int(ipaddress.IPv4Address(ip_str)))
        else:
            return None

    # get all ipv4 addresses among the local network adapters
    printer("Local Addresses:")
    local_addresses = set()
    with Indent(printer):
        adapters = ifaddr.get_adapters()
        for adapter in adapters:
            for ip in adapter.ips:
                ip_str = str(ip.ip)
                if re.match(r'^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$', ip_str):
                    address = read_ip(adapter.nice_name, ip_str, printer)
                    if address is not None:
                        local_addresses.add(address)
        printer('')

    # get all ipv4 addresses among the device's known routes
    printer("Device Address Candidates:")
    device_addresses = set()
    with Indent(printer):
        # keep only things that look like ip addresses
        device_ip_strs = set(re.findall(r'[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+',
            str(
                sed(
                    # TODO: this would be cleaner with 'adb shell netcfg' which I discovered too late

                    # dump the routing table
                    adb(['shell', 'ip', 'route']),

                    # print only lines containing 'src', and only the part after the 'src'
                    ['-n', r's#^.*src\(.*\)$#\1#p']
                    )
                ).strip()))

        for ip_str in device_ip_strs:
            address = read_ip("route entry",  ip_str, printer)
            if address is not None:
                device_addresses.add(address)
        printer('')

    # In an ip address, the more significant bits are subnet bits, less significant ones are network bits
    # XOR will give subnet zeros when two ip addresses are in the same subnet. Therefore, smaller distances
    # returned by this function indicate that the addresses are more likely to be able to talk to each other
    def subnet_distance(ip_a, ip_b):
        return ip_a.int ^ ip_b.int

    # Ping local from remote, and ping remote from local
    # Return true if both succeed
    def can_talk(local, remote, printer):

        printer("Pinging {} -> {}".format(remote, local))
        with Indent(printer):
            printer('''adb shell 'ping -c 4 {} && echo SUCCESS || echo FAIL' '''.format(local))
            with Indent(printer):
                remote2local = str(adb(['shell', 'ping -c 4 {} && echo SUCCESS || echo FAIL'.format(local)]))
                printer(remote2local)

        if 'SUCCESS' in remote2local:
            printer("Pinging {} -> {}".format(local, remote))
            with Indent(printer):
                printer('ping -c 4 {}'.format(local))
                with Indent(printer):
                    try:
                        local2remote = ping(['-c', '4', remote])
                    except sh.ErrorReturnCode as err:
                        local2remote = err
                    printer(local2remote)

            if local2remote.exit_code == 0:
                return True
        return False

    # sort local/remote pairs by distance
    matches = SortedDict()
    for local_ip, remote_ip in cross_product(local_addresses, device_addresses):
        matches[subnet_distance(local_ip, remote_ip)] = (local_ip.ip_str, remote_ip.ip_str)

    # check connectivity (nearest first)
    for local, remote in matches.values():
        if can_talk(local, remote, printer):
            return (local, remote)
Пример #28
0
def print_cpuid():
    printer = StatusPrinter(indent=0)
    printer("Getting device cpuid")
    with Indent(printer):
        cpuid = get_connected_device().cpuid
    print(cpuid)