-
-
Notifications
You must be signed in to change notification settings - Fork 563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add miio-extract-tokens tool for extracting tokens from sqlite databases #77
Conversation
…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.
mirobo/extract_tokens.py
Outdated
|
||
|
||
if __name__ == "__main__": | ||
main() |
There was a problem hiding this comment.
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') |
There was a problem hiding this comment.
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)
mirobo/extract_tokens.py
Outdated
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 |
There was a problem hiding this comment.
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)
mirobo/extract_tokens.py
Outdated
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 |
There was a problem hiding this comment.
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)
mirobo/extract_tokens.py
Outdated
click.echo("Saving db to %s" % fp) | ||
fp.write(db.read()) | ||
|
||
def read_tokens(db): |
There was a problem hiding this comment.
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
mirobo/extract_tokens.py
Outdated
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)) |
There was a problem hiding this comment.
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)
mirobo/extract_tokens.py
Outdated
ip = dev['ZLOCALIP'] | ||
click.echo("device at %s. token: %s" % (ip, token)) | ||
dump_raw(dev) | ||
raise NotImplementedError("Please report the previous output to developers") |
There was a problem hiding this comment.
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)
mirobo/extract_tokens.py
Outdated
raw = {k: dev[k] for k in dev.keys()} | ||
click.echo(pf(raw)) | ||
|
||
def decrypt_ztoken(ztoken): |
There was a problem hiding this comment.
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
mirobo/extract_tokens.py
Outdated
from Crypto.Cipher import AES | ||
from pprint import pformat as pf | ||
|
||
def dump_raw(dev): |
There was a problem hiding this comment.
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
mirobo/extract_tokens.py
Outdated
import tarfile | ||
import tempfile | ||
import sqlite3 | ||
import binascii |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'binascii' imported but unused
* 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') |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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 '';") |
There was a problem hiding this comment.
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)) |
There was a problem hiding this comment.
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)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
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: