Compare commits

...

289 Commits

Author SHA1 Message Date
TIP Automation User
70299b0238 Chg: update image tag in helm values to v2.8.0 2023-01-03 21:56:50 +00:00
TIP Automation User
3101cb1205 Chg: update image tag in helm values to v2.8.0-RC3 2022-12-20 20:40:47 +00:00
Stephane Bourque
cb5613ce7f Merge pull request #308 from Telecominfraproject/master
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-20 11:07:59 -08:00
Stephane Bourque
45b25c4e75 Merge pull request #307 from Telecominfraproject/WIFI-11956
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-20 10:07:01 -08:00
stephb9959
ea311f70a0 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-20 09:03:59 -08:00
stephb9959
e3265c86a5 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-20 08:46:44 -08:00
stephb9959
e537259208 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-20 08:46:34 -08:00
stephb9959
b9c7990344 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-20 00:02:11 -08:00
stephb9959
d5c1cfe2f1 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-20 00:00:18 -08:00
stephb9959
1a4f27cbbf https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 23:44:44 -08:00
stephb9959
11ad381534 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 23:35:26 -08:00
stephb9959
0b548a40f3 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 23:16:08 -08:00
stephb9959
28e5463196 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 23:13:03 -08:00
stephb9959
37ea632ac7 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 22:52:08 -08:00
stephb9959
2f641077e6 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 22:49:47 -08:00
stephb9959
78318f47c6 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 22:38:21 -08:00
stephb9959
c83c73a3ae https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 22:31:47 -08:00
stephb9959
6305be8c55 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 22:20:45 -08:00
stephb9959
4b325ef22c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 22:09:01 -08:00
stephb9959
a422dff7ae https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 21:57:06 -08:00
stephb9959
271ff4f6c4 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 21:45:17 -08:00
stephb9959
4cdd275d0b https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 21:18:41 -08:00
stephb9959
9a36e86949 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 18:16:35 -08:00
stephb9959
fa806ed16c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 17:43:34 -08:00
stephb9959
57c270973e https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 17:43:10 -08:00
stephb9959
17ebfb24f2 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 14:41:29 -08:00
stephb9959
26072691ab https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 14:30:36 -08:00
stephb9959
e8b3ea56e0 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 14:17:50 -08:00
stephb9959
2b1a72b838 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 14:10:19 -08:00
stephb9959
352afc487a https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 13:57:37 -08:00
stephb9959
6fae29981a https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 13:46:05 -08:00
stephb9959
9569de1b21 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 12:05:56 -08:00
stephb9959
1a952946b2 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-19 11:36:14 -08:00
stephb9959
3b52cf6111 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 23:43:00 -08:00
stephb9959
74197e2aee https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 22:15:17 -08:00
stephb9959
7152067b09 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 21:56:26 -08:00
stephb9959
ac3d061eee https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 21:47:45 -08:00
stephb9959
8ee67713bf https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 21:36:54 -08:00
stephb9959
e57cd4fea2 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 21:30:30 -08:00
stephb9959
5e3a71a6e7 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 20:23:00 -08:00
stephb9959
a602b8f844 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 20:15:01 -08:00
stephb9959
89da7d187a https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 20:10:16 -08:00
stephb9959
6c5533aa8b https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 20:05:59 -08:00
stephb9959
66249b258c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 20:00:36 -08:00
stephb9959
e03512ebf3 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:50:37 -08:00
stephb9959
b152c8477a https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:40:52 -08:00
stephb9959
a298c4254b https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:33:11 -08:00
stephb9959
b8f04c6d4a https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:28:10 -08:00
stephb9959
753dc5c068 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:23:26 -08:00
stephb9959
bf70d6b512 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:17:55 -08:00
stephb9959
760f11ca70 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:08:52 -08:00
stephb9959
2bcd0ccbcb https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:05:37 -08:00
stephb9959
0aee258af4 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 19:02:13 -08:00
stephb9959
9e879f306c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 18:58:41 -08:00
stephb9959
fb4a4d935a https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 18:55:40 -08:00
stephb9959
282552cdfa https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 17:55:05 -08:00
stephb9959
1d316ff28a https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 17:50:15 -08:00
stephb9959
1da866a7da https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 17:44:45 -08:00
stephb9959
1c628c28fa https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 16:17:07 -08:00
stephb9959
a350b30a9c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 16:10:48 -08:00
stephb9959
cf6c3f9337 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-18 15:56:40 -08:00
stephb9959
2388eac41d https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 08:33:34 -08:00
stephb9959
f0e0f2ba5b https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 08:28:53 -08:00
stephb9959
0c8b9caaf3 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 08:11:33 -08:00
stephb9959
c0edeb8b23 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 08:02:00 -08:00
stephb9959
fdcf74788d https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 07:59:20 -08:00
stephb9959
df9c82a4ae https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 07:37:37 -08:00
stephb9959
2963cec1fb https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 07:32:37 -08:00
stephb9959
8053e32c9c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 07:24:13 -08:00
stephb9959
1750ac5fb5 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 07:12:18 -08:00
stephb9959
b4d775db0c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 07:03:09 -08:00
stephb9959
3031483209 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 06:55:52 -08:00
stephb9959
97b990581d https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-17 06:47:52 -08:00
stephb9959
98fa4799cc https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 23:32:34 -08:00
stephb9959
95a853fc0e https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 22:58:49 -08:00
stephb9959
7a14cadbf5 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 22:56:45 -08:00
stephb9959
ab5efcc8c1 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 22:52:05 -08:00
stephb9959
bb71ff2bad https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 22:34:27 -08:00
stephb9959
c1a2efd32c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 22:11:10 -08:00
stephb9959
ca4d92fd66 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 16:21:32 -08:00
stephb9959
efb354031a https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 16:18:32 -08:00
stephb9959
180d01c89d https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 15:37:22 -08:00
stephb9959
f6c1a5e97f https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 15:29:58 -08:00
stephb9959
54e7caafc1 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 15:20:24 -08:00
stephb9959
e76c97540c https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 15:09:09 -08:00
stephb9959
3f01ef6d5e https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 14:57:12 -08:00
stephb9959
8e118c7f7b https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 14:55:29 -08:00
stephb9959
6dc5622bf2 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 14:50:49 -08:00
stephb9959
27a9ef01b6 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 14:38:38 -08:00
stephb9959
9390b9a646 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 14:25:20 -08:00
stephb9959
871f3c3436 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 14:16:19 -08:00
stephb9959
a41095a797 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 14:13:24 -08:00
stephb9959
bb94c9a813 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 14:02:13 -08:00
stephb9959
fcd991b8d6 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 13:56:05 -08:00
stephb9959
2df43cfd62 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 13:48:15 -08:00
stephb9959
014aafbd3d https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 13:42:49 -08:00
stephb9959
d1d058a848 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 12:34:21 -08:00
stephb9959
d492396182 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 12:30:55 -08:00
stephb9959
2c710412a1 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 12:16:27 -08:00
stephb9959
7dcade3d79 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 12:08:33 -08:00
stephb9959
dc73a2d54b https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 11:57:31 -08:00
Stephane Bourque
6c2bb5b395 Merge pull request #306 from Telecominfraproject/WIFI-11956
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-16 11:39:49 -08:00
stephb9959
fccf99cca5 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 11:39:19 -08:00
Stephane Bourque
0d91dd9a6e Merge pull request #305 from Telecominfraproject/WIFI-11956
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-16 11:14:13 -08:00
stephb9959
d84af0f18e https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 11:13:38 -08:00
Stephane Bourque
6b6c9ce0ae Merge pull request #304 from Telecominfraproject/WIFI-11956
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-16 10:11:31 -08:00
stephb9959
5a31d6427f https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 10:10:36 -08:00
Stephane Bourque
8b3ff4a560 Merge pull request #303 from Telecominfraproject/WIFI-11956
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-16 09:34:19 -08:00
stephb9959
53c81d2c76 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 09:33:25 -08:00
Stephane Bourque
518bfc0b2c Merge pull request #302 from Telecominfraproject/WIFI-11956
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-16 08:57:49 -08:00
stephb9959
c6851819d4 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 08:56:37 -08:00
Stephane Bourque
d5851753c2 Merge pull request #301 from Telecominfraproject/WIFI-11956
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-16 08:04:23 -08:00
stephb9959
379b1446f6 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-16 08:03:27 -08:00
TIP Automation User
86a254e1b3 Chg: update image tag in helm values to v2.8.0-RC2 2022-12-16 14:51:51 +00:00
Stephane Bourque
de260ecddc Merge pull request #300 from Telecominfraproject/master
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-15 11:40:55 -08:00
Stephane Bourque
6d50ef72b7 Merge pull request #299 from Telecominfraproject/WIFI-11956
https://telecominfraproject.atlassian.net/browse/WIFI-11956
2022-12-15 11:39:58 -08:00
stephb9959
f0954081c1 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 09:57:38 -08:00
stephb9959
9653d0affb https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 09:51:03 -08:00
stephb9959
dd626461e8 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 09:39:32 -08:00
stephb9959
048b33e134 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 09:36:29 -08:00
stephb9959
eff7a70f6b https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 09:08:05 -08:00
stephb9959
5f73966010 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 08:52:35 -08:00
stephb9959
911c9ac210 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 08:30:07 -08:00
stephb9959
f59c369b61 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 08:26:13 -08:00
stephb9959
526d239fe9 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 08:20:11 -08:00
stephb9959
939d704460 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 08:08:47 -08:00
stephb9959
b7e8da5e76 https://telecominfraproject.atlassian.net/browse/WIFI-11956
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-15 08:07:44 -08:00
Stephane Bourque
ad20736a14 Merge pull request #298 from Telecominfraproject/master
https://telecominfraproject.atlassian.net/browse/WIFI-11974
2022-12-14 20:52:58 -08:00
Stephane Bourque
c5d68e5397 Merge pull request #297 from Telecominfraproject/WIFI-11974
https://telecominfraproject.atlassian.net/browse/WIFI-11974
2022-12-14 11:55:50 -08:00
stephb9959
a2bbe71e53 https://telecominfraproject.atlassian.net/browse/WIFI-11974
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-14 11:55:27 -08:00
Stephane Bourque
1c0cf65145 Merge pull request #296 from Telecominfraproject/WIFI-11388
https://telecominfraproject.atlassian.net/browse/WIFI-11388
2022-12-14 11:40:53 -08:00
stephb9959
60d41e8569 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-14 11:32:43 -08:00
stephb9959
76698476b6 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-14 11:25:54 -08:00
Stephane Bourque
4e4ac89401 Merge pull request #295 from Telecominfraproject/WIFI-11388
https://telecominfraproject.atlassian.net/browse/WIFI-11388
2022-12-13 23:53:56 -08:00
stephb9959
e3e6a27348 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-13 23:29:06 -08:00
stephb9959
b419472fd7 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-13 16:11:42 -08:00
TIP Automation User
8f43f5945d Chg: update image tag in helm values to v2.8.0-RC1 2022-12-13 23:08:38 +00:00
Dmitry Dunaev
bd2af4df1d Merge pull request #292 from Telecominfraproject/feature/wifi-11905--docker-certificates-allowmismatch
[WIFI-11905] Add: docker option to set openwifi.certificates.allowmismatch
2022-12-13 20:09:35 +03:00
Dmitry Dunaev
bbbb4cd4fe [WIFI-11905] Chg: CERTIFICATES_ALLOWMISMATCH to false by def
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-12-13 17:08:24 +01:00
Stephane Bourque
445568152c Merge pull request #294 from Telecominfraproject/WIFI-11388
https://telecominfraproject.atlassian.net/browse/WIFI-11388
2022-12-13 07:03:42 -08:00
stephb9959
ce70ff0f21 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-13 07:03:11 -08:00
Stephane Bourque
6dbf16793e Merge pull request #293 from Telecominfraproject/WIFI-11388
https://telecominfraproject.atlassian.net/browse/WIFI-11388
2022-12-12 13:21:17 -08:00
stephb9959
eba69c8c35 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 12:31:42 -08:00
stephb9959
ae2e6c5ce6 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 12:06:01 -08:00
stephb9959
5a2a0cd074 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 12:04:08 -08:00
stephb9959
9c3a23a8a1 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 12:02:46 -08:00
stephb9959
b6f0f07bec https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 11:44:05 -08:00
stephb9959
e060e11cd2 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 11:40:42 -08:00
stephb9959
883245de68 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 11:36:56 -08:00
stephb9959
9cfc411a51 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 11:32:36 -08:00
stephb9959
fb3a785227 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 11:28:20 -08:00
stephb9959
3fe8958323 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 10:17:42 -08:00
stephb9959
117f0e1637 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 10:15:17 -08:00
stephb9959
b09b1d5690 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 10:10:53 -08:00
stephb9959
e073e2b713 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 10:00:07 -08:00
stephb9959
8343443bd7 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 09:56:15 -08:00
stephb9959
c5ed66c40c https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 09:51:24 -08:00
stephb9959
de65b2396c https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-12 08:56:22 -08:00
Dmitry Dunaev
c85cef57c8 [WIFI-11905] Add: docker option to set openwifi.certificates.allowmismatch
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-12-12 13:36:03 +01:00
stephb9959
6c9bae518a https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-11 10:44:06 -08:00
stephb9959
7232168037 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-11 10:18:54 -08:00
stephb9959
9da06d8384 https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-11 09:45:47 -08:00
stephb9959
296a4721db https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-11 09:43:11 -08:00
stephb9959
f2badf7b6d https://telecominfraproject.atlassian.net/browse/WIFI-11388
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 23:01:31 -08:00
Stephane Bourque
766be1aa3c Merge pull request #291 from Telecominfraproject/WIFI-11429
https://telecominfraproject.atlassian.net/browse/WIFI-11429
2022-12-10 10:24:19 -08:00
stephb9959
4812219e0d https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 10:20:36 -08:00
stephb9959
7b4e39aad2 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 10:08:43 -08:00
stephb9959
fbff951e22 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 10:08:14 -08:00
stephb9959
09198d5ec2 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 10:03:22 -08:00
stephb9959
3666995f7f https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 09:48:42 -08:00
stephb9959
0572674279 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 08:52:33 -08:00
stephb9959
19f2265161 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 08:40:09 -08:00
stephb9959
f613449dff https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 08:36:06 -08:00
stephb9959
a1291b1b16 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 08:31:22 -08:00
stephb9959
39ebc28396 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 08:25:53 -08:00
stephb9959
6017714363 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 08:20:29 -08:00
stephb9959
bff7092ce1 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-10 07:43:11 -08:00
stephb9959
1741742617 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 23:39:55 -08:00
stephb9959
b4a6bea1b4 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 23:37:18 -08:00
stephb9959
57e06b2d2f https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 23:24:24 -08:00
stephb9959
0bc7363dae https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 23:09:29 -08:00
stephb9959
44b2140230 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 22:58:44 -08:00
stephb9959
49bc934066 https://telecominfraproject.atlassian.net/browse/WIFI-11429
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 22:50:11 -08:00
Stephane Bourque
53d337f462 Merge pull request #290 from Telecominfraproject/WIFI-11333
https://telecominfraproject.atlassian.net/browse/WIFI-11333
2022-12-09 14:41:11 -08:00
stephb9959
66e7791b95 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 14:39:14 -08:00
stephb9959
2180c5ff23 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 14:10:59 -08:00
stephb9959
2f4fa7572e https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 13:39:47 -08:00
stephb9959
5923506237 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 13:38:58 -08:00
stephb9959
b9600654f8 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 13:35:11 -08:00
stephb9959
6b0a082ac9 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 12:17:52 -08:00
stephb9959
c5a108d672 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 11:59:46 -08:00
stephb9959
23c2925baf https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 11:55:14 -08:00
stephb9959
fa4c72d59c https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 11:42:54 -08:00
stephb9959
d66d901204 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 10:33:40 -08:00
stephb9959
b09eaf98cc https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-09 10:19:02 -08:00
Stephane Bourque
7f9bf85958 Merge pull request #289 from Telecominfraproject/WIFI-11909
https://telecominfraproject.atlassian.net/browse/WIFI-11909
2022-12-07 10:00:58 -08:00
stephb9959
d1d89fcd74 https://telecominfraproject.atlassian.net/browse/WIFI-11909
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-07 10:00:17 -08:00
Stephane Bourque
bc3f5700d4 Merge pull request #288 from Telecominfraproject/WIFI-11869
https://telecominfraproject.atlassian.net/browse/WIFI-11333
2022-12-07 09:45:25 -08:00
stephb9959
3a938fd615 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-07 09:44:18 -08:00
Stephane Bourque
dc3729aec2 Merge pull request #287 from Telecominfraproject/WIFI-11869
https://telecominfraproject.atlassian.net/browse/WIFI-11333
2022-12-07 08:37:33 -08:00
stephb9959
dd214ae5d1 https://telecominfraproject.atlassian.net/browse/WIFI-11333
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-07 08:36:48 -08:00
Stephane Bourque
8f7f8c5736 Merge pull request #286 from Telecominfraproject/WIFI-11869
https://telecominfraproject.atlassian.net/browse/WIFI-11869
2022-12-05 08:37:54 -08:00
stephb9959
00701a8de4 https://telecominfraproject.atlassian.net/browse/WIFI-11869
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-05 08:37:12 -08:00
Stephane Bourque
fc41c9aa2f Merge pull request #285 from Telecominfraproject/WIFI-11869
https://telecominfraproject.atlassian.net/browse/WIFI-11869
2022-12-05 08:36:40 -08:00
stephb9959
a5442eee0d https://telecominfraproject.atlassian.net/browse/WIFI-11869
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-05 08:35:14 -08:00
Stephane Bourque
9dcf5b5320 Merge pull request #284 from Telecominfraproject/WIFI-11869
https://telecominfraproject.atlassian.net/browse/WIFI-11869
2022-12-01 21:59:30 -08:00
stephb9959
28b5295a6e https://telecominfraproject.atlassian.net/browse/WIFI-11869
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 21:58:40 -08:00
stephb9959
8261ae34bd https://telecominfraproject.atlassian.net/browse/WIFI-11869
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 21:54:08 -08:00
Stephane Bourque
02baa9329c Merge pull request #283 from Telecominfraproject/WIFI-11779
https://telecominfraproject.atlassian.net/browse/WIFI-11865
2022-12-01 15:44:25 -08:00
stephb9959
7f01c7b861 https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 12:25:49 -08:00
stephb9959
8d0f0c227a https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 11:00:52 -08:00
stephb9959
c8170bc9f3 https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 10:53:22 -08:00
stephb9959
83003b66b9 https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 10:34:14 -08:00
stephb9959
cbdb15bc32 https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 10:23:16 -08:00
stephb9959
712e15407d https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 09:21:05 -08:00
stephb9959
e424e19d1c https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 08:44:01 -08:00
stephb9959
546d8dee98 https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 08:26:34 -08:00
stephb9959
60b9fc679a https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 08:17:14 -08:00
Stephane Bourque
79a4f24bc2 Merge pull request #282 from Telecominfraproject/WIFI-11779
https://telecominfraproject.atlassian.net/browse/WIFI-11865
2022-12-01 07:47:04 -08:00
stephb9959
02b8ecf300 https://telecominfraproject.atlassian.net/browse/WIFI-11865
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 07:45:25 -08:00
stephb9959
bdbc5a7a9d https://telecominfraproject.atlassian.net/browse/WIFI-11779
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 07:33:49 -08:00
Stephane Bourque
680fe18bac Merge pull request #281 from Telecominfraproject/WIFI-11779
https://telecominfraproject.atlassian.net/browse/WIFI-11779
2022-12-01 06:59:22 -08:00
stephb9959
dd08b2e426 https://telecominfraproject.atlassian.net/browse/WIFI-11779
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 06:57:56 -08:00
stephb9959
285b1630ee https://telecominfraproject.atlassian.net/browse/WIFI-11779
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 06:55:09 -08:00
stephb9959
fdcaf9054f https://telecominfraproject.atlassian.net/browse/WIFI-11779
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 06:41:27 -08:00
stephb9959
65b5585797 https://telecominfraproject.atlassian.net/browse/WIFI-11779
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 06:39:56 -08:00
stephb9959
b31fdb202c https://telecominfraproject.atlassian.net/browse/WIFI-11779
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-12-01 05:16:07 -08:00
Dmitry Dunaev
d13d906d11 [WIFI-11729] Fix: doc generation error
Signed-off-by: Dmitry Dunaev <dmitry@opsfleet.com>
2022-12-01 13:17:10 +03:00
Stephane Bourque
6a403ac916 Merge pull request #280 from Telecominfraproject/WIFI-11779
https://telecominfraproject.atlassian.net/browse/WIFI-11779
2022-11-30 21:59:40 -08:00
stephb9959
eff54e3202 https://telecominfraproject.atlassian.net/browse/WIFI-11779
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-30 21:53:44 -08:00
Stephane Bourque
0a7dd7c3f7 Merge pull request #279 from Telecominfraproject/WIFI-11430
https://telecominfraproject.atlassian.net/browse/WIFI-11430
2022-11-30 16:21:00 -08:00
stephb9959
cf7f962ed1 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-30 16:19:53 -08:00
stephb9959
f412df29b5 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-30 16:16:13 -08:00
stephb9959
31204bae6a https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-30 15:33:52 -08:00
stephb9959
a57cf08c00 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-30 11:43:22 -08:00
stephb9959
c0171156fa https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-30 11:38:27 -08:00
stephb9959
a456e95139 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-30 11:34:53 -08:00
stephb9959
7f8e2d0f7f https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 22:34:31 -08:00
stephb9959
d80aa68c40 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 22:06:12 -08:00
stephb9959
81c9090ec9 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 22:03:26 -08:00
stephb9959
0fa5c46f4b https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 21:54:20 -08:00
stephb9959
d75977140a https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 14:30:22 -08:00
stephb9959
b65440ba4e https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 14:26:45 -08:00
stephb9959
ee15f8b8c2 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 14:22:45 -08:00
stephb9959
aebf8ba783 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 14:18:35 -08:00
stephb9959
9f2436b123 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 14:17:32 -08:00
stephb9959
cd774ea2df https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 14:13:46 -08:00
stephb9959
007f54bc26 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 14:09:36 -08:00
stephb9959
9c03f3a9e3 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 13:45:09 -08:00
stephb9959
292365a837 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 13:36:05 -08:00
stephb9959
1091478e11 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-29 13:22:52 -08:00
Stephane Bourque
47b94b3c5a Merge pull request #278 from Telecominfraproject/WIFI-11779
https://telecominfraproject.atlassian.net/browse/WIFI-11779
2022-11-28 14:54:42 -08:00
stephb9959
7cd62e7b26 https://telecominfraproject.atlassian.net/browse/WIFI-11779
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-28 14:54:04 -08:00
Stephane Bourque
3397f2407a Merge pull request #277 from Telecominfraproject/WIFI-11778
https://telecominfraproject.atlassian.net/browse/WIFI-11778
2022-11-28 11:44:47 -08:00
stephb9959
52799659c8 https://telecominfraproject.atlassian.net/browse/WIFI-11778
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-28 11:43:13 -08:00
Stephane Bourque
86e88942b0 Merge pull request #276 from Telecominfraproject/WIFI-11777
https://telecominfraproject.atlassian.net/browse/WIFI-11777
2022-11-28 11:19:55 -08:00
stephb9959
11592ebb98 https://telecominfraproject.atlassian.net/browse/WIFI-11777
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-28 11:19:01 -08:00
Stephane Bourque
83f4bfc53d Merge pull request #275 from Telecominfraproject/WIFI-11754
https://telecominfraproject.atlassian.net/browse/WIFI-11755
2022-11-27 21:47:01 -08:00
stephb9959
43ed818015 https://telecominfraproject.atlassian.net/browse/WIFI-11755
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-27 21:24:26 -08:00
stephb9959
fd7f5b991a https://telecominfraproject.atlassian.net/browse/WIFI-11755
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-27 14:31:26 -08:00
Stephane Bourque
feebcb339a Merge pull request #274 from Telecominfraproject/WIFI-11754
https://telecominfraproject.atlassian.net/browse/WIFI-11754
2022-11-27 14:13:30 -08:00
stephb9959
0368d4e435 https://telecominfraproject.atlassian.net/browse/WIFI-11754
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-27 14:12:26 -08:00
Stephane Bourque
a57bad5bb9 Merge pull request #273 from Telecominfraproject/WIFI-11430
https://telecominfraproject.atlassian.net/browse/WIFI-11430
2022-11-27 13:56:47 -08:00
stephb9959
1ef20f232a https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-25 07:59:17 -08:00
stephb9959
78deaf8b38 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-25 07:53:35 -08:00
stephb9959
a1aec29ffd https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-24 11:57:50 -08:00
stephb9959
07dc8617a4 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-24 11:50:27 -08:00
stephb9959
34cef1ae0a https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-24 11:17:22 -08:00
stephb9959
144841d88d https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-24 11:11:59 -08:00
stephb9959
b46a713968 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-24 11:01:08 -08:00
stephb9959
4ec7c30e28 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-24 09:53:33 -08:00
stephb9959
16c5825e3a https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-24 08:04:24 -08:00
stephb9959
0f1129e51e https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 22:18:00 -08:00
stephb9959
3e54201be8 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 12:39:06 -08:00
stephb9959
c34fba4c22 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 12:28:51 -08:00
stephb9959
625f8c7a2b https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 12:22:28 -08:00
stephb9959
41a4a98c0a https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 12:12:36 -08:00
stephb9959
c858d954a9 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 12:04:14 -08:00
stephb9959
aa0410edb3 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 12:02:21 -08:00
stephb9959
97cb61b7cf https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 12:00:17 -08:00
stephb9959
0408d98538 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-23 11:53:25 -08:00
stephb9959
69e2f9640e https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-22 22:10:46 -08:00
stephb9959
efd20dc370 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-22 08:21:35 -08:00
stephb9959
7a42598150 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-22 07:57:35 -08:00
stephb9959
7a45d96d9a https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-22 07:28:20 -08:00
stephb9959
a4f7ccdba1 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-21 16:04:36 -08:00
stephb9959
a0b47aa4b3 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-21 15:43:39 -08:00
stephb9959
ee6dd54ab3 https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-21 15:39:52 -08:00
stephb9959
518ca7cc9d https://telecominfraproject.atlassian.net/browse/WIFI-11430
Signed-off-by: stephb9959 <stephane.bourque@gmail.com>
2022-11-21 15:29:36 -08:00
89 changed files with 5971 additions and 4351 deletions

View File

@@ -34,6 +34,7 @@ jobs:
git config --global user.name "TIP Automation User"
git pull
git checkout gh-pages || git checkout -b gh-pages
rm -rf docs
mv tmp-docs docs
git add docs
git commit -m'Update OpenAPI docs for GitHub pages'

View File

@@ -165,10 +165,6 @@ add_executable( owgw
src/CapabilitiesCache.h src/FindCountry.h
src/rttys/RTTYS_server.cpp
src/rttys/RTTYS_server.h
src/rttys/RTTYS_device.cpp
src/rttys/RTTYS_device.h
src/rttys/RTTYS_ClientConnection.cpp
src/rttys/RTTYS_ClientConnection.h
src/rttys/RTTYS_WebServer.cpp
src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h
src/SDKcalls.cpp
@@ -199,7 +195,7 @@ add_executable( owgw
src/AP_WS_Process_telemetry.cpp
src/AP_WS_Process_venuebroadcast.cpp
src/RADSEC_server.h
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/AP_restrictions.h)
src/UI_GW_WebSocketNotifications.cpp src/UI_GW_WebSocketNotifications.h src/framework/RESTAPI_SystemConfiguration.h src/ScriptManager.cpp src/ScriptManager.h src/RESTAPI/RESTAPI_scripts_handler.cpp src/RESTAPI/RESTAPI_scripts_handler.h src/RESTAPI/RESTAPI_script_handler.cpp src/RESTAPI/RESTAPI_script_handler.h src/storage/storage_scripts.cpp src/storage/storage_scripts.h src/SignatureMgr.cpp src/SignatureMgr.h)
if(NOT SMALL_BUILD)

View File

@@ -1,5 +1,5 @@
ARG DEBIAN_VERSION=11.5-slim
ARG POCO_VERSION=poco-tip-v1
ARG POCO_VERSION=poco-tip-v2
ARG CPPKAFKA_VERSION=tip-v1
ARG JSON_VALIDATOR_VERSION=2.1.0

82
RESTRICTED_DEVICES.md Normal file
View File

