Duo Auth
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
#define NUKI_HUB_VERSION "9.08"
|
||||
#define NUKI_HUB_VERSION_INT (uint32_t)908
|
||||
#define NUKI_HUB_BUILD "unknownbuildnr"
|
||||
#define NUKI_HUB_DATE "2025-01-17"
|
||||
#define NUKI_HUB_DATE "2025-01-20"
|
||||
|
||||
#define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest"
|
||||
#define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json"
|
||||
|
||||
@@ -38,7 +38,7 @@ HomeAssistantDiscovery::HomeAssistantDiscovery(NetworkDevice* device, Preference
|
||||
Log->println(curDevId);
|
||||
Log->print("Saved ID: ");
|
||||
Log->println(savedDevId);
|
||||
Log->println("Efuse ID and NukiHub device ID do not match, removing HASS setup for incorrect NukiHub device ID.");
|
||||
Log->println("Efuse ID and Nuki Hub device ID do not match, removing HomeAssistant setup for incorrect Nuki Hub device ID.");
|
||||
char uidString[20];
|
||||
itoa(_preferences->getUInt(preference_device_id_lock, 0), uidString, 10);
|
||||
removeHASSConfig(uidString);
|
||||
@@ -60,7 +60,7 @@ void HomeAssistantDiscovery::setupHASS(int type, uint32_t nukiId, char* nukiName
|
||||
if(type == 0)
|
||||
{
|
||||
publishHASSNukiHubConfig();
|
||||
Log->println("HASS setup for NukiHub completed.");
|
||||
Log->println("HomeAssistant setup for Nuki Hub completed.");
|
||||
}
|
||||
else if(type == 1)
|
||||
{
|
||||
@@ -71,7 +71,7 @@ void HomeAssistantDiscovery::setupHASS(int type, uint32_t nukiId, char* nukiName
|
||||
String lockTopic = _baseTopic;
|
||||
lockTopic.concat("/lock");
|
||||
publishHASSConfig((char*)"SmartLock", lockTopic.c_str(), nukiName, uidString, firmwareVersion, hardwareVersion, hasDoorSensor, hasKeypad, publishAuthData, (char*)"lock", (char*)"unlock", (char*)"unlatch");
|
||||
Log->println("HASS setup for lock completed.");
|
||||
Log->println("HomeAssistant setup for lock completed.");
|
||||
}
|
||||
else if(type == 2)
|
||||
{
|
||||
@@ -90,7 +90,7 @@ void HomeAssistantDiscovery::setupHASS(int type, uint32_t nukiId, char* nukiName
|
||||
publishHASSConfig((char*)"Opener", openerTopic.c_str(), nukiName, uidString, firmwareVersion, hardwareVersion, hasDoorSensor, hasKeypad, publishAuthData, (char*)"deactivateRTO", (char*)"activateRTO", (char*)"electricStrikeActuation");
|
||||
}
|
||||
|
||||
Log->println("HASS setup for opener completed.");
|
||||
Log->println("HomeAssistant setup for opener completed.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ void HomeAssistantDiscovery::publishHASSNukiHubConfig()
|
||||
JsonArray ids = dev["ids"].to<JsonArray>();
|
||||
ids.add(String("nuki_") + _nukiHubUidString);
|
||||
json["dev"]["mf"] = "Technyon";
|
||||
json["dev"]["mdl"] = "NukiHub";
|
||||
json["dev"]["mdl"] = "Nuki Hub";
|
||||
json["dev"]["name"] = _hostname.c_str();
|
||||
json["dev"]["sw"] = NUKI_HUB_VERSION;
|
||||
json["dev"]["hw"] = NUKI_HUB_HW;
|
||||
|
||||
@@ -76,6 +76,18 @@
|
||||
#define preference_mqtt_ssl_enabled (char*)"mqttSSLena"
|
||||
#define preference_lock_gemini_pin (char*)"geminiPin"
|
||||
#define preference_lock_gemini_enabled (char*)"geminiena"
|
||||
#define preference_cred_duo_enabled (char*)"duoena"
|
||||
#define preference_cred_duo_host (char*)"duoHost"
|
||||
#define preference_cred_duo_ikey (char*)"duoIkey"
|
||||
#define preference_cred_duo_skey (char*)"duoSkey"
|
||||
#define preference_cred_duo_user (char*)"duoUser"
|
||||
#define preference_https_fqdn (char*)"httpsFQDN"
|
||||
#define preference_bypass_proxy (char*)"credBypass"
|
||||
#define preference_cred_session_lifetime (char*)"credLf"
|
||||
#define preference_cred_session_lifetime_remember (char*)"credLfRmbr"
|
||||
#define preference_cred_session_lifetime_duo (char*)"credLfDuo"
|
||||
#define preference_cred_session_lifetime_duo_remember (char*)"credLfDuoRmbr"
|
||||
#define preference_cred_duo_approval (char*)"duoApprove"
|
||||
|
||||
// CHANGE DOES NOT REQUIRE REBOOT TO TAKE EFFECT
|
||||
#define preference_find_best_rssi (char*)"nwbestrssi"
|
||||
@@ -130,6 +142,7 @@
|
||||
#define preference_hybrid_reboot_on_disconnect (char*)"hybridRbtLck"
|
||||
|
||||
//NOT USER CHANGABLE
|
||||
#define preference_mfa_reconfigure (char*)"mfaRECONF"
|
||||
#define preference_ntw_reconfigure (char*)"ntwRECONF"
|
||||
#define preference_updater_version (char*)"updVer"
|
||||
#define preference_updater_build (char*)"updBuild"
|
||||
@@ -179,8 +192,15 @@ inline void initPreferences(Preferences* preferences)
|
||||
preferences->putBytes(preference_conf_lock_advanced_acl, (byte*)(&advancedLockConfigAclPrefs), sizeof(advancedLockConfigAclPrefs));
|
||||
uint32_t advancedOpenerConfigAclPrefs[21] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
|
||||
preferences->putBytes(preference_conf_opener_advanced_acl, (byte*)(&advancedOpenerConfigAclPrefs), sizeof(advancedOpenerConfigAclPrefs));
|
||||
|
||||
preferences->putString(preference_mqtt_lock_path, "nukihub");
|
||||
preferences->putString(preference_time_server, "pool.ntp.org");
|
||||
preferences->putString(preference_cred_duo_host, "");
|
||||
preferences->putString(preference_cred_duo_ikey, "");
|
||||
preferences->putString(preference_cred_duo_skey, "");
|
||||
preferences->putString(preference_cred_duo_user, "");
|
||||
preferences->putString(preference_https_fqdn, "");
|
||||
preferences->putString(preference_bypass_proxy, "");
|
||||
|
||||
preferences->putBool(preference_check_updates, true);
|
||||
preferences->putBool(preference_opener_continuous_mode, false);
|
||||
@@ -194,7 +214,6 @@ inline void initPreferences(Preferences* preferences)
|
||||
preferences->putBool(preference_enable_bootloop_reset, false);
|
||||
preferences->putBool(preference_show_secrets, false);
|
||||
preferences->putBool(preference_find_best_rssi, true);
|
||||
|
||||
preferences->putBool(preference_conf_info_enabled, true);
|
||||
preferences->putBool(preference_keypad_info_enabled, false);
|
||||
preferences->putBool(preference_keypad_topic_per_entry, false);
|
||||
@@ -208,6 +227,16 @@ inline void initPreferences(Preferences* preferences)
|
||||
preferences->putBool(preference_register_opener_as_app, false);
|
||||
preferences->putBool(preference_mqtt_ssl_enabled, false);
|
||||
preferences->putBool(preference_lock_gemini_enabled, false);
|
||||
preferences->putBool(preference_debug_connect, false);
|
||||
preferences->putBool(preference_debug_communication, false);
|
||||
preferences->putBool(preference_debug_readable_data, false);
|
||||
preferences->putBool(preference_debug_hex_data, false);
|
||||
preferences->putBool(preference_debug_command, false);
|
||||
preferences->putBool(preference_connect_mode, true);
|
||||
preferences->putBool(preference_retain_gpio, false);
|
||||
preferences->putBool(preference_enable_debug_mode, false);
|
||||
preferences->putBool(preference_cred_duo_enabled, false);
|
||||
preferences->putBool(preference_cred_duo_approval, false);
|
||||
|
||||
preferences->putInt(preference_mqtt_broker_port, 1883);
|
||||
preferences->putInt(preference_buffer_size, CHAR_BUFFER_SIZE);
|
||||
@@ -227,15 +256,10 @@ inline void initPreferences(Preferences* preferences)
|
||||
preferences->putInt(preference_query_interval_battery, 1800);
|
||||
preferences->putInt(preference_query_interval_keypad, 1800);
|
||||
preferences->putInt(preference_http_auth_type, 0);
|
||||
|
||||
preferences->putBool(preference_debug_connect, false);
|
||||
preferences->putBool(preference_debug_communication, false);
|
||||
preferences->putBool(preference_debug_readable_data, false);
|
||||
preferences->putBool(preference_debug_hex_data, false);
|
||||
preferences->putBool(preference_debug_command, false);
|
||||
preferences->putBool(preference_connect_mode, true);
|
||||
preferences->putBool(preference_retain_gpio, false);
|
||||
preferences->putBool(preference_enable_debug_mode, false);
|
||||
preferences->putInt(preference_cred_session_lifetime, 3600);
|
||||
preferences->putInt(preference_cred_session_lifetime_remember, 720);
|
||||
preferences->putInt(preference_cred_session_lifetime_duo, 3600);
|
||||
preferences->putInt(preference_cred_session_lifetime_duo_remember, 720);
|
||||
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32H2
|
||||
WiFi.begin();
|
||||
@@ -488,16 +512,19 @@ private:
|
||||
preference_update_from_mqtt, preference_show_secrets, preference_ble_tx_power, preference_webserial_enabled, preference_find_best_rssi, preference_lock_gemini_enabled,
|
||||
preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr, preference_network_custom_irq,
|
||||
preference_network_custom_rst, preference_network_custom_cs, preference_network_custom_sck, preference_network_custom_miso, preference_network_custom_mosi,
|
||||
preference_network_custom_pwr, preference_network_custom_mdio, preference_ntw_reconfigure, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count,
|
||||
preference_network_custom_pwr, preference_network_custom_mdio, preference_lock_max_auth_entry_count, preference_opener_max_auth_entry_count,
|
||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_auth_max_entries, preference_wifi_ssid, preference_wifi_pass,
|
||||
preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_mqtt_hass_enabled, preference_hass_device_discovery, preference_retain_gpio,
|
||||
preference_debug_connect, preference_debug_communication, preference_debug_readable_data, preference_debug_hex_data, preference_debug_command, preference_connect_mode,
|
||||
preference_lock_force_id, preference_lock_force_doorsensor, preference_lock_force_keypad, preference_opener_force_id, preference_opener_force_keypad, preference_nukihub_id
|
||||
preference_lock_force_id, preference_lock_force_doorsensor, preference_lock_force_keypad, preference_opener_force_id, preference_opener_force_keypad, preference_nukihub_id,
|
||||
preference_cred_duo_host, preference_cred_duo_ikey, preference_cred_duo_skey, preference_cred_duo_user, preference_cred_duo_enabled, preference_https_fqdn, preference_bypass_proxy,
|
||||
preference_cred_session_lifetime, preference_cred_session_lifetime_remember, preference_cred_session_lifetime_duo, preference_cred_session_lifetime_duo_remember,
|
||||
preference_cred_duo_approval
|
||||
};
|
||||
std::vector<char*> _redact =
|
||||
{
|
||||
preference_mqtt_user, preference_mqtt_password, preference_cred_user, preference_cred_password, preference_nuki_id_lock, preference_nuki_id_opener, preference_wifi_pass,
|
||||
preference_lock_gemini_pin
|
||||
preference_lock_gemini_pin, preference_cred_duo_host, preference_cred_duo_ikey, preference_cred_duo_skey, preference_cred_duo_user, preference_https_fqdn, preference_bypass_proxy
|
||||
};
|
||||
std::vector<char*> _boolPrefs =
|
||||
{
|
||||
@@ -508,10 +535,10 @@ private:
|
||||
preference_publish_authdata, preference_publish_debug_info, preference_official_hybrid_enabled, preference_mqtt_hass_enabled, preference_retain_gpio,
|
||||
preference_official_hybrid_actions, preference_official_hybrid_retry, preference_conf_info_enabled, preference_disable_non_json, preference_update_from_mqtt,
|
||||
preference_auth_control_enabled, preference_auth_topic_per_entry, preference_auth_info_enabled, preference_webserial_enabled, preference_hass_device_discovery,
|
||||
preference_ntw_reconfigure, preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_find_best_rssi,
|
||||
preference_keypad_check_code_enabled, preference_disable_network_not_connected, preference_find_best_rssi,
|
||||
preference_debug_connect, preference_debug_communication, preference_debug_readable_data, preference_debug_hex_data, preference_debug_command, preference_connect_mode,
|
||||
preference_lock_force_id, preference_lock_force_doorsensor, preference_lock_force_keypad, preference_opener_force_id, preference_opener_force_keypad, preference_mqtt_ssl_enabled,
|
||||
preference_hybrid_reboot_on_disconnect, preference_lock_gemini_enabled, preference_enable_debug_mode
|
||||
preference_hybrid_reboot_on_disconnect, preference_lock_gemini_enabled, preference_enable_debug_mode, preference_cred_duo_enabled, preference_cred_duo_approval
|
||||
};
|
||||
std::vector<char*> _bytePrefs =
|
||||
{
|
||||
@@ -528,7 +555,8 @@ private:
|
||||
preference_task_size_network, preference_task_size_nuki, preference_authlog_max_entries, preference_keypad_max_entries, preference_timecontrol_max_entries,
|
||||
preference_ble_tx_power, preference_network_custom_mdc, preference_network_custom_clk, preference_network_custom_phy, preference_network_custom_addr,
|
||||
preference_network_custom_irq, preference_network_custom_rst, preference_network_custom_cs, preference_network_custom_sck, preference_network_custom_miso,
|
||||
preference_network_custom_mosi, preference_network_custom_pwr, preference_network_custom_mdio, preference_http_auth_type
|
||||
preference_network_custom_mosi, preference_network_custom_pwr, preference_network_custom_mdio, preference_http_auth_type,
|
||||
preference_cred_session_lifetime, preference_cred_session_lifetime_remember, preference_cred_session_lifetime_duo, preference_cred_session_lifetime_duo_remember
|
||||
};
|
||||
std::vector<char*> _uintPrefs =
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -100,14 +100,20 @@ private:
|
||||
std::vector<int> _rssiList;
|
||||
String generateConfirmCode();
|
||||
String _confirmCode = "----";
|
||||
|
||||
void saveSessions();
|
||||
void loadSessions();
|
||||
|
||||
int checkDuoAuth(PsychicRequest *request);
|
||||
int checkDuoApprove();
|
||||
bool startDuoAuth();
|
||||
void saveSessions(bool duo = false);
|
||||
void loadSessions(bool duo = false);
|
||||
void clearSessions();
|
||||
esp_err_t logoutSession(PsychicRequest *request, PsychicResponse* resp);
|
||||
bool isAuthenticated(PsychicRequest *request);
|
||||
bool isAuthenticated(PsychicRequest *request, bool duo = false);
|
||||
bool processLogin(PsychicRequest *request, PsychicResponse* resp);
|
||||
int doAuthentication(PsychicRequest *request);
|
||||
esp_err_t buildLoginHtml(PsychicRequest *request, PsychicResponse* resp);
|
||||
esp_err_t buildLoginHtml(PsychicRequest *request, PsychicResponse* resp);
|
||||
esp_err_t buildDuoHtml(PsychicRequest *request, PsychicResponse* resp);
|
||||
esp_err_t buildDuoCheckHtml(PsychicRequest *request, PsychicResponse* resp);
|
||||
esp_err_t buildSSIDListHtml(PsychicRequest *request, PsychicResponse* resp);
|
||||
esp_err_t buildConfirmHtml(PsychicRequest *request, PsychicResponse* resp, const String &message, uint32_t redirectDelay = 5, bool redirect = false, String redirectTo = "/");
|
||||
esp_err_t buildOtaHtml(PsychicRequest *request, PsychicResponse* resp, bool debug = false);
|
||||
@@ -133,8 +139,22 @@ private:
|
||||
char _credUser[31] = {0};
|
||||
char _credPassword[31] = {0};
|
||||
bool _allowRestartToPortal = false;
|
||||
bool _isSSL = false;
|
||||
uint8_t _partitionType = 0;
|
||||
size_t _otaContentLen = 0;
|
||||
String _hostname;
|
||||
JsonDocument _httpSessions;
|
||||
JsonDocument _duoSessions;
|
||||
JsonDocument _sessionsOpts;
|
||||
struct tm timeinfo;
|
||||
bool _duoActiveRequest;
|
||||
bool _duoEnabled = false;
|
||||
int64_t _duoRequestTS = 0;
|
||||
String _duoTransactionId;
|
||||
String _duoHost;
|
||||
String _duoSkey;
|
||||
String _duoIkey;
|
||||
String _duoUser;
|
||||
String _duoCheckId;
|
||||
String _duoCheckIP;
|
||||
};
|
||||
|
||||
28
src/main.cpp
28
src/main.cpp
@@ -618,6 +618,20 @@ void setup()
|
||||
file2.close();
|
||||
key[filesize2] = '\0';
|
||||
|
||||
psychicServer = new PsychicHttpServer();
|
||||
psychicServer->config.ctrl_port = 20424;
|
||||
psychicServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) {
|
||||
String url = "https://" + request->host() + request->url();
|
||||
if (preferences->getString(preference_https_fqdn, "") != "")
|
||||
{
|
||||
url = "https://" + preferences->getString(preference_https_fqdn) + request->url();
|
||||
}
|
||||
|
||||
response->setCode(301);
|
||||
response->addHeader("Cache-Control", "no-cache");
|
||||
return response->redirect(url.c_str());
|
||||
});
|
||||
psychicServer->begin();
|
||||
psychicSSLServer = new PsychicHttpsServer;
|
||||
psychicSSLServer->ssl_config.httpd.max_open_sockets = 8;
|
||||
psychicSSLServer->setCertificate(cert, key);
|
||||
@@ -780,6 +794,20 @@ void setup()
|
||||
file2.close();
|
||||
key[filesize2] = '\0';
|
||||
|
||||
psychicServer = new PsychicHttpServer();
|
||||
psychicServer->config.ctrl_port = 20424;
|
||||
psychicServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) {
|
||||
String url = "https://" + request->host() + request->url();
|
||||
if (preferences->getString(preference_https_fqdn, "") != "")
|
||||
{
|
||||
url = "https://" + preferences->getString(preference_https_fqdn) + request->url();
|
||||
}
|
||||
|
||||
response->setCode(301);
|
||||
response->addHeader("Cache-Control", "no-cache");
|
||||
return response->redirect(url.c_str());
|
||||
});
|
||||
psychicServer->begin();
|
||||
psychicSSLServer = new PsychicHttpsServer;
|
||||
psychicSSLServer->ssl_config.httpd.max_open_sockets = 8;
|
||||
psychicSSLServer->setCertificate(cert, key);
|
||||
|
||||
Reference in New Issue
Block a user