diff --git a/CMakeLists.txt b/CMakeLists.txt index bd85bfe..d7dfcd6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_CXX_STANDARD 17) set(CMAKE_BUILD_TYPE Release) # manually set build type (Release / Debug) set(LIB_METHOD STATIC) #SHARED / STATIC -set(PROJECT_VERSION 1.3.1-dev) +set(PROJECT_VERSION 1.3.1) option(BUILD_DOC "Build documentation" ON) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) @@ -69,7 +69,7 @@ add_library(logger ${LIB_METHOD} set(SOURCE src/main.cpp src/IPRefresher.cpp - src/Credentials.cpp) + src/Config.cpp) add_executable(iprefresher ${SOURCE}) diff --git a/README.md b/README.md index 870b176..1d6aa64 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,16 @@ # DynuIPRefresher A lightweight C++ application to setup a service for refreshing a dynamic IP to the Dynu servers. +Dynu.com is a free DDns service and provides an API. + +## Installation +Download the latest Release at [Release_Page](https://github.com/Lukas-Heiligenbrunner/DynuIPRefresher/releases). +I'm providing executables for Debian/Ubuntu (.deb) and RHEL/Debian (.rpm). +But you can still compile the code my your own (see build section). + +## Configuration +There is a configuration file `/etc/iprefresher.cfg` where you have to specify the DYNU API key (get it from their homepage), the domainid and your domain. +Furthermore, you can optionally specify a Telegram API key and a Chat ID if you want to be notfied when your local ip changes. + ## Build ## Basic Build diff --git a/config/iprefresher.cfg b/config/iprefresher.cfg index cd5f136..e8a0dc5 100644 --- a/config/iprefresher.cfg +++ b/config/iprefresher.cfg @@ -9,4 +9,4 @@ domainname = "" ## Telegram API Config (optional) #telegramApiKey = "" -#chatId ="" +#chatId = "" diff --git a/inc/Credentials.h b/inc/Config.h similarity index 94% rename from inc/Credentials.h rename to inc/Config.h index db0acc5..1c9b728 100644 --- a/inc/Credentials.h +++ b/inc/Config.h @@ -6,7 +6,7 @@ #include -class Credentials { +class Config { public: static std::string dynuapikey; diff --git a/inc/IPRefresher.h b/inc/IPRefresher.h index c3e4b03..7220adf 100644 --- a/inc/IPRefresher.h +++ b/inc/IPRefresher.h @@ -11,6 +11,9 @@ public: */ void checkIPAdress(bool force); + /** + * default constructor + */ IPRefresher(); /** diff --git a/inc/Logger.h b/inc/Logger.h index 9bfc56a..d486f93 100644 --- a/inc/Logger.h +++ b/inc/Logger.h @@ -15,8 +15,8 @@ public: static void log(const std::string &message, int level); - static const int Debug; - static const int Message; - static const int Warning; - static const int Error; + static const int Debug = 4; + static const int Message = 3; + static const int Warning = 2; + static const int Error = 1; }; diff --git a/inc/api/DynuAPI.h b/inc/api/DynuAPI.h index c78148d..3d169fc 100644 --- a/inc/api/DynuAPI.h +++ b/inc/api/DynuAPI.h @@ -21,9 +21,9 @@ public: * @param domainId ID of domain received by Dynu * @param domainName domainname to refresh */ - void init(std::string dynuApiKey, std::string domainId, std::string domainName); + void init(const std::string& dynuApiKey, const std::string& domainId, const std::string& domainName); private: - std::string dynuapikey; + std::string dynuapikey; // Dynu API key std::string domainid; //id of the dynu domain std::string domainname; diff --git a/inc/api/Hashmap.h b/inc/api/Hashmap.h index e55db89..96f4717 100644 --- a/inc/api/Hashmap.h +++ b/inc/api/Hashmap.h @@ -4,7 +4,6 @@ #pragma once - #include #include diff --git a/inc/api/TelegramAPI.h b/inc/api/TelegramAPI.h index dc09035..5cdaaf0 100644 --- a/inc/api/TelegramAPI.h +++ b/inc/api/TelegramAPI.h @@ -14,7 +14,7 @@ public: * send telegram Message to predefined destination * @param text message */ - void sendMessage(std::string text); + int sendMessage(const std::string& text); /** * init Telegram api with apikey and chatid diff --git a/src/Credentials.cpp b/src/Config.cpp similarity index 76% rename from src/Credentials.cpp rename to src/Config.cpp index c1c124d..85bd460 100644 --- a/src/Credentials.cpp +++ b/src/Config.cpp @@ -2,20 +2,20 @@ // Created by lukas on 11.02.20. // -#include +#include #include #include #include "libconfig.h++" -std::string Credentials::dynuapikey; -std::string Credentials::domainid; //id of the dynu domain -std::string Credentials::domainname; +std::string Config::dynuapikey; +std::string Config::domainid; //id of the dynu domain +std::string Config::domainname; -std::string Credentials::telegramApiKey; -std::string Credentials::chatId; +std::string Config::telegramApiKey; +std::string Config::chatId; -bool Credentials::readCredentials() { +bool Config::readCredentials() { libconfig::Config cfg; try { cfg.readFile("/etc/iprefresher.cfg"); @@ -40,7 +40,6 @@ bool Credentials::readCredentials() { // optional parameters telegramApiKey = (std::string) cfg.lookup("telegramApiKey"); chatId = (std::string) cfg.lookup("chatId"); - std::cout << "Store name: " << dynuapikey << std::endl; } catch (const libconfig::SettingNotFoundException &nfex) { // triggered if setting is missing in config @@ -49,5 +48,5 @@ bool Credentials::readCredentials() { } } // check if needed values aren't empty - return !(Credentials::dynuapikey.empty() || Credentials::domainid.empty() || Credentials::domainname.empty()); + return !(Config::dynuapikey.empty() || Config::domainid.empty() || Config::domainname.empty()); } diff --git a/src/IPRefresher.cpp b/src/IPRefresher.cpp index c031ba6..d931fdd 100644 --- a/src/IPRefresher.cpp +++ b/src/IPRefresher.cpp @@ -14,7 +14,7 @@ #include #include -#include +#include void IPRefresher::checkIPAdress(bool force) { FileLogger logger; @@ -34,11 +34,11 @@ void IPRefresher::checkIPAdress(bool force) { Logger::message("ip changed! -- from :" + oldip + "to: " + ip); DynuAPI dynu; - dynu.init(Credentials::dynuapikey, Credentials::domainid, Credentials::domainname); + dynu.init(Config::dynuapikey, Config::domainid, Config::domainname); if (dynu.refreshIp(ip)) { TelegramAPI tele; - tele.init(Credentials::telegramApiKey, Credentials::chatId); + tele.init(Config::telegramApiKey, Config::chatId); tele.sendMessage(oldip + " moved to " + ip); } else { //error @@ -53,14 +53,16 @@ void IPRefresher::checkIPAdress(bool force) { IPRefresher::IPRefresher() = default; IPRefresher::IPRefresher(bool loop) { - if (Credentials::readCredentials()) { + if (loop) { Logger::message("startup of service"); - while (loop) { - Logger::message("starting check"); - checkIPAdress(false); - std::this_thread::sleep_for(std::chrono::milliseconds(300000)); + if (Config::readCredentials()) { + while (true) { + Logger::message("starting check"); + checkIPAdress(false); + std::this_thread::sleep_for(std::chrono::milliseconds(300000)); + } + } else { + std::cout << "incorrect credentials!" << std::endl; } - } else { - std::cout << "incorrect credentials!" << std::endl; } } diff --git a/src/Logger.cpp b/src/Logger.cpp index 5653cb3..6822bf0 100644 --- a/src/Logger.cpp +++ b/src/Logger.cpp @@ -7,12 +7,6 @@ #include "Logger.h" - -const int Logger::Warning = 1; -const int Logger::Debug = 2; -const int Logger::Message = 3; -const int Logger::Error = 4; - void Logger::debug(const std::string message) { log(message, Logger::Debug); } diff --git a/src/api/DynuAPI.cpp b/src/api/DynuAPI.cpp index 89c5aff..e91bad4 100644 --- a/src/api/DynuAPI.cpp +++ b/src/api/DynuAPI.cpp @@ -5,19 +5,16 @@ #include "api/DynuAPI.h" int DynuAPI::refreshIp(std:: string ip) { - Hashmap args; args.add("name", domainname); args.add("ipv4Address", ip); std::vector headers; - headers.push_back("accept: application/json"); - headers.push_back("User-Agent: Mozilla/5.0 (compatible; Rigor/1.0.0; http://rigor.com)"); - headers.push_back("API-Key: " + dynuapikey); + headers.emplace_back("accept: application/json"); + headers.emplace_back("User-Agent: Mozilla/5.0 (compatible; Rigor/1.0.0; http://rigor.com)"); + headers.emplace_back("API-Key: " + dynuapikey); - std::string dynurepl = request("https://api.dynu.com/v2/dns/" + domainid, true, args, headers); - -// std::cout << "[DEBUG] api reply:: " << dynurepl << std::endl; + const std::string dynurepl = request("https://api.dynu.com/v2/dns/" + domainid, true, args, headers); if (dynurepl != "{\"statusCode\":200}") { return -1; @@ -26,7 +23,7 @@ int DynuAPI::refreshIp(std:: string ip) { } } -void DynuAPI::init(std::string dynuApiKey, std::string domainId, std::string domainName) { +void DynuAPI::init(const std::string& dynuApiKey, const std::string& domainId, const std::string& domainName) { this->dynuapikey=dynuApiKey; this->domainid=domainId; this->domainname=domainName; diff --git a/src/api/TelegramAPI.cpp b/src/api/TelegramAPI.cpp index f44d589..3df25ea 100644 --- a/src/api/TelegramAPI.cpp +++ b/src/api/TelegramAPI.cpp @@ -4,7 +4,9 @@ #include "api/TelegramAPI.h" -void TelegramAPI::sendMessage(std::string text) { +#include + +int TelegramAPI::sendMessage(const std::string& text) { Hashmap args; args.add("chat_id", chatid); args.add("text", text); @@ -12,10 +14,16 @@ void TelegramAPI::sendMessage(std::string text) { std::vector headers; std::string reply = request("https://api.telegram.org/bot" + apikey + "/sendmessage", false, args, headers); -// std::cout << "[DEBUG] " << reply << std::endl; + + unsigned const long ULONG_MAX = -1; + if (reply.find("\"error_code\"") != ULONG_MAX) { + Logger::error("failed to refresh the ip (Dynu API)"); + return -1; + } + return 1; } -void TelegramAPI::init(std::string apikey, std::string chatid) { +void TelegramAPI::init(const std::string apikey, const std::string chatid) { this->apikey = apikey; this->chatid = chatid; } diff --git a/src/main.cpp b/src/main.cpp index 9c238be..3ef49ea 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,9 +1,16 @@ +// +// Created by lukas on 18.06.19. +// + #include #include #include #include -#include +#include +/** + * application entry point + */ int main(int argc, char *argv[]) { if (argc > 1) { std::string firstarg(argv[1]); @@ -17,7 +24,7 @@ int main(int argc, char *argv[]) { std::cout << "Version " << Version::VERSION << std::endl; } else if (firstarg == "-f" || firstarg == "--force") { IPRefresher ipr; - if (Credentials::readCredentials()) { + if (Config::readCredentials()) { ipr.checkIPAdress(true); } else { std::cout << "incorrect credentials!" << std::endl; @@ -31,12 +38,11 @@ int main(int argc, char *argv[]) { } else { IPRefresher ipr; Logger::message("starting check"); - if (Credentials::readCredentials()) { + if (Config::readCredentials()) { ipr.checkIPAdress(false); } else { std::cout << "incorrect credentials!" << std::endl; } - } return 0;