@@ -0,0 +1,82 @@
# Restricted devices
## What is a restricted device?
A restricted device is one that because of regulations or a desire for utmost security, requires signatures to access restricted or blocked
features. The restriction process is burnt in the device at manufacturing or later by running a specific command on the device. Once a device
is restricted, it cannot be unlocked.
## Current restrictions
Restrictions are stored on the AP in a protected partition. They are contained in a file called `restrictions.json`. Here is a sample:
```json
{
"country": [
"US", "CA"
],
"dfs": true,
"rtty": true,
"tty": true,
"developer": true,
"sysupgrade": true,
"commands": true,
"key_info": {
"vendor": "dummy",
"algo": "static"
}
}
```
- country
- List of countries where this device may be used
- dfs
- Disallow DFS Override during wifi-scan. If set to `true`, device will not allow to override DFS channels
- rtty
- Disallow the use of the RTTY command for this device
- tty
- Do not allow the AP to accept `tty` connection
- developer
- Internal use only.
- sysupgrade
- If set to `true`, only signed firmware upgrade command will be allowed.
- commands
- If set to `true`, do not allow commands.
- key_info
- This structure defines how signatures should be generated and verified in a secure system
- vendor
- An identified that must match the vendor name provided in the controller
- algo
- The signature algorithm. Here are the supported algorithms
- `static`
- A test algorithm that always returns and uses a value of `aaaaaaaaaa`. This should never be used in the field.
- `dgst-sha256`
- The default OpenSSL RSA signature generation and verification. The controller will use the following command to generate the signature
```sh
openssl dgst -sha256 -sign private-key.pem -out signature.txt myfile
```
- The AP will be using the following to verify the signature
```sh
openssl dgst -sha256 -verify public-key.pem -signature signature.txt myfile
```
## Creating signatures on the controller
When a device is restricted and a signature is required, the controller can generate the signature
for the specified `vendor`. However, on the controlelr side, you must configure the vendors. In
order to do so we suggest the following.
- Create a directory called `signatures` under your `certs` directory
- Copy the public and private keys for each `vendor` name. We suggest naming them accordingly
- `vendor`-private-key.pem
- `vendor`-public-key.pem
- In the `owgw.properties` file, you need to declare these signatures the following way
```properties
signature.manager.0.key.public = $OWGW_ROOT/certs/signatures/test1-public-key.pem
signature.manager.0.key.private = $OWGW_ROOT/certs/signatures/test1-private-key.pem
signature.manager.0.vendor = test1
signature.manager.1.key.public = $OWGW_ROOT/certs/signatures/test2-public-key.pem
signature.manager.1.key.private = $OWGW_ROOT/certs/signatures/test2-private-key.pem
signature.manager.1.vendor = test2
```
## How do you use the signatures?
There is nothing to do really. Now the controller will use the proper key to create the signatures
when it sends commands to the AP. It will use the algorithm that the device understands too. This is transparent
to the user. The `vendor` name used in the controller configuration must match the `vendor` name provided in the
`restrictions.json` file.

2
build
View File

@@ -1 +1 @@
44
94

View File

@@ -73,6 +73,7 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owgw"} \
STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owgw"} \
STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
CERTIFICATES_ALLOWMISMATCH=${CERTIFICATES_ALLOWMISMATCH:-"false"} \
envsubst < /owgw.properties.tmpl > $OWGW_CONFIG/owgw.properties
fi

View File

@@ -9,7 +9,7 @@ fullnameOverride: ""
images:
owgw:
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owgw
tag: master
tag: v2.8.0
pullPolicy: Always
# regcred:
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
@@ -230,6 +230,7 @@ configProperties:
openwifi.devicetypes.0: AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
openwifi.devicetypes.1: SWITCH:edgecore_ecs4100-12ph
openwifi.devicetypes.2: IOT:esp32
openwifi.certificates.allowmismatch: "false"
oui.download.uri: https://standards-oui.ieee.org/oui/oui.txt
firmware.autoupdate.policy.default: auto
iptocountry.provider: ipinfo

View File

@@ -49,6 +49,38 @@ components:
- IOT
- MESH
DeviceRestrictionsKeyInfo:
type: object
properties:
vendor:
type: string
algo:
type: string
DeviceRestrictions:
type: object
properties:
dfs:
type: boolean
ssh:
type: boolean
rtty:
type: boolean
tty:
type: boolean
developer:
type: boolean
upgrade:
type: boolean
commands:
type: boolean
country:
type: array
items:
type: string
key_info:
$ref: '#/components/schemas/DeviceRestrictionsKeyInfo'
Device:
type: object
description: Definition of uCentral device
@@ -107,12 +139,19 @@ components:
type: string
minLength: 2
maxLength: 2
FCC:
restrictedDevice:
type: boolean
default: false
certificateExpiryDate:
type: integer
format: int64
pendingConfiguration:
type: string
pendingConfigurationCmd:
type: string
format: uuid
restrictionDetails:
$ref: '#/components/schemas/DeviceRestrictions'
DeviceWithStatus:
type: object
@@ -214,6 +253,13 @@ components:
certificateDate:
type: integer
format: int64
pendingConfiguration:
type: string
pendingConfigurationCmd:
type: string
format: uuid
restrictionDetails:
$ref: '#/components/schemas/DeviceRestrictions'
DeviceList:
type: object
@@ -514,8 +560,11 @@ components:
enum:
- shell
- bundle
- diagnostic
script:
type: string
scriptId:
type: string
when:
type: integer
format: int64
@@ -527,6 +576,52 @@ components:
uri:
type: string
ScriptEntry:
type: object
properties:
id:
type: string
name:
type: string
description:
type: string
uri:
type: string
content:
type: string
version:
type: string
type:
enum:
- shell
- bundle
created:
type: integer
modified:
type: integer
author:
type: string
restricted:
type: array
items:
type: string
deferred:
type: boolean
default: false
timeout:
type: integer
default: 30
defaultUploadURI:
type: string
ScriptEntryList:
type: object
properties:
scripts:
type: array
items:
$ref: '#/components/schemas/ScriptEntry'
FactoryRequest:
type: object
properties:
@@ -2474,6 +2569,148 @@ paths:
404:
$ref: '#/components/responses/NotFound'
/scripts:
get:
tags:
- Scripting
summary: Returns a list scripts.
description: Get a list of scripts.
operationId: getScripts
parameters:
- in: query
description: Pagination start (starts at 0. If not specified, 0 is assumed)
name: offset
schema:
type: integer
required: false
- in: query
description: Maximum number of entries to return (if absent, no limit is assumed)
name: limit
schema:
type: integer
required: false
- in: query
description: Filter the results
name: filter
schema:
type: string
required: false
responses:
200:
description: List all scripts
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptEntryList'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/script/{uuid}:
get:
tags:
- Scripting
summary: Returns a script entry.
description: Get a specific script entry.
operationId: getScript
parameters:
- in: path
description: The UUID of the script
name: uuid
schema:
type: string
format: uuid
required: true
responses:
200:
description: A script entry
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptEntry'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
post:
tags:
- Scripting
summary: Create a new script.
operationId: createScript
parameters:
- in: path
description: The UUID of the script. Must be set to 0 for creation
name: uuid
schema:
type: string
format: uuid
required: true
requestBody:
description: Complet script entry
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptEntry'
responses:
200:
$ref: '#/components/schemas/ScriptEntry'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
put:
tags:
- Scripting
summary: Modify a script.
operationId: modifyScript
parameters:
- in: path
description: The UUID of the script.
name: uuid
schema:
type: string
format: uuid
required: true
requestBody:
description: Complete script entry. You may only modify the name, description, version, uri, and content
content:
application/json:
schema:
$ref: '#/components/schemas/ScriptEntry'
responses:
200:
$ref: '#/components/schemas/ScriptEntry'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
delete:
tags:
- Scripting
summary: Delete a script.
operationId: deleteScript
parameters:
- in: path
name: uuid
schema:
type: string
format: uuid
required: true
responses:
204:
$ref: '#/components/responses/Success'
403:
$ref: '#/components/responses/Unauthorized'
404:
$ref: '#/components/responses/NotFound'
/blacklist:
get:
tags:

View File

@@ -75,6 +75,7 @@ openwifi.autoprovisioning = true
openwifi.devicetypes.0 = AP:linksys_ea8300,edgecore_eap101,linksys_e8450-ubi
openwifi.devicetypes.1 = SWITCH:edgecore_ecs4100-12ph
openwifi.devicetypes.2 = IOT:esp32
openwifi.certificates.allowmismatch = ${CERTIFICATES_ALLOWMISMATCH}
oui.download.uri = https://standards-oui.ieee.org/oui/oui.txt
simulatorid = ${SIMULATORID}
iptocountry.default = US

View File

@@ -16,6 +16,7 @@
"weight" : 10,
"radsec" : true,
"radsecPort" : 2083,
"allowSelfSigned" : false,
"radsecSecret" : "radsec",
"radsecKey" : "LS0tLS1CRUdJTiBFQyBQUklWQVRFIEtFWS0tLS0tCk1IY0NBUUVFSUR6RnpXeTZlYXg0QVoxTySG9VUURRZ0FFS3BnWVBHMktPTVd2S0w1Z3NMRXpUc09rREg1M3NHaEQyS3RsRXBDTXVnNDNIZlFnTFVpUgpTR1R2S1l0bDFmbmJaU1lnY0RJdncxdjNYRy9hVDhOY2JBPT0KLS0tLS1FTkQgRUMgUFJJVkFURSBLRVktLS0tLQo=",
"radsecCert" : "LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUNRVENDQWVpZ0F3SUJBZ0lVY3BKS3pVM0Ba0dBMVVFQmhNQ1ZWTXhFekFSQmdOVkJBb1RDa0oxZEhSdmJuZHZiMlF4SFRBYkJnTlZCQU1URkVKMQpkSFJ2Ym5kdmIyUWdVbUZrYzJWaklFTkJNQjRYRFRJeU1EY3dNekExTWpVeE5Gb1hEVEkzTURVeE9UQTFNalV4Ck5Gb3dkVEVMTUFrR0ExVUVCaE1DVlZNeEV6QVJCZ05WQkFvVENrSjFkSFJ2Ym5kdmIyUXhOakEwQmdOVkJBTVQKTFdGeWFXeHBZUzVqWWpFd2FtTnVjemgxYlhCbk9HWnBjRFowTUM1dmNtbHZiaTVoY21WaE1USXdMbU52YlRFWgpNQmNHQ2dtU0pvbVQ4aXhrQVFFVENVZHZiMmRzWlRwVlV6QlpNQk1HQnlxR1NNNDlBZ0VHQ0NxR1NNNDlBd0VICkEwSUFCQ3FZR0R4dGlqakZyeWkrWUxDeE0wN0RwQXgrZDdCb1E5aXJaUktRakxvT054MzBJQzFJa1Voazd5bUwKWmRYNTIyVW1JSEF5TDhOYjkxeHYyay9EWEd5amdZa3dnWVl3RGdZRFZSMFBBUUgvQkFRREFnZUFNQk1HQTFVZApKUVFNTUFvR0NDc0dBUVVGQndNQ01Bd0dBMVVkRXdFQi93UUNNQUF3T0FZRFZSMFJCREV3TDRJdFlYSnBiR2xoCkxtTmlNVEJxWTI1ek9IVnRjR2M0Wm1sd05uUXdMbTl5YVc5dUxtRnlaV0V4TWpBdVkyOXRNQmNHQTFVZElBUVEKTUE0d0RBWUtLd1lCQkFIdUtnRUJCVEFLQmdncWhrak9QUVFEQWdOSEFEQkVBaUFwTmM1dUNBSkp6KzVyakdqdwpCWGtOdHE3UU83bWU5dUg5bkNsTDZnSVE5Z0lnUHM2VkVKVW5CcEZ0RktXbFF4eWJ1YlBxYnpJNjBPSERHQ0ExCmhXUk1PS1U9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K",

View File

