Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 110 lines (88 sloc) 3.51 KB
#!/usr/bin/env python
# coding: utf-8
#
# (c)2017 n0rc
import argparse
import requests
import hashlib
import json
import os
import sys
from lxml import etree
from requests.exceptions import SSLError
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
SID_NOAUTH = '0000000000000000'
def error_exit(msg):
print("[error] {}".format(msg))
sys.exit(1)
def ssl_error_exit():
error_exit("ssl certificate verification failed")
def get_config(config_file):
if os.path.isfile(config_file):
with open(config_file, 'r') as jf:
config = json.load(jf)
config['url_login'] = 'https://{}:{}/login_sid.lua'.format(config['host'], config['port'])
config['url_data'] = 'https://{}:{}/data.lua'.format(config['host'], config['port'])
return config
else:
error_exit("config file not found")
def get_sid(config):
try:
r = requests.get(config['url_login'], verify=config['verify_ssl'])
t = etree.XML(r.content)
challenge = t.xpath('//Challenge/text()')[0]
response = '{}-{}'.format(challenge, hashlib.md5('{}-{}'.format(challenge, config['password']).encode('utf-16-le')).hexdigest())
r = requests.get('{}?username={}&response={}'.format(config['url_login'], config['username'], response), verify=config['verify_ssl'])
t = etree.XML(r.content)
return t.xpath('//SID/text()')[0]
except SSLError:
ssl_error_exit()
def get_uid(config, sid, mac):
try:
payload = {'sid': sid, 'page': 'netDev'}
r = requests.post(config['url_data'], data=payload, verify=config['verify_ssl'])
devs = json.loads(r.content)
for dev in devs['data']['passive']:
if dev['mac'] == mac:
return dev['UID']
for dev in devs['data']['active']:
if dev['mac'] == mac:
return dev['UID']
return ''
except SSLError:
ssl_error_exit()
def wake_up(config, sid, uid):
try:
payload = {'sid': sid, 'dev': uid, 'oldpage': 'net/edit_device.lua', 'btn_wake': ''}
r = requests.post(config['url_data'], data=payload, verify=config['verify_ssl'])
if '"pid":"netDev"' in r.text:
return True
else:
return False
except SSLError:
ssl_error_exit()
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('device', help='device name (from config file) to sent wakeup to', default='default', nargs='?')
parser.add_argument('--config', '-c', default='wakeup.json', metavar='wakeup.json', help='use specified config file')
parser.add_argument('--ssl-no-verify', '-k', action='store_true', help='ignore ssl certificate verification')
args, _ = parser.parse_known_args()
config = get_config(args.config)
config['verify_ssl'] = not args.ssl_no_verify
if args.device in config['devices']:
target_mac = config['devices'][args.device]
else:
error_exit("unknown device {}".format(args.device))
sid = get_sid(config)
if sid == SID_NOAUTH:
error_exit("authentication failed")
else:
uid = get_uid(config, sid, target_mac)
if uid:
if wake_up(config, sid, uid):
print("[success] wakeup sent to {}".format(target_mac))
else:
error_exit("something went wrong while sending wakeup to {}".format(target_mac))
else:
error_exit("unknown mac {}".format(target_mac))