REDAC HybridController
Firmware for LUCIDAC/REDAC Teensy
Loading...
Searching...
No Matches
auth.cpp
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#include "net/auth.h"
6#include <Arduino.h>
7
8#include <net/auth.h>
9#include <nvmconfig/vendor.h>
10#include <utils/logging.h>
11
12void net::auth::Gatekeeper::reset_defaults() {
13#ifdef ANABRID_UNSAFE_INTERNET
14 enable_auth = false;
15#else
16 enable_auth = true;
17#endif
18
19 enable_users = true;
20 enable_whitelist = false; // Feature does not ship in v1.0
21
22 access_control_allow_origin = "*";
23
24 users.reset_defaults();
25 whitelist.list.clear();
26}
27
28void net::auth::UserPasswordAuthentification::reset_defaults() {
29 db.clear();
30
31 auto default_admin_password = nvmconfig::VendorOTP::get().default_admin_password;
32
33 // "user" is just a non-admin default user which new ... users ... are supposed to
34 // work with.
35 auto default_user_password = nvmconfig::VendorOTP::get().default_user_password;
36
37 if (!default_admin_password.empty())
38 db[admin] = default_admin_password;
39 if (!default_user_password.empty())
40 db[user] = default_user_password;
41
42 LOG_ALWAYS("UserPasswordAuthentification::reset_defaults() resetting admin and default user.");
43}
44
45void net::auth::UserPasswordAuthentification::fromJson(JsonObjectConst serialized_conf) {
46 db.clear();
47 for (JsonPairConst kv : serialized_conf) {
48 db[kv.key().c_str()] = kv.value().as<std::string>();
49 }
50}
51
52void net::auth::UserPasswordAuthentification::toJson(JsonObject target) const {
53 for (auto const &kv : db) {
54 target[kv.first] = kv.second;
55 }
56}
57
58void net::auth::UserPasswordAuthentification::status(JsonObject target) {
59 target["enabled"] = !is_disabled();
60 auto users = target.createNestedArray("users");
61 for (auto const &kv : db)
62 users.add(kv.first);
63 // don't tell the passwords!
64}
65
66int net::auth::Gatekeeper::login(JsonObjectConst msg_in, JsonObject &msg_out,
67 net::auth::AuthentificationContext &user_context) {
68 if (!enable_auth && !enable_users) {
69 msg_out["error"] = "No authentification neccessary. Auth system is currently disabled (either by firmware "
70 "build or user settings).";
71 return 10;
72 } else {
73 std::string new_user = msg_in["user"];
74 if (user_context.hasBetterClearenceThen(new_user)) {
75 // This case avoids users from locking themself out of the serial console where they
76 // always have admin permissions. It is not that interesting in a TCP/IP connection.
77 msg_out["error"] =
78 "Login can only upgrade privileges but you wold loose. Open a new connection instead.";
79 return 1;
80 } else if (!users.is_valid(new_user, msg_in["password"])) {
81 msg_out["error"] = "Invalid username or password.";
82
83 // todo: besseren DEBUG flag für finden, vgl.
84 // https://lab.analogparadigm.com/lucidac/firmware/hybrid-controller/-/merge_requests/3#note_2361
85 /*
86 #if defined(ANABRID_DEBUG) || defined(ANABRID_DEBUG_INIT)
87 // Show correct usernames and passwords on the console
88 Serial.println("Since authentificiation failed and debug mode is on, this is the list of currently
89 allowed passwords:");
90 // TODO: Use LOG statements instead of Serial.print.
91 StaticJsonDocument<500> kvmap;
92 write_to_json(kvmap.to<JsonObject>());
93 serializeJson(kvmap, Serial);
94 Serial.println();
95 #endif
96 */
97
98 return 2;
99 } else {
100 user_context.login(new_user);
101
102 LOG_ALWAYS("New authentification"); // TODO: user_context must be Printable or so.
103
104 return 0;
105 }
106 }
107}
108
109int net::auth::Gatekeeper::lock_acquire(JsonObjectConst msg_in, JsonObject &msg_out,
110 AuthentificationContext &user_context) {
111 // Registry asserts that user is logged in, i.e. user_context.can_do(SecurityLevel::RequiresLogin)
112 if (lock.is_locked()) {
113 msg_out["error"] = "Computer is already locked"; // say by whom: lock.user
114 return 1;
115 } else {
116 lock.enable_lock(user_context.user());
117 return 0;
118 }
119}
120
121int net::auth::Gatekeeper::lock_release(JsonObjectConst msg_in, JsonObject &msg_out,
122 AuthentificationContext &user_context) {
123 if (!enable_users || user_context.user() == lock.holder ||
124 user_context.can_do(SecurityLevel::RequiresAdmin)) {
125 lock.force_unlock();
126 return 0;
127 }
128 return 1;
129}