-
Notifications
You must be signed in to change notification settings - Fork 13
/
onboard.py
executable file
·68 lines (61 loc) · 2.56 KB
/
onboard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#!/usr/bin/env python3
#
# Author: Tim Serong <[email protected]>
#
# Usage: ./onboard.py <ssid> <password>
#
# This will send an onboarding packet to a virgin LIFX bulb, telling it to
# connect to your local WiFi network using the SSID and password provided
# as command line arguments. There is no error checking, so if it breaks
# you get to keep both pieces.
#
# IMPORTANT NOTES:
# - Only use this if you're connected to a virgin LIFX bulb's AP.
# - If your wireless network is using security other than WPA2 AES PSK, change
# the final value appended to onboard_packet appropriately.
# - This script has been tested three or four times on one LIFX Original
# and one LIFX Color 1000 bulb. It worked fine for me, but use at own risk.
# - If you get an SSL error, try temporarily setting MinProtocol = TLSv1.0
# in /etc/ssl/openssl.cnf (https://github.com/tserong/lifx-hacks/issues/2)
#
# Interesting commentary:
# - Both LIFX original and LIFX Color 1000 bulbs seem happy to take the
# onboarding packet ("SetAccessPoint") via an SSL connection to TCP port
# 56700.
# - The LIFX original bulbs can also be onboarded by sending the same packet
# via UDP broadcast on port 56700. This is presumably wildly insecure,
# what with not being encrypted and all. The LIFX Color 1000 bulbs seem to
# ignore SetAccessPoint packets sent via this means.
# - Once onboarded, the bulbs don't seem to accept TCP connections to port
# 56700 anymore.
#
import sys, socket, ssl
if len(sys.argv) != 3:
print("Usage: {0} <ssid> <password>".format(sys.argv[0]))
exit(1)
ssid = sys.argv[1][0:32]
passwd = sys.argv[2][0:64]
print("Will attempt to onboard using\n"
" ssid: {0}\n"
" password: {1}".format(ssid, passwd))
response = input("Continue? [y/N] ")
if not response or response[0] not in ['Y', 'y']:
exit(1)
onboard_packet = b'\x86\x00\x00\x34\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x31\x01\x00\x00\x02'
onboard_packet += ssid.ljust(32, '\x00').encode('utf-8')
onboard_packet += passwd.ljust(64, '\x00').encode('utf-8')
# 0x01 == OPEN
# 0x02 == WEP_PSK (allegedly not supported)
# 0x03 == WPA_TKIP_PSK
# 0x04 == WPA_AES_PSK
# 0x05 == WPA2_AES_PSK
# 0x06 == WPA2_TKIP_PSK
# 0x07 == WPA2_MIXED_PSK
onboard_packet += b'\x05'
ctx = ssl.create_default_context()
ctx.check_hostname = False
ctx.verify_mode = ssl.CERT_NONE
sock = ctx.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sock.connect(('172.16.0.1', 56700))
sock.write(onboard_packet)
print("LIFX bulb probably onboarded. Best of luck ;-)")