diff options
-rw-r--r-- | README.md | 100 |
1 files changed, 88 insertions, 12 deletions
@@ -1,13 +1,89 @@ | |||
1 | Ubiquiti Inform Protocol in Golang | 1 | # Ubiquiti Inform Protocol in Golang |
2 | ================================== | 2 | This repo contains a Golang implementation of the Ubiquiti Networks |
3 | This repo contains a Golang implementation of the Ubiquiti Networks Inform | 3 | Inform protocol used by the Unifi access points and the mFi machine |
4 | protocol used by the Unifi access points and the mFi machine networking | 4 | networking components. The primary purpose of this repository is to |
5 | components. The primary focus is an implementation compatible with mFi | 5 | implement the core inform protocol for interoperability with Ubiquiti |
6 | components but the library should also be compatible with Unifi devices. | 6 | products. It is not recommended to use this protocol as the base for |
7 | 7 | any new product development, it's rather Ubiquiti specific and not very | |
8 | This repo is a work in progress and is not yet considered stable. If you find | 8 | secure in the bootstrap phase (uses well-known keys over plaintext |
9 | it useful patches are welcome, just open a pull request. | 9 | channels). |
10 | 10 | ||
11 | There is a feature-complete Python version of this API, a set of tools useful | 11 | This work is largely based on |
12 | for reverse engineering the protocol and an in-progress protocol spec at | ||
13 | [ubntmfi](https://github.com/mcrute/ubntmfi/blob/master/inform_protocol.md) | 12 | [ubntmfi](https://github.com/mcrute/ubntmfi/blob/master/inform_protocol.md) |
13 | |||
14 | ## Status | ||
15 | This repo is a work in progress and semi-maintained, it is not yet | ||
16 | considered stable. If you find it useful patches are welcome, just open | ||
17 | a pull request. | ||
18 | |||
19 | This repository should work well with older mFi components and modern | ||
20 | Unifi components as well. The author has tested with devices as new as | ||
21 | the U6-Mesh devices. | ||
22 | |||
23 | ## Missing Features | ||
24 | If you need these then feel free to implement them. Pull requests are | ||
25 | accepted. | ||
26 | |||
27 | - Support for writing AES GCM packets | ||
28 | - Support for writing zlib compressed packets | ||
29 | - Support for writing snappy compressed packets | ||
30 | |||
31 | ## Protocol | ||
32 | The inform protocol works over HTTP or HTTPS in the case of modern | ||
33 | equipment, older equipment did not support HTTPS. The `mcad` daemon | ||
34 | on the devices is responsible for speaking the inform protocol to the | ||
35 | controller. | ||
36 | |||
37 | A device will `POST` an HTTP request to the controller with a | ||
38 | content-type of `application/x-binary` which contains a payload encoded | ||
39 | in inform format. The server will respond with a payload that is inform | ||
40 | encoded. | ||
41 | |||
42 | ## Packet Format | ||
43 | Packets are binary and transmitted in big-endian format. | ||
44 | |||
45 | | Size | Type | Purpose | Notes | | ||
46 | | -------- | -------- | ------------------------ | ------------------------------------ | | ||
47 | | 4 bytes | `int32` | Protocol Magic Number | Must always be `1414414933` (`UBNT`) | | ||
48 | | 4 bytes | `int32` | Packet Version | Currently this is `0` | | ||
49 | | 6 bytes | `[]byte` | Device MAC Address | Used for crypto-key lookup | | ||
50 | | 2 bytes | `int16` | Flags | See below | | ||
51 | | 16 bytes | `[]byte` | Encryption IV | | | ||
52 | | 4 bytes | `int32` | Data Version | Currently this is `1` | | ||
53 | | 4 bytes | `int32` | Encrypted Payload Length | | | ||
54 | | n bytes | `[]byte` | Encrypted Payload | See below | | ||
55 | |||
56 | ### Flags | ||
57 | | Flag | Name | Purpose | | ||
58 | | ---- | ----------------- | ----------------------------------------------- | | ||
59 | | `1` | Encrypted | Indicates that the payload is encrypted | | ||
60 | | `2` | Zlib Compressed | Indicates that payload is zlib compressed | | ||
61 | | `4` | Snappy Compressed | Indicates that payload is snappy compressed | | ||
62 | | `8` | GCM Encrypted | Indicates that packet is encrypted with AES GCM | | ||
63 | |||
64 | ### Encryption | ||
65 | There are two encryption modes AES 128 CBC and AES 128 GCM. GCM is used | ||
66 | in newer devices and CBC in older devices. The same key is used for | ||
67 | either mode. It's stored as `x_authkey` in the Unifi database and is | ||
68 | encoded as hex. The key must be decoded before decryption. | ||
69 | |||
70 | AES GCM requires authentication data to decrypt the packet. The | ||
71 | authentication data is the following fields encoded in big-endian binary | ||
72 | format. | ||
73 | |||
74 | - Protocol Magic Number | ||
75 | - Packet Version | ||
76 | - Device MAC Address | ||
77 | - Flags | ||
78 | - Encryption IV | ||
79 | - Data Version | ||
80 | - Data Length | ||
81 | |||
82 | In CBC mode the data is padded to fit a full AES block. In GCM mode the | ||
83 | final block appears to be a padding/garbage block. | ||
84 | |||
85 | ### Payload | ||
86 | The payload is a JSON string that is device and application specific. | ||
87 | The payload may also (but is not required to be) be compressed using | ||
88 | either [snappy](https://github.com/golang/snappy) or zlib compression as | ||
89 | indicated by the flags. | ||