Skip to content

Commit c29b850

Browse files
committed
Release 2.0.3
1 parent f8417ee commit c29b850

35 files changed

+1125
-327
lines changed

CHANGELOG.md

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Changelog
2+
3+
## 2.0.3 - 2019-03-14
4+
5+
* sys_linux: Fixed stdout/stderr redirection for logging
6+
* sys_linux: Added detection of implicit no-cups mode by uri files
7+
* net: Fixed authtoken cleanup in http close
8+
* cups: Fixed skipping credentials during rotation
9+
* ral: Changed pipe read strategy in ral_master to allow partial reads
10+
* tc: Fixed last-resort CUPS triggering from TC backoff
11+
* lgwsim: Changed socket read strategy in lgwsim
12+
* examples: Added CUPS example
13+
14+
## 2.0.2 - 2019-01-30
15+
16+
* cups: Fixed CUPS HTTP POST request. Now contains `Hosts` header.
17+
* tc: Changed backoff strategy of LNS connection.
18+
* ral: Fixed FSK parameters for TX
19+
* ral: Added starvation prevention measure in lgw1 rxpolling loop.
20+
* net: Fixed large file delivery in httpd/web.
21+
* net: Fixed gzip detection heuristic in httpd/web
22+
23+
## 2.0.1 - 2019-01-07
24+
25+
* Initial public release.

README.md

+14-11
Original file line numberDiff line numberDiff line change
@@ -43,13 +43,13 @@ The following is a three-step quick start guide on how to build and run Station.
4343
#### Step 1: Cloning the Station Repository
4444

4545
``` sourceCode
46-
git clone https://github.com/lorabasics/station.git $STATION_REPO
46+
git clone https://github.com/lorabasics/basicstation.git
4747
```
4848

4949
#### Step 2: Compiling the Station Binary
5050

5151
``` sourceCode
52-
cd $STATION_REPO
52+
cd basicstation
5353
make platform=rpi variant=std
5454
```
5555

@@ -62,7 +62,7 @@ The build process consists of the following steps:
6262
#### Step 3: Running the Example Configuration on a Raspberry Pi
6363

6464
``` sourceCode
65-
cd $STATION_REPO/examples/live-s2.sm.tc
65+
cd examples/live-s2.sm.tc
6666
RADIODEV=/dev/spidev0.0 ../../build-rpi-std/bin/station
6767
```
6868

@@ -76,12 +76,14 @@ Next,
7676

