REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
auth.h
Go to the documentation of this file.
1// Copyright (c) 2023 anabrid GmbH
2// Contact: https://www.anabrid.com/licensing/
3// SPDX-License-Identifier: MIT OR GPL-2.0-or-later
4
5#pragma once
6
7#ifdef ARDUINO
8
9#include <IPAddress.h>
10#include <Printable.h>
11#include <cstring>
12#include <list>
13#include <map>
14
15#include "utils/durations.h"
16#include "utils/json.h"
17#include "utils/mac.h"
18#include "utils/singleton.h"
19
21
22namespace net {
23
30namespace auth {
31
36
37using User = std::string;
38
39class AuthentificationContext; // defined below
40
53 // bool enable_authentification;
54 std::map<User, std::string> db;
55
56public:
58 static constexpr const char *admin = "admin";
59
61 static constexpr const char *user = "user";
62
63 void reset_defaults();
64
65 bool is_disabled() const { return /* !enable_authentification ||*/ db.empty(); }
66
67 bool is_valid(const User &user, const std::string &pwd) {
68 return /*is_disabled() ||*/ (db.count(user) && db[user] == pwd);
69 }
70
71 bool can_do(const User &user, SecurityLevel task) const {
72 // if(is_disabled()) return true;
74 return user == admin;
76 return !user.empty();
77 /* if RequiresNothing */ return true;
78 }
79
80 // note that these serializations deal with the sensitive user+password information
81 // and are only used for eeprom::UserSettings.
82 void fromJson(JsonObjectConst serialized_conf);
83 void toJson(JsonObject target) const;
84
85 // if you want to let (any) remote users know something, use this
86 void status(JsonObject target);
87};
88
90
92class RemoteIdentifier { // : public Printable { // no inheritance for POD
93public:
94 IPAddress ip;
95
96 bool isLocal() const {
97 return ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0;
98 } // (uint32_t)ip) doesnt work
99
100 size_t printTo(Print &p) const { return isLocal() ? p.print("[serial-local]") : ip.printTo(p); }
101};
102
109 static constexpr utils::time_ms max_lock_duration = 3 * 60 * 1000; // 3min...
110
111 void check() {
113 /* force_unlock(): */ holder.clear();
114 }
115
116 bool is_locked() {
117 check();
118 return !holder.empty();
119 }
120
121 void force_unlock() { holder.clear(); }
122
123 void enable_lock(const User &user) {
124 holder = user;
126 }
127};
128
136 uint8_t max_known_stations = 20;
137 constexpr static utils::time_ms max_waiting_time = 10 * 1000; // 10sec
138
139 struct EndpointInformation {
140 IPAddress ip;
141 utils::duration last_failure;
142 uint8_t failures = 0;
143 };
144
145 std::list<EndpointInformation> endpoints;
146
147 void clean() {
148 if (endpoints.size() >= max_known_stations)
149 endpoints.pop_front();
150 endpoints.remove_if([](EndpointInformation &a) { return a.last_failure.expired(max_waiting_time); });
151 }
152
153 EndpointInformation *find(const IPAddress &ip) {
154 for (auto &e : endpoints)
155 if (e.ip == ip)
156 return &e;
157 return nullptr;
158 }
159
160public:
161 utils::time_ms failure_time(const IPAddress &ip) {
162 clean();
163 EndpointInformation *e;
164 uint8_t failures = 1;
165 if ((e = find(ip)))
166 failures = ++e->failures;
167 else
168 endpoints.push_back({ip, utils::duration(), failures});
169 return failures * failures * 100; // roughly 1sec after 3 attempts then up to 10secs timeout
170 }
171};
172
184
187
190
192 // TODO, check also websocket_upgrade Origin field.
193
195 int login(JsonObjectConst msg_in, JsonObject &msg_out, AuthentificationContext &user_context);
196 int lock_acquire(JsonObjectConst msg_in, JsonObject &msg_out, AuthentificationContext &user_context);
197 int lock_release(JsonObjectConst msg_in, JsonObject &msg_out, AuthentificationContext &user_context);
198
199
200 std::string name() const { return "auth"; }
201
202 void reset_defaults() override;
203
212
213 void toJson(JsonObject target, nvmconfig::Context c = nvmconfig::Context::Flash) const override {
214 JSON_SET(target, enable_auth);
215 JSON_SET(target, enable_users);
216 JSON_SET(target, enable_whitelist);
217 JSON_SET(target, users);
218 JSON_SET(target, whitelist);
220 }
221};
222
224
231class AuthentificationContext : public Printable {
232 static UserPasswordAuthentification &auth() { return Gatekeeper::get().users; }
233
234 RemoteIdentifier _remote;
235 User _user;
236
237public:
239
241
243
244 bool can_do(SecurityLevel task) const {
245 // TODO Also implement IP-based access here
246 #ifdef ANABRID_UNSAFE_INTERNET
247 return true;
248 #else
249 return !Gatekeeper::get().enable_auth || !Gatekeeper::get().enable_users || auth().can_do(_user, task);
250 #endif
251 }
252
257
258 void login(const User &user) { _user = user; }
259
260 User user() const { return _user.empty() ? "[nobody]" : _user; }
261
262 size_t printTo(Print &p) const override {
263 return p.print(user().c_str()) + p.print("@") + _remote.printTo(p);
264 }
265};
266
267} // namespace auth
268} // namespace net
269
270#endif // ARDUINO
A thin wrapper around the username.
Definition auth.h:231
bool hasBetterClearenceThen(const User &other) const
Definition auth.h:253
bool can_do(SecurityLevel task) const
Definition auth.h:244
void login(const User &user)
Definition auth.h:258
void set_remote_identifier(RemoteIdentifier r)
Definition auth.h:242
size_t printTo(Print &p) const override
Definition auth.h:262
Simple failed login backoff to avoid login brute force attempts.
Definition auth.h:135
utils::time_ms failure_time(const IPAddress &ip)
Definition auth.h:161
Some basic information about the remote station. We interpret 0.0.0.0 als a local terminal.
Definition auth.h:92
bool isLocal() const
Definition auth.h:96
size_t printTo(Print &p) const
Definition auth.h:100
A simple plaintext Username+Password authentification scheme backed against the EEPROM UserSettings.
Definition auth.h:52
void toJson(JsonObject target) const
Definition auth.cpp:53
static constexpr const char * user
This is the default non-admin user.
Definition auth.h:61
bool is_valid(const User &user, const std::string &pwd)
Definition auth.h:67
static constexpr const char * admin
The admin user is singular and has all permissions.
Definition auth.h:58
void reset_defaults()
reset to distributor defaults
Definition auth.cpp:29
void fromJson(JsonObjectConst serialized_conf)
Definition auth.cpp:46
bool can_do(const User &user, SecurityLevel task) const
Definition auth.h:71
Define singletons which are not static-space allocated (and thus consume valuable ICTM space).
Definition singleton.h:46
static Gatekeeper & get()
Definition singleton.h:48
utils::status status
Definition daq.h:28
uint32_t src
Definition flasher.cpp:63
#define JSON_GET(src, key)
Definition json.h:15
#define JSON_CONVERT_SUGAR(type)
Definition json.h:11
#define JSON_GET_AS(src, key, type)
Definition json.h:18
#define JSON_SET(target, key)
Definition json.h:21
std::string User
Definition auth.h:37
SecurityLevel
Simple security levels for the message handlers.
Definition auth.h:35
Definition auth.h:22
@ Flash
Flash-Facing (writing/reading)
uint32_t time_ms
Definition durations.h:12
Facilities to lock a LUCIDAC device by a single user.
Definition auth.h:106
void force_unlock()
Definition auth.h:121
void enable_lock(const User &user)
Definition auth.h:123
static constexpr utils::time_ms max_lock_duration
Definition auth.h:109
utils::duration locked_at
Definition auth.h:108
Actually carries out login.
Definition auth.h:180
void toJson(JsonObject target, nvmconfig::Context c=nvmconfig::Context::Flash) const override
Definition auth.h:213
FailToBan ban
Definition auth.h:189
std::string name() const
Definition auth.h:200
int lock_release(JsonObjectConst msg_in, JsonObject &msg_out, AuthentificationContext &user_context)
Definition auth.cpp:121
void reset_defaults() override
Definition auth.cpp:13
UserPasswordAuthentification users
Definition auth.h:185
std::string access_control_allow_origin
For webserver: CORS setting.
Definition auth.h:191
bool enable_users
Enable/disable login at all, i.e. the user-password authentification.
Definition auth.h:182
void fromJson(JsonObjectConst src, nvmconfig::Context c=nvmconfig::Context::Flash) override
Definition auth.h:204
int lock_acquire(JsonObjectConst msg_in, JsonObject &msg_out, AuthentificationContext &user_context)
Definition auth.cpp:109
DeviceLock lock
Definition auth.h:188
bool enable_auth
Overall switch to enable/disable security hardness.
Definition auth.h:181
utils::IPMaskList whitelist
Definition auth.h:186
bool enable_whitelist
Enable/disable the IP Whitelist lookup.
Definition auth.h:183
int login(JsonObjectConst msg_in, JsonObject &msg_out, AuthentificationContext &user_context)
Carrys out an actual login.
Definition auth.cpp:67
Represents a list of IP Addresses.
Definition mac.h:65
Simple time tracking (up to 50 days)
Definition durations.h:15
bool expired(time_ms period) const
Returns true if period expired, false otherwise.
Definition durations.h:23