@@ -28,6 +28,8 @@
#include "fmt/format.h"
#include "framework/ow_constants.h"
#include "RADIUS_proxy_server.h"
@@ -290,7 +292,7 @@ namespace OpenWifi {
bool Sent;
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
GWWebSocketNotifications::SingleDeviceConfigurationChange_t Notification;
Notification.content.serialNumber = D.SerialNumber;

View File

@@ -15,7 +15,6 @@
#include "Poco/Net/WebSocket.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "AP_restrictions.h"
namespace OpenWifi {
@@ -78,7 +77,7 @@ namespace OpenWifi {
State = State_;
}
inline void GetRestrictions(AP_Restrictions & R) const {
inline void GetRestrictions(GWObjects::DeviceRestrictions & R) const {
std::shared_lock G(ConnectionMutex_);
R = Restrictions_;
}
@@ -115,7 +114,7 @@ namespace OpenWifi {
friend class AP_WS_Server;
inline AP_Restrictions Restrictions() const {
inline GWObjects::DeviceRestrictions Restrictions() const {
std::shared_lock G(ConnectionMutex_);
return Restrictions_;
}
@@ -150,7 +149,7 @@ namespace OpenWifi {
std::atomic_flag Dead_=false;
std::atomic_bool DeviceValidated_=false;
std::atomic_bool Valid_=false;
AP_Restrictions Restrictions_;
OpenWifi::GWObjects::DeviceRestrictions Restrictions_;
static inline std::atomic_uint64_t ConcurrentStartingDevices_=0;

View File

@@ -50,12 +50,10 @@ namespace OpenWifi {
}
bool RestrictedDevice = false;
if(ParamsObj->has("restricted") && ParamsObj->get("restricted").isBoolean()) {
if(Capabilities->has("restrictions")){
RestrictedDevice = true;
if(Capabilities->has("restrictions")) {
auto RestrictionObject = Capabilities->getObject("restrictions");
Restrictions_.initialize(Logger_, SerialNumber_, RestrictionObject);
}
Poco::JSON::Object::Ptr RestrictionObject = Capabilities->getObject("restrictions");
Restrictions_.from_json(RestrictionObject);
}
State_.locale = FindCountryFromIP()->Get(IP);
@@ -97,9 +95,15 @@ namespace OpenWifi {
++Updated;
}
if(Restrictions_ != DeviceInfo.restrictionDetails) {
DeviceInfo.restrictionDetails = Restrictions_;
++Updated;
}
if(Updated) {
StorageService()->UpdateDevice(DeviceInfo);
}
uint64_t UpgradedUUID=0;
LookForUpgrade(UUID,UpgradedUUID);
State_.UUID = UpgradedUUID;
@@ -111,7 +115,7 @@ namespace OpenWifi {
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
if(State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
if (( Utils::SerialNumberMatch(CN_, SerialNumber_, AP_WS_Server()->MismatchDepth())) ||
if (( Utils::SerialNumberMatch(CN_, SerialNumber_, (int)AP_WS_Server()->MismatchDepth())) ||
AP_WS_Server()->IsSimSerialNumber(CN_)) {
State_.VerifiedCertificate = GWObjects::VERIFIED;
poco_information(Logger_, fmt::format("CONNECT({}): Fully validated and authenticated device. Session={} ConnectionCompletion Time={}",
@@ -127,9 +131,8 @@ namespace OpenWifi {
State_.connectionCompletionTime));
} else {
poco_information(
Logger_, fmt::format("CONNECT({}): Serial number mismatch disallowed. Device rejected. CN={} Serial={} Session={} ConnectionCompletion Time={}",
CId_, CN_, SerialNumber_, State_.sessionId,
State_.connectionCompletionTime));
Logger_, fmt::format("CONNECT({}): Serial number mismatch disallowed. Device rejected. CN={} Serial={} Session={}",
CId_, CN_, SerialNumber_, State_.sessionId));
return EndConnection();
}
}

View File

@@ -9,6 +9,7 @@
#include "framework/ow_constants.h"
#include "framework/MicroServiceFuncs.h"
#include "fmt/format.h"
#include "framework/ow_constants.h"
namespace OpenWifi {
void AP_WS_Connection::Process_recovery(Poco::JSON::Object::Ptr ParamsObj) {
@@ -51,7 +52,7 @@ namespace OpenWifi {
Poco::JSON::Stringifier::stringify(Params, O);
Cmd.Details = O.str();
bool Sent;
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(),SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
CommandManager()->PostCommand(CommandManager()->Next_RPC_ID(), APCommands::Commands::reboot, SerialNumber_, Cmd.Command, Params, Cmd.UUID, Sent);
StorageService()->AddCommand(SerialNumber_, Cmd, Storage::CommandExecutionType::COMMAND_EXECUTED);
poco_information(Logger_, fmt::format("RECOVERY({}): Recovery mode received, need for a reboot.", CId_));
} else {

View File

@@ -296,7 +296,7 @@ namespace OpenWifi {
return false;
}
bool AP_WS_Server::Connected(uint64_t SerialNumber, AP_Restrictions & Restrictions) const {
bool AP_WS_Server::Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions & Restrictions) const {
std::shared_ptr<AP_WS_Connection> DevicePtr;
{
std::lock_guard Lock(WSServerMutex_);

View File

@@ -134,7 +134,7 @@ namespace OpenWifi {
}
bool GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
bool Connected(uint64_t SerialNumber, AP_Restrictions & Restrictions) const ;
bool Connected(uint64_t SerialNumber, GWObjects::DeviceRestrictions & Restrictions) const ;
bool Connected(uint64_t SerialNumber) const ;
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {

View File

@@ -1,77 +0,0 @@
//
// Created by stephane bourque on 2022-11-14.
//
#pragma once
#include <string>
#include <set>
#include "Poco/JSON/Object.h"
#include "Poco/Logger.h"
#include "fmt/format.h"
/*
{
“country”: [
“US”, “CA”
],
“dfs”: true,
“ssh”: true,
“rtty”: true,
“tty”: true,
“developer”: true,
“sysupgrade”: true,
“commands”: true
}
*/
namespace OpenWifi {
class AP_Restrictions {
public:
inline bool initialize(Poco::Logger & Logger, const std::string & serialNumber, const Poco::JSON::Object::Ptr &O) {
try {
dfs_ = O->optValue("dfs",false);
ssh_ = O->optValue("ssh",false);
rtty_ = O->optValue("rtty",false);
tty_ = O->optValue("tty",false);
developer_ = O->optValue("developer",false);
sysupgrade_ = O->optValue("sysupgrade",false);
commands_ = O->optValue("commands",false);
if(O->has("country") && O->isArray("country")) {
auto Countries = O->getArray("country");
for(const auto &country:*Countries) {
countries_.insert(Poco::toLower(country.toString()));
}
}
return true;
} catch (...) {
poco_error(Logger,fmt::format("Cannot parse restrictions for device {}", serialNumber));
}
return false;
}
[[nodiscard]] inline auto dfs_not_allowed() const { return dfs_; }
[[nodiscard]] inline auto ssh_not_allowed() const { return ssh_; }
[[nodiscard]] inline auto rtty_not_allowed() const { return rtty_; }
[[nodiscard]] inline auto tty_not_allowed() const { return tty_; }
[[nodiscard]] inline auto developer_not_allowed() const { return developer_; }
[[nodiscard]] inline auto sysupgrade_not_allowed() const { return sysupgrade_; }
[[nodiscard]] inline auto commands_not_allowed() const { return commands_; }
[[nodiscard]] inline bool valid_country(const std::string &c) const {
if(countries_.empty())
return true;
return countries_.find(Poco::toLower(c))!=countries_.end();
}
private:
std::set<std::string> countries_;
bool dfs_ = false;
bool ssh_ = false;
bool rtty_ = false;
bool tty_ = false;
bool developer_ = false;
bool sysupgrade_ = false;
bool commands_ = false;
};
}

View File

@@ -67,11 +67,11 @@ R"lit(
"ipv4": {
"addressing": "static",
"dhcp": {
"lease-count": 10000,
"lease-count": 100,
"lease-first": 10,
"lease-time": "6h"
},
"subnet": "192.168.1.1/16"
"subnet": "192.168.1.1/24"
},
"name": "LAN",
"role": "downstream",

View File

@@ -34,13 +34,13 @@ namespace OpenWifi {
Poco::JSON::Object::Ptr Payload = Resp->Payload_;
std::string SerialNumberStr = Utils::IntToSerialNumber(Resp->SerialNumber_);
std::ostringstream SS;
Payload->stringify(SS);
bool NoReply = false;
if (!Payload->has(uCentralProtocol::ID)) {
poco_error(Logger(), fmt::format("({}): Invalid RPC response.", SerialNumberStr));
} else {
uint64_t ID = Payload->get(uCentralProtocol::ID);
std::shared_ptr<promise_type_t> TmpRpcEntry;
poco_debug(Logger(),fmt::format("({}): Processing {} response.", SerialNumberStr, ID));
if (ID > 1) {
std::lock_guard Lock(LocalMutex_);
@@ -53,16 +53,65 @@ namespace OpenWifi {
std::chrono::duration<double, std::milli> rpc_execution_time =
std::chrono::high_resolution_clock::now() -
RPC->second.submitted;
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
rpc_execution_time, true);
if (RPC->second.rpc_entry) {
RPC->second.rpc_entry->set_value(Payload);
}
poco_debug(Logger(),
fmt::format("({}): Received RPC answer {}. Command={}",
SerialNumberStr, ID, RPC->second.Command));
OutStandingRequests_.erase(ID);
SerialNumberStr, ID, APCommands::to_string(RPC->second.Command)));
if(RPC->second.Command==APCommands::Commands::script) {
if(RPC->second.State==2) {
// look at the payload to see if we should continue or not...
if (RPC->second.rpc_entry) {
TmpRpcEntry = RPC->second.rpc_entry;
}
// Payload->stringify(std::cout);
if (Payload->has("result")) {
auto Result = Payload->getObject("result");
if (Result->has("status")) {
auto Status = Result->getObject("status");
// Status->stringify(std::cout);
std::uint64_t Error = Status->get("error");
if(Error==0) {
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
rpc_execution_time, true);
RPC->second.State = 1 ;
} else {
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
rpc_execution_time, true);
std::string ErrorTxt = Status->get("result");
StorageService()->CancelWaitFile(RPC->second.UUID, ErrorTxt);
RPC->second.State = 0 ;
}
}
} else {
// std::cout << "Bad payload on command result" << std::endl;
RPC->second.State=0;
}
} else {
// std::cout << "Completing script 2 phase commit." << std::endl;
StorageService()->CommandCompleted(RPC->second.UUID, Payload,
rpc_execution_time, true);
NoReply = true;
RPC->second.State=0;
}
} else {
if(RPC->second.Command!=APCommands::Commands::telemetry) {
StorageService()->CommandCompleted(
RPC->second.UUID, Payload, rpc_execution_time, true);
}
if (RPC->second.rpc_entry) {
TmpRpcEntry = RPC->second.rpc_entry;
}
RPC->second.State = 0 ;
}
if(RPC->second.State==0) {
OutStandingRequests_.erase(ID);
}
}
if(!NoReply && TmpRpcEntry != nullptr)
TmpRpcEntry->set_value(Payload);
}
}
}
@@ -120,7 +169,7 @@ namespace OpenWifi {
if(delta > 10min) {
MyLogger.debug(fmt::format("{}: Command={} for {} Timed out.",
request->second.UUID,
request->second.Command,
APCommands::to_string(request->second.Command),
Utils::IntToSerialNumber(request->second.SerialNumber)));
request = OutStandingRequests_.erase(request);
} else {
@@ -189,14 +238,15 @@ namespace OpenWifi {
continue;
}
std::string ExecutingCommand, ExecutingUUID;
std::string ExecutingUUID;
APCommands::Commands ExecutingCommand=APCommands::Commands::unknown;
if (CommandRunningForDevice(Utils::SerialNumberToInt(Cmd.SerialNumber),
ExecutingUUID, ExecutingCommand)) {
poco_trace(
MyLogger,
fmt::format(
"{}: Serial={} Command={} Device is already busy with command {} (Command={})."
, Cmd.UUID, Cmd.SerialNumber, Cmd.Command,ExecutingUUID, ExecutingCommand));
, Cmd.UUID, Cmd.SerialNumber, Cmd.Command, ExecutingUUID, APCommands::to_string(ExecutingCommand)));
continue;
}
@@ -205,7 +255,7 @@ namespace OpenWifi {
poco_information(MyLogger, fmt::format("{}: Serial={} Command={} Preparing execution.",
Cmd.UUID, Cmd.SerialNumber, Cmd.Command));
auto Params = P.parse(Cmd.Details).extract<Poco::JSON::Object::Ptr>();
auto Result = PostCommandDisk(Next_RPC_ID(), Cmd.SerialNumber, Cmd.Command,
auto Result = PostCommandDisk(Next_RPC_ID(), APCommands::to_apcommand(Cmd.Command.c_str()), Cmd.SerialNumber, Cmd.Command,
*Params, Cmd.UUID, Sent);
if (Sent) {
StorageService()->SetCommandExecuted(Cmd.UUID);
@@ -240,9 +290,10 @@ namespace OpenWifi {
}
std::shared_ptr<CommandManager::promise_type_t> CommandManager::PostCommand(
uint64_t RPCID,
uint64_t RPC_ID,
APCommands::Commands Command,
const std::string &SerialNumber,
const std::string &Command,
const std::string &CommandStr,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool oneway_rpc,
@@ -255,31 +306,33 @@ namespace OpenWifi {
std::stringstream ToSend;
CommandInfo Idx;
Idx.Id = oneway_rpc ? 1 : RPCID;
Idx.Id = oneway_rpc ? 1 : RPC_ID;
Idx.SerialNumber = SerialNumberInt;
Idx.Command = Command;
if(Command == APCommands::Commands::script)
Idx.State=2;
Idx.UUID = UUID;
Poco::JSON::Object CompleteRPC;
CompleteRPC.set(uCentralProtocol::JSONRPC, uCentralProtocol::JSONRPC_VERSION);
CompleteRPC.set(uCentralProtocol::ID, RPCID);
CompleteRPC.set(uCentralProtocol::METHOD, Command);
CompleteRPC.set(uCentralProtocol::ID, RPC_ID);
CompleteRPC.set(uCentralProtocol::METHOD, CommandStr);
CompleteRPC.set(uCentralProtocol::PARAMS, Params);
Poco::JSON::Stringifier::stringify(CompleteRPC, ToSend);
Idx.rpc_entry = disk_only ? nullptr : std::make_shared<CommandManager::promise_type_t>();
poco_debug(Logger(), fmt::format("{}: Sending command. ID: {}", UUID, RPCID));
poco_debug(Logger(), fmt::format("{}: Sending command {} to {}. ID: {}", UUID, CommandStr, SerialNumber, RPC_ID));
if(AP_WS_Server()->SendFrame(SerialNumber, ToSend.str())) {
if(!oneway_rpc) {
std::lock_guard M(Mutex_);
OutStandingRequests_[RPCID] = Idx;
OutStandingRequests_[RPC_ID] = Idx;
}
poco_debug(Logger(), fmt::format("{}: Sent command. ID: {}", UUID, RPCID));
poco_debug(Logger(), fmt::format("{}: Sent command. ID: {}", UUID, RPC_ID));
Sent=true;
return Idx.rpc_entry;
}
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPCID));
poco_warning(Logger(), fmt::format("{}: Failed to send command. ID: {}", UUID, RPC_ID));
return nullptr;
}
} // namespace

View File

@@ -49,10 +49,11 @@ namespace OpenWifi {
using promise_type_t = std::promise<objtype_t>;
struct CommandInfo {
std::uint64_t Id=0;
std::uint64_t SerialNumber=0;
std::string Command;
std::string UUID;
std::uint64_t Id=0;
std::uint64_t SerialNumber=0;
APCommands::Commands Command;
std::string UUID;
std::uint64_t State=1;
std::chrono::time_point<std::chrono::high_resolution_clock> submitted = std::chrono::high_resolution_clock::now();
std::shared_ptr<promise_type_t> rpc_entry;
};
@@ -76,12 +77,15 @@ namespace OpenWifi {
}
std::shared_ptr<promise_type_t> PostCommandOneWayDisk(uint64_t RPC_ID,
APCommands::Commands Command,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPC_ID, SerialNumber,
return PostCommand(RPC_ID,
Command,
SerialNumber,
Method,
Params,
UUID,
@@ -90,12 +94,14 @@ namespace OpenWifi {
std::shared_ptr<promise_type_t> PostCommandDisk(
uint64_t RPC_ID,
APCommands::Commands Command,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPC_ID,
Command,
SerialNumber,
Method,
Params,
@@ -105,12 +111,15 @@ namespace OpenWifi {
std::shared_ptr<promise_type_t> PostCommand(
uint64_t RPC_ID,
APCommands::Commands Command,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPC_ID, SerialNumber,
return PostCommand(RPC_ID,
Command,
SerialNumber,
Method,
Params,
UUID,
@@ -120,12 +129,14 @@ namespace OpenWifi {
std::shared_ptr<promise_type_t> PostCommandOneWay(
uint64_t RPC_ID,
APCommands::Commands Command,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,
const std::string &UUID,
bool & Sent) {
return PostCommand(RPC_ID,
Command,
SerialNumber,
Method,
Params,
@@ -153,7 +164,7 @@ namespace OpenWifi {
OutStandingRequests_.erase(Id);
}
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string & uuid, std::string &command) {
inline bool CommandRunningForDevice(std::uint64_t SerialNumber, std::string & uuid, APCommands::Commands &command) {
std::lock_guard Lock(LocalMutex_);
for(const auto &[Request,Command]:OutStandingRequests_) {
@@ -190,6 +201,7 @@ namespace OpenWifi {
std::shared_ptr<promise_type_t> PostCommand(
uint64_t RPCID,
APCommands::Commands Command,
const std::string &SerialNumber,
const std::string &Method,
const Poco::JSON::Object &Params,

View File

@@ -28,6 +28,8 @@
#include "rttys/RTTYS_server.h"
#include "framework/UI_WebSocketClientServer.h"
#include "UI_GW_WebSocketNotifications.h"
#include "ScriptManager.h"
#include "SignatureMgr.h"
namespace OpenWifi {
class Daemon *Daemon::instance() {
@@ -50,6 +52,8 @@ namespace OpenWifi {
RTTYS_server(),
RADIUS_proxy_server(),
VenueBroadcaster(),
ScriptManager(),
SignatureManager(),
AP_WS_Server()
});
return &instance;

View File

@@ -7,14 +7,45 @@
#include "framework/utils.h"
namespace OpenWifi {
void DeviceDashboard::Create() {
uint64_t Now = Utils::Now();
if(LastRun_==0 || (Now-LastRun_)>120) {
DB_.reset();
StorageService()->AnalyzeCommands(DB_.commands);
StorageService()->AnalyzeDevices(DB_);
LastRun_ = Now;
bool DeviceDashboard::Get(GWObjects::Dashboard &D, Poco::Logger & Logger) {
uint64_t Now = Utils::Now();
if(!ValidDashboard_ || LastRun_==0 || (Now-LastRun_)>120) {
Generate(D, Logger);
} else {
std::lock_guard G(DataMutex_);
D = DB_;
}
return ValidDashboard_;
};
void DeviceDashboard::Generate(GWObjects::Dashboard &D, Poco::Logger & Logger ) {
if (GeneratingDashboard_.load()) {
// std::cout << "Trying to generate dashboard but already being generated" << std::endl;
while(GeneratingDashboard_.load()) {
Poco::Thread::trySleep(100);
}
std::lock_guard G(DataMutex_);
D = DB_;
} else {
GeneratingDashboard_ = true;
ValidDashboard_ = false;
try {
// std::cout << "Generating dashboard." << std::endl;
poco_information(Logger, "DASHBOARD: Generating a new dashboard.");
GWObjects::Dashboard NewData;
StorageService()->AnalyzeCommands(NewData.commands);
StorageService()->AnalyzeDevices(NewData);
LastRun_ = Utils::Now();
NewData.snapshot = LastRun_;
D = NewData;
std::lock_guard G(DataMutex_);
DB_ = NewData;
ValidDashboard_=true;
} catch(...) {
}
GeneratingDashboard_ = false;
}
}
}

View File

@@ -4,19 +4,24 @@
#pragma once
#include <mutex>
#include "RESTObjects//RESTAPI_GWobjects.h"
#include "framework/OpenWifiTypes.h"
#include "Poco/Logger.h"
namespace OpenWifi {
class DeviceDashboard {
public:
DeviceDashboard() { DB_.reset(); }
void Create();
[[nodiscard]] const GWObjects::Dashboard & Report() const { return DB_;}
bool Get(GWObjects::Dashboard &D, Poco::Logger & Logger);
private:
GWObjects::Dashboard DB_;
uint64_t LastRun_=0;
inline void Reset() { DB_.reset(); }
std::mutex DataMutex_;
volatile std::atomic_bool GeneratingDashboard_=false;
volatile bool ValidDashboard_=false;
GWObjects::Dashboard DB_;
uint64_t LastRun_=0;
void Generate(GWObjects::Dashboard &D, Poco::Logger & Logger);
};
}

View File

@@ -22,7 +22,7 @@ namespace OpenWifi {
struct UploadId {
std::string UUID;
std::uint64_t Expires;
std::uint64_t Expires;
std::string Type;
};

View File

@@ -291,6 +291,8 @@ static const struct tok radius_attribute_names[] = {
constexpr unsigned char CoA_ACK = 44;
constexpr unsigned char CoA_NAK = 45;
constexpr unsigned char ATTR_MessageAuthenticator = 80;
inline bool IsAuthentication(unsigned char t) {
return (t == RADIUS::Access_Request ||
t == RADIUS::Access_Accept ||
@@ -330,6 +332,11 @@ static const struct tok radius_attribute_names[] = {
return "Unknown";
}
inline void MakeRadiusAuthenticator(unsigned char *authenticator) {
for(int i=0;i<16;i++)
authenticator[i]=std::rand() & 0xff;
}
//
// From: https://github.com/Telecominfraproject/wlan-dictionary/blob/main/dictionary.tip
//
@@ -666,6 +673,44 @@ static const struct tok radius_attribute_names[] = {
bool Valid_=false;
};
class RadiusOutputPacket {
public:
explicit RadiusOutputPacket(const std::string &Secret)
: Secret_(Secret) {
}
inline void MakeStatusMessage() {
P_.code = RADCMD_STATUS_SER;
P_.identifier = std::rand() & 0x00ff;
MakeRadiusAuthenticator(P_.authenticator);
unsigned char MessageAuthenticator[16]{0};
AddAttribute(ATTR_MessageAuthenticator,sizeof(MessageAuthenticator),MessageAuthenticator);
P_.rawlen = 1 + 1 + 2 + 16 + 1 + 1 + 16;
Poco::HMACEngine<Poco::MD5Engine> H(Secret_);
H.update((const unsigned char *)&P_, P_.rawlen);
auto digest = H.digest();
int p = 0;
for (const auto &i : digest)
P_.attributes[1 + 1 + p++] = i;
}
inline void AddAttribute(unsigned char attr, uint8_t len, const unsigned char * data) {
P_.attributes[AttributesLen_++] = attr;
P_.attributes[AttributesLen_++] = len;
memcpy(&P_.attributes[AttributesLen_],data,len);
AttributesLen_+=len;
}
[[nodiscard]] inline const unsigned char * Data() const { return (const unsigned char *) &P_;}
[[nodiscard]] inline std::uint16_t Len() const { return P_.rawlen; }
private:
RawRadiusPacket P_;
uint16_t AttributesLen_=0;
std::string Secret_;
};
inline std::ostream &operator<<(std::ostream &os, RadiusPacket const &P) {
os << P.Attrs_ ;
return os;

View File

@@ -22,124 +22,132 @@ namespace OpenWifi {
ConfigFilename_ = MicroServiceDataDirectory()+"/radius_pool_config.json";
Poco::File Config(ConfigFilename_);
enabled_ = MicroServiceConfigGetBool("radius.proxy.enable",false);
if(!enabled_ && !Config.exists()) {
Enabled_ = MicroServiceConfigGetBool("radius.proxy.enable",false);
if(!Enabled_ && !Config.exists()) {
StopRADSECServers();
return 0;
}
poco_notice(Logger(),"Starting...");
enabled_ = true;
Enabled_ = true;
Poco::Net::SocketAddress AuthSockAddrV4(Poco::Net::AddressFamily::IPv4,
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true);
AuthenticationSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV4,true,true);
Poco::Net::SocketAddress AuthSockAddrV6(Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.authentication.port",DEFAULT_RADIUS_AUTHENTICATION_PORT));
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true);
AuthenticationSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AuthSockAddrV6,true,true);
Poco::Net::SocketAddress AcctSockAddrV4(Poco::Net::AddressFamily::IPv4,
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true);
AccountingSocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV4,true,true);
Poco::Net::SocketAddress AcctSockAddrV6(Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.accounting.port",DEFAULT_RADIUS_ACCOUNTING_PORT));
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true);
AccountingSocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(AcctSockAddrV6,true,true);
Poco::Net::SocketAddress CoASockAddrV4(Poco::Net::AddressFamily::IPv4,
MicroServiceConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4,true);
CoASocketV4_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV4,true,true);
Poco::Net::SocketAddress CoASockAddrV6(Poco::Net::AddressFamily::IPv6,
MicroServiceConfigGetInt("radius.proxy.coa.port",DEFAULT_RADIUS_CoA_PORT));
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6,true);
CoASocketV6_ = std::make_unique<Poco::Net::DatagramSocket>(CoASockAddrV6,true,true);
RadiusReactor_.addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_.reset();
RadiusReactor_ = std::make_unique<Poco::Net::SocketReactor>();
RadiusReactor_->addEventHandler(*AuthenticationSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
RadiusReactor_.addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_->addEventHandler(*AuthenticationSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
RadiusReactor_.addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_->addEventHandler(*AccountingSocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
RadiusReactor_.addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_->addEventHandler(*AccountingSocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
RadiusReactor_.addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_->addEventHandler(*CoASocketV4_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnCoASocketReadable));
RadiusReactor_.addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
RadiusReactor_->addEventHandler(*CoASocketV6_,Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnCoASocketReadable));
ParseConfig();
// start RADSEC servers...
StopRADSECServers();
StartRADSECServers();
RadiusReactorThread_.start(RadiusReactor_);
RadiusReactorThread_.start(*RadiusReactor_);
Utils::SetThreadName(RadiusReactorThread_,"rad:reactor");
running_ = true;
Running_ = true;
return 0;
}
void RADIUS_proxy_server::Stop() {
poco_information(Logger(),"Stopping...");
if(enabled_ && running_) {
RadiusReactor_.removeEventHandler(
if(Enabled_ && Running_) {
poco_information(Logger(),"Stopping...");
RadiusReactor_->removeEventHandler(
*AuthenticationSocketV4_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
RadiusReactor_.removeEventHandler(
RadiusReactor_->removeEventHandler(
*AuthenticationSocketV6_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAuthenticationSocketReadable));
RadiusReactor_.removeEventHandler(
RadiusReactor_->removeEventHandler(
*AccountingSocketV4_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
RadiusReactor_.removeEventHandler(
RadiusReactor_->removeEventHandler(
*AccountingSocketV6_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnAccountingSocketReadable));
RadiusReactor_.removeEventHandler(
RadiusReactor_->removeEventHandler(
*CoASocketV4_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnCoASocketReadable));
RadiusReactor_.removeEventHandler(
RadiusReactor_->removeEventHandler(
*CoASocketV6_,
Poco::NObserver<RADIUS_proxy_server, Poco::Net::ReadableNotification>(
*this, &RADIUS_proxy_server::OnCoASocketReadable));
AuthenticationSocketV4_->close();
AuthenticationSocketV6_->close();
AccountingSocketV4_->close();
AccountingSocketV6_->close();
CoASocketV4_->close();
CoASocketV6_->close();
AuthenticationSocketV4_.reset();
AuthenticationSocketV6_.reset();
AccountingSocketV4_.reset();
AccountingSocketV6_.reset();
CoASocketV4_.reset();
CoASocketV6_.reset();
StopRADSECServers();
RadiusReactor_.stop();
RadiusReactor_->stop();
RadiusReactorThread_.join();
enabled_=false;
running_=false;
Running_=false;
poco_information(Logger(),"Stopped...");
}
poco_information(Logger(),"Stopped...");
}
void RADIUS_proxy_server::StartRADSECServers() {
std::lock_guard G(Mutex_);
for(const auto &pool:PoolList_.pools) {
for(const auto &entry:pool.authConfig.servers) {
if(entry.radsec) {
StartRADSECServer(entry);
RADSECservers_[ Poco::Net::SocketAddress(entry.ip,0) ] = std::make_unique<RADSEC_server>(*RadiusReactor_,entry);
}
}
}
}
void RADIUS_proxy_server::StopRADSECServers() {
std::lock_guard G(Mutex_);
RADSECservers_.clear();
}
void RADIUS_proxy_server::StartRADSECServer(const GWObjects::RadiusProxyServerEntry &E) {
RADSECservers_[ Poco::Net::SocketAddress(E.ip,0) ] = std::make_unique<RADSEC_server>(RadiusReactor_,E);
}
void RADIUS_proxy_server::OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf) {
Poco::Net::SocketAddress Sender;
RADIUS::RadiusPacket P;
@@ -208,7 +216,7 @@ namespace OpenWifi {
void RADIUS_proxy_server::SendAccountingData(const std::string &serialNumber, const char *buffer, std::size_t size) {
if(Pools_.empty() || !enabled_)
if(!Continue())
return;
try {
@@ -266,7 +274,7 @@ namespace OpenWifi {
void RADIUS_proxy_server::SendAuthenticationData(const std::string &serialNumber, const char *buffer, std::size_t size) {
if(Pools_.empty() || !enabled_)
if(!Continue())
return;
try {
@@ -319,7 +327,7 @@ namespace OpenWifi {
void RADIUS_proxy_server::SendCoAData(const std::string &serialNumber, const char *buffer, std::size_t size) {
if(Pools_.empty() || !enabled_)
if(!Continue())
return;
try {
@@ -389,7 +397,7 @@ namespace OpenWifi {
};
if(setAsDefault && D.useRADSEC)
defaultIsRADSEC_ = true;
DefaultIsRADSEC_ = true;
if(S.family()==Poco::Net::IPAddress::IPv4) {
TotalV4 += server.weight;
@@ -483,26 +491,26 @@ namespace OpenWifi {
}
}
if(defaultIsRADSEC_) {
if(DefaultIsRADSEC_) {
UseRADSEC = true;
return (IsV4 ? Pools_[defaultPoolIndex_].AuthV4[0].Addr : Pools_[defaultPoolIndex_].AuthV6[0].Addr );
return (IsV4 ? Pools_[DefaultPoolIndex_].AuthV4[0].Addr : Pools_[DefaultPoolIndex_].AuthV6[0].Addr );
}
switch(rtype) {
case radius_type::auth: {
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].AuthV4
: Pools_[defaultPoolIndex_].AuthV6,
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AuthV4
: Pools_[DefaultPoolIndex_].AuthV6,
RequestedAddress);
}
case radius_type::acct:
default: {
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].AcctV4
: Pools_[defaultPoolIndex_].AcctV6,
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].AcctV4
: Pools_[DefaultPoolIndex_].AcctV6,
RequestedAddress);
}
case radius_type::coa: {
return ChooseAddress(IsV4 ? Pools_[defaultPoolIndex_].CoaV4
: Pools_[defaultPoolIndex_].CoaV6,
return ChooseAddress(IsV4 ? Pools_[DefaultPoolIndex_].CoaV4
: Pools_[DefaultPoolIndex_].CoaV6,
RequestedAddress);
}
}
@@ -621,7 +629,6 @@ namespace OpenWifi {
void RADIUS_proxy_server::SetConfig(const GWObjects::RadiusProxyPoolList &C) {
std::lock_guard G(Mutex_);
PoolList_ = C;
Poco::JSON::Object Disk;
C.to_json(Disk);
@@ -630,17 +637,17 @@ namespace OpenWifi {
Disk.stringify(ofs);
ofs.close();
if(!running_) {
Start();
}
ParseConfig();
Stop();
ResetConfig();
PoolList_ = C;
Start();
}
void RADIUS_proxy_server::ResetConfig() {
PoolList_.pools.clear();
Pools_.clear();
defaultPoolIndex_=0;
DefaultPoolIndex_=0;
DefaultIsRADSEC_=false;
}
void RADIUS_proxy_server::DeleteConfig() {
@@ -653,8 +660,8 @@ namespace OpenWifi {
} catch (...) {
}
ResetConfig();
Stop();
ResetConfig();
}
void RADIUS_proxy_server::GetConfig(GWObjects::RadiusProxyPoolList &C) {

View File

@@ -29,7 +29,7 @@ namespace OpenWifi {
int Start() final;
void Stop() final;
inline bool Enabled() const { return enabled_; }
inline bool Enabled() const { return Enabled_; }
void OnAccountingSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
void OnAuthenticationSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
@@ -44,7 +44,6 @@ namespace OpenWifi {
void GetConfig(GWObjects::RadiusProxyPoolList &C);
void StartRADSECServers();
void StartRADSECServer(const GWObjects::RadiusProxyServerEntry &E);
void StopRADSECServers();
struct Destination {
@@ -62,6 +61,10 @@ namespace OpenWifi {
std::vector<std::string> realms;
};
inline bool Continue() const {
return Running_ && Enabled_ && !Pools_.empty();
}
private:
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV4_;
std::unique_ptr<Poco::Net::DatagramSocket> AccountingSocketV6_;
@@ -69,8 +72,8 @@ namespace OpenWifi {
std::unique_ptr<Poco::Net::DatagramSocket> AuthenticationSocketV6_;
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV4_;
std::unique_ptr<Poco::Net::DatagramSocket> CoASocketV6_;
Poco::Net::SocketReactor RadiusReactor_;
Poco::Thread RadiusReactorThread_;
std::unique_ptr<Poco::Net::SocketReactor> RadiusReactor_;
Poco::Thread RadiusReactorThread_;
GWObjects::RadiusProxyPoolList PoolList_;
std::string ConfigFilename_;
@@ -87,10 +90,10 @@ namespace OpenWifi {
};
std::vector<RadiusPool> Pools_;
uint defaultPoolIndex_=0;
bool enabled_=false;
bool defaultIsRADSEC_=false;
std::atomic_bool running_=false;
uint DefaultPoolIndex_=0;
bool Enabled_=false;
bool DefaultIsRADSEC_=false;
std::atomic_bool Running_=false;
RADIUS_proxy_server() noexcept:
SubSystemServer("RADIUS-PROXY", "RADIUS-PROXY", "radius.proxy")

View File

@@ -33,15 +33,17 @@ namespace OpenWifi {
Logger_(Poco::Logger::get(fmt::format("RADSEC: {}@{}:{}",
Server_.name ,
Server_.ip,
Server_.port)))
{
ReconnectThread_.start(*this);
Server_.port))) {
Start();
}
~RADSEC_server() {
if(ReconnectThread_.isRunning()) {
Stop();
}
Stop();
}
inline int Start() {
ReconnectThread_.start(*this);
return 0;
}
inline void Stop() {
@@ -52,12 +54,22 @@ namespace OpenWifi {
}
inline void run() final {
Poco::Thread::trySleep(3000);
std::uint64_t LastStatus=0 ;
auto RadSecKeepAlive = MicroServiceConfigGetInt("radsec.keepalive",120);
while(TryAgain_) {
if(!Connected_) {
std::unique_lock G(Mutex_);
std::lock_guard G(LocalMutex_);
LastStatus = Utils::Now() ;
Connect();
} else if( (Utils::Now() - LastStatus) > RadSecKeepAlive) {
RADIUS::RadiusOutputPacket P(Server_.radsecSecret);
P.MakeStatusMessage();
poco_information(Logger_,"Keep-Alive message.");
Socket_->sendBytes(P.Data(), P.Len());
LastStatus = Utils::Now();
}
Poco::Thread::trySleep(3000);
Poco::Thread::trySleep(!Connected_ ? 3000 : 10000);
}
}
@@ -65,22 +77,23 @@ namespace OpenWifi {
try {
if (Connected_) {
RADIUS::RadiusPacket P(buffer, length);
// std::cout << serial_number << " Sending " << P.PacketType() << " " << length << " bytes" << std::endl;
int sent_bytes;
if (P.VerifyMessageAuthenticator(Server_.radsecSecret)) {
poco_debug(Logger_,fmt::format("{}: {} Sending {} bytes", serial_number,
P.PacketType(), length));
poco_debug(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
P.PacketType(), length));
sent_bytes = Socket_->sendBytes(buffer, length);
} else {
poco_debug(Logger_,fmt::format("{}: {} Sending {} bytes", serial_number,
P.PacketType(), length));
poco_debug(Logger_, fmt::format("{}: {} Sending {} bytes", serial_number,
P.PacketType(), length));
P.ComputeMessageAuthenticator(Server_.radsecSecret);
sent_bytes = Socket_->sendBytes(P.Buffer(), length);
}
return (sent_bytes == length);
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
} catch (...) {
poco_warning(Logger_,"Exception occurred: while sending data.");
}
return false;
}
@@ -90,7 +103,7 @@ namespace OpenWifi {
try {
auto NumberOfReceivedBytes = Socket_->receiveBytes(Buffer,sizeof(Buffer));
if(NumberOfReceivedBytes>40) {
if(NumberOfReceivedBytes>=20) {
RADIUS::RadiusPacket P(Buffer,NumberOfReceivedBytes);
if (P.IsAuthentication()) {
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
@@ -101,9 +114,7 @@ namespace OpenWifi {
AP_WS_Server()->SendRadiusAuthenticationData(SerialNumber, Buffer,
NumberOfReceivedBytes);
} else {
poco_debug(Logger_,
fmt::format("Invalid AUTH packet received in proxy dropped. No serial number Source={}",
Socket_->address().toString()));
poco_debug(Logger_, "AUTH packet dropped.");
}
} else if (P.IsAccounting()) {
auto SerialNumber = P.ExtractSerialNumberFromProxyState();
@@ -114,53 +125,72 @@ namespace OpenWifi {
AP_WS_Server()->SendRadiusAccountingData(SerialNumber, Buffer,
NumberOfReceivedBytes);
} else {
poco_debug(Logger_,
fmt::format("Invalid ACCT packet received in proxy dropped. No serial number Source={}",
Socket_->address().toString()));
poco_debug(Logger_, "ACCT packet dropped.");
}
} else if (P.IsAuthority()) {
auto SerialNumber = P.ExtractSerialNumberTIP();
if(!SerialNumber.empty()) {
poco_debug(Logger_,
fmt::format("{}: {} Received {} bytes.", SerialNumber,
P.PacketType(), NumberOfReceivedBytes));
AP_WS_Server()->SendRadiusCoAData(SerialNumber, Buffer,
NumberOfReceivedBytes);
} else {
poco_debug(Logger_, "CoA/DM packet dropped.");
}
} else {
poco_warning(Logger_,fmt::format("Unknown packet: Type: {} (type={}) Length={}", P.PacketType(), P.PacketTypeInt(), P.BufferLen()));
}
} else {
poco_warning(Logger_,"Invalid packet received. Resetting the connection.");
Disconnect();
}
} catch (const Poco::Exception &E) {
Logger_.log(E);
Disconnect();
} catch (...) {
Disconnect();
poco_warning(Logger_,"Exception occurred. Resetting the connection.");
}
}
inline void onError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf) {
std::cout << "onError" << std::endl;
poco_warning(Logger_,"Socker error. Terminating connection.");
Disconnect();
}
inline void onShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
std::cout << "onShutdown" << std::endl;
poco_warning(Logger_,"Socker socket shutdown. Terminating connection.");
Disconnect();
}
inline bool Connect() {
if(TryAgain_) {
std::lock_guard G(LocalMutex_);
Poco::TemporaryFile CertFile_(MicroServiceDataDirectory());
Poco::TemporaryFile KeyFile_(MicroServiceDataDirectory());
std::vector<Poco::TemporaryFile> CaCertFiles_;
std::vector<std::unique_ptr<Poco::TemporaryFile>> CaCertFiles_;
DecodeFile(CertFile_.path(), Server_.radsecCert);
DecodeFile(KeyFile_.path(), Server_.radsecKey);
for(auto &cert:Server_.radsecCacerts) {
CaCertFiles_.emplace_back(Poco::TemporaryFile(MicroServiceDataDirectory()));
DecodeFile(CaCertFiles_[CaCertFiles_.size()-1].path(), cert);
CaCertFiles_.emplace_back(std::make_unique<Poco::TemporaryFile>(MicroServiceDataDirectory()));
DecodeFile(CaCertFiles_[CaCertFiles_.size()-1]->path(), cert);
}
Poco::Net::Context::Ptr SecureContext = Poco::AutoPtr<Poco::Net::Context>(
new Poco::Net::Context(Poco::Net::Context::TLS_CLIENT_USE,
KeyFile_.path(),
CertFile_.path(),""));
if(Server_.allowSelfSigned) {
SecureContext->setSecurityLevel(Poco::Net::Context::SECURITY_LEVEL_NONE);
SecureContext->enableExtendedCertificateVerification(false);
}
for(const auto &ca:CaCertFiles_) {
Poco::Crypto::X509Certificate cert(ca.path());
Poco::Crypto::X509Certificate cert(ca->path());
SecureContext->addCertificateAuthority(cert);
}
@@ -172,7 +202,10 @@ namespace OpenWifi {
poco_information(Logger_, "Attempting to connect");
Socket_->connect(Destination, Poco::Timespan(100, 0));
Socket_->completeHandshake();
Socket_->verifyPeerCertificate();
if(!Server_.allowSelfSigned) {
Socket_->verifyPeerCertificate();
}
if(Socket_->havePeerCertificate()) {
Peer_Cert_ = std::make_unique<Poco::Crypto::X509Certificate>(Socket_->peerCertificate());
@@ -194,9 +227,6 @@ namespace OpenWifi {
*Socket_,
Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
*this, &RADSEC_server::onShutdown));
Socket_->setBlocking(false);
Socket_->setNoDelay(true);
Socket_->setKeepAlive(true);
Connected_ = true;
poco_information(Logger_,fmt::format("Connected. CN={}",CommonName()));
@@ -216,7 +246,7 @@ namespace OpenWifi {
inline void Disconnect() {
if(Connected_) {
std::unique_lock G(Mutex_);
std::lock_guard G(LocalMutex_);
Reactor_.removeEventHandler(
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ReadableNotification>(
@@ -227,6 +257,7 @@ namespace OpenWifi {
Reactor_.removeEventHandler(
*Socket_, Poco::NObserver<RADSEC_server, Poco::Net::ShutdownNotification>(
*this, &RADSEC_server::onShutdown));
Socket_->close();
Connected_ = false;
}
poco_information(Logger_,"Disconnecting.");
@@ -259,7 +290,7 @@ namespace OpenWifi {
}
private:
std::recursive_mutex Mutex_;
std::recursive_mutex LocalMutex_;
Poco::Net::SocketReactor &Reactor_;
GWObjects::RadiusProxyServerEntry Server_;
Poco::Logger &Logger_;

View File

@@ -34,6 +34,7 @@ namespace OpenWifi::RESTAPI_RPC {
}
void WaitForCommand(uint64_t RPCID,
APCommands::Commands Command,
bool RetryLater,
GWObjects::CommandDetails &Cmd,
Poco::JSON::Object & Params,
@@ -64,7 +65,7 @@ namespace OpenWifi::RESTAPI_RPC {
bool Sent;
std::chrono::time_point<std::chrono::high_resolution_clock> rpc_submitted = std::chrono::high_resolution_clock::now();
std::shared_ptr<CommandManager::promise_type_t> rpc_endpoint =
CommandManager()->PostCommand(RPCID, Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, Sent);
CommandManager()->PostCommand(RPCID, Command, Cmd.SerialNumber, Cmd.Command, Params, Cmd.UUID, Sent);
if(RetryLater && (!Sent || rpc_endpoint== nullptr)) {
Logger.information(fmt::format("{},{}: Pending completion. Device is not connected.", Cmd.UUID, RPCID));

View File

@@ -18,10 +18,13 @@
#include "StorageService.h"
#include "framework/RESTAPI_Handler.h"
#include "framework/ow_constants.h"
namespace OpenWifi::RESTAPI_RPC {
void WaitForCommand(
uint64_t RPCID,
APCommands::Commands Command,
bool RetryLater,
GWObjects::CommandDetails &Cmd,
Poco::JSON::Object & Params,

View File

@@ -20,6 +20,8 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
poco_debug(Logger(),fmt::format("BLACKLIST-DELETE: {}", SerialNumber));
GWObjects::BlackListedDevice D;
if(!StorageService()->GetBlackListDevice(SerialNumber, D)) {
return NotFound();
@@ -38,14 +40,12 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
poco_debug(Logger(),fmt::format("BLACKLIST-GET: {}", SerialNumber));
GWObjects::BlackListedDevice D;
if(!StorageService()->GetBlackListDevice(SerialNumber, D)) {
return NotFound();
}
Poco::JSON::Object Answer;
D.to_json(Answer);
return ReturnObject(Answer);
return Object(D);
}
void RESTAPI_blacklist::DoPost() {
@@ -60,6 +60,8 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
poco_debug(Logger(),fmt::format("BLACKLIST-POST: {}", D.serialNumber));
Poco::toLowerInPlace(D.serialNumber);
if(StorageService()->IsBlackListed(D.serialNumber)) {
return BadRequest(RESTAPI::Errors::SerialNumberExists);
@@ -70,12 +72,8 @@ namespace OpenWifi {
if(StorageService()->AddBlackListDevice(D)) {
GWObjects::BlackListedDevice CreatedDevice;
StorageService()->GetBlackListDevice(D.serialNumber,CreatedDevice);
Poco::JSON::Object Answer;
CreatedDevice.to_json(Answer);
return ReturnObject(Answer);
return Object(CreatedDevice);
}
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
@@ -92,6 +90,8 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
poco_debug(Logger(),fmt::format("BLACKLIST-PUT: {}", SerialNumber));
GWObjects::BlackListedDevice NewDevice;
if(!NewDevice.from_json(Obj)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
@@ -104,10 +104,7 @@ namespace OpenWifi {
GWObjects::BlackListedDevice CreatedDevice;
StorageService()->GetBlackListDevice(SerialNumber,CreatedDevice);
Poco::JSON::Object Answer;
CreatedDevice.to_json(Answer);
return ReturnObject(Answer);
return Object(CreatedDevice);
}
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}

View File

@@ -10,22 +10,16 @@
namespace OpenWifi {
void RESTAPI_blacklist_list::DoGet() {
std::vector<GWObjects::BlackListedDevice> Devices;
poco_debug(Logger(),fmt::format("BLACKLIST-GET: Device serial number list"));
Poco::JSON::Array Arr;
Poco::JSON::Object Answer;
std::vector<GWObjects::BlackListedDevice> Devices;
if(QB_.CountOnly) {
auto Count = StorageService()->GetBlackListDeviceCount();
return ReturnCountOnly(Count);
} else if(StorageService()->GetBlackListDevices(QB_.Offset, QB_.Limit, Devices)) {
for(const auto &i:Devices) {
Poco::JSON::Object O;
i.to_json(O);
Arr.add(O);
}
return Object("devices",Devices);
}
Answer.set("devices", Arr);
return ReturnObject(Answer);
NotFound();
}
}

View File

@@ -20,9 +20,7 @@ namespace OpenWifi {
GWObjects::CommandDetails Command;
if (StorageService()->GetCommand(CommandUUID, Command)) {
Poco::JSON::Object RetObj;
Command.to_json(RetObj);
return ReturnObject(RetObj);
return Object(Command);
}
return NotFound();
}

View File

@@ -24,15 +24,7 @@ namespace OpenWifi {
StorageService()->GetCommands(SerialNumber, QB_.StartDate, QB_.EndDate, QB_.Offset, QB_.Limit,
Commands);
}
Poco::JSON::Array ArrayObj;
for (const auto &i : Commands) {
Poco::JSON::Object Obj;
i.to_json(Obj);
ArrayObj.add(Obj);
}
Poco::JSON::Object RetObj;
RetObj.set(RESTAPI::Protocol::COMMANDS, ArrayObj);
ReturnObject(RetObj);
return Object(RESTAPI::Protocol::COMMANDS, Commands);
}
void RESTAPI_commands::DoDelete() {

View File

@@ -22,9 +22,7 @@ namespace OpenWifi {
std::string Name = ORM::Escape(GetBinding(RESTAPI::Protocol::NAME, ""));
GWObjects::DefaultConfiguration DefConfig;
if (StorageService()->GetDefaultConfiguration(Name, DefConfig)) {
Poco::JSON::Object Obj;
DefConfig.to_json(Obj);
return ReturnObject(Obj);
return Object(DefConfig);
}
NotFound();
}
@@ -106,12 +104,9 @@ namespace OpenWifi {
GWObjects::DefaultConfiguration ModifiedConfig;
StorageService()->GetDefaultConfiguration(Name,ModifiedConfig);
Poco::JSON::Object Answer;
ModifiedConfig.to_json(Answer);
return ReturnObject(Answer);
return Object(ModifiedConfig);
}
BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
}

View File

@@ -23,16 +23,6 @@ namespace OpenWifi {
std::vector<GWObjects::DefaultConfiguration> DefConfigs;
StorageService()->GetDefaultConfigurations(QB_.Offset, QB_.Limit, DefConfigs);
Poco::JSON::Array Objects;
for (const auto &i : DefConfigs) {
Poco::JSON::Object Obj;
i.to_json(Obj);
Objects.add(Obj);
}
Poco::JSON::Object RetObj;
RetObj.set(RESTAPI::Protocol::CONFIGURATIONS, Objects);
ReturnObject(RetObj);
return Object(RESTAPI::Protocol::CONFIGURATIONS, DefConfigs);
}
}

View File

@@ -8,9 +8,11 @@
namespace OpenWifi {
void RESTAPI_deviceDashboardHandler::DoGet() {
Daemon()->GetDashboard().Create();
Poco::JSON::Object Answer;
Daemon()->GetDashboard().Report().to_json(Answer);
ReturnObject(Answer);
poco_information(Logger(),fmt::format("GET-DASHBOARD: {}", Requester()));
GWObjects::Dashboard Data;
if(Daemon()->GetDashboard().Get(Data, Logger())) {
return Object(Data);
}
return BadRequest(RESTAPI::Errors::InternalError);
}
}

View File

@@ -21,6 +21,8 @@
#include "TelemetryStream.h"
#include "CommandManager.h"
#include "SignatureMgr.h"
#include "framework/ConfigurationValidator.h"
#include "framework/KafkaTopics.h"
#include "framework/ow_constants.h"
@@ -50,33 +52,40 @@ namespace OpenWifi {
return NotFound();
}
auto Command = APCommands::to_apcommand(Command_.c_str());
if(Command==APCommands::Commands::unknown) {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
Poco::Thread::current()->setName(fmt::format("{}:{}:{}", Command_, TransactionId_, SerialNumber_));
if (Command_ == RESTAPI::Protocol::CAPABILITIES){
return GetCapabilities();
} else if (Command_ == RESTAPI::Protocol::LOGS) {
return GetLogs();
} else if (Command_ == RESTAPI::Protocol::HEALTHCHECKS) {
return GetChecks();
} else if (Command_ == RESTAPI::Protocol::STATISTICS) {
return GetStatistics();
} else if (Command_ == RESTAPI::Protocol::STATUS) {
return GetStatus();
} else if (Command_ == RESTAPI::Protocol::RTTY) {
AP_Restrictions Restrictions;
if(!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
auto UUID = MicroServiceCreateUUID();
auto RPC = CommandManager()->Next_RPC_ID();
poco_debug(Logger_,fmt::format("Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
TransactionId_, UUID, RPC,
Poco::Thread::current()->id()));
return Rtty(UUID,RPC,60000ms, Restrictions);
} else {
return BadRequest(RESTAPI::Errors::InvalidCommand);
switch(Command) {
case APCommands::Commands::capabilities:
return GetCapabilities();
case APCommands::Commands::logs:
return GetLogs();
case APCommands::Commands::healthchecks:
return GetChecks();
case APCommands::Commands::statistics:
return GetStatistics();
case APCommands::Commands::status:
return GetStatus();
case APCommands::Commands::rtty: {
GWObjects::DeviceRestrictions Restrictions;
if(!AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
auto UUID = MicroServiceCreateUUID();
auto RPC = CommandManager()->Next_RPC_ID();
poco_debug(Logger_,fmt::format("Command rtty TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
TransactionId_, UUID, RPC,
Poco::Thread::current()->id()));
return Rtty(UUID,RPC,60000ms, Restrictions);
};
default:
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
}
@@ -94,44 +103,50 @@ namespace OpenWifi {
return NotFound();
}
auto Command = APCommands::to_apcommand(Command_.c_str());
if(Command==APCommands::Commands::unknown) {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command_, TransactionId_,SerialNumber_));
if (Command_ == RESTAPI::Protocol::CAPABILITIES) {
switch(Command) {
case APCommands::Commands::capabilities:
return DeleteCapabilities();
} else if (Command_ == RESTAPI::Protocol::LOGS){
case APCommands::Commands::logs:
return DeleteLogs();
} else if (Command_ == RESTAPI::Protocol::HEALTHCHECKS){
case APCommands::Commands::healthchecks:
return DeleteChecks();
} else if (Command_ == RESTAPI::Protocol::STATISTICS) {
case APCommands::Commands::statistics:
return DeleteStatistics();
} else {
default:
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
}
struct PostDeviceCommand {
const char * Command;
bool AllowParallel=false;
bool RequireConnection = true;
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds, const AP_Restrictions &R );
APCommands::Commands Command=APCommands::Commands::unknown;
bool AllowParallel=false;
bool RequireConnection = true;
void (RESTAPI_device_commandHandler::*funPtr)(const std::string &, std::uint64_t, std::chrono::milliseconds, const GWObjects::DeviceRestrictions &R );
std::chrono::milliseconds Timeout=120ms;
};
const std::vector<PostDeviceCommand> PostCommands =
static const std::vector<PostDeviceCommand> PostCommands =
{
{ RESTAPI::Protocol::CONFIGURE, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
{ RESTAPI::Protocol::UPGRADE, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
{ RESTAPI::Protocol::REBOOT, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
{ RESTAPI::Protocol::FACTORY, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
{ RESTAPI::Protocol::LEDS, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
{ RESTAPI::Protocol::TRACE, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
{ RESTAPI::Protocol::REQUEST, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
{ RESTAPI::Protocol::WIFISCAN, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
{ RESTAPI::Protocol::EVENTQUEUE, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
{ RESTAPI::Protocol::TELEMETRY, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
{ RESTAPI::Protocol::PING, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
{ RESTAPI::Protocol::SCRIPT, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
{ APCommands::Commands::configure, false, false, &RESTAPI_device_commandHandler::Configure, 120000ms },
{ APCommands::Commands::upgrade, false, false, &RESTAPI_device_commandHandler::Upgrade, 30000ms },
{ APCommands::Commands::reboot, false, true, &RESTAPI_device_commandHandler::Reboot, 30000ms },
{ APCommands::Commands::factory, false, false, &RESTAPI_device_commandHandler::Factory, 30000ms },
{ APCommands::Commands::leds, false, true, &RESTAPI_device_commandHandler::LEDs, 120000ms },
{ APCommands::Commands::trace, false, true, &RESTAPI_device_commandHandler::Trace, 300000ms },
{ APCommands::Commands::request, false, true, &RESTAPI_device_commandHandler::MakeRequest, 120000ms },
{ APCommands::Commands::wifiscan, false, true, &RESTAPI_device_commandHandler::WifiScan, 120000ms },
{ APCommands::Commands::eventqueue, false, true, &RESTAPI_device_commandHandler::EventQueue, 30000ms },
{ APCommands::Commands::telemetry, false, true, &RESTAPI_device_commandHandler::Telemetry, 30000ms },
{ APCommands::Commands::ping, false, true, &RESTAPI_device_commandHandler::Ping, 60000ms },
{ APCommands::Commands::script, false, true, &RESTAPI_device_commandHandler::Script, 300000ms }
};
void RESTAPI_device_commandHandler::DoPost() {
@@ -141,32 +156,39 @@ namespace OpenWifi {
if(!Utils::NormalizeMac(SerialNumber_)) {
return BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
auto Command = APCommands::to_apcommand(Command_.c_str());
if(Command==APCommands::Commands::unknown) {
return BadRequest(RESTAPI::Errors::InvalidCommand);
}
SerialNumberInt_ = Utils::SerialNumberToInt(SerialNumber_);
GWObjects::Device TheDevice;
if(!StorageService()->GetDevice(SerialNumber_,TheDevice)) {
return NotFound();
}
for(const auto &Command:PostCommands) {
if(Command_==Command.Command) {
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command.Command, TransactionId_,SerialNumber_));
AP_Restrictions Restrictions;
if(Command.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
CallCanceled(Command.Command, RESTAPI::Errors::DeviceNotConnected);
for(const auto &PostCommand:PostCommands) {
if(Command==PostCommand.Command) {
Poco::Thread::current()->setName(fmt::format("{}:{}:{}",Command_, TransactionId_,SerialNumber_));
GWObjects::DeviceRestrictions Restrictions;
if(PostCommand.RequireConnection && !AP_WS_Server()->Connected(SerialNumberInt_, Restrictions)) {
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceNotConnected);
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
std::string Command_UUID, CommandName;
if(!Command.AllowParallel && CommandManager()->CommandRunningForDevice(SerialNumberInt_,Command_UUID,CommandName)) {
auto Extra = fmt::format("UUID={} Command={}", Command_UUID, CommandName);
CallCanceled(Command.Command, RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
std::string Command_UUID;
APCommands::Commands CommandName;
if(!PostCommand.AllowParallel && CommandManager()->CommandRunningForDevice(SerialNumberInt_,Command_UUID,CommandName)) {
auto Extra = fmt::format("UUID={} Command={}", Command_UUID, APCommands::to_string(CommandName));
CallCanceled(Command_.c_str(), RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
return BadRequest(RESTAPI::Errors::DeviceIsAlreadyBusy, Extra);
}
auto UUID = MicroServiceCreateUUID();
auto RPC = CommandManager()->Next_RPC_ID();
poco_debug(Logger_,fmt::format("Command {} TID={} can proceed. Identified as {} and RPCID as {}. thr_id={}",
Command.Command, TransactionId_, UUID, RPC,
Command_, TransactionId_, UUID, RPC,
Poco::Thread::current()->id()));
return (*this.*Command.funPtr)(UUID,RPC,Command.Timeout, Restrictions);
return (*this.*PostCommand.funPtr)(UUID,RPC,PostCommand.Timeout, Restrictions);
}
}
return BadRequest(RESTAPI::Errors::InvalidCommand);
@@ -207,6 +229,9 @@ namespace OpenWifi {
if (AP_WS_Server()->GetStatistics(SerialNumber_, Stats) && !Stats.empty()) {
return ReturnRawJSON(Stats);
}
if(AP_WS_Server()->Connected(SerialNumberInt_)) {
return BadRequest(RESTAPI::Errors::NoDeviceStatisticsYet);
}
return BadRequest(RESTAPI::Errors::DeviceNotConnected);
}
@@ -226,12 +251,13 @@ namespace OpenWifi {
QB_.Offset, QB_.Limit, Stats);
}
Poco::JSON::Array ArrayObj;
Poco::JSON::Array::Ptr ArrayObj = Poco::SharedPtr<Poco::JSON::Array>(new Poco::JSON::Array);
for (const auto &i : Stats) {
Poco::JSON::Object Obj;
i.to_json(Obj);
ArrayObj.add(Obj);
Poco::JSON::Object::Ptr Obj = Poco::SharedPtr<Poco::JSON::Object>(new Poco::JSON::Object);
i.to_json(*Obj);
ArrayObj->add(Obj);
}
Poco::JSON::Object RetObj;
RetObj.set(RESTAPI::Protocol::DATA, ArrayObj);
RetObj.set(RESTAPI::Protocol::SERIALNUMBER, SerialNumber_);
@@ -349,7 +375,7 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::NoRecordsDeleted);
}
void RESTAPI_device_commandHandler::Ping(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::Ping(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("PING({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
if (Obj->has(RESTAPI::Protocol::SERIALNUMBER)) {
@@ -373,7 +399,7 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, nullptr, Logger_);
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::ping,false,Cmd, Params, *Request, *Response, timeout, nullptr, nullptr, Logger_);
GWObjects::CommandDetails Cmd2;
if(StorageService()->GetCommand(CMD_UUID,Cmd2)) {
@@ -409,12 +435,8 @@ namespace OpenWifi {
return t=="shell" || t=="bundle";
}
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::Script(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("SCRIPT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
const auto &Obj = ParsedBody_;
GWObjects::ScriptRequest SCR;
@@ -423,11 +445,25 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if (SCR.serialNumber.empty() ||
SCR.script.empty() ||
!ValidateScriptType(SCR.type)) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
bool DiagnosticScript = (SCR.type=="diagnostic");
if(!SCR.script.empty() && !SCR.scriptId.empty()) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
return UnAuthorized(RESTAPI::Errors::InvalidScriptSelection);
}
if(!Internal_ && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT && SCR.scriptId.empty()) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if (SCR.script.empty() && SCR.scriptId.empty() && !DiagnosticScript) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
return BadRequest(RESTAPI::Errors::InvalidScriptSelection);
}
if(DiagnosticScript && (!SCR.scriptId.empty() || !SCR.script.empty())){
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::InvalidScriptSelection);
return BadRequest(RESTAPI::Errors::InvalidScriptSelection);
}
if (SerialNumber_ != SCR.serialNumber) {
@@ -435,13 +471,48 @@ namespace OpenWifi {
return BadRequest(RESTAPI::Errors::SerialNumberMismatch);
}
if(!SCR.uri.empty() && !Utils::ValidateURI(SCR.uri)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
GWObjects::Device D;
if(!StorageService()->GetDevice(SerialNumber_,D)) {
return NotFound();
}
if(D.restrictedDevice && SCR.signature.empty()) {
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
if(!SCR.scriptId.empty()) {
GWObjects::ScriptEntry Existing;
if(!StorageService()->ScriptDB().GetRecord("id",SCR.scriptId,Existing)) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
// verify the role...
if(Existing.restricted.empty() && UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
if (std::find(Existing.restricted.begin(), Existing.restricted.end(),
SecurityObjects::UserTypeToString(UserInfo_.userinfo.userRole)) ==
end(Existing.restricted)) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC, RESTAPI::Errors::ACCESS_DENIED);
return UnAuthorized(RESTAPI::Errors::ACCESS_DENIED);
}
}
poco_information(Logger_,fmt::format("SCRIPT({},{}): TID={} Name={}", CMD_UUID, CMD_RPC, TransactionId_, Existing.name));
SCR.script = Existing.content;
SCR.type = Existing.type;
if(!ParsedBody_->has("deferred"))
SCR.deferred = Existing.deferred;
if(!ParsedBody_->has("timeout"))
SCR.timeout = Existing.timeout;
} else {
if(!DiagnosticScript && !ValidateScriptType(SCR.type)) {
CallCanceled("SCRIPT", CMD_UUID, CMD_RPC,RESTAPI::Errors::MissingOrInvalidParameters);
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
}
uint64_t ap_timeout = SCR.timeout==0 ? 30 : SCR.timeout;
@@ -469,8 +540,21 @@ namespace OpenWifi {
if(!SCR.signature.empty()) {
Params.set(uCentralProtocol::SIGNATURE, SCR.signature);
}
if(D.restrictedDevice && SCR.signature.empty()) {
SCR.signature = SignatureManager()->Sign(R, SCR.script);
}
if(D.restrictedDevice && SCR.signature.empty()) {
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
}
// convert script to base64 ...
auto EncodedScript = Utils::base64encode((const unsigned char *)SCR.script.c_str(),SCR.script.size());
Params.set(uCentralProtocol::TYPE, SCR.type);
Params.set(uCentralProtocol::SCRIPT, SCR.script);
if(!DiagnosticScript) {
Params.set(uCentralProtocol::SCRIPT, EncodedScript);
}
Params.set(uCentralProtocol::WHEN, SCR.when);
std::stringstream ParamStream;
@@ -478,10 +562,10 @@ namespace OpenWifi {
Cmd.Details = ParamStream.str();
FileUploader()->AddUUID(CMD_UUID, 15min, "script_result");
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::script,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
void RESTAPI_device_commandHandler::Configure(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::Configure(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("CONFIGURE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -526,14 +610,14 @@ namespace OpenWifi {
Cmd.Details = ParamStream.str();
// AP_WS_Server()->SetPendingUUID(SerialNumber_, NewUUID);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::configure,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::Upgrade(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("UPGRADE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -548,16 +632,11 @@ namespace OpenWifi {
}
GWObjects::Device DeviceInfo;
if(!StorageService()->GetDevice(SerialNumber_,DeviceInfo)) {
return NotFound();
}
std::string FWSignature = GetParameter("FWsignature","");
if(FWSignature.empty() && R.sysupgrade_not_allowed()) {
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
}
auto URI = GetS(RESTAPI::Protocol::URI, Obj);
auto When = GetWhen(Obj);
@@ -576,21 +655,32 @@ namespace OpenWifi {
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
Params.set(uCentralProtocol::URI, URI);
Params.set(uCentralProtocol::KEEP_REDIRECTOR, KeepRedirector ? 1 : 0);
if(!FWSignature.empty()) {
Params.set(uCentralProtocol::FWSIGNATURE, FWSignature);
if(DeviceInfo.restrictionDetails.upgrade && FWSignature.empty()) {
Poco::URI uri(URI);
FWSignature = SignatureManager()->Sign(DeviceInfo.restrictionDetails,uri);
}
if(FWSignature.empty() && DeviceInfo.restrictionDetails.upgrade) {
return BadRequest(RESTAPI::Errors::DeviceRequiresSignature);
}
if(!FWSignature.empty()) {
Params.set(uCentralProtocol::SIGNATURE, FWSignature);
}
Params.set(uCentralProtocol::WHEN, When);
std::stringstream ParamStream;
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd,Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::upgrade,true,Cmd,Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::Reboot(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("REBOOT({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -619,12 +709,12 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::reboot, false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingSerialNumber);
}
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::Factory(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("FACTORY-RESET({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -659,12 +749,12 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::factory,true,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::LEDs(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("LEDS({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -707,12 +797,12 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::leds,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::Trace(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("TRACE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -760,12 +850,12 @@ namespace OpenWifi {
Cmd.Details = ParamStream.str();
FileUploader()->AddUUID(CMD_UUID, 10min, "trace");
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::trace,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::WifiScan(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::WifiScan(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("WIFISCAN({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -795,7 +885,7 @@ namespace OpenWifi {
Params.set(uCentralProtocol::SERIAL, SerialNumber_);
if(R.dfs_not_allowed() && OverrideDFS) {
if(R.dfs && OverrideDFS) {
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
}
@@ -809,13 +899,13 @@ namespace OpenWifi {
std::stringstream ParamStream;
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::wifiscan,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
if (Cmd.ErrorCode == 0) {
KafkaManager()->PostMessage(KafkaTopics::WIFISCAN, SerialNumber_, Cmd.Results);
}
}
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::EventQueue(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("EVENT-QUEUE({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -844,7 +934,7 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::eventqueue,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_);
if(Cmd.ErrorCode==0) {
KafkaManager()->PostMessage(KafkaTopics::DEVICE_EVENT_QUEUE, SerialNumber_,
Cmd.Results);
@@ -854,7 +944,7 @@ namespace OpenWifi {
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::MakeRequest(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
void RESTAPI_device_commandHandler::MakeRequest(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("FORCE-REQUEST({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -891,15 +981,17 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_ );
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::request,false,Cmd, Params, *Request, *Response, timeout, nullptr, this, Logger_ );
}
BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R) {
#define DBGLINE { std::cout << __LINE__ << std::endl; }
void RESTAPI_device_commandHandler::Rtty(const std::string &CMD_UUID, uint64_t CMD_RPC, std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R) {
poco_information(Logger_,fmt::format("RTTY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
if(R.rtty_not_allowed()) {
if(R.rtty) {
return BadRequest(RESTAPI::Errors::DeviceIsRestricted);
}
@@ -907,14 +999,15 @@ namespace OpenWifi {
GWObjects::Device Device;
if (StorageService()->GetDevice(SerialNumber_, Device)) {
static std::uint64_t rtty_sid = 0;
rtty_sid += std::rand();
GWObjects::RttySessionDetails Rtty{
.SerialNumber = SerialNumber_,
.Server = MicroServiceConfigGetString("rtty.server", "localhost"),
.Port = MicroServiceConfigGetInt("rtty.port", 5912),
.Token = MicroServiceConfigGetString("rtty.token", "nothing"),
.TimeOut = MicroServiceConfigGetInt("rtty.timeout", 60),
.ConnectionId = Utils::ComputeHash(SerialNumber_,Utils::Now()).substr(0,RTTY_DEVICE_TOKEN_LENGTH),
.ConnectionId = Utils::ComputeHash(SerialNumber_,Utils::Now(),rtty_sid).substr(0,RTTY_DEVICE_TOKEN_LENGTH),
.Started = Utils::Now(),
.CommandUUID = CMD_UUID,
.ViewPort = MicroServiceConfigGetInt("rtty.viewport", 5913),
@@ -954,7 +1047,7 @@ namespace OpenWifi {
Params.stringify(ParamStream);
Cmd.Details = ParamStream.str();
poco_information(Logger_,fmt::format("RTTY: user={} serial={} rttyid={} token={} cmd={}.", Requester(), SerialNumber_, Rtty.ConnectionId, Rtty.Token, CMD_UUID));
return RESTAPI_RPC::WaitForCommand(CMD_RPC,false,Cmd, Params, *Request, *Response, timeout, &ReturnedObject, this, Logger_);
return RESTAPI_RPC::WaitForCommand(CMD_RPC, APCommands::Commands::rtty,false,Cmd, Params, *Request, *Response, timeout, &ReturnedObject, this, Logger_);
}
return NotFound();
}
@@ -962,9 +1055,7 @@ namespace OpenWifi {
return ReturnStatus(Poco::Net::HTTPResponse::HTTP_SERVICE_UNAVAILABLE);
}
// #define DBG { std::cout << __LINE__ << std::endl; }
void RESTAPI_device_commandHandler::Telemetry(const std::string &CMD_UUID, uint64_t CMD_RPC, [[maybe_unused]] std::chrono::milliseconds timeout, [[maybe_unused]] const AP_Restrictions &R){
void RESTAPI_device_commandHandler::Telemetry(const std::string &CMD_UUID, uint64_t CMD_RPC, [[maybe_unused]] std::chrono::milliseconds timeout, [[maybe_unused]] const GWObjects::DeviceRestrictions &R){
poco_information(Logger_,fmt::format("TELEMETRY({},{}): TID={} user={} serial={}", CMD_UUID, CMD_RPC, TransactionId_, Requester(), SerialNumber_));
const auto &Obj = ParsedBody_;
@@ -981,7 +1072,6 @@ namespace OpenWifi {
std::stringstream oooss;
Obj->stringify(oooss);
// std::cout << "Payload:" << oooss.str() << std::endl;
std::uint64_t Lifetime = 60 * 60 ; // 1 hour
std::uint64_t Interval = 5;

View File

@@ -9,7 +9,7 @@
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "AP_restrictions.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
namespace OpenWifi {
class RESTAPI_device_commandHandler : public RESTAPIHandler {
@@ -34,19 +34,19 @@ namespace OpenWifi {
void GetChecks();
void DeleteChecks();
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const AP_Restrictions &R);
void Configure(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Upgrade(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Reboot(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Factory(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void LEDs(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Trace(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void MakeRequest(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void WifiScan(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void EventQueue(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Rtty(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Telemetry(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Ping(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
void Script(const std::string &UUID, uint64_t RPC, std::chrono::milliseconds timeout, const GWObjects::DeviceRestrictions &R);
static auto PathName() { return std::list<std::string>{"/api/v1/device/{serialNumber}/{command}"}; };
void DoGet() final;

View File

@@ -32,9 +32,7 @@ namespace OpenWifi {
CompleteDeviceInfo(Device, Answer);
return ReturnObject(Answer);
} else {
Poco::JSON::Object Obj;
Device.to_json(Obj);
return ReturnObject(Obj);
return Object(Device);
}
}
NotFound();
@@ -139,9 +137,7 @@ namespace OpenWifi {
if (StorageService()->CreateDevice(Device)) {
SetCurrentConfigurationID(SerialNumber, Device.UUID);
Poco::JSON::Object DevObj;
Device.to_json(DevObj);
return ReturnObject(DevObj);
return Object(Device);
}
InternalError(RESTAPI::Errors::RecordNotCreated);
}
@@ -191,9 +187,9 @@ namespace OpenWifi {
Existing.LastConfigurationChange = Utils::Now();
if (StorageService()->UpdateDevice(Existing)) {
SetCurrentConfigurationID(SerialNumber, Existing.UUID);
Poco::JSON::Object DevObj;
NewDevice.to_json(DevObj);
return ReturnObject(DevObj);
GWObjects::Device UpdatedDevice;
StorageService()->GetDevice(SerialNumber, UpdatedDevice);
return Object(UpdatedDevice);
}
InternalError(RESTAPI::Errors::RecordNotUpdated);
}

View File

@@ -25,7 +25,12 @@ namespace OpenWifi {
if (!StorageService()->GetAttachedFileContent(UUID, SerialNumber, FileContent, FileType)) {
return NotFound();
}
SendFileContent(FileContent,"pcap",UUID+".pcap");
if(FileType=="pcap")
SendFileContent(FileContent,"application/vnd.tcpdump.pcap",UUID+".pcap");
else if(FileType=="gzip")
SendFileContent(FileContent,"application/gzip",UUID+".tar.gz");
else
SendFileContent(FileContent,"application/txt",UUID+".txt");
}
void RESTAPI_file::DoDelete() {

View File

@@ -14,9 +14,7 @@ namespace OpenWifi {
Poco::Thread::current()->id()));
GWObjects::RadiusProxyPoolList C;
RADIUS_proxy_server()->GetConfig(C);
Poco::JSON::Object Answer;
C.to_json(Answer);
return ReturnObject(Answer);
return Object(C);
}
void RESTAPI_radiusProxyConfig_handler::DoDelete() {
@@ -77,7 +75,7 @@ namespace OpenWifi {
TransactionId_, Requester(),
Poco::Thread::current()->id()));
RADIUS_proxy_server()->SetConfig(C);
return ReturnObject(*ParsedBody_);
return Object(C);
}
}

View File

@@ -18,6 +18,8 @@
#include "RESTAPI/RESTAPI_telemetryWebSocket.h"
#include "RESTAPI/RESTAPI_iptocountry_handler.h"
#include "RESTAPI/RESTAPI_radiusProxyConfig_handler.h"
#include "RESTAPI/RESTAPI_script_handler.h"
#include "RESTAPI/RESTAPI_scripts_handler.h"
#include "framework/RESTAPI_SystemCommand.h"
#include "framework/RESTAPI_WebSocketServer.h"
@@ -46,6 +48,8 @@ namespace OpenWifi {
RESTAPI_blacklist_list,
RESTAPI_iptocountry_handler,
RESTAPI_radiusProxyConfig_handler,
RESTAPI_scripts_handler,
RESTAPI_script_handler,
RESTAPI_capabilities_handler, RESTAPI_telemetryWebSocket>(Path,Bindings,L, S, TransactionId);
}
@@ -65,6 +69,8 @@ namespace OpenWifi {
RESTAPI_blacklist,
RESTAPI_iptocountry_handler,
RESTAPI_radiusProxyConfig_handler,
RESTAPI_scripts_handler,
RESTAPI_script_handler,
RESTAPI_blacklist_list>(Path,Bindings,L, S, TransactionId);
}
}

View File

@@ -0,0 +1,160 @@
//
// Created by stephane bourque on 2022-11-21.
//
#include "RESTAPI_script_handler.h"
namespace OpenWifi {
void RESTAPI_script_handler::DoGet() {
std::string UUID = GetBinding("uuid","");
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::ScriptEntry SE;
if(DB_.GetRecord("id",UUID, SE)) {
return Object(SE);
}
return NotFound();
}
void RESTAPI_script_handler::DoDelete() {
std::string UUID = GetBinding("uuid","");
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
}
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(DB_.DeleteRecord("id",UUID)) {
return OK();
}
return NotFound();
}
void RESTAPI_script_handler::DoPost() {
std::string UUID = GetBinding("uuid","");
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
}
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::ScriptEntry SE;
if(!SE.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if( SE.name.empty() ||
SE.author.empty() ||
(SE.type!="bundle" && SE.type!="shell") ||
SE.content.empty() ||
SE.version.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!SE.restricted.empty()) {
for(const auto &role:SE.restricted) {
if(SecurityObjects::UserTypeFromString(role)==SecurityObjects::UNKNOWN) {
return BadRequest(RESTAPI::Errors::InvalidUserRole);
}
}
std::sort(SE.restricted.begin(),SE.restricted.end());
}
if(!SE.uri.empty() && !Utils::ValidateURI(SE.uri)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
if(!SE.defaultUploadURI.empty() && !Utils::ValidateURI(SE.defaultUploadURI)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
SE.id = MicroServiceCreateUUID();
SE.created = SE.modified = Utils::Now();
if(DB_.CreateRecord(SE)) {
return Object(SE);
}
return BadRequest(RESTAPI::Errors::RecordNotCreated);
}
void RESTAPI_script_handler::DoPut() {
std::string UUID = GetBinding("uuid","");
if(UserInfo_.userinfo.userRole!=SecurityObjects::ROOT) {
return BadRequest(RESTAPI::Errors::ACCESS_DENIED);
}
if(UUID.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
GWObjects::ScriptEntry SE;
if(!SE.from_json(ParsedBody_)) {
return BadRequest(RESTAPI::Errors::InvalidJSONDocument);
}
if(!SE.restricted.empty()) {
for(const auto &role:SE.restricted) {
if(SecurityObjects::UserTypeFromString(role)==SecurityObjects::UNKNOWN) {
return BadRequest(RESTAPI::Errors::InvalidUserRole);
}
}
std::sort(SE.restricted.begin(),SE.restricted.end());
}
GWObjects::ScriptEntry Existing;
if(!DB_.GetRecord("id", UUID, Existing)) {
return NotFound();
}
if(ParsedBody_->has("name") && SE.name.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(ParsedBody_->has("content") && SE.content.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(ParsedBody_->has("version") && SE.version.empty()) {
return BadRequest(RESTAPI::Errors::MissingOrInvalidParameters);
}
if(!SE.uri.empty() && !Utils::ValidateURI(SE.uri)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
if(!SE.defaultUploadURI.empty() && !Utils::ValidateURI(SE.defaultUploadURI)) {
return BadRequest(RESTAPI::Errors::InvalidURI);
}
if(ParsedBody_->has("restricted")) {
Existing.restricted = SE.restricted;
}
AssignIfPresent(ParsedBody_, "name", Existing.name);
AssignIfPresent(ParsedBody_, "description", Existing.description);
AssignIfPresent(ParsedBody_, "uri", Existing.uri);
AssignIfPresent(ParsedBody_, "content", Existing.content);
AssignIfPresent(ParsedBody_, "version", Existing.version);
AssignIfPresent(ParsedBody_, "deferred", Existing.deferred);
AssignIfPresent(ParsedBody_, "timeout", Existing.timeout);
AssignIfPresent(ParsedBody_, "defaultUploadURI", Existing.defaultUploadURI);
Existing.modified = Utils::Now();
if(DB_.UpdateRecord("id", UUID, Existing)) {
return Object(Existing);
}
return BadRequest(RESTAPI::Errors::RecordNotUpdated);
}
} // namespace OpenWifi

View File

@@ -0,0 +1,31 @@
//
// Created by stephane bourque on 2022-11-21.
//
#pragma once
#include "framework/RESTAPI_Handler.h"
#include "StorageService.h"
namespace OpenWifi {
class RESTAPI_script_handler : public RESTAPIHandler {
public:
RESTAPI_script_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_PUT,
Poco::Net::HTTPRequest::HTTP_POST,
Poco::Net::HTTPRequest::HTTP_DELETE,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal){};
static auto PathName() { return std::list<std::string>{"/api/v1/script/{uuid}"}; };
private:
ScriptDB & DB_{ StorageService()->ScriptDB() };
void DoGet() final;
void DoDelete() final;
void DoPost() final;
void DoPut() final;
};
}

View File

@@ -0,0 +1,20 @@
//
// Created by stephane bourque on 2022-11-21.
//
#include "RESTAPI_scripts_handler.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "StorageService.h"
namespace OpenWifi {
void RESTAPI_scripts_handler::DoGet() {
GWObjects::ScriptEntryList L;
StorageService()->ScriptDB().GetRecords(QB_.Offset,QB_.Limit,L.scripts);
Poco::JSON::Object Answer;
L.to_json(Answer);
return ReturnObject(Answer);
}
} // namespace OpenWifi

View File

@@ -0,0 +1,25 @@
//
// Created by stephane bourque on 2022-11-21.
//
#pragma once
#include "framework/RESTAPI_Handler.h"
namespace OpenWifi {
class RESTAPI_scripts_handler : public RESTAPIHandler {
public:
RESTAPI_scripts_handler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
bool Internal)
: RESTAPIHandler(bindings, L,
std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_GET,
Poco::Net::HTTPRequest::HTTP_OPTIONS},
Server, TransactionId, Internal){};
static auto PathName() { return std::list<std::string>{"/api/v1/scripts"}; };
void DoGet() final;
void DoDelete() final{};
void DoPost() final{};
void DoPut() final{};
};
}

View File

@@ -51,7 +51,9 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"locale", locale);
field_to_json(Obj,"restrictedDevice", restrictedDevice);
field_to_json(Obj,"pendingConfiguration", pendingConfiguration);
field_to_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd);
field_to_json(Obj,"restrictionDetails", restrictionDetails);
}
void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
@@ -93,6 +95,9 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"entity", entity);
field_from_json(Obj,"locale", locale);
field_from_json(Obj,"restrictedDevice", restrictedDevice);
field_from_json(Obj,"pendingConfiguration", pendingConfiguration);
field_from_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd);
field_from_json(Obj,"restrictionDetails", restrictionDetails);
return true;
} catch (const Poco::Exception &E) {
}
@@ -304,6 +309,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"serialNumber",serialNumber);
field_to_json(Obj,"timeout",timeout);
field_to_json(Obj,"type",type);
field_to_json(Obj,"scriptId",scriptId);
field_to_json(Obj,"script",script);
field_to_json(Obj,"when",when);
field_to_json(Obj,"signature", signature);
@@ -317,6 +323,7 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"timeout",timeout);
field_from_json(Obj,"type",type);
field_from_json(Obj,"script",script);
field_from_json(Obj,"scriptId",scriptId);
field_from_json(Obj,"when",when);
field_from_json(Obj,"signature", signature);
field_from_json(Obj,"deferred", deferred);
@@ -392,6 +399,7 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"secret",secret);
field_to_json(Obj,"certificate",certificate);
field_to_json(Obj,"radsec",radsec);
field_to_json(Obj,"allowSelfSigned",allowSelfSigned);
field_to_json(Obj,"radsecPort",radsecPort);
field_to_json(Obj,"radsecSecret",radsecSecret);
field_to_json(Obj,"radsecCacerts",radsecCacerts);
@@ -410,6 +418,7 @@ namespace OpenWifi::GWObjects {
field_from_json(Obj,"secret",secret);
field_from_json(Obj,"certificate",certificate);
field_from_json(Obj,"radsec",radsec);
field_from_json(Obj,"allowSelfSigned",allowSelfSigned);
field_from_json(Obj,"radsecSecret",radsecSecret);
field_from_json(Obj,"radsecPort",radsecPort);
field_from_json(Obj,"radsecCacerts",radsecCacerts);
@@ -422,5 +431,117 @@ namespace OpenWifi::GWObjects {
}
return false;
}
void ScriptEntry::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"id", id);
field_to_json(Obj,"name", name);
field_to_json(Obj,"description", description);
field_to_json(Obj,"uri", uri);
field_to_json(Obj,"content", content);
field_to_json(Obj,"version", version);
field_to_json(Obj,"type", type);
field_to_json(Obj,"created", created);
field_to_json(Obj,"modified", modified);
field_to_json(Obj,"author", author);
field_to_json(Obj,"restricted", restricted);
field_to_json(Obj,"deferred", deferred);
field_to_json(Obj,"timeout", timeout);
field_to_json(Obj,"defaultUploadURI", defaultUploadURI);
}
bool ScriptEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"id", id);
field_from_json(Obj,"name", name);
field_from_json(Obj,"description", description);
field_from_json(Obj,"uri", uri);
field_from_json(Obj,"content", content);
field_from_json(Obj,"version", version);
field_from_json(Obj,"type", type);
field_from_json(Obj,"created", created);
field_from_json(Obj,"modified", modified);
field_from_json(Obj,"author", author);
field_from_json(Obj,"restricted", restricted);
field_from_json(Obj,"deferred", deferred);
field_from_json(Obj,"timeout", timeout);
field_from_json(Obj,"defaultUploadURI", defaultUploadURI);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void ScriptEntryList::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"scripts",scripts);
}
bool ScriptEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"scripts",scripts);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"vendor", vendor);
field_to_json(Obj,"algo", algo);
}
bool DeviceRestrictionsKeyInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"vendor", vendor);
field_from_json(Obj,"algo", algo);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
void DeviceRestrictions::to_json(Poco::JSON::Object &Obj) const {
field_to_json(Obj,"dfs", dfs);
field_to_json(Obj,"ssh", ssh);
field_to_json(Obj,"rtty", rtty);
field_to_json(Obj,"tty", tty);
field_to_json(Obj,"developer", developer);
field_to_json(Obj,"upgrade", upgrade);
field_to_json(Obj,"commands", commands);
field_to_json(Obj,"country", country);
field_to_json(Obj,"key_info", key_info);
}
bool DeviceRestrictions::from_json(const Poco::JSON::Object::Ptr &Obj) {
try {
field_from_json(Obj,"dfs", dfs);
field_from_json(Obj,"ssh", ssh);
field_from_json(Obj,"rtty", rtty);
field_from_json(Obj,"tty", tty);
field_from_json(Obj,"developer", developer);
field_from_json(Obj,"upgrade", upgrade);
field_from_json(Obj,"commands", commands);
field_from_json(Obj,"country", country);
field_from_json(Obj,"key_info", key_info);
return true;
} catch (const Poco::Exception &E) {
}
return false;
}
bool DeviceRestrictionsKeyInfo::operator!=(const OpenWifi::GWObjects::DeviceRestrictionsKeyInfo &T) const {
return (T.algo!=algo) || (T.vendor!=vendor);
}
bool DeviceRestrictions::operator!=(const OpenWifi::GWObjects::DeviceRestrictions &T) const {
return ( (T.dfs!=dfs) ||
(T.rtty!=rtty) ||
(T.upgrade!=upgrade) ||
(T.commands != commands) ||
(T.developer != developer) ||
(T.ssh !=ssh) ||
(T.key_info != key_info) ||
(T.country != country) );
}
}

View File

@@ -47,6 +47,33 @@ namespace OpenWifi::GWObjects {
void to_json(Poco::JSON::Object &Obj) const;
};
struct DeviceRestrictionsKeyInfo {
std::string vendor;
std::string algo;
bool operator !=(const DeviceRestrictionsKeyInfo &b) const;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct DeviceRestrictions {
bool dfs = false;
bool ssh = false;
bool rtty = false;
bool tty = false;
bool developer = false;
bool upgrade = false;
bool commands = false;
std::vector<std::string> country;
DeviceRestrictionsKeyInfo key_info;
bool operator !=(const DeviceRestrictions &D) const;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct Device {
std::string SerialNumber;
std::string DeviceType;
@@ -71,6 +98,9 @@ namespace OpenWifi::GWObjects {
uint64_t modified=0;
std::string locale;
bool restrictedDevice=false;
std::string pendingConfiguration;
std::string pendingConfigurationCmd;
DeviceRestrictions restrictionDetails;
void to_json(Poco::JSON::Object &Obj) const;
void to_json_with_status(Poco::JSON::Object &Obj) const;
@@ -216,11 +246,39 @@ namespace OpenWifi::GWObjects {
void to_json(Poco::JSON::Object &Obj) const;
};
struct ScriptEntry {
std::string id;
std::string name;
std::string description;
std::string uri;
std::string content;
std::string version;
std::string type;
std::uint64_t created;
std::uint64_t modified;
std::string author;
Types::StringVec restricted;
bool deferred=false;
std::uint64_t timeout=30;
std::string defaultUploadURI;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ScriptEntryList {
std::vector<ScriptEntry> scripts;
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
struct ScriptRequest {
std::string serialNumber;
uint64_t timeout=30;
std::string type;
std::string script;
std::string scriptId;
std::uint64_t when;
std::string signature;
bool deferred;
@@ -238,6 +296,7 @@ namespace OpenWifi::GWObjects {
std::string secret;
std::string certificate;
bool radsec=false;
bool allowSelfSigned=false;
uint16_t radsecPort=2083;
std::string radsecSecret;
std::string radsecKey;
@@ -279,4 +338,5 @@ namespace OpenWifi::GWObjects {
void to_json(Poco::JSON::Object &Obj) const;
bool from_json(const Poco::JSON::Object::Ptr &Obj);
};
}

23
src/ScriptManager.cpp Normal file
View File

@@ -0,0 +1,23 @@
//
// Created by stephane bourque on 2022-11-21.
//
#include "ScriptManager.h"
#include "framework/MicroServiceFuncs.h"
#include <fstream>
#include "Poco/JSON/Parser.h"
namespace OpenWifi {
int ScriptManager::Start() {
poco_notice(Logger(),"Starting...");
ScriptDir_ = MicroServiceConfigPath("script.manager.directory", MicroServiceDataDirectory() + "/included_scripts" );
return 0;
}
void ScriptManager::Stop() {
poco_notice(Logger(),"Stopping...");
poco_notice(Logger(),"Stopped...");
}
} // namespace OpenWifi

34
src/ScriptManager.h Normal file
View File

@@ -0,0 +1,34 @@
//
// Created by stephane bourque on 2022-11-21.
//
#pragma once
#include "framework/SubSystemServer.h"
namespace OpenWifi {
class ScriptManager : public SubSystemServer {
public:
static auto instance() {
auto static instance_ = new ScriptManager;
return instance_;
}
int Start();
void Stop();
private:
std::string ScriptDir_;
explicit ScriptManager() noexcept:
SubSystemServer("ScriptManager", "SCRIPT-MGR", "script.manager")
{
}
};
inline auto ScriptManager() { return ScriptManager::instance(); }
} // namespace OpenWifi

7
src/SignatureMgr.cpp Normal file
View File

@@ -0,0 +1,7 @@
//
// Created by stephane bourque on 2022-11-22.
//
#include "SignatureMgr.h"
namespace OpenWifi {} // namespace OpenWifi

176
src/SignatureMgr.h Normal file
View File

@@ -0,0 +1,176 @@
//
// Created by stephane bourque on 2022-11-22.
//
#pragma once
#include <fstream>
#include <shared_mutex>
#include "framework/SubSystemServer.h"
#include "framework/MicroServiceFuncs.h"
#include "framework/utils.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "Poco/DigestStream.h"
#include "Poco/DigestEngine.h"
#include "Poco/Crypto/RSADigestEngine.h"
#include "Poco/StreamCopier.h"
#include "Poco/File.h"
#include "Poco/StringTokenizer.h"
#include "Poco/TemporaryFile.h"
#include "fmt/format.h"
namespace OpenWifi {
class SignatureManager : public SubSystemServer {
public:
inline static auto instance() {
static auto instance_ = new SignatureManager;
return instance_;
}
struct SignatureCacheEntry {
std::string vendor_uri_hash;
std::string signature;
};
inline int Start() final {
poco_notice(Logger(),"Starting...");
std::shared_lock L(KeyMutex_);
CacheFilename_ = MicroServiceDataDirectory() + "/signature_cache";
Poco::File CacheFile(CacheFilename_);
if(CacheFile.exists()) {
std::fstream CacheFileContent(CacheFilename_, std::ios_base::in);
std::string line;
while(std::getline(CacheFileContent, line)) {
auto Tokens = Poco::StringTokenizer(line,":");
if(Tokens.count()==2) {
SignatureCache_[Tokens[0]] = Tokens[1];
}
}
}
poco_information(Logger(),fmt::format("Found {} entries in signature cache.", SignatureCache_.size()));
// read all the key vendors.
// signature.manager.0.key.public
// signature.manager.0.key.private
// signature.manager.0.vendor
int i=0;
while(true) {
auto Vendor = MicroServiceConfigGetString("signature.manager." + std::to_string(i) + ".vendor","");
auto PrivateKey = MicroServiceConfigPath("signature.manager." + std::to_string(i) + ".key.private","");
auto PublicKey = MicroServiceConfigPath("signature.manager." + std::to_string(i) + ".key.public","");
if(Vendor.empty() || PrivateKey.empty() || PublicKey.empty()) {
break;
}
Poco::File PubKey(PublicKey), PrivKey(PrivateKey);
if(PubKey.exists() && PrivKey.exists()) {
Keys_[Vendor] = Poco::SharedPtr<Poco::Crypto::RSAKey>(
new Poco::Crypto::RSAKey(PublicKey, PrivateKey, ""));
}
++i;
}
poco_information(Logger(),fmt::format("{} signatures in dictionary.", Keys_.size()));
return 0;
}
inline void Stop() final {
poco_notice(Logger(),"Stopping...");
poco_notice(Logger(),"Stopped...");
}
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions, const std::string &Data) const {
std::shared_lock L(KeyMutex_);
try {
if (Restrictions.key_info.algo == "static") {
return "aaaaaaaaaa";
}
auto Vendor = Keys_.find(Restrictions.key_info.vendor);
if (Vendor == Keys_.end()) {
poco_error( Logger(), fmt::format("{}: vendor unknown.", Vendor->first));
return "";
}
if (Restrictions.key_info.algo == "dgst-sha256") {
Poco::Crypto::RSADigestEngine R(*Vendor->second, "SHA256");
Poco::DigestOutputStream ostr(R);
ostr << Data;
ostr.flush();
auto Signature = Utils::base64encode(
(const unsigned char *)R.signature().data(), R.signature().size());
return Signature;
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return "";
}
inline std::string Sign(const GWObjects::DeviceRestrictions &Restrictions, const Poco::URI &uri) {
std::shared_lock L(KeyMutex_);
try {
if (Restrictions.key_info.algo == "static") {
return "aaaaaaaaaa";
}
auto Vendor = Keys_.find(Restrictions.key_info.vendor);
if (Vendor == Keys_.end()) {
poco_error( Logger(), fmt::format("{}: vendor unknown.", Restrictions.key_info.vendor));
return "";
}
if (Restrictions.key_info.algo == "dgst-sha256") {
auto FileHash =
Utils::ComputeHash(Restrictions.key_info.vendor, Restrictions.key_info.algo, uri.getPathAndQuery());
auto CacheEntry = SignatureCache_.find(FileHash);
if (CacheEntry != end(SignatureCache_)) {
return CacheEntry->second;
}
Poco::TemporaryFile TempDownloadedFile;
if (Utils::wgetfile(uri, TempDownloadedFile.path())) {
Poco::Crypto::RSADigestEngine R(*Vendor->second, "SHA256");
Poco::DigestOutputStream ofs(R);
std::fstream ifs(TempDownloadedFile.path(),
std::ios_base::in | std::ios_base::binary);
Poco::StreamCopier::copyStream(ifs, ofs);
ofs.flush();
auto Signature = Utils::base64encode((const unsigned char *)R.signature().data(),R.signature().size());
SignatureCache_[FileHash] = Signature;
SaveCache();
return Signature;
}
}
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return "";
}
void SaveCache() {
std::ofstream ofs(CacheFilename_, std::ios_base::trunc | std::ios_base::out);
for(const auto &[hash,signature]:SignatureCache_) {
ofs << hash << ":" << signature << std::endl;
}
}
private:
mutable std::shared_mutex KeyMutex_;
std::map<std::string, Poco::SharedPtr<Poco::Crypto::RSAKey>> Keys_;
std::map<std::string,std::string> SignatureCache_;
std::string CacheFilename_;
explicit SignatureManager() noexcept
: SubSystemServer("SignatureManager", "SIGNATURE-MGR", "signature.manager") {}
};
inline auto SignatureManager() { return SignatureManager::instance(); }
}

View File

@@ -12,7 +12,14 @@ namespace OpenWifi::StateUtils {
return 5;
}
bool ComputeAssociations(const Poco::JSON::Object::Ptr & RawObject,
static int BandToInt(const std::string &band) {
if(band=="2G") return 2;
if(band=="5G") return 5;
if(band=="6G") return 6;
return 2;
}
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject,
uint64_t &Radios_2G,
uint64_t &Radios_5G, uint64_t &Radios_6G) {
Radios_2G = 0 ;
@@ -24,47 +31,56 @@ namespace OpenWifi::StateUtils {
// map of phy to 2g/5g
std::map<std::string,int> RadioPHYs;
// parse radios and get the phy out with the band
bool UseBandInfo = false;
for(auto const &i:*RA) {
Poco::JSON::Parser p2;
// Poco::JSON::Parser p2;
auto RadioObj = i.extract<Poco::JSON::Object::Ptr>();
if(RadioObj->has("phy") && RadioObj->has("channel")) {
if(RadioObj->has("band")) {
// std::cout << "Use band info" << std::endl;
UseBandInfo = true ;
} else if(RadioObj->has("phy") && RadioObj->has("channel")) {
if(RadioObj->isArray("channel")) {
auto ChannelArray = RadioObj->getArray("channel");
if(ChannelArray->size()) {
RadioPHYs[RadioObj->get("phy").toString()] =
RadioPHYs[RadioObj->get("phy")] =
ChannelToBand( ChannelArray->getElement<uint64_t>(0) );
}
} else {
RadioPHYs[RadioObj->get("phy").toString()] =
RadioPHYs[RadioObj->get("phy")] =
ChannelToBand(RadioObj->get("channel"));
}
}
}
auto IA = RawObject->getArray("interfaces");
for(auto const &i:*IA) {
auto InterfaceObj = i.extract<Poco::JSON::Object::Ptr>();
auto InterfaceArray = RawObject->getArray("interfaces");
for(auto const &interface:*InterfaceArray) {
auto InterfaceObj = interface.extract<Poco::JSON::Object::Ptr>();
if(InterfaceObj->isArray("ssids")) {
auto SSIDA = InterfaceObj->getArray("ssids");
for(const auto &s:*SSIDA) {
auto SSIDinfo = s.extract<Poco::JSON::Object::Ptr>();
if(SSIDinfo->isArray("associations") && SSIDinfo->has("phy")) {
auto PHY = SSIDinfo->get("phy").toString();
auto SSIDArray = InterfaceObj->getArray("ssids");
for(const auto &ssid:*SSIDArray) {
auto SSID_info = ssid.extract<Poco::JSON::Object::Ptr>();
if(SSID_info->isArray("associations") && SSID_info->has("phy")) {
int Radio = 2;
auto Rit = RadioPHYs.find(PHY);
if(Rit!=RadioPHYs.end())
Radio = Rit->second;
auto AssocA = SSIDinfo->getArray("associations");
if(Radio==2) {
Radios_2G += AssocA->size();
if(UseBandInfo) {
Radio = BandToInt(SSID_info->get("band"));
} else {
auto PHY = SSID_info->get("phy");
auto Rit = RadioPHYs.find(PHY);
if (Rit != RadioPHYs.end())
Radio = Rit->second;
}
else {
Radios_5G += AssocA->size();
auto AssocA = SSID_info->getArray("associations");
switch(Radio) {
case 2: Radios_2G += AssocA->size(); break;
case 5: Radios_5G += AssocA->size(); break;
case 6: Radios_6G += AssocA->size(); break;
default: Radios_2G += AssocA->size(); break;
}
}
}
}
}
// std::cout << Radios_2G << " " << Radios_5G << " " << Radios_6G << std::endl;
return true;
}
return false;

View File

@@ -7,6 +7,6 @@
#include "Poco/JSON/Object.h"
namespace OpenWifi::StateUtils {
bool ComputeAssociations(const Poco::JSON::Object::Ptr & RawObject, uint64_t &Radios_2G,
bool ComputeAssociations(const Poco::JSON::Object::Ptr RawObject, uint64_t &Radios_2G,
uint64_t &Radios_5G, uint64_t &Radio_6G);
}

View File

@@ -18,36 +18,40 @@ namespace OpenWifi {
void Archiver::onTimer([[maybe_unused]] Poco::Timer &timer){
Utils::SetThreadName("strg-archiver");
auto now = Utils::Now();
for(const auto &i:DBs_) {
if (!Poco::icompare(i.DBName, "healthchecks")) {
for(const auto &[DBName, Keep]:DBs_) {
if (!Poco::icompare(DBName, "healthchecks")) {
poco_information(Logger(),"Archiving HealthChecks...");
StorageService()->RemoveHealthChecksRecordsOlderThan(
now - (i.HowManyDays * 24 * 60 * 60));
} else if (!Poco::icompare(i.DBName, "statistics")) {
now - (Keep * 24 * 60 * 60));
} else if (!Poco::icompare(DBName, "statistics")) {
poco_information(Logger(),"Archiving Statistics...");
StorageService()->RemoveStatisticsRecordsOlderThan(
now - (i.HowManyDays * 24 * 60 * 60));
} else if (!Poco::icompare(i.DBName, "devicelogs")) {
now - (Keep * 24 * 60 * 60));
} else if (!Poco::icompare(DBName, "devicelogs")) {
poco_information(Logger(),"Archiving Device Logs...");
StorageService()->RemoveDeviceLogsRecordsOlderThan(
now - (i.HowManyDays * 24 * 60 * 60));
} else if (!Poco::icompare(i.DBName, "commandlist")) {
now - (Keep * 24 * 60 * 60));
} else if (!Poco::icompare(DBName, "commandlist")) {
poco_information(Logger(),"Archiving Command History...");
StorageService()->RemoveCommandListRecordsOlderThan(
now - (i.HowManyDays * 24 * 60 * 60));
now - (Keep * 24 * 60 * 60));
} else if (!Poco::icompare(DBName, "fileuploads")) {
poco_information(Logger(),"Archiving Upload files...");
StorageService()->RemoveUploadedFilesRecordsOlderThan(
now - (Keep * 24 * 60 * 60));
} else {
poco_information(Logger(),fmt::format("Cannot archive DB '{}'", i.DBName));
poco_information(Logger(),fmt::format("Cannot archive DB '{}'", DBName));
}
}
AppServiceRegistry().Set("lastStorageArchiverRun", (uint64_t) now);
}
static auto CalculateDelta(int H, int M) {
static auto CalculateDelta(std::uint64_t H, std::uint64_t M) {
Poco::LocalDateTime dt;
Poco::LocalDateTime scheduled(dt.year(), dt.month(), dt.day(), H, M, 0);
Poco::LocalDateTime scheduled(dt.year(), dt.month(), dt.day(), (int)H, (int)M, 0);
size_t delta = 0;
if ((dt.hour() < H) || (dt.hour()==H && dt.minute()<M)) {
std::uint64_t delta = 0;
if ((dt.hour() < (int)H) || (dt.hour()==(int)H && dt.minute()<(int)M)) {
delta = scheduled.timestamp().epochTime() - dt.timestamp().epochTime();
} else {
delta = (24*60*60) - (dt.timestamp().epochTime() - scheduled.timestamp().epochTime());
@@ -69,13 +73,13 @@ namespace OpenWifi {
auto Schedule = MicroServiceConfigGetString("archiver.schedule","03:00");
auto S = Poco::StringTokenizer(Schedule,":");
int RunAtHour_, RunAtMin_;
std::uint64_t RunAtHour_, RunAtMin_;
if(S.count()!=2) {
RunAtHour_ = 3 ;
RunAtMin_ = 0;
} else {
RunAtHour_ = std::atoi(S[0].c_str());
RunAtMin_ = std::atoi(S[1].c_str());
RunAtHour_ = std::strtoull(S[0].c_str(), nullptr, 10);
RunAtMin_ = std::strtoull(S[1].c_str(), nullptr, 10);
}
for(int i=0;i<20;i++) {
@@ -86,10 +90,7 @@ namespace OpenWifi {
if(Poco::icompare(DBName,DB)==0) {
std::string Key = "archiver.db." + std::to_string(i) + ".keep";
auto Keep = MicroServiceConfigGetInt(Key,7);
Archiver_->AddDb(Archiver::ArchiverDBEntry{
.DBName = DB,
.HowManyDays = Keep
});
Archiver_->AddDb(DB, Keep);
}
}
}

View File

@@ -13,28 +13,26 @@
namespace OpenWifi {
static const std::list<std::string> AllInternalDBNames{"healthchecks", "statistics", "devicelogs" , "commandlist" };
static const std::list<std::string> AllInternalDBNames{"healthchecks", "statistics", "devicelogs" , "commandlist", "fileuploads"};
class Archiver {
public:
struct ArchiverDBEntry {
std::string DBName;
uint64_t HowManyDays=7;
};
typedef std::vector<ArchiverDBEntry> ArchiverDBEntryVec;
explicit Archiver(Poco::Logger &Logger):
Logger_(Logger) {
for(const auto &db:AllInternalDBNames) {
DBs_[db] = 7 ;
}
}
void onTimer(Poco::Timer & timer);
inline void AddDb(const ArchiverDBEntry &E ) {
DBs_.push_back(E);
inline void AddDb(const std::string &dbname, std::uint64_t retain) {
DBs_[dbname] = retain;
}
inline Poco::Logger & Logger() { return Logger_; }
private:
Poco::Logger &Logger_;
ArchiverDBEntryVec DBs_;
Poco::Logger &Logger_;
std::map<std::string,std::uint64_t> DBs_;
};
class StorageArchiver : public SubSystemServer {

View File

@@ -17,6 +17,10 @@ namespace OpenWifi {
Create_Tables();
InitializeBlackListCache();
ScriptDB_ = std::make_unique<OpenWifi::ScriptDB>("Scripts", "scr", dbType_,*Pool_, Logger());
ScriptDB_->Create();
ScriptDB_->Initialize();
return 0;
}

View File

@@ -12,6 +12,7 @@
#include "RESTObjects//RESTAPI_GWobjects.h"
#include "Poco/Net/IPAddress.h"
#include "CentralConfig.h"
#include "storage/storage_scripts.h"
namespace OpenWifi {
@@ -29,6 +30,8 @@ namespace OpenWifi {
COMMAND_EXECUTING
};
inline OpenWifi::ScriptDB & ScriptDB() { return *ScriptDB_; }
inline std::string to_string(const CommandExecutionType &C) {
switch(C) {
case CommandExecutionType::COMMAND_PENDING: return "pending";
@@ -147,10 +150,8 @@ namespace OpenWifi {
bool GetReadyToExecuteCommands( uint64_t Offset, uint64_t HowMany, std::vector<GWObjects::CommandDetails> & Commands );
bool CommandExecuted(std::string & UUID);
bool CommandCompleted(std::string & UUID, Poco::JSON::Object::Ptr ReturnVars, const std::chrono::duration<double, std::milli> & execution_time, bool FullCommand);
// bool AttachFileToCommand(std::string & UUID);
bool AttachFileDataToCommand(std::string & UUID, const std::stringstream &s, const std::string &Type);
bool CancelWaitFile( std::string & UUID, std::string & ErrorText );
// bool GetAttachedFile(std::string & UUID, const std::string & SerialNumber, const std::string & FileName, std::string &Type);
bool GetAttachedFileContent(std::string & UUID, const std::string & SerialNumber, std::string & FileContent, std::string &Type);
bool RemoveAttachedFile(std::string & UUID);
bool SetCommandResult(std::string & UUID, std::string & Result);
@@ -177,6 +178,7 @@ namespace OpenWifi {
bool RemoveDeviceLogsRecordsOlderThan(uint64_t Date);
bool RemoveStatisticsRecordsOlderThan(uint64_t Date);
bool RemoveCommandListRecordsOlderThan(uint64_t Date);
bool RemoveUploadedFilesRecordsOlderThan(uint64_t Date);
int Create_Tables();
int Create_Statistics();
@@ -197,6 +199,8 @@ namespace OpenWifi {
private:
std::unique_ptr<OpenWifi::ScriptDB> ScriptDB_;
};
inline auto StorageService() { return Storage::instance(); }

View File

@@ -51,7 +51,13 @@ namespace OpenWifi {
poco_information(Logger(),"Starting...");
Running_=true;
Port_ = (int)MicroServiceConfigGetInt("alb.port",15015);
Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_);
Poco::Net::IPAddress Addr(Poco::Net::IPAddress::wildcard(
Poco::Net::Socket::supportsIPv6() ? Poco::Net::AddressFamily::IPv6
: Poco::Net::AddressFamily::IPv4));
Poco::Net::SocketAddress SockAddr(Addr, Port_);
Poco::Net::ServerSocket ClientSocket(SockAddr, 64);
Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_);
auto Params = new Poco::Net::HTTPServerParams;
Params->setName("ws:alb");
Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params);

File diff suppressed because it is too large Load Diff

View File

@@ -245,7 +245,7 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
@@ -274,7 +274,7 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled color console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]] bool DisableWebSocketLogging,[[maybe_unused]] const std::string & FormatterPattern) {
@@ -327,6 +327,7 @@ namespace OpenWifi {
Poco::Logger::root().setChannel(Splitter);
}
}
Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
}
void DaemonPostInitialization(Poco::Util::Application &self);

View File

@@ -102,6 +102,48 @@ namespace OpenWifi {
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::TimeoutException &E) {
poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::NoThreadAvailableException &E) {
poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::OutOfMemoryException &E) {
poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::BadCastException &E) {
poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::DataException &E) {
poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::PoolOverflowException &E) {
poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::SystemException &E) {
poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),
E.displayText(),
E.message(),
E.what()));
} catch (const Poco::RuntimeException &E) {
poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}",
t_name, t_id, E.code(),

View File

@@ -633,6 +633,18 @@ namespace OpenWifi {
ReturnObject(Answer);
}
template<typename T> void Object(const char *Name, const std::vector<T> & Objects) {
Poco::JSON::Object Answer;
RESTAPI_utils::field_to_json(Answer,Name,Objects);
ReturnObject(Answer);
}
template <typename T> void Object(const T &O) {
Poco::JSON::Object Answer;
O.to_json(Answer);
ReturnObject(Answer);
}
Poco::Logger & Logger() { return Logger_; }
virtual void DoGet() = 0 ;

View File

@@ -119,7 +119,7 @@ namespace OpenWifi {
}
bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) {
std::lock_guard G(Mutex_);
std::lock_guard G(LocalMutex_);
for(const auto &Client:Clients_) {
if(Client.second->UserName_ == UserName) {
@@ -139,7 +139,7 @@ namespace OpenWifi {
}
void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) {
std::lock_guard G(Mutex_);
std::lock_guard G(LocalMutex_);
for(const auto &Client:Clients_) {
try {
@@ -189,7 +189,6 @@ namespace OpenWifi {
void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
UI_WebSocketClientServer::ClientList::iterator Client;
std::lock_guard G(LocalMutex_);
try {
@@ -295,6 +294,7 @@ namespace OpenWifi {
void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
try {
std::lock_guard G(LocalMutex_);
auto Client = Clients_.find(pNf->socket().impl()->sockfd());
if (Client == end(Clients_))
return;

View File

@@ -229,7 +229,11 @@ namespace OpenWifi::RESTAPI::Errors {
static const struct msg ApiKeyDoesNotExist{1150,"API Key does not exist."};
static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."};
}
static const struct msg InvalidURI{1152,"Invalid URI."};
static const struct msg InvalidScriptSelection{1153,"Only script or scriptId must be specified. Not both."};
static const struct msg NoDeviceStatisticsYet{1154,"Device statistics not available yet."};
}
@@ -524,6 +528,63 @@ namespace OpenWifi::uCentralProtocol::Events {
};
}
namespace OpenWifi::APCommands {
enum class Commands:uint8_t {
capabilities,
logs,
healthchecks,
statistics,
status,
rtty,
configure,
upgrade,
reboot,
factory,
leds,
trace,
request,
wifiscan,
eventqueue,
telemetry,
ping,
script,
unknown
};
inline static const std::vector<const char *> uCentralAPCommands {
RESTAPI::Protocol::CAPABILITIES,
RESTAPI::Protocol::LOGS,
RESTAPI::Protocol::HEALTHCHECKS,
RESTAPI::Protocol::STATISTICS,
RESTAPI::Protocol::STATUS,
RESTAPI::Protocol::RTTY,
RESTAPI::Protocol::CONFIGURE,
RESTAPI::Protocol::UPGRADE,
RESTAPI::Protocol::REBOOT,
RESTAPI::Protocol::FACTORY,
RESTAPI::Protocol::LEDS,
RESTAPI::Protocol::TRACE,
RESTAPI::Protocol::REQUEST,
RESTAPI::Protocol::WIFISCAN,
RESTAPI::Protocol::EVENTQUEUE,
RESTAPI::Protocol::TELEMETRY,
RESTAPI::Protocol::PING,
RESTAPI::Protocol::SCRIPT};
inline const char * to_string(Commands Cmd) {
return uCentralAPCommands[(uint8_t)Cmd];
}
inline Commands to_apcommand(const char *cmd) {
for(auto i=(uint8_t)Commands::capabilities;i!=(uint8_t)Commands::unknown;++i) {
if(strcmp(uCentralAPCommands[i],cmd)==0)
return (Commands)i;
}
return Commands::unknown;
}
}
namespace OpenWifi::Provisioning::DeviceClass {
static const char * ANY = "any";

View File

@@ -487,6 +487,25 @@ void ReplaceVariables( std::string & Content , const Types::StringPairVec & P) {
return false;
}
[[nodiscard]] bool wgetfile(const Poco::URI &uri, const std::string &FileName) {
try {
Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
// send request
Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPath(), Poco::Net::HTTPMessage::HTTP_1_1);
session.sendRequest(req);
Poco::Net::HTTPResponse res;
std::istream &is = session.receiveResponse(res);
std::fstream os(FileName,std::ios_base::trunc | std::ios_base::binary | std::ios_base::out);
Poco::StreamCopier::copyStream(is,os);
return true;
} catch (...) {
}
return false;
}
bool ExtractBase64CompressedData(const std::string &CompressedData,
std::string &UnCompressedData, uint64_t compress_sz ) {
std::istringstream ifs(CompressedData);
@@ -531,4 +550,14 @@ bool ExtractBase64CompressedData(const std::string &CompressedData,
return "*******";
}
[[nodiscard]] bool ValidateURI(const std::string &uri) {
try {
Poco::URI u(uri);
return true;
} catch (...) {
}
return false;
}
}

View File

@@ -11,6 +11,7 @@
#include <random>
#include <regex>
#include <thread>
#include <shared_mutex>
#include "Poco/Thread.h"
#include "Poco/StringTokenizer.h"
@@ -115,8 +116,10 @@ namespace OpenWifi::Utils {
[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F);
[[nodiscard]] std::string SecondsToNiceText(uint64_t Seconds);
[[nodiscard]] bool wgets(const std::string &URL, std::string &Response);
[[nodiscard]] bool IsAlphaNumeric(const std::string &s);
[[nodiscard]] bool wgetfile(const Poco::URI &uri, const std::string &FileName);
[[nodiscard]] bool IsAlphaNumeric(const std::string &s);
[[nodiscard]] std::string SanitizeToken(const std::string &Token);
[[nodiscard]] bool ValidateURI(const std::string &uri);
template< typename T >
std::string int_to_hex( T i )
@@ -126,6 +129,23 @@ namespace OpenWifi::Utils {
<< std::hex << i;
return stream.str();
}
inline bool SpinLock_Read(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms=100) {
while(!M.try_lock_shared() && Flag) {
Poco::Thread::yield();
Poco::Thread::trySleep((long)wait_ms);
}
return Flag;
}
inline bool SpinLock_Write(std::shared_mutex &M, volatile bool &Flag, uint64_t wait_ms=100) {
while(!M.try_lock() && Flag) {
Poco::Thread::yield();
Poco::Thread::trySleep(wait_ms);
}
return Flag;
}
bool ExtractBase64CompressedData(const std::string &CompressedData,
std::string &UnCompressedData, uint64_t compress_sz );
}

View File

@@ -1,175 +0,0 @@
//
// Created by stephane bourque on 2021-11-23.
//
#include "RTTYS_ClientConnection.h"
#include "rttys/RTTYS_device.h"
#include "rttys/RTTYS_server.h"
#include "fmt/format.h"
#include "nlohmann/json.hpp"
namespace OpenWifi {
RTTYS_ClientConnection::RTTYS_ClientConnection(
Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response,
Poco::Net::SocketReactor &reactor,
const std::string &Id)
:
Reactor_(reactor),
Id_(Id),
Logger_(Poco::Logger::get(fmt::format("RTTY-client({})",Id_)))
{
Valid_ = true;
WS_ = std::make_unique<Poco::Net::WebSocket>(request,response);
WS_->setBlocking(false);
WS_->setNoDelay(true);
WS_->setKeepAlive(true);
Registered_ = true;
Reactor_.addEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ReadableNotification>(
*this, &RTTYS_ClientConnection::onSocketReadable));
Reactor_.addEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ShutdownNotification>(
*this, &RTTYS_ClientConnection::onSocketShutdown));
Logger_.information("Starting connection");
}
RTTYS_ClientConnection::~RTTYS_ClientConnection() {
poco_information(Logger_,
fmt::format("Client {} session ending", Id_)
);
DeRegister();
}
void RTTYS_ClientConnection::DeRegister() {
Valid_ = false;
if(Registered_) {
Registered_ = false;
Reactor_.removeEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ReadableNotification>(
*this, &RTTYS_ClientConnection::onSocketReadable));
Reactor_.removeEventHandler(
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ShutdownNotification>(
*this, &RTTYS_ClientConnection::onSocketShutdown));
}
}
void RTTYS_ClientConnection::EndConnection() {
DeRegister();
RTTYS_server()->NotifyClientDisconnect(Id_, this);
}
void RTTYS_ClientConnection::onSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
bool MustDisconnect = false;
{
if(!Valid_ || !Registered_)
return;
std::lock_guard G(Mutex_);
try {
int flags;
Poco::Buffer<char> IncomingFrame(0);
auto n = WS_->receiveFrame(IncomingFrame, flags);
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
switch (Op) {
case Poco::Net::WebSocket::FRAME_OP_PING: {
WS_->sendFrame("", 0,
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
} break;
case Poco::Net::WebSocket::FRAME_OP_PONG: {
} break;
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
if (n == 0) {
Logger_.information("Socket readable shutdown.");
MustDisconnect = true;
} else {
std::string s((char *)IncomingFrame.begin(), IncomingFrame.size());
try {
auto Doc = nlohmann::json::parse(s);
if (Doc.contains("type")) {
auto Type = Doc["type"];
if (Type == "winsize") {
auto cols = Doc["cols"];
auto rows = Doc["rows"];
if (!RTTYS_server()->WindowSize(Id_, cols, rows)) {
Logger_.information("Winsize shutdown.");
MustDisconnect = true;
}
}
}
} catch (...) {
// just ignore parse errors
Logger_.information("Frame text exception shutdown.");
MustDisconnect = true;
}
}
} break;
case Poco::Net::WebSocket::FRAME_OP_BINARY: {
if (n == 0) {
Logger_.information("Frame binary size shutdown.");
MustDisconnect = true;
} else {
poco_trace(Logger_, fmt::format("Sending {} key strokes to device.", n));
if (!RTTYS_server()->SendKeyStrokes(
Id_, (const unsigned char *)IncomingFrame.begin(),
IncomingFrame.size())) {
Logger_.information("Sendkeystrokes shutdown.");
MustDisconnect = true;
}
}
} break;
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
Logger_.information("Frame frame close shutdown.");
MustDisconnect = true;
} break;
default: {
}
}
} catch (...) {
Logger_.information("Frame readable shutdown.");
MustDisconnect = true;
}
}
if(MustDisconnect) {
EndConnection();
}
}
void RTTYS_ClientConnection::SendData( const u_char *Buf, size_t len ) {
if(!Valid_ || !Registered_)
return;
try {
WS_->sendFrame(Buf, len,
Poco::Net::WebSocket::FRAME_FLAG_FIN |
Poco::Net::WebSocket::FRAME_OP_BINARY);
return;
} catch (...) {
Logger_.information("SendData shutdown.");
}
EndConnection();
}
void RTTYS_ClientConnection::SendData( const std::string &s) {
if(!Valid_ || !Registered_)
return;
try {
WS_->sendFrame(s.c_str(), s.length());
return;
} catch (...) {
Logger_.information("SendData shutdown.");
}
EndConnection();
}
void RTTYS_ClientConnection::onSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
Logger_.information("Socket shutdown.");
EndConnection();
}
}

View File

@@ -1,49 +0,0 @@
//
// Created by stephane bourque on 2021-11-23.
//
#pragma once
#include "Poco/Net/WebSocket.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/NObserver.h"
#include "Poco/Net/SocketNotification.h"
#include "Poco/FIFOBuffer.h"
#include "Poco/Logger.h"
#include <mutex>
#include <shared_mutex>
namespace OpenWifi {
class RTTYS_ClientConnection {
public:
RTTYS_ClientConnection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response,
Poco::Net::SocketReactor & reactor,
const std::string &Id);
~RTTYS_ClientConnection();
void onSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
void onSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
void SendData( const u_char *Buf, size_t len );
void SendData( const std::string & S );
void DeRegister();
[[nodiscard]] inline std::string ID() { return Id_; }
[[nodiscard]] inline bool Valid() { return Valid_; }
private:
Poco::Net::SocketReactor &Reactor_;
std::string Id_;
std::unique_ptr<Poco::Net::WebSocket> WS_;
Poco::Logger &Logger_;
std::string Sid_;
std::recursive_mutex Mutex_;
volatile bool Valid_=false;
volatile bool Registered_=false;
void EndConnection();
};
}

View File

@@ -7,9 +7,8 @@
#include "Poco/Net/HTTPServerRequest.h"
#include "Poco/Net/HTTPServerResponse.h"
#include "RTTYS_ClientConnection.h"
#include "RTTYS_WebServer.h"
#include "RTTYS_server.h"
#include "RTTYS_WebServer.h"
#include "fmt/format.h"
#include "nlohmann/json.hpp"
@@ -37,7 +36,7 @@ namespace OpenWifi {
}
try {
RTTYS_server()->CreateNewClient(request,response,T[2]);
RTTYS_server()->CreateWSClient(request,response,T[2]);
} catch (...) {
poco_warning(Logger_,"Exception during WS creation");
}
@@ -113,7 +112,7 @@ namespace OpenWifi {
Utils::SetThreadName("rt:webserver");
[[maybe_unused]] uint64_t id = rtty_ws_id++;
poco_debug(Logger(),fmt::format("{}: Starting request.",id));
poco_trace(Logger(),fmt::format("{}: Starting request.",id));
Poco::URI uri(request.getURI());
auto Path = uri.getPath();
@@ -135,7 +134,7 @@ namespace OpenWifi {
if (ParsedPath.count() > 1) {
if (ParsedPath[1] == "connect") {
response.redirect(Poco::replace(Path,"/connect/","/rtty/"));
poco_debug(Logger(),fmt::format("{}: Redirect: {}",id,Path));
poco_trace(Logger(),fmt::format("{}: Redirect: {}",id,Path));
return;
} else if (ParsedPath[1] == "authorized") {
SetCommonHeaders(request,response, false);
@@ -144,7 +143,7 @@ namespace OpenWifi {
response.setContentType("application/json");
std::ostream &answer = response.send();
answer << to_string(doc);
poco_debug(Logger(),fmt::format("{}: Finishing authorization request.",id));
poco_trace(Logger(),fmt::format("{}: Finishing authorization request.",id));
return;
} else if (ParsedPath[1] == "fontsize") {
SetCommonHeaders(request,response, false);
@@ -153,7 +152,7 @@ namespace OpenWifi {
response.setContentType("application/json");
std::ostream &answer = response.send();
answer << to_string(doc);
poco_debug(Logger(),fmt::format("{}: Finishing font size request.",id));
poco_trace(Logger(),fmt::format("{}: Finishing font size request.",id));
return;
}
}
@@ -161,12 +160,12 @@ namespace OpenWifi {
}
if(Path.find("../")!=std::string::npos) {
poco_debug(Logger(),fmt::format("{}: Finishing request.",id));
poco_trace(Logger(),fmt::format("{}: Finishing request.",id));
return;
}
if(Path.find("~/")!=std::string::npos) {
poco_debug(Logger(),fmt::format("{}: Finishing request.",id));
poco_trace(Logger(),fmt::format("{}: Finishing request.",id));
return;
}
@@ -176,7 +175,7 @@ namespace OpenWifi {
// std::cout << id << ": Path " << Path << " does not exist" << std::endl;
Path = RTTYS_server()->UIAssets() + "/index.html";
response.sendFile(Path,"text/html");
poco_debug(Logger(),fmt::format("{}: Finishing request.",id));
poco_trace(Logger(),fmt::format("{}: Finishing request.",id));
return;
}
Poco::Path P(Path);
@@ -193,7 +192,7 @@ namespace OpenWifi {
} else if (Ext == "css") {
Type = "text/css; charset=utf-8";
if(IsFileGZipped(Path)) {
poco_debug(Logger(),fmt::format("{}: Downloading UI Assets.",id));
poco_trace(Logger(),fmt::format("{}: Downloading UI Assets.",id));
response.set("Content-Encoding", "gzip");
}
} else if (Ext == "ico")
@@ -207,7 +206,7 @@ namespace OpenWifi {
response.setContentLength(F.getSize());
response.sendFile(Path, Type);
poco_debug(Logger(),fmt::format("{}: Finishing request.",id));
poco_trace(Logger(),fmt::format("{}: Finishing request.",id));
}
RTTYS_Client_RequestHandlerFactory::RTTYS_Client_RequestHandlerFactory(Poco::Logger & L)

View File

@@ -1,524 +0,0 @@
//
// Created by stephane bourque on 2021-11-23.
//
#include "RTTYS_device.h"
#include "rttys/RTTYS_server.h"
#include "Poco/Net/SecureStreamSocketImpl.h"
#include "Poco/Net/StreamSocket.h"
#include "nlohmann/json.hpp"
#include "fmt/format.h"
void dump(const u_char *b, uint s) {
static const char hex[] = "0123456789abcdef";
int l=0;
std::cout << std::endl;
while(s) {
std::string SS;
SS += (hex[(*b & 0xf0) >> 4]);
SS += (hex[(*b & 0x0f)]);
std::cout << SS << " ";
l++;
if((l % 16) == 0)
std::cout << std::endl;
b++;
--s;
}
std::cout << std::endl;
}
#define SOCKET_DEBUG(X,Y,Z) { std::cout << __func__ << ":" << __LINE__ << std::endl; (Z)=socket_.sendBytes(X,Y); dump(X,Y); }
namespace OpenWifi {
RTTYS_Device_ConnectionHandler::RTTYS_Device_ConnectionHandler(Poco::Net::StreamSocket& socket, Poco::Net::SocketReactor & reactor):
socket_(socket),
reactor_(reactor),
Logger_(Poco::Logger::get(fmt::format("RTTY-device({})",socket_.peerAddress().toString())))
{
// std::thread T([=]() { CompleteConnection(); });
// T.detach();
inBuf_ = std::make_unique<Poco::FIFOBuffer>(RTTY_DEVICE_BUFSIZE);
CompleteConnection();
}
void RTTYS_Device_ConnectionHandler::CompleteConnection() {
try {
valid_=true;
device_address_ = socket_.peerAddress();
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl *>(socket_.impl());
while (true) {
auto V = SS->completeHandshake();
if (V == 1)
break;
}
if ((SS->secure())) {
poco_information(Logger(), "Secure connection.");
}
socket_.setBlocking(false);
socket_.setKeepAlive(true);
socket_.setNoDelay(true);
socket_.setReceiveTimeout(Poco::Timespan(60*60,0));
registered_=true;
reactor_.addEventHandler(
socket_,
Poco::NObserver<RTTYS_Device_ConnectionHandler, Poco::Net::ReadableNotification>(
*this, &RTTYS_Device_ConnectionHandler::onSocketReadable));
reactor_.addEventHandler(
socket_,
Poco::NObserver<RTTYS_Device_ConnectionHandler, Poco::Net::ShutdownNotification>(
*this, &RTTYS_Device_ConnectionHandler::onSocketShutdown));
} catch (...) {
poco_warning(Logger(), "Device caused exception while completing connection.");
std::unique_lock G(M_);
EndConnection();
}
}
RTTYS_Device_ConnectionHandler::~RTTYS_Device_ConnectionHandler() {
poco_information(Logger_,
fmt::format("Device {} session ending", id_)
);
DeRegister();
}
void RTTYS_Device_ConnectionHandler::DeRegister() {
if(registered_) {
registered_ = false;
reactor_.removeEventHandler(
socket_,
Poco::NObserver<RTTYS_Device_ConnectionHandler, Poco::Net::ReadableNotification>(
*this, &RTTYS_Device_ConnectionHandler::onSocketReadable));
reactor_.removeEventHandler(
socket_,
Poco::NObserver<RTTYS_Device_ConnectionHandler, Poco::Net::ShutdownNotification>(
*this, &RTTYS_Device_ConnectionHandler::onSocketShutdown));
}
}
void RTTYS_Device_ConnectionHandler::EndConnection() {
if(valid_) {
valid_ = false;
DeRegister();
if(deviceIsRegistered_) {
deviceIsRegistered_ = false;
RTTYS_server()->NotifyDeviceDisconnect(id_, this);
} else {
delete this;
}
}
}
[[maybe_unused]] static void dump(unsigned char *p,uint l) {
for(uint i=0;i<l;i++) {
std::cout << std::hex << (uint) p[i] << " ";
if(i % 16 == 0)
std::cout << std::endl;
}
std::cout << std::dec << std::endl ;
}
void RTTYS_Device_ConnectionHandler::onSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
bool good = true;
if(!valid_ || !registered_)
return;
std::unique_lock G(M_);
try {
auto received_bytes = socket_.receiveBytes(*inBuf_);
if (received_bytes == 0) {
poco_information(Logger(), fmt::format("{}: Device Closing connection - 0 bytes received.",id_));
return EndConnection();
}
while (inBuf_->isReadable() && good) {
uint32_t msg_len = 0;
if (waiting_for_bytes_ != 0) {
} else {
if (inBuf_->used() >= RTTY_HDR_SIZE) {
auto *head = (unsigned char *)inBuf_->begin();
last_command_ = head[0];
msg_len = head[1] * 256 + head[2];
inBuf_->drain(RTTY_HDR_SIZE);
} else {
good = false;
continue;
}
}
switch (last_command_) {
case msgTypeRegister: {
good = do_msgTypeRegister(msg_len);
} break;
case msgTypeLogin: {
good = do_msgTypeLogin(msg_len);
} break;
case msgTypeLogout: {
good = do_msgTypeLogout(msg_len);
} break;
case msgTypeTermData: {
good = do_msgTypeTermData(msg_len);
} break;
case msgTypeWinsize: {
good = do_msgTypeWinsize(msg_len);
} break;
case msgTypeCmd: {
good = do_msgTypeCmd(msg_len);
} break;
case msgTypeHeartbeat: {
good = do_msgTypeHeartbeat(msg_len);
} break;
case msgTypeFile: {
good = do_msgTypeFile(msg_len);
} break;
case msgTypeHttp: {
good = do_msgTypeHttp(msg_len);
} break;
case msgTypeAck: {
good = do_msgTypeAck(msg_len);
} break;
case msgTypeMax: {
good = do_msgTypeMax(msg_len);
} break;
default: {
poco_warning(Logger(),
fmt::format("{}: Unknown command {} from device. GW closing connection.", id_,
(int)last_command_));
good = false;
}
}
}
} catch (const Poco::Exception &E) {
good = false;
poco_warning(Logger(),fmt::format("{}: Exception: {} GW closing connection.", id_, E.what()));
} catch (const std::exception &E) {
poco_warning(Logger(),fmt::format("{}: std::exception: {}. GW closing connection.", id_, E.what()));
good = false;
}
if(!good) {
return EndConnection();
}
}
void RTTYS_Device_ConnectionHandler::onSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf) {
poco_information(Logger(),fmt::format("{}: Connection being closed - socket shutdown.",id_));
EndConnection();
}
bool RTTYS_Device_ConnectionHandler::SendToClient(const u_char *Buf, int Len) {
u_char bb[64000]{0};
if(old_rtty_) {
bb[0] = session_id_[0];
memcpy(&bb[1],Buf,Len);
} else {
bb[0] = 0;
memcpy(&bb[1],Buf,Len);
}
return RTTYS_server()->SendToClient(id_, Buf, Len );
}
bool RTTYS_Device_ConnectionHandler::SendToClient(const std::string &S) {
if(!valid_ || !registered_)
return false;
return RTTYS_server()->SendToClient(id_,S);
}
bool RTTYS_Device_ConnectionHandler::KeyStrokes(const u_char *buf, size_t len) {
if(!valid_ || !registered_)
return false;
if(len<=(sizeof(small_buf_)-RTTY_HDR_SIZE-session_length_)) {
small_buf_[0] = msgTypeTermData;
small_buf_[1] = ((len-1+session_length_) & 0xff00) >> 8;
small_buf_[2] = ((len-1+session_length_) & 0x00ff);
memcpy(&small_buf_[RTTY_HDR_SIZE],session_id_,session_length_);
memcpy(&small_buf_[RTTY_HDR_SIZE+session_length_], &buf[1], len-1);
try {
auto Sent = socket_.sendBytes(small_buf_, RTTY_HDR_SIZE + session_length_ + len - 1);
return (Sent==(int)(RTTY_HDR_SIZE + session_length_ + len - 1));
} catch (...) {
return false;
}
} else {
auto Msg = std::make_unique<unsigned char []>(len + RTTY_HDR_SIZE + session_length_);
Msg.get()[0] = msgTypeTermData;
Msg.get()[1] = ((len-1+session_length_) & 0xff00) >> 8;
Msg.get()[2] = ((len-1+session_length_) & 0x00ff);
memcpy((Msg.get()+RTTY_HDR_SIZE),session_id_,session_length_);
memcpy((Msg.get()+RTTY_HDR_SIZE+session_length_), &buf[1], len-1);
try {
auto Sent = socket_.sendBytes(Msg.get(), RTTY_HDR_SIZE + session_length_ + len - 1);
return (Sent==(int)( RTTY_HDR_SIZE + session_length_ + len - 1));
} catch (...) {
return false;
}
}
}
bool RTTYS_Device_ConnectionHandler::WindowSize(int cols, int rows) {
if(!valid_ || !registered_)
return false;
u_char outBuf[8+RTTY_SESSION_ID_LENGTH]{0};
outBuf[0] = msgTypeWinsize;
outBuf[1] = 0 ;
outBuf[2] = 4 + session_length_ ;
memcpy(&outBuf[RTTY_HDR_SIZE],session_id_,session_length_);
outBuf[RTTY_HDR_SIZE+0+session_length_] = cols >> 8 ;
outBuf[RTTY_HDR_SIZE+1+session_length_] = cols & 0x00ff;
outBuf[RTTY_HDR_SIZE+2+session_length_] = rows >> 8;
outBuf[RTTY_HDR_SIZE+3+session_length_] = rows & 0x00ff;
try {
auto Sent = socket_.sendBytes(outBuf, RTTY_HDR_SIZE + 4 + session_length_ );
return (Sent==(int)(RTTY_HDR_SIZE + 4 + session_length_));
} catch (...) {
}
return false;
}
bool RTTYS_Device_ConnectionHandler::Login() {
if(!valid_ || !registered_)
return false;
u_char outBuf[RTTY_HDR_SIZE+RTTY_SESSION_ID_LENGTH]{0};
outBuf[0] = msgTypeLogin;
outBuf[1] = 0;
if(old_rtty_) {
outBuf[2] = 0;
} else {
outBuf[2] = RTTY_SESSION_ID_LENGTH;
std::strncpy(session_id_,Utils::ComputeHash(id_,token_).substr(0,RTTY_SESSION_ID_LENGTH/2).c_str(),RTTY_SESSION_ID_LENGTH);
memcpy(&outBuf[RTTY_HDR_SIZE],session_id_,RTTY_SESSION_ID_LENGTH);
}
try {
poco_information(Logger(),fmt::format("{}: Device login", id_));
auto Sent = socket_.sendBytes( outBuf, RTTY_HDR_SIZE + (old_rtty_ ? 0 : RTTY_SESSION_ID_LENGTH));
return Sent==(int)(RTTY_HDR_SIZE + (old_rtty_ ? 0 : RTTY_SESSION_ID_LENGTH));
} catch (const Poco::IOException &E) {
return false;
} catch (const Poco::Exception &E) {
return false;
}
}
bool RTTYS_Device_ConnectionHandler::Logout() {
if(!valid_ || !registered_)
return false;
u_char outBuf[4+RTTY_SESSION_ID_LENGTH]{0};
outBuf[0] = msgTypeLogout;
outBuf[1] = 0;
outBuf[2] = session_length_;
memcpy(&outBuf[3],session_id_,session_length_);
poco_information(Logger(),fmt::format("{}: Logout", id_));
try {
auto Sent = socket_.sendBytes(outBuf, RTTY_HDR_SIZE + session_length_);
return Sent==(int)(RTTY_HDR_SIZE+session_length_);
} catch (...) {
}
return false;
}
std::string RTTYS_Device_ConnectionHandler::ReadString() {
std::string Res;
while(inBuf_->used()) {
char C;
inBuf_->read(&C,1);
if(C==0) {
break;
}
Res += C;
}
return Res;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeRegister([[maybe_unused]] std::size_t msg_len) {
bool good = true;
if(deviceIsRegistered_)
return false;
try {
// establish if this is an old rtty or a new one.
old_rtty_ = ((*inBuf_)[0] != 0x03); // rtty_proto_ver for full session ID inclusion
if(old_rtty_) {
session_length_ = 1;
} else {
inBuf_->drain(1); // remove protocol if used.
session_length_ = RTTY_SESSION_ID_LENGTH;
}
id_ = ReadString();
desc_ = ReadString();
token_ = ReadString();
if(id_.size()!=RTTY_DEVICE_TOKEN_LENGTH || token_.size()!=RTTY_DEVICE_TOKEN_LENGTH || desc_.empty()) {
return false;
}
poco_information(Logger(),
fmt::format("{}: Description:{} Device registration", id_, desc_));
if(!RTTYS_server()->NotifyDeviceRegistration(id_,token_,this)) {
return false;
}
u_char OutBuf[8];
OutBuf[0] = msgTypeRegister;
OutBuf[1] = 0; // Data length
OutBuf[2] = 4; //
OutBuf[3] = 0; // Error
OutBuf[4] = 'O';
OutBuf[5] = 'K';
OutBuf[6] = 0;
if (socket_.sendBytes(OutBuf, 7) != 7) {
poco_information(Logger(),
fmt::format("{}: Description:{} Could not send data to complete registration",
id_, desc_));
good = false;
}
deviceIsRegistered_ = true;
} catch (...) {
good = false;
}
return good;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeLogin([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for login", id_));
if(!deviceIsRegistered_)
return false;
nlohmann::json doc;
char Error;
if(old_rtty_) {
inBuf_->read(&Error, 1);
inBuf_->read(&session_id_[0], session_length_);
} else {
char session[RTTY_SESSION_ID_LENGTH+1]{0};
inBuf_->read(&session[0], session_length_);
inBuf_->read(&Error, 1);
}
doc["type"] = "login";
doc["err"] = Error;
const auto login_msg = to_string(doc);
return SendToClient(login_msg);
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeLogout([[maybe_unused]] std::size_t msg_len) {
if(!deviceIsRegistered_)
return false;
char session[RTTY_SESSION_ID_LENGTH];
if(old_rtty_) {
inBuf_->read(&session[0],1);
} else {
inBuf_->read(&session[0],RTTY_SESSION_ID_LENGTH);
}
poco_information(Logger(),fmt::format("{}: Logout", id_));
return false;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeTermData(std::size_t msg_len) {
if(!deviceIsRegistered_)
return false;
bool good;
if(waiting_for_bytes_>0) {
if(inBuf_->used()<waiting_for_bytes_) {
waiting_for_bytes_ = waiting_for_bytes_ - inBuf_->used();
good = SendToClient((unsigned char *)inBuf_->begin(), (int) inBuf_->used());
inBuf_->drain();
} else {
good = SendToClient((unsigned char *)inBuf_->begin(), waiting_for_bytes_);
inBuf_->drain(waiting_for_bytes_);
waiting_for_bytes_ = 0 ;
}
} else {
if(old_rtty_) {
inBuf_->drain(1);
msg_len -= 1;
} else {
inBuf_->drain(RTTY_SESSION_ID_LENGTH);
msg_len -= RTTY_SESSION_ID_LENGTH;
}
if(inBuf_->used()<msg_len) {
good = SendToClient((unsigned char *)inBuf_->begin(), inBuf_->used());
waiting_for_bytes_ = msg_len - inBuf_->used();
inBuf_->drain();
} else {
waiting_for_bytes_ = 0 ;
good = SendToClient((unsigned char *)inBuf_->begin(), msg_len);
inBuf_->drain(msg_len);
}
}
return good;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeWinsize([[maybe_unused]] std::size_t msg_len) {
if(!deviceIsRegistered_)
return false;
poco_information(Logger(),fmt::format("{}: Asking for msgTypeWinsize", id_));
return true;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeCmd([[maybe_unused]] std::size_t msg_len) {
if(!deviceIsRegistered_)
return false;
poco_information(Logger(),fmt::format("{}: Asking for msgTypeCmd", id_));
return true;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeHeartbeat([[maybe_unused]] std::size_t msg_len) {
if(!deviceIsRegistered_)
return false;
u_char MsgBuf[RTTY_HDR_SIZE + 16]{0};
if(msg_len)
inBuf_->drain(msg_len);
MsgBuf[0] = msgTypeHeartbeat;
MsgBuf[1] = 0;
MsgBuf[2] = 0;
auto Sent = socket_.sendBytes(MsgBuf, RTTY_HDR_SIZE);
return Sent == RTTY_HDR_SIZE;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeFile([[maybe_unused]] std::size_t msg_len) {
if(!deviceIsRegistered_)
return false;
poco_information(Logger(),fmt::format("{}: Asking for msgTypeFile", id_));
return true;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeHttp([[maybe_unused]] std::size_t msg_len) {
if(!deviceIsRegistered_)
return false;
poco_information(Logger(),fmt::format("{}: Asking for msgTypeHttp", id_));
return true;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeAck([[maybe_unused]] std::size_t msg_len) {
if(!deviceIsRegistered_)
return false;
poco_information(Logger(),fmt::format("{}: Asking for msgTypeAck", id_));
return true;
}
bool RTTYS_Device_ConnectionHandler::do_msgTypeMax([[maybe_unused]] std::size_t msg_len) {
poco_information(Logger(),fmt::format("{}: Asking for msgTypeMax", id_));
return true;
}
}

View File

@@ -1,93 +0,0 @@
//
// Created by stephane bourque on 2021-11-23.
//
#pragma once
#include <array>
#include <shared_mutex>
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/SocketNotification.h"
#include "Poco/FIFOBuffer.h"
#include "Poco/Net/TCPServerConnectionFactory.h"
#include "Poco/Logger.h"
namespace OpenWifi {
constexpr std::size_t RTTY_DEVICE_BUFSIZE=64000;
constexpr std::size_t RTTY_SESSION_ID_LENGTH=32;
constexpr std::size_t RTTY_HDR_SIZE=3;
class RTTYS_Device_ConnectionHandler{
public:
enum RTTY_MSG_TYPE {
msgTypeRegister = 0,
msgTypeLogin,
msgTypeLogout,
msgTypeTermData,
msgTypeWinsize,
msgTypeCmd,
msgTypeHeartbeat,
msgTypeFile,
msgTypeHttp,
msgTypeAck,
msgTypeMax };
explicit RTTYS_Device_ConnectionHandler(Poco::Net::StreamSocket& socket, Poco::Net::SocketReactor& reactor);
~RTTYS_Device_ConnectionHandler();
bool Login();
bool Logout();
[[nodiscard]] bool SendToClient(const u_char *buf, int len);
[[nodiscard]] bool SendToClient(const std::string &S);
[[nodiscard]] bool WindowSize(int cols, int rows);
[[nodiscard]] bool KeyStrokes(const u_char *buf, size_t len);
std::string ReadString();
// inline auto SessionID() const { return conn_id_; }
void onSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
void onSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
inline Poco::Logger &Logger() { return Logger_; }
inline bool Valid() const { return valid_; }
private:
Poco::Net::StreamSocket socket_;
Poco::Net::SocketReactor &reactor_;
std::unique_ptr<Poco::FIFOBuffer> inBuf_;
Poco::Logger &Logger_;
volatile bool valid_=false;
volatile bool old_rtty_=true;
Poco::Net::SocketAddress device_address_;
std::shared_mutex M_;
std::string id_;
std::string token_;
std::string desc_;
char session_id_[RTTY_SESSION_ID_LENGTH+1]{0};
std::uint64_t session_length_=1;
std::size_t waiting_for_bytes_{0};
u_char last_command_=0;
volatile bool registered_=false;
unsigned char small_buf_[64+RTTY_SESSION_ID_LENGTH];
volatile bool deviceIsRegistered_=false;
void EndConnection() ;
void CompleteConnection();
void DeRegister();
[[nodiscard]] bool do_msgTypeRegister(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeLogin(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeLogout(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeTermData(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeWinsize(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeCmd(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeHeartbeat(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeFile(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeHttp(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeAck(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeMax(std::size_t msg_len);
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -12,119 +12,45 @@
#include "Poco/NotificationQueue.h"
#include "Poco/Timer.h"
#include "Poco/Net/HTTPServer.h"
#include "Poco/Net/WebSocket.h"
#include "framework/SubSystemServer.h"
#include "framework/utils.h"
#include "rttys/RTTYS_device.h"
#include "rttys/RTTYS_ClientConnection.h"
#include <fmt/format.h>
using namespace std::chrono_literals;
namespace OpenWifi {
constexpr uint RTTY_DEVICE_TOKEN_LENGTH=32;
constexpr std::size_t RTTY_DEVICE_BUFSIZE=64000;
constexpr std::size_t RTTY_SESSION_ID_LENGTH=32;
constexpr std::size_t RTTY_HDR_SIZE=3;
class RTTYS_Device_ConnectionHandler;
class RTTYS_ClientConnection;
class RTTYS_server;
template <typename T> class MutexLockerDbg {
public:
MutexLockerDbg(const std::string &name, T &L) :
name_(name),
L_(L)
{
std::cout << name_ << ":L:0:" << Poco::Thread::current()->name() << ":" << Poco::Thread::currentTid() << std::endl;
L_.lock();
std::cout << name_ << ":L:1:" << Poco::Thread::current()->name() << ":" << Poco::Thread::currentTid() << std::endl;
}
~MutexLockerDbg() {
std::cout << name_ << ":U:0:" << Poco::Thread::current()->name() << ":" << Poco::Thread::currentTid() << std::endl;
L_.unlock();
std::cout << name_ << ":U:1:" << Poco::Thread::current()->name() << ":" << Poco::Thread::currentTid() << std::endl;
}
private:
std::string name_;
T & L_;
};
enum class RTTYS_Notification_type {
unknown,
device_disconnection,
client_disconnection,
client_registration,
device_registration
};
class RTTYS_Notification: public Poco::Notification {
public:
RTTYS_Notification(const RTTYS_Notification_type &type, const std::string &id,
RTTYS_Device_ConnectionHandler * device) :
type_(type),
id_(id),
device_(device) {
}
RTTYS_Notification(const RTTYS_Notification_type &type, const std::string &id,
RTTYS_ClientConnection * client) :
type_(type),
id_(id),
client_(client) {
}
RTTYS_Notification(const RTTYS_Notification_type &type,
const std::string &id,
const std::string &token,
RTTYS_Device_ConnectionHandler * device) :
type_(type),
id_(id),
token_(token),
device_(device) {
}
RTTYS_Notification_type type_=RTTYS_Notification_type::unknown;
std::string id_;
std::string token_;
RTTYS_Device_ConnectionHandler *device_= nullptr;
RTTYS_ClientConnection *client_ = nullptr;
};
class RTTYS_server * RTTYS_server();
class RTTYS_EndPoint {
public:
RTTYS_EndPoint(const std::string &Token, const std::string &SerialNumber, const std::string &UserName ):
Token_(Token),
SerialNumber_(SerialNumber),
UserName_(UserName)
{
Created_ = std::chrono::high_resolution_clock::now();
}
RTTYS_EndPoint(const std::string &Id, const std::string &Token, const std::string &SerialNumber, const std::string &UserName );
~RTTYS_EndPoint();
inline void SetClient(RTTYS_ClientConnection *Client) {
ClientConnected_ = std::chrono::high_resolution_clock::now();
Client_ = std::unique_ptr<RTTYS_ClientConnection>(Client);
}
enum RTTY_MSG_TYPE {
msgTypeRegister = 0,
msgTypeLogin,
msgTypeLogout,
msgTypeTermData,
msgTypeWinsize,
msgTypeCmd,
msgTypeHeartbeat,
msgTypeFile,
msgTypeHttp,
msgTypeAck,
msgTypeMax };
inline void SetDevice(RTTYS_Device_ConnectionHandler* Device) {
DeviceConnected_ = std::chrono::high_resolution_clock::now();
Device_ = std::unique_ptr<RTTYS_Device_ConnectionHandler>(Device);
}
inline bool Login() {
if(Device_!= nullptr) {
return Device_->Login();
}
return false;
}
inline void DisconnectClient() {
ClientDisconnected_ = std::chrono::high_resolution_clock::now();
}
inline void DisconnectDevice() {
DeviceDisconnected_ = std::chrono::high_resolution_clock::now();
}
bool Login();
bool Logout();
[[nodiscard]] inline bool TooOld() {
std::chrono::time_point<std::chrono::high_resolution_clock> now = std::chrono::high_resolution_clock::now();
@@ -141,51 +67,6 @@ namespace OpenWifi {
return true;
}
if(!Joined_ && (now-Created_)>30s) {
return true;
}
return false;
}
bool SendToClient(const u_char *Buf, std::size_t Len) {
if(Client_!= nullptr && Client_->Valid()) {
Client_->SendData(Buf,Len);
return true;
}
return false;
}
inline bool KeyStrokes(const u_char *buffer, std::size_t len) {
if( Device_!= nullptr && Device_->Valid() )
return Device_->KeyStrokes(buffer,len);
return false;
}
inline bool WindowSize( int cols, int rows) {
if(Device_!= nullptr && Device_->Valid())
return Device_->WindowSize(cols,rows);
return false;
}
[[nodiscard]] inline bool ValidClient() const {
return Client_!= nullptr && Client_->Valid();
}
[[nodiscard]] inline bool ValidDevice() const {
return Device_!= nullptr && Device_->Valid();
}
[[nodiscard]] inline bool Joined() volatile const { return Joined_; }
void Join() {
Joined_=true;
}
inline bool SendToClient(const std::string &S) {
if(Client_!= nullptr && Client_->Valid()) {
Client_->SendData(S);
return true;
}
return false;
}
@@ -205,20 +86,47 @@ namespace OpenWifi {
return std::chrono::duration<double>{ClientDisconnected_ - ClientConnected_}.count();
}
private:
std::string Token_;
std::string SerialNumber_;
std::string UserName_;
std::unique_ptr<RTTYS_ClientConnection> Client_;
std::unique_ptr<RTTYS_Device_ConnectionHandler> Device_;
std::string Id_;
[[nodiscard]] bool do_msgTypeRegister(Poco::Net::Socket &Socket, Poco::Buffer<char> &B, [[maybe_unused]] std::size_t msg_len);
[[nodiscard]] bool do_msgTypeLogin(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeLogout(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeTermData(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeWinsize(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeCmd(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeHeartbeat(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeFile(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeHttp(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeAck(std::size_t msg_len);
[[nodiscard]] bool do_msgTypeMax(std::size_t msg_len);
bool SendToClient(const u_char *buf, int len);
bool SendToClient(const std::string &S);
[[nodiscard]] bool WindowSize(int cols, int rows);
[[nodiscard]] bool KeyStrokes(const u_char *buf, size_t len);
inline Poco::Logger & Logger() { return Logger_; }
Poco::Net::SocketAddress device_address_;
std::string Id_;
std::string Token_;
std::string SerialNumber_;
std::string UserName_;
std::unique_ptr<Poco::Net::StreamSocket> DeviceSocket_;
std::unique_ptr<Poco::Net::WebSocket> WSSocket_;
Poco::Logger &Logger_;
std::unique_ptr<Poco::FIFOBuffer> DeviceInBuf_;
char session_id_[RTTY_SESSION_ID_LENGTH+1]{0};
std::uint64_t session_length_=1;
std::size_t waiting_for_bytes_{0};
u_char last_command_=0;
unsigned char small_buf_[64+RTTY_SESSION_ID_LENGTH];
std::uint64_t TID_=0;
bool old_rtty_=false;
bool completed_=false;
std::chrono::time_point<std::chrono::high_resolution_clock>
Created_{0s},DeviceDisconnected_{0s},
ClientDisconnected_{0s},DeviceConnected_{0s} ,ClientConnected_{0s};
volatile bool Joined_=false;
};
class RTTYS_server : public SubSystemServer, Poco::Runnable
class RTTYS_server : public SubSystemServer
{
public:
static auto instance() {
@@ -232,77 +140,97 @@ namespace OpenWifi {
inline auto UIAssets() { return RTTY_UIAssets_; }
bool CreateEndPoint(const std::string &Id, const std::string & Token, const std::string & UserName, const std::string & SerialNumber );
bool SendKeyStrokes(const std::string &Id, const u_char *buffer, std::size_t s);
bool WindowSize(const std::string &Id, int cols, int rows);
bool SendToClient(const std::string &id, const u_char *Buf, std::size_t Len);
bool SendToClient(const std::string &id, const std::string &s);
bool ValidId(const std::string &Id);
void run() final;
inline void NotifyDeviceDisconnect(const std::string &id, RTTYS_Device_ConnectionHandler *device) {
ResponseQueue_.enqueueNotification(new RTTYS_Notification(RTTYS_Notification_type::device_disconnection,id,device));
}
inline void NotifyClientDisconnect(const std::string &id, RTTYS_ClientConnection *client) {
ResponseQueue_.enqueueNotification(new RTTYS_Notification(RTTYS_Notification_type::client_disconnection,id,client));
}
inline bool NotifyDeviceRegistration(const std::string &id, const std::string &token, RTTYS_Device_ConnectionHandler *device) {
{
std::lock_guard G(LocalMutex_);
if (EndPoints_.find(id) == end(EndPoints_))
return false;
}
ResponseQueue_.enqueueNotification(new RTTYS_Notification(RTTYS_Notification_type::device_registration,id,token,device));
return true;
}
inline void NotifyClientRegistration(const std::string &id, RTTYS_ClientConnection *client) {
ResponseQueue_.enqueueNotification(new RTTYS_Notification(RTTYS_Notification_type::client_registration,id,client));
}
void CreateNewClient(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response, const std::string &id);
void onTimer(Poco::Timer & timer);
inline bool UseInternal() const {
return Internal_;
}
inline Poco::Net::SocketReactor & ClientReactor() { return ClientReactor_; }
std::string ReadString(unsigned char *buf, int len, int &pos);
void onDeviceAccept(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
void onDeviceSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
void onDeviceSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
void onDeviceSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
void onClientSocketReadable(const Poco::AutoPtr<Poco::Net::ReadableNotification>& pNf);
void onClientSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification>& pNf);
void onClientSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification>& pNf);
void RemoveConnectingDeviceEventHandlers(Poco::Net::StreamSocket &Socket);
void RemoveClientEventHandlers(Poco::Net::StreamSocket &Socket);
void RemoveDeviceEventHandlers(Poco::Net::StreamSocket &Socket);
void AddConnectingDeviceEventHandlers(Poco::Net::StreamSocket &Socket);
void AddClientEventHandlers(Poco::Net::StreamSocket &Socket, std::shared_ptr<RTTYS_EndPoint> EndPoint);
void AddDeviceEventHandlers(Poco::Net::StreamSocket &Socket, std::shared_ptr<RTTYS_EndPoint> EndPoint);
void onConnectingDeviceData(const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf);
void onConnectingDeviceShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
void onConnectingDeviceError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
bool do_msgTypeRegister(Poco::Net::StreamSocket &Socket, unsigned char *Buffer, int Len);
bool do_msgTypeHeartbeat(Poco::Net::StreamSocket &Socket);
void CloseDevice(std::shared_ptr<RTTYS_EndPoint> Device);
void CloseClient(std::shared_ptr<RTTYS_EndPoint> Client);
void CloseConnection(std::shared_ptr<RTTYS_EndPoint> Connection);
inline auto Uptime() const { return Utils::Now() - Started_; }
void CreateWSClient(
Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response,
const std::string &Id);
Poco::Net::SocketReactor & Reactor() { return Reactor_; }
void SendData( std::shared_ptr<RTTYS_EndPoint> & Connection, const u_char *Buf, size_t len );
void SendData( std::shared_ptr<RTTYS_EndPoint> & Connection, const std::string &s) ;
inline std::shared_ptr<RTTYS_EndPoint> FindConnection(const std::string &Id,const std::string &Token) {
std::shared_ptr<RTTYS_EndPoint> Res;
auto EndPoint = EndPoints_.find(Id);
if(EndPoint!=end(EndPoints_) && EndPoint->second->Token_==Token) {
Res = EndPoint->second;
}
return Res;
}
void LogStdException(const std::exception &E, const char *msg);
private:
Poco::Net::SocketReactor ClientReactor_;
Poco::Net::SocketReactor DeviceReactor_;
Poco::Thread ClientReactorThread_;
Poco::Net::SocketReactor Reactor_;
Poco::Thread ReactorThread_;
std::string RTTY_UIAssets_;
bool Internal_ = false;
bool NoSecurity_=false;
volatile bool Running_ = false;
std::map<std::string,std::unique_ptr<RTTYS_EndPoint>> EndPoints_; // id, endpoint
std::unique_ptr<Poco::Net::HTTPServer> WebServer_;
std::unique_ptr<Poco::Net::SocketAcceptor<RTTYS_Device_ConnectionHandler>> DeviceAcceptor_;
Poco::Thread DeviceReactorThread_;
Poco::NotificationQueue ResponseQueue_;
std::atomic_bool NotificationManagerRunning_=false;
Poco::Thread NotificationManager_;
std::map<std::string,std::shared_ptr<RTTYS_EndPoint>> EndPoints_; // id, endpoint
std::map<int, std::shared_ptr<RTTYS_EndPoint> > Connections_;
std::map<int, std::pair<Poco::Net::StreamSocket,std::chrono::time_point<std::chrono::high_resolution_clock>>> ConnectingDevices_;
Poco::Timer Timer_;
std::unique_ptr<Poco::TimerCallback<RTTYS_server>> GCCallBack_;
std::list<std::unique_ptr<RTTYS_Device_ConnectionHandler>> FailedDevices;
std::list<std::unique_ptr<RTTYS_ClientConnection>> FailedClients;
std::recursive_mutex LocalMutex_;
std::mutex ServerMutex_;
std::atomic_uint64_t TotalEndPoints_=0;
std::atomic_uint64_t FailedNumDevices_=0;
std::atomic_uint64_t FailedNumClients_=0;
double TotalConnectedDeviceTime_=0.0;
double TotalConnectedClientTime_=0.0;
std::chrono::duration<double,std::milli> TotalConnectedDeviceTime_{0ms},
TotalConnectedClientTime_{0ms};
std::atomic_uint64_t Started_=Utils::Now();
std::atomic_uint64_t MaxConcurrentSessions_=0;
std::unique_ptr<Poco::Net::ServerSocket> DeviceSocket_;
std::unique_ptr<Poco::Net::SecureServerSocket> SecureDeviceSocket_;
static inline std::uint64_t CurrentTID_=0;
explicit RTTYS_server() noexcept:
SubSystemServer("RTTY_Server", "RTTY-SVR", "rtty.server")
@@ -310,6 +238,6 @@ namespace OpenWifi {
}
};
inline RTTYS_server * RTTYS_server() { return RTTYS_server::instance(); }
inline class RTTYS_server * RTTYS_server() { return RTTYS_server::instance(); }
} // namespace OpenWifi

View File

@@ -120,6 +120,8 @@ typedef Poco::Tuple<
Poco::Data::Keywords::use(SerialNumber),
Poco::Data::Keywords::use(Command);
Delete.execute();
Delete.reset(Sess);
return true;
} catch(const Poco::Exception &E) {
Logger().log(E);
@@ -205,6 +207,8 @@ typedef Poco::Tuple<
ConvertCommandRecord(i, R);
Commands.push_back(R);
}
Select.reset(Sess);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -237,6 +241,7 @@ typedef Poco::Tuple<
Delete << IntroStatement + DateSelector;
Delete.execute();
Delete.reset(Sess);
return true;
} catch (const Poco::Exception &E) {
@@ -274,7 +279,7 @@ typedef Poco::Tuple<
if (Records.size() < HowMany)
Done = true;
}
Select.reset(Sess);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -343,6 +348,8 @@ typedef Poco::Tuple<
Poco::Data::Keywords::use(Status),
Poco::Data::Keywords::use(Window);
Update.execute();
Update.reset(Sess);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
@@ -359,6 +366,7 @@ typedef Poco::Tuple<
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Window);
Update.execute();
Update.reset(Sess);
} catch (const Poco::Exception &E) {
Logger().log(E);
}
@@ -418,6 +426,11 @@ typedef Poco::Tuple<
Delete << ConvertParams(St), Poco::Data::Keywords::use(UUID);
Delete.execute();
Delete.reset(Sess);
St = "DELETE FROM FileUploads WHERE UUID=?";
Delete << ConvertParams(St), Poco::Data::Keywords::use(UUID);
Delete.execute();
Delete.reset(Sess);
return true;
} catch (const Poco::Exception &E) {
@@ -446,6 +459,7 @@ typedef Poco::Tuple<
ConvertCommandRecord(i,R);
Commands.push_back(R);
}
Select.reset(Sess);
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -586,23 +600,26 @@ typedef Poco::Tuple<
bool Storage::AttachFileDataToCommand(std::string & UUID, const std::stringstream & FileContent, const std::string &Type) {
try {
Poco::Data::Session Sess = Pool_->get();
auto Now = Utils::Now();
uint64_t WaitForFile = 0;
Poco::Data::Statement Update(Sess);
uint64_t Size = FileContent.str().size();
std::string St{
"UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=? WHERE UUID=?"};
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Statement(Sess);
Update << ConvertParams(St),
std::string StatementStr;
// Get the existing command
StatementStr = "UPDATE CommandList SET WaitingForFile=?, AttachDate=?, AttachSize=? WHERE UUID=?";
Statement << ConvertParams(StatementStr),
Poco::Data::Keywords::use(WaitForFile),
Poco::Data::Keywords::use(Now),
Poco::Data::Keywords::use(Size),
Poco::Data::Keywords::use(UUID);
Update.execute();
Statement.execute();
if (Size < FileUploader()->MaxSize()) {
@@ -644,9 +661,11 @@ typedef Poco::Tuple<
Poco::Data::Statement Select1(Sess);
std::string TmpSerialNumber;
std::string st1{"SELECT SerialNumber FROM CommandList WHERE UUID=?"};
std::string st1{"SELECT SerialNumber, Command FROM CommandList WHERE UUID=?"};
std::string Command;
Select1 << ConvertParams(st1),
Poco::Data::Keywords::into(TmpSerialNumber),
Poco::Data::Keywords::into(Command),
Poco::Data::Keywords::use(UUID);
Select1.execute();
@@ -655,15 +674,18 @@ typedef Poco::Tuple<
}
std::string St2{"SELECT FileContent, Type FROM FileUploads WHERE UUID=?"};
Poco::Data::Statement Select2(Sess);
Select2 << ConvertParams(St2),
Poco::Data::Keywords::into(L),
Poco::Data::Keywords::into(Type),
Poco::Data::Keywords::use(UUID);
Select2.execute();
FileContent.assign(L.content().begin(),L.content().end());
if(Command=="script")
Type = "gzip";
else if(Command=="trace")
Type = "pcap";
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
@@ -712,6 +734,21 @@ typedef Poco::Tuple<
return false;
}
bool Storage::RemoveUploadedFilesRecordsOlderThan(uint64_t Date) {
try {
Poco::Data::Session Sess = Pool_->get();
Poco::Data::Statement Delete(Sess);
std::string St1{"delete from FileUploads where Created<?"};
Delete << ConvertParams(St1), Poco::Data::Keywords::use(Date);
Delete.execute();
return true;
} catch (const Poco::Exception &E) {
Logger().log(E);
}
return false;
}
bool Storage::RemoveCommandListRecordsOlderThan(uint64_t Date) {
try {
Poco::Data::Session Sess = Pool_->get();

View File

@@ -48,7 +48,10 @@ namespace OpenWifi {
"entity, "
"modified, "
"locale,"
"restrictedDevice"
"restrictedDevice,"
"pendingConfiguration, "
"pendingConfigurationCmd, "
"restrictionDetails "
};
const static std::string DB_DeviceUpdateFields{
@@ -74,10 +77,13 @@ namespace OpenWifi {
"entity=?, "
"modified=?, "
"locale=?, "
"restrictedDevice=?"
"restrictedDevice=?, "
"pendingConfiguration=?, "
"pendingConfigurationCmd=?, "
"restrictionDetails=? "
};
const static std::string DB_DeviceInsertValues{" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "};
const static std::string DB_DeviceInsertValues{" VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?) "};
typedef Poco::Tuple<
std::string,
@@ -102,7 +108,10 @@ namespace OpenWifi {
std::string,
uint64_t,
std::string,
bool
bool,
std::string,
std::string,
std::string
> DeviceRecordTuple;
typedef std::vector<DeviceRecordTuple> DeviceRecordList;
@@ -130,6 +139,9 @@ namespace OpenWifi {
D.modified = R.get<20>();
D.locale = R.get<21>();
D.restrictedDevice = R.get<22>();
D.pendingConfiguration = R.get<23>();
D.pendingConfigurationCmd = R.get<24>();
D.restrictionDetails = RESTAPI_utils::to_object<OpenWifi::GWObjects::DeviceRestrictions>(R.get<25>());
}
void ConvertDeviceRecord(const GWObjects::Device &D, DeviceRecordTuple & R) {
@@ -156,6 +168,9 @@ namespace OpenWifi {
R.set<20>(D.modified);
R.set<21>(D.locale);
R.set<22>(D.restrictedDevice);
R.set<23>(D.pendingConfiguration);
R.set<24>(D.pendingConfigurationCmd);
R.set<25>(RESTAPI_utils::to_string(D.restrictionDetails));
}
bool Storage::GetDeviceCount(uint64_t &Count) {

View File

@@ -98,6 +98,7 @@ namespace OpenWifi {
ConvertHealthCheckRecord(i,R);
Checks.push_back(R);
}
Select.reset(Sess);
return true;
}
catch (const Poco::Exception &E) {
@@ -125,6 +126,7 @@ namespace OpenWifi {
ConvertHealthCheckRecord(i,R);
Checks.push_back(R);
}
Select.reset(Sess);
return true;
}
catch (const Poco::Exception &E) {

View File

@@ -107,6 +107,7 @@ namespace OpenWifi {
ConvertLogsRecord(i,R);
Stats.push_back(R);
}
Select.reset(Sess);
return true;
}
catch (const Poco::Exception &E) {
@@ -144,6 +145,7 @@ namespace OpenWifi {
Delete << StatementStr + DateSelector + TypeSelector;
Delete.execute();
Delete.reset(Sess);
return true;
}
@@ -172,6 +174,7 @@ namespace OpenWifi {
ConvertLogsRecord(i,R);
Stats.push_back(R);
}
Select.reset(Sess);
return true;
}
catch (const Poco::Exception &E) {

View File

@@ -0,0 +1,136 @@
//
// Created by stephane bourque on 2022-11-21.
//
#include "storage_scripts.h"
#include "framework/RESTAPI_utils.h"
#include "fmt/format.h"
#include "framework/AppServiceRegistry.h"
namespace OpenWifi {
static ORM::FieldVec ScriptDB_Fields{
ORM::Field{"id", 36, true},
ORM::Field{"name", ORM::FieldType::FT_TEXT},
ORM::Field{"description", ORM::FieldType::FT_TEXT},
ORM::Field{"uri", ORM::FieldType::FT_TEXT},
ORM::Field{"content", ORM::FieldType::FT_TEXT},
ORM::Field{"version", ORM::FieldType::FT_TEXT},
ORM::Field{"type", ORM::FieldType::FT_TEXT},
ORM::Field{"created", ORM::FieldType::FT_BIGINT},
ORM::Field{"modified", ORM::FieldType::FT_BIGINT},
ORM::Field{"author", ORM::FieldType::FT_TEXT},
ORM::Field{"restricted", ORM::FieldType::FT_TEXT},
ORM::Field{"deferred", ORM::FieldType::FT_BOOLEAN},
ORM::Field{"timeout", ORM::FieldType::FT_BIGINT},
ORM::Field{"defaultUploadURI", ORM::FieldType::FT_TEXT}
};
static ORM::IndexVec MakeIndices(const std::string & shortname) {
return ORM::IndexVec{
{std::string(shortname + "_name_index"),
ORM::IndexEntryVec{
{
std::string("name"),
ORM::Indextype::ASC }}}
};
};
ScriptDB::ScriptDB( const std::string &TableName, const std::string &Shortname ,OpenWifi::DBType T,
Poco::Data::SessionPool &P, Poco::Logger &L) :
DB(T, TableName.c_str(), ScriptDB_Fields, MakeIndices(Shortname), P, L, Shortname.c_str()) {
}
bool ScriptDB::Upgrade([[maybe_unused]] uint32_t from, uint32_t &to) {
to = Version();
std::vector<std::string> Script{
};
for(const auto &i:Script) {
try {
auto Session = Pool_.get();
Session << i , Poco::Data::Keywords::now;
} catch (...) {
}
}
return true;
}
void ScriptDB::Initialize() {
bool Initialized = false;
AppServiceRegistry().Get("script_db_initialized",Initialized);
if(Initialized)
return;
GWObjects::ScriptEntry SE;
SE.id = MicroServiceCreateUUID();
SE.name = "ASB Bundle";
SE.description = "Automated on-demand detailed debugging information collection from an AP";
SE.uri = "https://telecominfraproject.atlassian.net/wiki/spaces/WIFI/pages/1678147585/AP+Support+Bundle+ASB";
SE.version = "1.0";
SE.author = "blogic";
SE.modified = SE.created = Utils::Now();
SE.type = "bundle";
SE.deferred = true;
SE.timeout = 30;
SE.content = std::string{
R"lit(
bundle.wifi();
let paths = [
[ 'network.wireless', 'status' ],
[ 'network.device', 'status' ],
[ 'network.interface', 'dump' ],
[ 'log', 'read', { stream: false } ],
];
for (let path in paths)
bundle.ubus(path[0], path[1], path[2]);
for (let config in [ 'network', 'wireless', 'dhcp', 'firewall', 'system' ])
bundle.uci(config);
for (let cmd in [ "route", "ifconfig", "logread" ])
bundle.shell(cmd);
)lit"};
if(CreateRecord(SE)) {
AppServiceRegistry().Set("script_db_initialized",true);
poco_information(Logger(), "Script DB has been in initialized.");
return;
}
poco_error(Logger(), "Script DB could not be initialized.");
}
} // OpenWifi
template<> void ORM::DB<OpenWifi::ScriptRecordTuple, OpenWifi::GWObjects::ScriptEntry>::Convert(const OpenWifi::ScriptRecordTuple &In, OpenWifi::GWObjects::ScriptEntry &Out) {
Out.id = In.get<0>();
Out.name = In.get<1>();
Out.description = In.get<2>();
Out.uri = In.get<3>();
Out.content = In.get<4>();
Out.version = In.get<5>();
Out.type = In.get<6>();
Out.created = In.get<7>();
Out.modified = In.get<8>();
Out.author = In.get<9>();
Out.restricted = OpenWifi::RESTAPI_utils::to_object_array(In.get<10>());
Out.deferred = In.get<11>();
Out.timeout = In.get<12>();
Out.defaultUploadURI = In.get<13>();
}
template<> void ORM::DB<OpenWifi::ScriptRecordTuple, OpenWifi::GWObjects::ScriptEntry>::Convert(const OpenWifi::GWObjects::ScriptEntry &In, OpenWifi::ScriptRecordTuple &Out) {
Out.set<0>(In.id);
Out.set<1>(In.name);
Out.set<2>(In.description);
Out.set<3>(In.uri);
Out.set<4>(In.content);
Out.set<5>(In.version);
Out.set<6>(In.type);
Out.set<7>(In.created);
Out.set<8>(In.modified);
Out.set<9>(In.author);
Out.set<10>(OpenWifi::RESTAPI_utils::to_string(In.restricted));
Out.set<11>(In.deferred);
Out.set<12>(In.timeout);
Out.set<13>(In.defaultUploadURI);
}

View File

@@ -0,0 +1,42 @@
//
// Created by stephane bourque on 2022-11-21.
//
#pragma once
#include "framework/orm.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
namespace OpenWifi {
typedef Poco::Tuple<
std::string, // id
std::string, // name
std::string, // description
std::string, // uri
std::string, // content
std::string, // version
std::string, // type
uint64_t, // created = 0;
uint64_t, // modified = 0;
std::string, // author
std::string, // restricted
bool, // deferred
uint64_t, // timeout
std::string
> ScriptRecordTuple;
typedef std::vector <ScriptRecordTuple> ScriptRecordTupleList;
class ScriptDB : public ORM::DB<ScriptRecordTuple, GWObjects::ScriptEntry> {
public:
ScriptDB( const std::string &name, const std::string &shortname, OpenWifi::DBType T, Poco::Data::SessionPool & P, Poco::Logger &L);
virtual ~ScriptDB() {}
inline uint32_t Version() override {
return 1;
}
bool Upgrade(uint32_t from, uint32_t &to) override;
void Initialize();
};
}

View File

@@ -130,11 +130,13 @@ namespace OpenWifi {
ConvertStatsRecord(i,R);
Stats.emplace_back(R);
}
Select.reset(Sess);
return true;
}
catch (const Poco::Exception &E) {
poco_warning(Logger(),fmt::format("{}: Failed with: {}", std::string(__func__), E.displayText()));
}
return false;
}

View File

@@ -81,7 +81,11 @@ namespace OpenWifi {
"subscriber VARCHAR(64), "
"entity VARCHAR(64), "
"modified BIGINT,"
"locale varchar(32) "
"locale varchar(32), "
"restrictedDevice BOOLEAN, "
"pendingConfiguration TEXT, "
"pendingConfigurationCmd VARCHAR(64), "
"restrictionDetails TEXT "
",INDEX DeviceOwner (Owner ASC),"
"INDEX LocationIndex (Location ASC))", Poco::Data::Keywords::now;
} else if(dbType_==sqlite || dbType_==pgsql) {
@@ -108,7 +112,10 @@ namespace OpenWifi {
"entity VARCHAR(64) , "
"modified BIGINT,"
"locale varchar(32), "
"restrictedDevice BOOLEAN "
"restrictedDevice BOOLEAN, "
"pendingConfiguration TEXT,"
"pendingConfigurationCmd VARCHAR(64), "
"restrictionDetails TEXT "
")", Poco::Data::Keywords::now;
Sess << "CREATE INDEX IF NOT EXISTS DeviceOwner ON Devices (Owner ASC)", Poco::Data::Keywords::now;
Sess << "CREATE INDEX IF NOT EXISTS DeviceLocation ON Devices (Location ASC)", Poco::Data::Keywords::now;
@@ -121,6 +128,9 @@ namespace OpenWifi {
"alter table devices add column modified bigint",
"alter table devices add column locale varchar(32)",
"alter table devices add column restrictedDevice boolean",
"alter table devices add column pendingConfiguration TEXT",
"alter table devices add column pendingConfigurationCmd VARCHAR(64)",
"alter table devices add column restrictionDetails TEXT",
};
for(const auto &i:Script) {

View File

@@ -794,6 +794,22 @@ stats7count() {
jq < ${result_file}
}
listscripts() {
curl ${FLAGS} -X GET "https://${OWGW}/api/v1/scripts" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
jq < ${result_file}
}
getscript() {
curl ${FLAGS} -X GET "https://${OWGW}/api/v1/script/$1" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer ${token}" > ${result_file}
jq < ${result_file}
}
check_response() {
if [ -s "$1" ]; then
@@ -1065,6 +1081,8 @@ case "$1" in
"notifications") login; notifications "$2"; logout;;
"stats7") login; stats7 "$2"; logout;;
"stats7count") login; stats7count "$2"; logout;;
"listscripts") login; listscripts; logout;;
"getscript") login; getscript "$2"; logout;;
"testtoken") testtoken;;
*) help ;;
esac

View File

@@ -0,0 +1,9 @@
#!/bin/bash
private_key_name="$1"-private-key.pem
public_key_name="$1"-public-key.pem
echo "Generating private key..."
openssl genrsa -out ${private_key_name} 2048
echo "Extracting public key"
openssl rsa -in ${private_key_name} -outform PEM -pubout -out ${public_key_name}

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvDyH5dKXDH6inAB6HeKekywaPoHi/kogKtsezOEaSoijdrJm
8k3ohC4NzmmXzMa9taaQCE5DMDq1ZWuv8uKyCyRSqhnBIqj6Oa7KRzVnYDpk4Vkd
FS+A++VpYhYVFeUFhtb6Ey1gkXVjOXiy3UiJuEv9aeX2PzL3IUF+o4cfkOe42QQB
k3hgWFhinjb39TtssrhUt1+/kq2EEFZmjKK7szTqpjBTZKgfvL7pkjtZ1+V7/G5R
pkYCrITh9WqyBp2lFyQbnN4GIrPVc+pr1Tk0ZbgAyRnkNaijLm79akNt3xIBzJSB
46kAUjZsKJY/Kh3FM4OoqvJRwYcWvoMXb8rRaQIDAQABAoIBAQCVgS4ep0g5MEtO
xEI5gkiYc6rUgq0bcxxhbW/lIdST5jqOh9ukD6ThdwKYMt3SUvdSU1yKfD55C+gP
CZzRuKPYnZzaZWI0eSlkryMRs6TLlRWStgiXTwePCgLNWOSeYywkkJJGsP/GCAor
F2ZYwsg/jHtVpMQUJhKKY06F60hy+Xtpe8fYEkbLfh1j7OzwBKGZOn+lp2YXXJBU
3ccSwwIpJQu/O9SM8rMchL7izNU60zONYlswr3fF148mMwDS9RYMBMCPqb6wNfNm
EhmMPR7PlsJmlV96rlniwbTh0/I67w7xEThFM2xRx2JZjBZVYD5GMNWE3tKBQnwX
H23PXzuRAoGBAOfWBTxDJZzAMXU8EK12su8bhFOv13D7HlGUA+Y2a9ngzs/rOZmg
buNTjLyod50dSPjZm2b2TDZOXPrA13b3HR+NTfDYzhMElzr4DWPF/X4c2qRylWqb
8G8xrrTsq1HQYTWbJI60zuorD8s+w3Kt/G2w6Iq590Q4Iw7uHMra8IbvAoGBAM/b
KX5BxliqNQIv3+XnSEBhQqLbE7VjPJztXtsknAO8mv/vUJJWta9NjoCGKdaKh4KF
9u88ixkfvOYYVZTbQwUhNCj5PuqW+i2ikmAucMsiVoPBXFUqnoIA5274+hQ7sf0K
JndP7FDKiJkAGb0nF6okmEQO+tHji6oL31ITde0nAoGASEyQOWjfU/ED+4GN2erI
hpTYQZj24P8PR3WXebXDEKFxHZpHzkcgDbjCjRskolS9qw2BzyxEPDNX/8Mf7rPF
208f3VpfecLWvscYteLK2Qd6kApD2oljA+pEh5u/GbaYejU1w2NTm+dt935NSXhE
3phrDMhN+nJfTIqpZAG/PPUCgYEAi5tWSTkAcbkQlYF2TsKDIsqwqRWgLSqUIYrF
NUdnipL5QIGKil+29CGRXv29yB2PWrmD27e8bYmFpL4fbTW/1AgzMnoGKiZxrokM
65EFrUpI9YG/9GwFvqfAyiZsQX6+04gnwedqf/EowirxHrzNBjhCFSRCjwrYWcRT
oJr1j+0CgYA7LktUigAIoLTlo09nGoN7UBySRBRCn6e+vSSyasWLVQ3KPX9tmKDH
UXSSFoki+vcbFG/IgrwfawhmPlcXUPxa021Kj0HPiNGrKK/klhuSmkWulP9xzuAM
8SqN58+BnOYxFQDXJq2ui6NJ+I1O7Mj+uaSiNzpMgqcHazRQy5c+cQ==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvDyH5dKXDH6inAB6HeKe
kywaPoHi/kogKtsezOEaSoijdrJm8k3ohC4NzmmXzMa9taaQCE5DMDq1ZWuv8uKy
CyRSqhnBIqj6Oa7KRzVnYDpk4VkdFS+A++VpYhYVFeUFhtb6Ey1gkXVjOXiy3UiJ
uEv9aeX2PzL3IUF+o4cfkOe42QQBk3hgWFhinjb39TtssrhUt1+/kq2EEFZmjKK7
szTqpjBTZKgfvL7pkjtZ1+V7/G5RpkYCrITh9WqyBp2lFyQbnN4GIrPVc+pr1Tk0
ZbgAyRnkNaijLm79akNt3xIBzJSB46kAUjZsKJY/Kh3FM4OoqvJRwYcWvoMXb8rR
aQIDAQAB
-----END PUBLIC KEY-----

View File

@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAvPbxCM3RvHaAZq0G9yXgzaHy9q/RzuIKiCC8cmVQ2PsTvx2m
YP75Ech0omMbWr+nfcgNGHrIxmTXM8Jr77oH9J1pUiBZj0plWp3Bj6S4on7OfRBi
tq6rFUvjyGVg08Khp+KLnPE2Ga+YksC/mK7oXjYRyjH99uX9pOCPJDj1rFpsvDjP
0xu9nkgvhWfzqPvLsLZv5RHM+a1TigckSGl3CpWUNkU/o7ozfvMUQgTBvalbCSTY
9PE3JvkoPd2DARoOmtpAsUkCVx5V18+j5aCxYIG8tPONh8addblLYeskKI9PvzSE
hmazT5deaQHSSLwZo96qtXcdMPIilcSqet9NfQIDAQABAoIBABSEi691Caz5AQAl
EXiMeFhbmVIHzTQ1fwdA5rVVIu4sdPxvb71gchLoPSHUuQelf748lo9t5ZcFJAjO
t4GUJYD+Bo2QTaktXsv0DSxXqmSaeDlEKjPDy3fIgbckqtrTa1IbWyVzW3h2hI6K
t0MQ2tI/9LaLrxO77UqVx3UbajGIf/M2GI91ZChaEa37YpIDu1so4NNZIzGQV3oT
Gq+XpWOtmw/6Dk2AEQHdibytge58yTXZLoe49n02X2UepHNd9Bnwv5WvmJZqgA+r
UI67YCfg35NoT45p7RMYcZCHvZU7+nYMCgDxV9o91VpylZ99plhFVRZSCfI0Ynrq
t9aX4tECgYEA9QSTbTGDZwzmKHHc75ZapjJKkATnszOYF7pgRqOv+5UWayhy3J/z
hyTAGjGr2FQH5HwGAvAwVsJ1WhQHedk/W8lqea+EqCHSau/HGsYQKD061jP0x2G6
zSiBKi0sHxFDRztV9Llny2eCLHGBR+yFQRZW1DwLwpsFg8EeYIcmoV8CgYEAxW8w
sJHW8uz3wW0ntE0dSKVEKImb+pgNI0LS30X0KJilDTliNLHPphhYQvEl4H2t2XXd
x3O4KbQ0fnXi7iyEO6v95ZH8P4OcjpZ2wXV51t8H5DD9hCTXc7yLR+FhaH3XoNVf
EETjiTwPdCa0MsswKRF/39chYQ1sF5a6n6t+MqMCgYEA8jPjyDz5uBR4L+Lek7f9
Q+zS6CrxH6QQ5OPH6AxHGlr2HleNs6oqAZ3CiCIxzVbDtokjKCRmpFz1xGWoPjsS
9pjUOBXY/JrydeMw3raLojtkvfn+LlndXpB7nkWpJ8zYxMFS5uegQuG/PE+3jHGy
B/UdQA9bULQNb4CnlqQC++ECgYEAunNWFPm1d7aoBygRXemRZSCF7I6AGjjr90fN
IwPKH2iAPqvZfZAKXH4TJCzeK1IlEv+HkStMWT4QcPjddTXfLwcvAFVMVaLx/4pC
3lIV3QDFUA+f6uJsAaWmFxzWQ7rMHtxCKXgVNW3d3kAK3wkaEz6ud3KP2Dq3wNMc
rVtkE2cCgYB5cNbmStIlmc/bpBGkfW7Sv1RwPVCV3U5Vv4NDoM+EDJ4UDmRKB0Ht
cG5bfym6bgcBOWVAQNsNgpGJGAfF3RIVzeFgiD/cDDG04dIia9T7HuSbsJSoXYde
gSI068hPzfh3xksus0RPPr5DDKlTUsD5e02ZgrlmRez6ILV2dMhyCQ==
-----END RSA PRIVATE KEY-----

View File

@@ -0,0 +1,9 @@
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvPbxCM3RvHaAZq0G9yXg
zaHy9q/RzuIKiCC8cmVQ2PsTvx2mYP75Ech0omMbWr+nfcgNGHrIxmTXM8Jr77oH
9J1pUiBZj0plWp3Bj6S4on7OfRBitq6rFUvjyGVg08Khp+KLnPE2Ga+YksC/mK7o
XjYRyjH99uX9pOCPJDj1rFpsvDjP0xu9nkgvhWfzqPvLsLZv5RHM+a1TigckSGl3
CpWUNkU/o7ozfvMUQgTBvalbCSTY9PE3JvkoPd2DARoOmtpAsUkCVx5V18+j5aCx
YIG8tPONh8addblLYeskKI9PvzSEhmazT5deaQHSSLwZo96qtXcdMPIilcSqet9N
fQIDAQAB
-----END PUBLIC KEY-----