Skip to content

Add miio-extract-tokens tool for extracting tokens from sqlite databases#77

Merged
rytilahti merged 3 commits intomasterfrom
token_extractor
Sep 14, 2017
Merged

Add miio-extract-tokens tool for extracting tokens from sqlite databases#77
rytilahti merged 3 commits intomasterfrom
token_extractor

Conversation

@rytilahti
Copy link
Copy Markdown
Owner

@rytilahti rytilahti commented Sep 14, 2017

This is to simplify the process for token and device type extraction,
and will probably later merged to the CLI tool to generate config files
based on known devices.

Tested to work fine on .tar files extracted from Android backups
as well as sqlite DBs from both Android and Apple. Related to #75.

Example output:

± miio-extract-tokens backup/backup.tar
Opened backup/backup.tar
Extracting to /tmp/tmpqvfj2l1x
Reading tokens from Android DB
Gateway (lumi.gateway.v3) at 192.168.XXX. token: 91c52a27eff00b95XX (mac: 28:6C:07:XX, ssid: XXX)
room1 (yeelink.light.color1) at 192.168.XXX. token: a37905aa9a587faXX (mac: F0:B4:29:XX, ssid: XXX)
room2 (yeelink.light.color1) at 192.168.XXX. token: 86b130eac015b2bd2dXX (mac: 28:6C:07:XX, ssid: XXX)
Flower Care (hhcc.plantmonitor.v1) at 134.XXX.XXX. token: 124f90d87b4b9XX (mac: C4:7C:8D:XX, ssid: )
Mi Robot Vacuum (rockrobo.vacuum.v1) at 192.168.XXX. token: 476e6b70343055XXX (mac: 28:6C:07:XX, ssid: XXX)

…ses.

This is to simplify the process for token and device type extraction,
and will probably later merged to the CLI tool to generate config files
based on known devices.

Tested to work fine on .tar files extracted from Android backups,
support for Apple databases is incomplete. Related to #75.


if __name__ == "__main__":
main() No newline at end of file
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no newline at end of file


@click.command()
@click.argument('backup')
@click.option('--write-to-disk', type=click.File('wb'), help='writes sqlite3 db to a file for debugging')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (105 > 79 characters)

is_android = conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='devicerecord';").fetchone() is not None
is_apple = conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='ZDEVICE'").fetchone() is not None
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (106 > 79 characters)

conn.row_factory = sqlite3.Row
with conn:
is_android = conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='devicerecord';").fetchone() is not None
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (112 > 79 characters)

click.echo("Saving db to %s" % fp)
fp.write(db.read())

def read_tokens(db):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1

name = dev['name']
ssid = dev['ssid']
token = dev['token']
click.echo("%s (%s) at %s. token: %s (mac: %s, ssid: %s)" % (name, model, ip, token, mac, ssid))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (104 > 79 characters)

ip = dev['ZLOCALIP']
click.echo("device at %s. token: %s" % (ip, token))
dump_raw(dev)
raise NotImplementedError("Please report the previous output to developers")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (80 > 79 characters)

raw = {k: dev[k] for k in dev.keys()}
click.echo(pf(raw))

def decrypt_ztoken(ztoken):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1

from Crypto.Cipher import AES
from pprint import pformat as pf

def dump_raw(dev):
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

expected 2 blank lines, found 1

import tarfile
import tempfile
import sqlite3
import binascii
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'binascii' imported but unused

@coveralls
Copy link
Copy Markdown

coveralls commented Sep 14, 2017

Coverage Status

Coverage decreased (-1.3%) to 33.316% when pulling 3be9f4c on token_extractor into 688add1 on master.

@coveralls
Copy link
Copy Markdown

coveralls commented Sep 14, 2017

Coverage Status

Coverage decreased (-1.3%) to 33.333% when pulling 2000fab on token_extractor into 688add1 on master.

* Refactor the code into a class for further use
* add --dump-raw and --dump-all (prints devs without IP addrs, such as linked BT devices)
@click.command()
@click.argument('backup')
@click.option('--write-to-disk', type=click.File('wb'), help='writes sqlite3 db to a file for debugging')
@click.option('--dump-all', is_flag=True, default=False, help='dump devices without ip addresses')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (98 > 79 characters)

is_android = self.conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='devicerecord';").fetchone() is not None
is_apple = self.conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='ZDEVICE'").fetchone() is not None
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (110 > 79 characters)

self.conn.row_factory = sqlite3.Row
with self.conn:
is_android = self.conn.execute(
"SELECT name FROM sqlite_master WHERE type='table' AND name='devicerecord';").fetchone() is not None
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (116 > 79 characters)

name = dev['name']
token = dev['token']
if ip or self.dump_all:
click.echo("%s\n\tModel: %s\n\tIP address: %s\n\tToken: %s\n\tMAC: %s" % (name, model, ip, token, mac))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (119 > 79 characters)


def read_android(self):
click.echo("Reading tokens from Android DB")
c = self.conn.execute("SELECT * FROM devicerecord WHERE token IS NOT '';")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (82 > 79 characters)

name = dev['ZNAME']
token = BackupDatabaseReader.decrypt_ztoken(dev['ZTOKEN'])
if ip or self.dump_all:
click.echo("%s\n\tModel: %s\n\tIP address: %s\n\tToken: %s\n\tMAC: %s" % (name, model, ip, token, mac))
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

line too long (119 > 79 characters)

@coveralls
Copy link
Copy Markdown

coveralls commented Sep 14, 2017

Coverage Status

Coverage decreased (-1.5%) to 33.088% when pulling fdfb5de on token_extractor into 688add1 on master.

Copy link
Copy Markdown
Collaborator

@syssi syssi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@rytilahti rytilahti merged commit 69ae780 into master Sep 14, 2017
@rytilahti rytilahti deleted the token_extractor branch September 14, 2017 19:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants