Browse Source

0.8.78

* try to finalize API token protection
pull/1433/head
lumapu 1 year ago
parent
commit
8b2db4abfa
  1. 3
      src/CHANGES.md
  2. 12
      src/app.h
  3. 5
      src/appInterface.h
  4. 40
      src/web/Protection.h
  5. 24
      src/web/RestApi.h
  6. 4
      src/web/web.h

3
src/CHANGES.md

@ -1,5 +1,8 @@
# Development Changes # Development Changes
## 0.8.78 - 2024-02-09
* finalized API token access #1415
## 0.8.77 - 2024-02-08 ## 0.8.77 - 2024-02-08
* merge PR: BugFix: ACK #1414 * merge PR: BugFix: ACK #1414
* fix suspicious if condition #1416 * fix suspicious if condition #1416

12
src/app.h

@ -251,8 +251,8 @@ class app : public IApp, public ah::Scheduler {
mProtection->lock(); mProtection->lock();
} }
char *unlock(const char *clientIp) override { char *unlock(const char *clientIp, bool loginFromWeb) override {
return mProtection->unlock(clientIp); return mProtection->unlock(clientIp, loginFromWeb);
} }
void resetLockTimeout(void) override { void resetLockTimeout(void) override {
@ -263,12 +263,8 @@ class app : public IApp, public ah::Scheduler {
return mProtection->isProtected(); return mProtection->isProtected();
} }
bool isProtected(const char *clientIp) const override { bool isProtected(const char *token, bool askedFromWeb) const override {
return mProtection->isProtected(clientIp); return mProtection->isProtected(token, askedFromWeb);
}
bool isProtected(const char *clientIp, const char *token) const override {
return mProtection->isProtected(clientIp, token);
} }
bool getNrfEnabled(void) override { bool getNrfEnabled(void) override {

5
src/appInterface.h

@ -62,11 +62,10 @@ class IApp {
virtual uint32_t getMqttTxCnt() = 0; virtual uint32_t getMqttTxCnt() = 0;
virtual void lock(void) = 0; virtual void lock(void) = 0;
virtual char *unlock(const char *clientIp) = 0; virtual char *unlock(const char *clientIp, bool loginFromWeb) = 0;
virtual void resetLockTimeout(void) = 0; virtual void resetLockTimeout(void) = 0;
virtual bool isProtected(void) const = 0; virtual bool isProtected(void) const = 0;
virtual bool isProtected(const char *clientIp) const = 0; virtual bool isProtected(const char *token, bool askedFromWeb) const = 0;
virtual bool isProtected(const char *clientIp, const char *token) const = 0;
virtual uint16_t getHistoryValue(uint8_t type, uint16_t i) = 0; virtual uint16_t getHistoryValue(uint8_t type, uint16_t i) = 0;
virtual uint16_t getHistoryMaxDay() = 0; virtual uint16_t getHistoryMaxDay() = 0;

40
src/web/Protection.h

@ -40,8 +40,9 @@ class Protection {
// auto logout // auto logout
if(0 != mLogoutTimeout) { if(0 != mLogoutTimeout) {
if (0 == --mLogoutTimeout) { if (0 == --mLogoutTimeout) {
if(mPwd[0] != '\0') if(mPwd[0] != '\0') {
mProtected = true; mProtected = true;
}
} }
} }
} }
@ -49,13 +50,17 @@ class Protection {
void lock(void) { void lock(void) {
mProtected = true; mProtected = true;
mLoginIp.fill(0); mLoginIp.fill(0);
mToken.fill(0);
} }
char *unlock(const char *clientIp) { char *unlock(const char *clientIp, bool loginFromWeb) {
mLogoutTimeout = LOGOUT_TIMEOUT; mLogoutTimeout = LOGOUT_TIMEOUT;
mProtected = false; mProtected = false;
ah::ip2Arr(static_cast<uint8_t*>(mLoginIp.data()), clientIp);
genToken(); if(loginFromWeb)
ah::ip2Arr(static_cast<uint8_t*>(mLoginIp.data()), clientIp);
else
genToken();
return reinterpret_cast<char*>(mToken.data()); return reinterpret_cast<char*>(mToken.data());
} }
@ -69,28 +74,25 @@ class Protection {
return mProtected; return mProtected;
} }
bool isProtected(const char *clientIp, const char *token) const { bool isProtected(const char *token, bool askedFromWeb) const { // token == clientIp
if(isProtected(clientIp))
return true;
if(0 == mToken[0]) // token is zero
return true;
return (0 != strncmp(token, mToken.data(), 16));
}
bool isProtected(const char *clientIp) const {
if(mProtected) if(mProtected)
return true; return true;
if(mPwd[0] == '\0') if(mPwd[0] == '\0')
return false; return false;
std::array<uint8_t, 4> ip; if(askedFromWeb) { // check IP address
ah::ip2Arr(static_cast<uint8_t*>(ip.data()), clientIp); std::array<uint8_t, 4> ip;
for(uint8_t i = 0; i < 4; i++) { ah::ip2Arr(static_cast<uint8_t*>(ip.data()), token);
if(mLoginIp[i] != ip[i]) for(uint8_t i = 0; i < 4; i++) {
if(mLoginIp[i] != ip[i])
return true;
}
} else { // API call - check token
if(0 == mToken[0]) // token is zero
return true; return true;
return (0 != strncmp(token, mToken.data(), 16));
} }
return false; return false;

24
src/web/RestApi.h

@ -266,7 +266,7 @@ class RestApi {
obj[F("modules")] = String(mApp->getVersionModules()); obj[F("modules")] = String(mApp->getVersionModules());
obj[F("build")] = String(AUTO_GIT_HASH); obj[F("build")] = String(AUTO_GIT_HASH);
obj[F("env")] = String(ENV_NAME); obj[F("env")] = String(ENV_NAME);
obj[F("menu_prot")] = mApp->isProtected(request->client()->remoteIP().toString().c_str()); obj[F("menu_prot")] = mApp->isProtected(request->client()->remoteIP().toString().c_str(), true);
obj[F("menu_mask")] = (uint16_t)(mConfig->sys.protectionMask ); obj[F("menu_mask")] = (uint16_t)(mConfig->sys.protectionMask );
obj[F("menu_protEn")] = (bool) (mConfig->sys.adminPwd[0] != '\0'); obj[F("menu_protEn")] = (bool) (mConfig->sys.adminPwd[0] != '\0');
obj[F("cst_lnk")] = String(mConfig->plugin.customLink); obj[F("cst_lnk")] = String(mConfig->plugin.customLink);
@ -833,7 +833,7 @@ class RestApi {
bool setCtrl(JsonObject jsonIn, JsonObject jsonOut, const char *clientIP) { bool setCtrl(JsonObject jsonIn, JsonObject jsonOut, const char *clientIP) {
if(F("auth") == jsonIn[F("cmd")]) { if(F("auth") == jsonIn[F("cmd")]) {
if(String(jsonIn["val"]) == String(mConfig->sys.adminPwd)) if(String(jsonIn["val"]) == String(mConfig->sys.adminPwd))
jsonOut["token"] = mApp->unlock(clientIP); jsonOut["token"] = mApp->unlock(clientIP, false);
else { else {
jsonOut[F("error")] = F(AUTH_ERROR); jsonOut[F("error")] = F(AUTH_ERROR);
return false; return false;
@ -841,20 +841,10 @@ class RestApi {
return true; return true;
} }
/*if(mConfig->sys.adminPwd[0] != '\0') { // check if admin password is set
if(strncmp("*", clientIP, 1) != 0) { // no call from MqTT
const char* token = jsonIn["token"];
if(mApp->isProtected(clientIP, token)) {
jsonOut[F("error")] = F(IS_PROTECTED);
jsonOut[F("bla")] = String(token);
return false;
}
}
}*/
if(mConfig->sys.adminPwd[0] != '\0') { // check if admin password is set if(mConfig->sys.adminPwd[0] != '\0') { // check if admin password is set
if(strncmp("*", clientIP, 1) != 0) { // no call from MqTT if(strncmp("*", clientIP, 1) != 0) { // no call from MqTT
if(mApp->isProtected(clientIP)) { const char* token = jsonIn["token"];
if(mApp->isProtected(token, false)) {
jsonOut[F("error")] = F(IS_PROTECTED); jsonOut[F("error")] = F(IS_PROTECTED);
return false; return false;
} }
@ -904,15 +894,15 @@ class RestApi {
} }
bool setSetup(JsonObject jsonIn, JsonObject jsonOut, const char *clientIP) { bool setSetup(JsonObject jsonIn, JsonObject jsonOut, const char *clientIP) {
/*if(mConfig->sys.adminPwd[0] != '\0') { // check if admin password is set if(mConfig->sys.adminPwd[0] != '\0') { // check if admin password is set
if(strncmp("*", clientIP, 1) != 0) { // no call from MqTT if(strncmp("*", clientIP, 1) != 0) { // no call from MqTT
const char* token = jsonIn["token"]; const char* token = jsonIn["token"];
if(mApp->isProtected(clientIP, token)) { if(mApp->isProtected(token, false)) {
jsonOut[F("error")] = F(IS_PROTECTED); jsonOut[F("error")] = F(IS_PROTECTED);
return false; return false;
} }
} }
}*/ }
#if !defined(ETHERNET) #if !defined(ETHERNET)
if(F("scan_wifi") == jsonIn[F("cmd")]) if(F("scan_wifi") == jsonIn[F("cmd")])

4
src/web/web.h

@ -227,7 +227,7 @@ class Web {
} }
void checkProtection(AsyncWebServerRequest *request) { void checkProtection(AsyncWebServerRequest *request) {
if(mApp->isProtected(request->client()->remoteIP().toString().c_str())) { if(mApp->isProtected(request->client()->remoteIP().toString().c_str(), true)) {
checkRedirect(request); checkRedirect(request);
return; return;
} }
@ -314,7 +314,7 @@ class Web {
if (request->args() > 0) { if (request->args() > 0) {
if (String(request->arg("pwd")) == String(mConfig->sys.adminPwd)) { if (String(request->arg("pwd")) == String(mConfig->sys.adminPwd)) {
mApp->unlock(request->client()->remoteIP().toString().c_str()); mApp->unlock(request->client()->remoteIP().toString().c_str(), true);
request->redirect("/"); request->redirect("/");
} }
} }

Loading…
Cancel
Save