7777
* consult the help menu of Station via `station --help`,
7878
* inspect the `station.conf` and `cups-boot.*` [example configuration files](/examples/live-s2.sm.tc),
79-
* tune your local [configuration](https://doc.sm.tc/station/conf.html).
79+
* tune your local [configuration](https://doc.sm.tc/station/conf.html),
80+
* learn how to [compile Station](https://doc.sm.tc/station/compile.html) for your target platform.
8081

8182
Check out the other examples:
8283

83-
* [Simulation Example](/examples/simulation)
84-
* [Station to Pkfwd Protocol Bridge Example](/examples/station2pkfwd)
84+
* [Simulation Example](/examples/simulation) - An introduction to the simulation environment.
85+
* [CUPS Example](/examples/cups) - Demonstration of the CUPS protocol within the simulation environment.
86+
* [Station to Pkfwd Protocol Bridge Example](/examples/station2pkfwd) - Connect Basic Station to LNS supporting the legacy protocol.
8587

8688
## Usage
8789

@@ -113,16 +115,17 @@ Usage: station [OPTION...]
113115
then keep only FILE. If ROT is 1 then keep one
114116
more old log file around. Overrides environment
115117
STATION_LOGFILE.
116-
-N, --no-tc Do not connect to a LNS. Only run CUPS functionality.
118+
-N, --no-tc Do not connect to a LNS. Only run CUPS
119+
functionality.
117120
-p, --params Print current parameter settings.
118121
-t, --temp=DIR Temp directory for frequently written files.
119122
Default is /tmp. Overrides environment
120123
STATION_TEMPDIR.
121124
-x, --eui-prefix=id6 Turn MAC address into EUI by adding this prefix.
122-
If the argument has value ff:fe00:0 then the EUI is
123-
formed by inserting FFFE in the middle. If absent
124-
use MAC or routerid as is. Overrides environment
125-
STATION_EUIPREFIX.
125+
If the argument has value ff:fe00:0 then the EUI
126+
is formed by inserting FFFE in the middle. If
127+
absent use MAC or routerid as is. Overrides
128+
environment STATION_EUIPREFIX.
126129
-?, --help Give this help list
127130
--usage Give a short usage message
128131
-v, --version Print station version.

VERSION.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.0.2
1+
2.0.3

examples/cups/README.md

+268
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,268 @@
1+
# CUPS Protocol Example
2+
3+
Station implements a gateway management protocol for managing credentials and firmware updates. Read more about it [here](https://doc.sm.tc/station/cupsproto.html).
4+
5+
This example demonstrates the common scenario of credentials bootstrapping: In the factory, a set of gateways are personalized with initial credentials to a central CUPS server instance (say `cups-0`). Their final destination is not yet known at the time of manufacturing. After one of these gateways is deployed and powered-on the first time, it has to be pointed to and provided credentials for its final LNS (say `tc-0`) in a secure way. Since `cups-0` is operated by an independent third party, it does not have access to the credentials needed to connect to `tc-0`. Therefore, the gateway is first redirected to the CUPS server (`cups-1`) which is operated by the owner of `tc-0` and can therefore provide the final credentials and potentially the latest firmware update.
6+
7+
Using the Station simulation environment, this example implements the two CUPS servers `cups-0` and `cups-1`, as well as the LNS server `tc-0` and configures them to perform the credentials bootstrapping procedure described above. For the purpose of this example, the identities of the three entities are rooted each in a different CA. Client and server credentials are signed by the same CA.
8+
9+
```
10+
CUPS "A" CA
11+
+- cups-0.{crt,key} server auth
12+
+- cups-router-1.{crt,key} client auth
13+
CUPS "B" CA
14+
+- cups-1.{crt,key} server auth
15+
+- cups-router-1.{crt,key} client auth
16+
TC CA
17+
+- muxs-0.{crt,key} server auth
18+
+- infos-0.{crt,key} server auth
19+
+- tc-router-1.{crt,key} client auth
20+
```
21+
22+
**Disclaimer:** The focus of this example is to demonstrate the capabilities of the CUPS protocol based on a common usage scenario for gateway management. For this purpose and the sake of simplicity, the PKI employed in this example is setup in very simple way and does not resemble a production grade PKI.
23+
24+
## Relevant Files
25+
26+
* `sim.py`: Mockup server-side implementations of the CUPS and LNS Station protocols.
27+
* `prep.sh`: Setup script for generating keys, certificates and configuration files for the credentials bootstrapping scenario.
28+
* `emulate.sh`: A script containing a sequence of cURL requests to CUPS, emulating the behavior of Station under this scenario. This can be used to investigate the exact payloads exchanged during the call sequence.
29+
* `makefile`: Top level makefile which can be used to setup and run the simulation.
30+
31+
## Prerequisites
32+
33+
The simulation example requires
34+
35+
* Python 3.5+
36+
* Python packages according to `requirements.txt`
37+
* make, bash, curl, openssl, gzip, xxd
38+
* Optional: tmux
39+
40+
A possible way to setup a compatible python environment is using `virtualenv` and `pip`:
41+
42+
```
43+
virtualenv -p python3.6 pyenv
44+
. pyenv/bin/activate
45+
pip install -r requirements.txt
46+
```
47+
48+
## Usage
49+
50+
The CUPS example is controlled via a makefile with multiple targets:
51+
52+
* `make station`: Build the `testsim` station variant.
53+
* `make prep`: Setup the expected directory structure (keys, certificates, config) without executing the simulation.
54+
* `make sim`: Run the simulation in a single process. Log output of all components is interleaved in one terminal
55+
* `make tmux`: Run the simulation in multiple processes inside different panes of a tmux split window.
56+
* `make emulate`: Execute the call sequence via a set of cURL commands, emulating the behavior of Station in this scenario.
57+
* `make clean`: Bring local directory into initial state.
58+
59+
## Explanation
60+
61+
In order to understand what is going on, let's dissect the log output produced by the `emulate` target. For the sake of clarity the log output shown here has slightly reduced verbosity.
62+
63+
### Startup
64+
```
65+
# make emulate
66+
67+
./prep.sh
68+
== Build PKI ==
69+
cups-0/cups-0.crt: OK
70+
cups-0/cups-router-1.crt: OK
71+
cups-1/cups-1.crt: OK
72+
cups-1/cups-router-1.crt: OK
73+
tc-0/muxs-0.crt: OK
74+
tc-0/infos-0.crt: OK
75+
tc-0/tc-router-1.crt: OK
76+
== Prepare FW Update 1.0.0 -> 2.0.0 ==
77+
```
78+
79+
The `emulate` target first executes the `prep.sh` script which sets up the folder structure as expected by the simulation. First, the three self-signed CA certificates are generated and used to sign the certificates of all our server entities `cups-0`, `cups-1`, `tc-0`, as well as the client certificates for `router-1` expected by each of them. A signing key pair is generated and a signed updated is placed in `cups-1`. The public part of the signing key is copied to the Station home directory `./shome`. The final directory structure will look like this:
80+
81+
```
82+
.
83+
├── cups-0
84+
│ ├── cups-0.crt
85+
│ ├── cups-0.key
86+
│ ├── cups-0.trust
87+
│ ├── cups.ca
88+
│ ├── cups-router-1.cfg
89+
│ ├── cups-router-1.crt
90+
│ ├── cups-router-1.key
91+
│ └── cups-router-1.trust
92+
├── cups-1
93+
│ ├── 2.0.0.bin
94+
│ ├── 2.0.0.bin.sig-0
95+
│ ├── cups-1.crt
96+
│ ├── cups-1.key
97+
│ ├── cups-1.trust
98+
│ ├── cups.ca
99+
│ ├── cups-router-1.cfg
100+
│ ├── cups-router-1.crt
101+
│ ├── cups-router-1.key
102+
│ ├── cups-router-1.trust
103+
│ └── sig-0.key
104+
├── shome
105+
│ ├── cups.crt
106+
│ ├── cups.key
107+
│ ├── cups.trust
108+
│ ├── cups.uri
109+
│ ├── sig-0.key
110+
│ ├── station.conf
111+
│ └── version.txt
112+
├── tc-0
113+
│ ├── infos-0.crt
114+
│ ├── infos-0.key
115+
│ ├── infos-0.trust
116+
│ ├── muxs-0.crt
117+
│ ├── muxs-0.key
118+
│ ├── muxs-0.trust
119+
│ ├── tc.ca
120+
│ ├── tc-router-1.crt
121+
│ ├── tc-router-1.key
122+
│ └── tc-router-1.trust
123+
└── upd-sig
124+
├── sig-0.prime256v1.pem
125+
└── sig-0.prime256v1.pub
126+
```
127+
128+
Once the `prep.sh` script completed, the `emulate.sh` script will start the server simulation if no running CUPS services were detected on localhost.
129+
130+
```
131+
./emulate.sh
132+
Starting CUPS.
133+
LgwSimServer starting...
134+
Starting INFOS (tc-0/infos-0) on Port 6038 (muxsuri=wss://localhost:6039/router)
135+
Starting MUXS (tc-0/muxs-0) on Port 6039
136+
Starting CUPS (cups-0/cups-0) on Port 6040
137+
Starting CUPS (cups-1/cups-1) on Port 6041
138+
```
139+
140+
Before the initial request, a list of client credentials and their CRC32 hashes is shown. These CRC32 hashes serve as identifiers for the credentials sets in the CUPS protocol. Since all keys are generated by `prep.sh`, these hashes will differ in your case:
141+
142+
```
143+
CRC32 0xF13E8FC2 (4047409090) shome/sig-0.key
144+
CRC32 0xAFC40ED3 (2948861651) cups-0/cups-router-1.{trust,crt,key}
145+
CRC32 0x22220992 (572656018) cups-1/cups-router-1.{trust,crt,key}
146+
CRC32 0xE0F91F83 (3774422915) tc-0/tc-router-1.{trust,crt,key}
147+
```
148+
149+
An empty credentials set corresponds to a zero-byte sequence of length 12, which yields a non-zero CRC32.
150+
151+
```
152+
CRC32 0x7BD5C66F (2077607535) _empty_set_
153+
```
154+
155+
### Request 1: CUPS Redirection
156+
157+
```
158+
==== #1 [CUPS-0] REQUEST ===================
159+
{
160+
"router": "::1",
161+
"model": "linux",
162+
"package": "1.0.0",
163+
"station": "Emulated Station",
164+
"cupsUri": "https://localhost:6040",
165+
"tcUri": "",
166+
"cupsCredCrc": 2948861651,
167+
"tcCredCrc": 2077607535,
168+
"keys": [ 4047409090 ]
169+
}
170+
==== #1 [CUPS-0] RESPONSE ===================
171+
CUPS: No target version configured for this router. No update.
172+
CUPS: No fw update required
173+
< CUPS Response:
174+
cupsUri : b'https://localhost:6041' <- [https://localhost:6040]
175+
tcUri : b'' -- []
176+
cupsCred: 911 bytes -- [22220992] <- [AFC40ED3]
177+
tcCred : 0 bytes -- [7BD5C66F]
178+
sigCrc : 00000000
179+
sig : 0 bytes
180+
fw : 0 bytes -- [1.0.0]
181+
182+
HTTP/1.1 200 OK
183+
Content-Length: 947
184+
Content-Type: application/octet-stream
185+
Server: Python/3.6 aiohttp/2.3.9
186+
187+
[ Binary dump of response body ]
188+
```
189+
190+
In the first request to `cups-0`, Station receives a new CUPS URI and new CUPS credentials for connecting to `cups-1`.
191+
192+
### Request 2: LNS Credentials and Firmware Update
193+
194+
```
195+
==== #2 [CUPS-1] REQUEST ===================
196+
{
197+
"router": "::1",
198+
"model": "linux",
199+
"package": "1.0.0",
200+
"station": "Emulated Station",
201+
"cupsUri": "https://localhost:6041",
202+
"tcUri": "",
203+
"cupsCredCrc": 572656018,
204+
"tcCredCrc": 2077607535,
205+
"keys": [ 4047409090 ]
206+
}
207+
==== #2 [CUPS-1] RESPONSE ===================
208+
CUPS: Target version: 2.0.0 (cups-1/2.0.0.bin)
209+
CUPS: Found signing key cups-1/sig-0.key -> CRC F13E8FC2
210+
CUPS: Found signature cups-1/2.0.0.bin.sig-0
211+
CUPS: Found matching signing key with CRC F13E8FC2
212+
< CUPS Response:
213+
cupsUri : b'' -- [https://localhost:6041]
214+
tcUri : b'wss://localhost:6038' <- []
215+
cupsCred: 0 bytes -- [22220992]
216+
tcCred : 900 bytes -- [E0F91F83] <- [7BD5C66F]
217+
sigCrc : F13E8FC2
218+
sig : 74 bytes
219+
fw : 83 bytes -- [2.0.0] <- [1.0.0]
220+
221+
HTTP/1.1 200 OK
222+
Content-Length: 1091
223+
Content-Type: application/octet-stream
224+
Server: Python/3.6 aiohttp/2.3.9
225+
226+
[ Binary dump of response body ]
227+
```
228+
229+
The second request is directed to `cups-1`. The response contains a firmware update (in this case a bash script) together with a signature. The signature originates from the private key which corresponds to the one of the public keys identified by the key CRCs in the `keys` list of the request. This mechanism allows the server to choose out of multiple signatures the one which can be verified by the gateway. The response also contains the URI and credentials of the LNS endpoint (`tcUri` and `tcCred`).
230+
231+
### Request 3: Steady State
232+
233+
```
234+
==== #3 [CUPS-1] REQUEST ===================
235+
{
236+
"router": "::1",
237+
"model": "linux",
238+
"package": "2.0.0",
239+
"station": "Emulated Station",
240+
"cupsUri": "https://localhost:6041",
241+
"tcUri": "wss://localhost:6038",
242+
"cupsCredCrc": 572656018,
243+
"tcCredCrc": 3774422915,
244+
"keys": [ 4047409090 ]
245+
}
246+
==== #3 [CUPS-1] RESPONSE ===================
247+
CUPS: Target version: 2.0.0 (cups-1/2.0.0.bin)
248+
CUPS: Found signing key cups-1/sig-0.key -> CRC F13E8FC2
249+
CUPS: Found signature cups-1/2.0.0.bin.sig-0
250+
CUPS: No fw update required
251+
< CUPS Response:
252+
cupsUri : b'' -- [https://localhost:6041]
253+
tcUri : b'' -- [wss://localhost:6038]
254+
cupsCred: 0 bytes -- [22220992]
255+
tcCred : 0 bytes -- [E0F91F83]
256+
sigCrc : 00000000
257+
sig : 0 bytes
258+
fw : 0 bytes -- [2.0.0]
259+
260+
HTTP/1.1 200 OK
261+
Content-Length: 14
262+
Content-Type: application/octet-stream
263+
Server: Python/3.6 aiohttp/2.3.9
264+
265+
00000000: 0000 0000 0000 0000 0000 0000 0000 ..............
266+
```
267+
268+
The third request is answered with an all-zero response, meaning that the condition of the gateway corresponds to the target state expected by the CUPS server. The all-zero response puts Station into a low-dutycycle re-sync mode.

0 commit comments

Comments
 (0)