diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml new file mode 100644 index 0000000000000000000000000000000000000000..6ee4e493c717dbc7c232b116c8d8a8a31a24ccd8 --- /dev/null +++ b/.idea/codeStyles/Project.xml @@ -0,0 +1,53 @@ +<component name="ProjectCodeStyleConfiguration"> + <code_scheme name="Project" version="173"> + <Objective-C> + <option name="INDENT_NAMESPACE_MEMBERS" value="0" /> + <option name="INDENT_C_STRUCT_MEMBERS" value="2" /> + <option name="INDENT_CLASS_MEMBERS" value="2" /> + <option name="INDENT_VISIBILITY_KEYWORDS" value="1" /> + <option name="INDENT_INSIDE_CODE_BLOCK" value="2" /> + <option name="KEEP_STRUCTURES_IN_ONE_LINE" value="true" /> + <option name="KEEP_CASE_EXPRESSIONS_IN_ONE_LINE" value="true" /> + <option name="FUNCTION_NON_TOP_AFTER_RETURN_TYPE_WRAP" value="0" /> + <option name="FUNCTION_TOP_AFTER_RETURN_TYPE_WRAP" value="0" /> + <option name="FUNCTION_PARAMETERS_WRAP" value="5" /> + <option name="FUNCTION_CALL_ARGUMENTS_WRAP" value="5" /> + <option name="TEMPLATE_CALL_ARGUMENTS_WRAP" value="5" /> + <option name="TEMPLATE_CALL_ARGUMENTS_ALIGN_MULTILINE" value="true" /> + <option name="CLASS_CONSTRUCTOR_INIT_LIST_WRAP" value="5" /> + <option name="ALIGN_INIT_LIST_IN_COLUMNS" value="false" /> + <option name="HEADER_GUARD_STYLE_PATTERN" value="${PROJECT_NAME}_${PROJECT_REL_PATH}_${FILE_NAME}_${EXT}_" /> + </Objective-C> + <Objective-C-extensions> + <rules> + <rule entity="MACRO" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" /> + <rule entity="NAMESPACE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" /> + <rule entity="CLASS,ENUM,UNION,TYPEDEF" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" /> + <rule entity="CLASS_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="_" /> + <rule entity="STRUCT_MEMBER_FIELD" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" /> + <rule entity="ENUMERATOR" visibility="ANY" specifier="ANY" prefix="" style="SCREAMING_SNAKE_CASE" suffix="" /> + <rule entity="GLOBAL_FUNCTION,CLASS_MEMBER_FUNCTION,STRUCT_MEMBER_FUNCTION" visibility="ANY" specifier="ANY" prefix="" style="PASCAL_CASE" suffix="" /> + <rule entity="PARAMETER,LOCAL_VARIABLE" visibility="ANY" specifier="ANY" prefix="" style="SNAKE_CASE" suffix="" /> + <rule entity="GLOBAL_VARIABLE,LOCAL_VARIABLE" visibility="ANY" specifier="CONST" prefix="k" style="PASCAL_CASE" suffix="" /> + </rules> + </Objective-C-extensions> + <codeStyleSettings language="ObjectiveC"> + <option name="KEEP_BLANK_LINES_IN_DECLARATIONS" value="1" /> + <option name="KEEP_BLANK_LINES_IN_CODE" value="1" /> + <option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1" /> + <option name="BLANK_LINES_BEFORE_IMPORTS" value="0" /> + <option name="BLANK_LINES_AFTER_IMPORTS" value="0" /> + <option name="BLANK_LINES_AROUND_CLASS" value="0" /> + <option name="BLANK_LINES_AROUND_METHOD" value="0" /> + <option name="BLANK_LINES_AROUND_METHOD_IN_INTERFACE" value="0" /> + <option name="ALIGN_MULTILINE_BINARY_OPERATION" value="false" /> + <option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true" /> + <option name="FOR_STATEMENT_WRAP" value="1" /> + <option name="ASSIGNMENT_WRAP" value="1" /> + <indentOptions> + <option name="INDENT_SIZE" value="2" /> + <option name="CONTINUATION_INDENT_SIZE" value="4" /> + </indentOptions> + </codeStyleSettings> + </code_scheme> +</component> \ No newline at end of file diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 0000000000000000000000000000000000000000..79ee123c2b23e069e35ed634d687e17f731cc702 --- /dev/null +++ b/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ +<component name="ProjectCodeStyleConfiguration"> + <state> + <option name="USE_PER_PROJECT_SETTINGS" value="true" /> + </state> +</component> \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index e8981b035f3225055259da5179bc83f8e90e8cf5..2e89d2c6f9dcf1844a98216b20366f7a7a9931b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,10 +6,6 @@ set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) set(CMAKE_AUTOUIC ON) -if (UNIX) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") -endif () - if (WIN32) # On Windows Machines set this to the install directory of Qt set(Qt5_DIR "C:/Qt/Qt5.12.10/5.12.10/mingw73_64/lib/cmake/Qt5") @@ -22,17 +18,39 @@ set(QT_VERSION 5) set(REQUIRED_LIBS Core Gui Widgets) set(REQUIRED_LIBS_QUALIFIED Qt5::Core Qt5::Gui Qt5::Widgets) +add_executable(${PROJECT_NAME} + src/icon.rc + src/healthprobe.cpp + src/logger.cpp + src/openconnectmanager.cpp + src/openconnectwidget.cpp + src/openconnectwidget.ui + src/openconnectwindow.cpp + src/openconnectwindow.ui + src/popupinfo.cpp + src/popupinfo.ui + src/utils.cpp + src/main.cpp) + if (WIN32) - include_directories(${CMAKE_SOURCE_DIR}/libs ${AUTOGEN_BUILD_DIR}/include src src/win) + target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/libs ${CMAKE_BINARY_DIR} .) elseif (UNIX) include(FindPkgConfig) pkg_search_module(OPENCONNECT REQUIRED openconnect) - include_directories(${OPENCONNECT_INCLUDE_DIRS} ${CMAKE_SOURCE_DIR}/libs ${AUTOGEN_BUILD_DIR}/include src) + target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/libs ${CMAKE_BINARY_DIR} .) endif () -file(GLOB SOURCES "src/*.cpp" "src/*.ui" "src/*.rc") - -add_executable(${PROJECT_NAME} ${SOURCES}) +if (WIN32) + set_target_properties(${PROJECT_NAME} PROPERTIES + AUTOGEN_BUILD_DIR "${CMAKE_BINARY_DIR}/autogen") +elseif (UNIX) + set_target_properties(${PROJECT_NAME} PROPERTIES + RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_BINARY_DIR}/bin" + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_BINARY_DIR}/bin" + RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_BINARY_DIR}/bin" + RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_BINARY_DIR}/bin" + AUTOGEN_BUILD_DIR "${CMAKE_BINARY_DIR}/autogen") +endif () add_custom_target(copy_resources) add_dependencies(${PROJECT_NAME} copy_resources) diff --git a/src/healthprobe.cpp b/src/healthprobe.cpp index 7b16ddc900a228fb417c8bf143294cc804d09302..e7add1e7d85d4ad5ffc5dd9774f399b39145d299 100644 --- a/src/healthprobe.cpp +++ b/src/healthprobe.cpp @@ -1,125 +1,137 @@ -#include "healthprobe.h" +/* + * Copyright 2021 Lukas Koenen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "src/healthprobe.h" #include <iostream> HealthProbe::HealthProbe(QObject *parent) : QObject(parent), monitoring_state_(), health_check_timer_(new QTimer(parent)), power_management_event_check_timer_(new QTimer( - parent)), power_management_tracker_timer_(new QTimer(parent)) { - power_management_event_check_timer_->setInterval(10 * 1000); - // set interval for the time tracker timer to next midnight - power_management_tracker_timer_->setInterval( - QDateTime::currentDateTime().msecsTo(QDateTime(QDate::currentDate().addDays(1), QTime(00, 00)))); - - connect(this, &HealthProbe::SignalPossiblePowerManagementEvent, this, &HealthProbe::SlotHealthCheck); - connect(power_management_event_check_timer_, SIGNAL(timeout()), this, SLOT(SlotPowerManagementEventCheck())); - connect(health_check_timer_, SIGNAL(timeout()), this, SLOT(SlotHealthCheck())); - - power_management_tracker_timer_->start(); - power_management_event_check_timer_->start(); - UpdateTimerInterval(); + parent)), power_management_tracker_timer_(new QTimer(parent)) { + power_management_event_check_timer_->setInterval(10 * 1000); + // set interval for the time tracker timer to next midnight + power_management_tracker_timer_->setInterval( + QDateTime::currentDateTime().msecsTo(QDateTime(QDate::currentDate().addDays(1), QTime(00, 00)))); + + connect(this, &HealthProbe::SignalPossiblePowerManagementEvent, this, &HealthProbe::SlotHealthCheck); + connect(power_management_event_check_timer_, SIGNAL(timeout()), this, SLOT(SlotPowerManagementEventCheck())); + connect(health_check_timer_, SIGNAL(timeout()), this, SLOT(SlotHealthCheck())); + + power_management_tracker_timer_->start(); + power_management_event_check_timer_->start(); + UpdateTimerInterval(); } HealthProbe::~HealthProbe() { - if (health_check_timer_->isActive()) { - health_check_timer_->stop(); - } - if (power_management_event_check_timer_->isActive()) { - power_management_event_check_timer_->stop(); - } - if (power_management_tracker_timer_->isActive()) { - power_management_tracker_timer_->stop(); - } - - delete health_check_timer_; - delete power_management_event_check_timer_; - delete power_management_tracker_timer_; + if (health_check_timer_->isActive()) { + health_check_timer_->stop(); + } + if (power_management_event_check_timer_->isActive()) { + power_management_event_check_timer_->stop(); + } + if (power_management_tracker_timer_->isActive()) { + power_management_tracker_timer_->stop(); + } + + delete health_check_timer_; + delete power_management_event_check_timer_; + delete power_management_tracker_timer_; } void HealthProbe::SetMonitoringState(HealthProbe::MonitoringStates monitoring_state) { - monitoring_state_ = monitoring_state; - UpdateTimerInterval(); + monitoring_state_ = monitoring_state; + UpdateTimerInterval(); } void HealthProbe::SlotHealthCheck(HealthProbe::HealthCheckReason reason) { - if ( + if ( #ifdef __WIN32 -system("ping -n 1 -l 1 netbox.fbi.h-da.de > NUL") + system("ping -n 1 -l 1 netbox.fbi.h-da.de > NUL") #elif __linux -system("ping -c1 -s1 netbox.fbi.h-da.de > /dev/null 2>&1") + system("ping -c1 -s1 netbox.fbi.h-da.de > /dev/null 2>&1") #endif -!= 0) { - if (reason == HealthProbe::HealthCheckReason::kPeriodicEvent) { - switch (monitoring_state_.GetCurrentState()) { - case HealthProbe::MonitoringStates::kDisconnected: - case HealthProbe::MonitoringStates::kStartup: - break; - case HealthProbe::MonitoringStates::kIdle: - emit SignalHealthCheckFailed(); - } - } else { - emit SignalHealthCheckFailed(); - } - } else if (monitoring_state_.GetCurrentState() == HealthProbe::MonitoringStates::kStartup) { - SetMonitoringState(HealthProbe::MonitoringStates::kIdle); + != 0) { + if (reason == HealthProbe::HealthCheckReason::kPeriodicEvent) { + switch (monitoring_state_.GetCurrentState()) { + case HealthProbe::MonitoringStates::kDisconnected: + case HealthProbe::MonitoringStates::kStartup:break; + case HealthProbe::MonitoringStates::kIdle:emit SignalHealthCheckFailed(); + } + } else { + emit SignalHealthCheckFailed(); } + } else if (monitoring_state_.GetCurrentState() == HealthProbe::MonitoringStates::kStartup) { + SetMonitoringState(HealthProbe::MonitoringStates::kIdle); + } } void HealthProbe::SlotPowerManagementEventCheck() { - int difference = (int) abs(power_management_tracker_timer_->remainingTime() - QDateTime::currentDateTime().msecsTo( - QDateTime(QDate::currentDate().addDays(1), QTime(00, 00)))); - - if (difference > 500) { - if (difference > 2000) { - // possible power management event do an immediate health check - emit SignalPossiblePowerManagementEvent(); - } - - power_management_tracker_timer_->stop(); - power_management_tracker_timer_->setInterval( - QDateTime::currentDateTime().msecsTo(QDateTime(QDate::currentDate().addDays(1), QTime(00, 00)))); - power_management_tracker_timer_->start(); + int difference = static_cast<int>(abs( + power_management_tracker_timer_->remainingTime() + - QDateTime::currentDateTime().msecsTo(QDateTime(QDate::currentDate().addDays(1), QTime(00, 00))))); + + if (difference > 500) { + if (difference > 2000) { + // possible power management event do an immediate health check + emit SignalPossiblePowerManagementEvent(); } + power_management_tracker_timer_->stop(); + power_management_tracker_timer_->setInterval( + QDateTime::currentDateTime().msecsTo(QDateTime(QDate::currentDate().addDays(1), QTime(00, 00)))); + power_management_tracker_timer_->start(); + } } void HealthProbe::UpdateTimerInterval() { - int timer_interval = monitoring_state_.GetTimerInterval(); + int timer_interval = monitoring_state_.GetTimerInterval(); - if (health_check_timer_->isActive()) { - health_check_timer_->stop(); - } + if (health_check_timer_->isActive()) { + health_check_timer_->stop(); + } - if (timer_interval != INT_MAX) { - health_check_timer_->setInterval(timer_interval * 1000); - health_check_timer_->start(); - } + if (timer_interval != INT_MAX) { + health_check_timer_->setInterval(timer_interval * 1000); + health_check_timer_->start(); + } } HealthProbe::MonitoringState::MonitoringState() : monitoring_state_(HealthProbe::MonitoringStates::kDisconnected), kStartupTimerInterval_(30), kIdleTimerInterval_(60) {} int HealthProbe::MonitoringState::GetTimerInterval() { - switch (monitoring_state_) { - case HealthProbe::MonitoringStates::kDisconnected: - return INT_MAX; - case HealthProbe::MonitoringStates::kStartup: - return kStartupTimerInterval_; - case HealthProbe::MonitoringStates::kIdle: - return kIdleTimerInterval_; - } + switch (monitoring_state_) { + case HealthProbe::MonitoringStates::kDisconnected:return INT_MAX; + case HealthProbe::MonitoringStates::kStartup:return kStartupTimerInterval_; + case HealthProbe::MonitoringStates::kIdle:return kIdleTimerInterval_; + } - return INT_MAX; + return INT_MAX; } HealthProbe::MonitoringStates HealthProbe::MonitoringState::GetCurrentState() { - return monitoring_state_; + return monitoring_state_; } void HealthProbe::MonitoringState::operator=(HealthProbe::MonitoringStates monitoring_state) { - monitoring_state_ = monitoring_state; + monitoring_state_ = monitoring_state; } bool HealthProbe::MonitoringState::operator==(HealthProbe::MonitoringStates other_monitoring_state) { - return monitoring_state_ == other_monitoring_state; + return monitoring_state_ == other_monitoring_state; } diff --git a/src/healthprobe.h b/src/healthprobe.h index ce4cea829272a1ced953263da76ebf41aa2128d8..a5df127d2ee092d46de64979b634e2630a984d58 100644 --- a/src/healthprobe.h +++ b/src/healthprobe.h @@ -1,113 +1,129 @@ -#ifndef OPENCONNECT_HDA_HEALTHPROBE_H -#define OPENCONNECT_HDA_HEALTHPROBE_H +/* + * Copyright 2021 Lukas Koenen + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef SRC_HEALTHPROBE_H_ +#define SRC_HEALTHPROBE_H_ #include <QObject> #include <QTimer> #include <QDate> class HealthProbe : public QObject { -Q_OBJECT - -public: - explicit HealthProbe(QObject *parent = nullptr); - - ~HealthProbe() override; - - enum MonitoringStates { - kDisconnected, - kStartup, - kIdle - }; - - enum HealthCheckReason { - kPeriodicEvent, - kPowerManagementEvent - }; + Q_OBJECT + + public: + explicit HealthProbe(QObject *parent = nullptr); + + ~HealthProbe() override; + + enum MonitoringStates { + kDisconnected, + kStartup, + kIdle + }; + + enum HealthCheckReason { + kPeriodicEvent, + kPowerManagementEvent + }; + + /** + * Set the monitoring state + * + * @param monitoring_state part of the MonitoringSates Enum + */ + void SetMonitoringState(HealthProbe::MonitoringStates monitoring_state); + + signals: + + /** + * Signal to show that the health check failed + */ + void SignalHealthCheckFailed(); + + /** + * Signal to show that there is the possibility that a power management event occurred + * + * @param reason part of the HealthCheckReason Enum + */ + void SignalPossiblePowerManagementEvent( + HealthProbe::HealthCheckReason reason = HealthProbe::HealthCheckReason::kPowerManagementEvent); + + private slots: + + /** + * Slot to handle health check requests + * + * @param reason part of the HealthCheckReason Enum, representing the reason behind the request + */ + void SlotHealthCheck(HealthProbe::HealthCheckReason reason = HealthProbe::HealthCheckReason::kPeriodicEvent); + + /** + * Slot to Handle possible power management events + */ + void SlotPowerManagementEventCheck(); + + private: + class MonitoringState { + public: + MonitoringState(); + + ~MonitoringState() = default; /** - * Set the monitoring state + * Get the timer interval for the current state * - * @param monitoring_state part of the MonitoringSates Enum - */ - void SetMonitoringState(HealthProbe::MonitoringStates monitoring_state); - -signals: - - /** - * Signal to show that the health check failed + * @return int containing the timer interval in ms */ - void SignalHealthCheckFailed(); + int GetTimerInterval(); /** - * Signal to show that there is the possibility that a power management event occurred + * Get the current monitoring state * - * @param reason part of the HealthCheckReason Enum + * @return element of the MonitoringStates enum that represents the current state */ - void SignalPossiblePowerManagementEvent( - HealthProbe::HealthCheckReason reason = HealthProbe::HealthCheckReason::kPowerManagementEvent); - -private slots: + HealthProbe::MonitoringStates GetCurrentState(); /** - * Slot to handle health check requests + * Assignment operator used to set the current monitoring state * - * @param reason part of the HealthCheckReason Enum, representing the reason behind the request - */ - void SlotHealthCheck(HealthProbe::HealthCheckReason reason = HealthProbe::HealthCheckReason::kPeriodicEvent); - - /** - * Slot to Handle possible power management events + * @param monitoring_state element of the MonitoringStates Enum */ - void SlotPowerManagementEventCheck(); - -private: - class MonitoringState { - public: - MonitoringState(); - - ~MonitoringState() = default; - - /** - * Get the timer interval for the current state - * - * @return int containing the timer interval in ms - */ - int GetTimerInterval(); + void operator=(HealthProbe::MonitoringStates monitoring_state); - /** - * Get the current monitoring state - * - * @return element of the MonitoringStates enum that represents the current state - */ - HealthProbe::MonitoringStates GetCurrentState(); + bool operator==(HealthProbe::MonitoringStates other_monitoring_state); - /** - * Assignment operator used to set the current monitoring state - * - * @param monitoring_state element of the MonitoringStates Enum - */ - void operator=(HealthProbe::MonitoringStates monitoring_state); + private: + HealthProbe::MonitoringStates monitoring_state_; - bool operator==(HealthProbe::MonitoringStates other_monitoring_state); + const int kStartupTimerInterval_; + const int kIdleTimerInterval_; + }; - private: - HealthProbe::MonitoringStates monitoring_state_; + /** + * Function to update timer interval based on the current monitoring state + */ + void UpdateTimerInterval(); - const int kStartupTimerInterval_; - const int kIdleTimerInterval_; - }; + HealthProbe::MonitoringState monitoring_state_; - /** - * Function to update timer interval based on the current monitoring state - */ - void UpdateTimerInterval(); - - HealthProbe::MonitoringState monitoring_state_; - - QTimer *health_check_timer_; - QTimer *power_management_event_check_timer_; - QTimer *power_management_tracker_timer_; + QTimer *health_check_timer_; + QTimer *power_management_event_check_timer_; + QTimer *power_management_tracker_timer_; }; - -#endif //OPENCONNECT_HDA_HEALTHPROBE_H +#endif // SRC_HEALTHPROBE_H_ diff --git a/src/logger.cpp b/src/logger.cpp index 114d0a60b3c21a5b6a3d14b6fa3fb68dfa9816e2..071cbcc5ecd6b82ef77345680b9893977a2426f5 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -15,46 +15,46 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "logger.h" +#include "src/logger.h" -const std::string Logger::Component::kOpenconnect = "Openconnect"; -const std::string Logger::Component::kVPNC = "VPNC"; -const std::string Logger::Component::kGUI = "GUI"; - -const std::string Logger::kLogLevelNames[spdlog::level::n_levels] = SPDLOG_LEVEL_NAMES; +const char *Logger::Component::kOpenconnect = "Openconnect"; std::shared_ptr<spdlog::logger> Logger::file_logger_ = nullptr; std::shared_ptr<spdlog::logger> Logger::Instance() { - return file_logger_; + if (file_logger_ == nullptr) { + throw std::runtime_error("logger is not initialised"); + } + + return file_logger_; } void Logger::Setup(const spdlog::level::level_enum &level, const std::string &file_name, int max_file_size, int max_number_of_files) { #ifdef __WIN32 - fs::path log_file_path = fs::path(GetApplicationDirectory()) / "logs"; + fs::path log_file_path = fs::path(GetApplicationDirectory()) / "logs"; #else - fs::path log_file_path = fs::path("/var/log/openconnect-hda"); + fs::path log_file_path = fs::path("/var/log/openconnect-hda"); #endif - if (!fs::exists(log_file_path)) fs::create_directory(log_file_path); + if (!fs::exists(log_file_path)) fs::create_directory(log_file_path); - try { - Logger::file_logger_ = spdlog::rotating_logger_mt("openconnect-logger", (log_file_path / file_name).string(), - 1048576 * max_file_size, - max_number_of_files); + try { + Logger::file_logger_ = spdlog::rotating_logger_mt("openconnect-logger", (log_file_path / file_name).string(), + 1048576 * max_file_size, + max_number_of_files); #ifdef __WIN32 - if (level <= spdlog::level::debug) { - ShowWindow(GetConsoleWindow(), SW_SHOW); - } else { - ShowWindow(GetConsoleWindow(), SW_HIDE); - } + if (level <= spdlog::level::debug) { + ShowWindow(GetConsoleWindow(), SW_SHOW); + } else { + ShowWindow(GetConsoleWindow(), SW_HIDE); + } #endif - Logger::file_logger_->set_level(level); - } catch (const spdlog::spdlog_ex &exception) { - PopupInfo info("Setting up logger failed: " + std::string(exception.what()), nullptr); + Logger::file_logger_->set_level(level); + } catch (const spdlog::spdlog_ex &exception) { + PopupInfo info("Setting up logger failed: " + std::string(exception.what()), nullptr); - exit(1); - } + exit(1); + } } diff --git a/src/logger.h b/src/logger.h index 41cbdd9820ce6649818e06867f14faa801c4671d..bdc1bacafe5cb8ecffa495aa173ad66d56544164 100644 --- a/src/logger.h +++ b/src/logger.h @@ -15,59 +15,56 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef OPENCONNECT_GUI_LOGGER_H -#define OPENCONNECT_GUI_LOGGER_H +#ifndef SRC_LOGGER_H_ +#define SRC_LOGGER_H_ -#include "spdlog/sinks/rotating_file_sink.h" +#include <QEventLoop> #include <string> #include <iostream> #include <filesystem> +#include <memory> +#include <utility> -#include <QEventLoop> +#include "libs/spdlog/sinks/rotating_file_sink.h" -#include "utils.h" -#include "popupinfo.h" +#include "src/utils.h" +#include "src/popupinfo.h" namespace fs = std::filesystem; class Logger { -public: - Logger() = delete; - - ~Logger() = delete; + public: + Logger() = delete; - // Component class to represent the different parts of the application - class Component { - public: - static const std::string kOpenconnect; - static const std::string kVPNC; - static const std::string kGUI; - }; + ~Logger() = delete; - /** - * Returns a Instance of the logger - * - * @return reference to the logger - */ - [[nodiscard]] static std::shared_ptr<spdlog::logger> Instance(); + // Component class to represent the different parts of the application + class Component { + public: + static const char *kOpenconnect; + }; - /** - * Setup file logger - * - * @param level level_enum representing log level at which to log -> off to disable logging - * @param file_name string that contains the path where the log files should be placed - * @param max_file_size int representing the max size of a log file in mb, before the logger creates a new file - * @param max_number_of_files int representing the max number of simultaneously existing files - */ - static void Setup(const spdlog::level::level_enum &level, const std::string &file_name, int max_file_size, - int max_number_of_files); + /** + * Returns a Instance of the logger + * + * @return reference to the logger + */ + [[nodiscard]] static std::shared_ptr<spdlog::logger> Instance(); - // array containing log level names as strings - static const std::string kLogLevelNames[spdlog::level::n_levels]; + /** + * Setup file logger + * + * @param level level_enum representing log level at which to log -> off to disable logging + * @param file_name string that contains the path where the log files should be placed + * @param max_file_size int representing the max size of a log file in mb, before the logger creates a new file + * @param max_number_of_files int representing the max number of simultaneously existing files + */ + static void Setup(const spdlog::level::level_enum &level, const std::string &file_name, int max_file_size, + int max_number_of_files); -private: - static std::shared_ptr<spdlog::logger> file_logger_; + private: + static std::shared_ptr<spdlog::logger> file_logger_; }; -#endif //OPENCONNECT_GUI_LOGGER_H +#endif // SRC_LOGGER_H_ diff --git a/src/main.cpp b/src/main.cpp index cab236d154caab53acf2f1849ca5de1479060a7d..af4269f68b34bfe47e08e3f51edd067921c0e0a5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,103 +14,100 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ - -#ifdef __linux - -#include <unistd.h> - -#endif - #include <QApplication> -#include "argparse/argparse.h" +#include "libs/argparse/argparse.h" -#include "openconnectwindow.h" -#include "logger.h" +#include "src/openconnectwindow.h" +#include "src/logger.h" int main(int argc, const char *argv[]) { - argparse::ArgumentParser parser( + argparse::ArgumentParser parser( #ifdef __WIN32 - "openconnect-hda.exe" + "openconnect-hda.exe" #else - "openconnect-hda" + "openconnect-hda" #endif - , "openconnect gui wrapper"); - parser.add_argument() - .names({"-l", "--license"}) - .description( - "print license information, supply w to print the warranty information, c for redistribution conditions") - .required(false); - parser.add_argument() - .names({"-v", "--verbose"}) - .description("verbose output") - .required(false); - parser.enable_help(); - - if (argparse::ArgumentParser::Result error_message = parser.parse(argc, argv)) { - PopupInfo info(error_message.what(), nullptr); - + , "openconnect gui wrapper"); + parser.add_argument() + .names({"-l", "--license"}) + .description( + "print license information, supply w to print the warranty information, c for redistribution conditions") + .required(false); + parser.add_argument() + .names({"-v", "--verbose"}) + .description("verbose output") + .required(false); + parser.enable_help(); + + if (argparse::ArgumentParser::Result error_message = parser.parse(argc, argv)) { + std::cout << error_message.what() << std::endl; + return 1; + } + + if (parser.exists("help")) { + parser.print_help(); + return 0; + } + + if (parser.exists("license")) { + switch (char license_option = parser.get<char>("license")) { + case '\000': { + std::cout + << "openconnect-hda Copyright (C) 2021 Lukas Koenen\n" + "This program comes with ABSOLUTELY NO WARRANTY; for details type `-l, --license w'.\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; type `-l, --license c' for details." + << std::endl; + break; + } + case 'w': { + std::cout + << "THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\n" + "EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\n" + "PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED,\n" + "INCLUDING, BUT NOT LIMITED TO, " + "THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.\n" + "THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.\n" + "SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, " + "REPAIR OR CORRECTION." + << std::endl; + break; + } + case 'c': { + std::cout + << "This program is free software:\n" + "You can redistribute it and/or modify it under the terms of the GNU General Public License\n" + "as published by the Free Software Foundation, either version 3 of the License, or any later version." + << std::endl; + break; + } + default: { + std::cout << std::string( + "unsupported license_option --license ").append(1, license_option) + " use -h to show help"; return 1; + } } - - if (parser.exists("help")) { - parser.print_help(); - return 0; - } - - if (parser.exists("license")) { - switch (char license_option = parser.get<char>("license")) { - case '\000': { - std::cout << "openconnect-hda Copyright (C) 2021 Lukas Koenen\n" - "This program comes with ABSOLUTELY NO WARRANTY; for details type `-l, --license w'.\n" - "This is free software, and you are welcome to redistribute it\n" - "under certain conditions; type `-l, --license c' for details." << std::endl; - break; - } - case 'w': { - std::cout << "THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY\n" - "APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT\n" - "HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY\n" - "OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,\n" - "THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n" - "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM\n" - "IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF\n" - "ALL NECESSARY SERVICING, REPAIR OR CORRECTION." << std::endl; - break; - } - case 'c': { - std::cout << "This program is free software: you can redistribute it and/or modify\n" - "it under the terms of the GNU General Public License as published by\n" - "the Free Software Foundation, either version 3 of the License, or\n" - "(at your license_option) any later version." << std::endl; - break; - } - default: { - std::cout << std::string("unsupported license_option --license ").append(1, license_option) + - " use -h to show help"; - return 1; - } - } - return 0; - } + return 0; + } #ifdef __linux - if (geteuid()) { - return RelaunchAsRoot(argc, argv); - } + if (geteuid()) { + return RelaunchAsRoot(argc, argv); + } #endif - QApplication application(argc, (char **) argv); + QApplication application(argc, const_cast<char **>(argv)); - // max file size is in mb - if (parser.exists("verbose")) { - Logger::Setup(spdlog::level::trace, "openconnect-log", 1, 3); - } else { - Logger::Setup(spdlog::level::off, "openconnect-log", 1, 3); - } + // max file size is in mb + if (parser.exists("verbose")) { + Logger::Setup(spdlog::level::trace, "openconnect-log", 1, 3); + } else { + Logger::Setup(spdlog::level::off, "openconnect-log", 1, 3); + } - OpenconnectWindow openconnect_window; - openconnect_window.show(); + OpenconnectWindow openconnect_window; + openconnect_window.show(); - return QApplication::exec(); + return QApplication::exec(); } diff --git a/src/openconnect.h b/src/openconnect.h index 0dbe1026127521d1ec54f1c789b144c9776b2159..bff760fa6bbf93d4eecc1b9468fd4970774a600d 100644 --- a/src/openconnect.h +++ b/src/openconnect.h @@ -17,12 +17,12 @@ * Lesser General Public License for more details. */ -#ifndef __OPENCONNECT_H__ -#define __OPENCONNECT_H__ +#ifndef SRC_OPENCONNECT_H_ +#define SRC_OPENCONNECT_H_ -#include <stdint.h> -#include <sys/types.h> #include <unistd.h> +#include <sys/types.h> +#include <cstdint> #ifdef __cplusplus extern "C" { @@ -178,64 +178,63 @@ extern "C" { * #endif */ #define OPENCONNECT_CHECK_VER(maj, min) \ - (OPENCONNECT_API_VERSION_MAJOR > (maj) || \ - (OPENCONNECT_API_VERSION_MAJOR == (maj) && \ - OPENCONNECT_API_VERSION_MINOR >= (min))) + (OPENCONNECT_API_VERSION_MAJOR > (maj) || \ + (OPENCONNECT_API_VERSION_MAJOR == (maj) && \ + OPENCONNECT_API_VERSION_MINOR >= (min))) /****************************************************************************/ /* Enumeration of supported VPN protocols */ -#define OC_PROTO_PROXY (1<<0) -#define OC_PROTO_CSD (1<<1) -#define OC_PROTO_AUTH_CERT (1<<2) -#define OC_PROTO_AUTH_OTP (1<<3) -#define OC_PROTO_AUTH_STOKEN (1<<4) -#define OC_PROTO_PERIODIC_TROJAN (1<<5) +#define OC_PROTO_PROXY (1<<0) +#define OC_PROTO_CSD (1<<1) +#define OC_PROTO_AUTH_CERT (1<<2) +#define OC_PROTO_AUTH_OTP (1<<3) +#define OC_PROTO_AUTH_STOKEN (1<<4) +#define OC_PROTO_PERIODIC_TROJAN (1<<5) struct oc_vpn_proto { - const char *name; - const char *pretty_name; - const char *description; - unsigned int flags; + const char *name; + const char *pretty_name; + const char *description; + unsigned int flags; }; /****************************************************************************/ /* Authentication form processing */ -#define OC_FORM_OPT_TEXT 1 -#define OC_FORM_OPT_PASSWORD 2 -#define OC_FORM_OPT_SELECT 3 -#define OC_FORM_OPT_HIDDEN 4 -#define OC_FORM_OPT_TOKEN 5 +#define OC_FORM_OPT_TEXT 1 +#define OC_FORM_OPT_PASSWORD 2 +#define OC_FORM_OPT_SELECT 3 +#define OC_FORM_OPT_HIDDEN 4 +#define OC_FORM_OPT_TOKEN 5 -#define OC_FORM_RESULT_ERR -1 -#define OC_FORM_RESULT_OK 0 -#define OC_FORM_RESULT_CANCELLED 1 -#define OC_FORM_RESULT_NEWGROUP 2 +#define OC_FORM_RESULT_ERR (-1) +#define OC_FORM_RESULT_OK 0 +#define OC_FORM_RESULT_CANCELLED 1 +#define OC_FORM_RESULT_NEWGROUP 2 #ifdef __OPENCONNECT_PRIVATE__ -#define OC_FORM_RESULT_LOGGEDIN 255 - -#define OC_FORM_OPT_SECOND_AUTH 0x8000 +#define OC_FORM_RESULT_LOGGEDIN 255 +#define OC_FORM_OPT_SECOND_AUTH 0x8000 #endif -#define OC_FORM_OPT_IGNORE 0x0001 -#define OC_FORM_OPT_NUMERIC 0x0002 +#define OC_FORM_OPT_IGNORE 0x0001 +#define OC_FORM_OPT_NUMERIC x0002 /* char * fields are static (owned by XML parser) and don't need to be freed by the form handling code — except for value, which for TEXT and PASSWORD options is allocated by openconnect_set_option_value() when process_form() interacts with the user and must be freed. */ struct oc_form_opt { - struct oc_form_opt *next; - int type; - char *name; - char *label; - char *_value; /* Use openconnect_set_option_value() to set this */ - unsigned int flags; - void *reserved; + struct oc_form_opt *next; + int type; + char *name; + char *label; + char *_value; /* Use openconnect_set_option_value() to set this */ + unsigned int flags; + void *reserved; }; /* To set the value to a form use the following function */ @@ -243,89 +242,89 @@ int openconnect_set_option_value(struct oc_form_opt *opt, const char *value); /* All fields are static, owned by the XML parser */ struct oc_choice { - char *name; - char *label; - char *auth_type; - char *override_name; - char *override_label; + char *name; + char *label; + char *auth_type; + char *override_name; + char *override_label; #ifdef __OPENCONNECT_PRIVATE__ - int second_auth; - char *secondary_username; - int secondary_username_editable; - int noaaa; + int second_auth; + char *secondary_username; + int secondary_username_editable; + int noaaa; #endif }; struct oc_form_opt_select { - struct oc_form_opt form; - int nr_choices; - struct oc_choice **choices; + struct oc_form_opt form; + int nr_choices; + struct oc_choice **choices; }; /* All char * fields are static, owned by the XML parser */ struct oc_auth_form { - char *banner; - char *message; - char *error; - char *auth_id; - char *method; - char *action; - struct oc_form_opt *opts; - struct oc_form_opt_select *authgroup_opt; - int authgroup_selection; + char *banner; + char *message; + char *error; + char *auth_id; + char *method; + char *action; + struct oc_form_opt *opts; + struct oc_form_opt_select *authgroup_opt; + int authgroup_selection; }; struct oc_split_include { - const char *route; - struct oc_split_include *next; + const char *route; + struct oc_split_include *next; }; struct oc_ip_info { - const char *addr; - const char *netmask; - const char *addr6; - const char *netmask6; - const char *dns[3]; - const char *nbns[3]; - const char *domain; - const char *proxy_pac; - int mtu; - - struct oc_split_include *split_dns; - struct oc_split_include *split_includes; - struct oc_split_include *split_excludes; - - /* The elements above this line come from server-provided CSTP headers, - * so they should be handled with caution. gateway_addr is generated - * locally from getnameinfo(). */ - char *gateway_addr; + const char *addr; + const char *netmask; + const char *addr6; + const char *netmask6; + const char *dns[3]; + const char *nbns[3]; + const char *domain; + const char *proxy_pac; + int mtu; + + struct oc_split_include *split_dns; + struct oc_split_include *split_includes; + struct oc_split_include *split_excludes; + + /* The elements above this line come from server-provided CSTP headers, + * so they should be handled with caution. gateway_addr is generated + * locally from getnameinfo(). */ + char *gateway_addr; }; struct oc_vpn_option { - char *option; - char *value; - struct oc_vpn_option *next; + char *option; + char *value; + struct oc_vpn_option *next; }; struct oc_stats { - uint64_t tx_pkts; - uint64_t tx_bytes; - uint64_t rx_pkts; - uint64_t rx_bytes; + uint64_t tx_pkts; + uint64_t tx_bytes; + uint64_t rx_pkts; + uint64_t rx_bytes; }; struct oc_cert { - int der_len; - unsigned char *der_data; - void *reserved; + int der_len; + unsigned char *der_data; + void *reserved; }; /****************************************************************************/ -#define PRG_ERR 0 -#define PRG_INFO 1 -#define PRG_DEBUG 2 -#define PRG_TRACE 3 +#define PRG_ERR 0 +#define PRG_INFO 1 +#define PRG_DEBUG 2 +#define PRG_TRACE 3 /* Byte commands to write into the cmd_fd: * @@ -339,29 +338,29 @@ struct oc_cert { * cookie. * STATS calls the stats_handler. */ -#define OC_CMD_CANCEL 'x' -#define OC_CMD_PAUSE 'p' -#define OC_CMD_DETACH 'd' -#define OC_CMD_STATS 's' +#define OC_CMD_CANCEL 'x' +#define OC_CMD_PAUSE 'p' +#define OC_CMD_DETACH 'd' +#define OC_CMD_STATS 's' -#define RECONNECT_INTERVAL_MIN 10 -#define RECONNECT_INTERVAL_MAX 100 +#define RECONNECT_INTERVAL_MIN 10 +#define RECONNECT_INTERVAL_MAX 100 struct openconnect_info; typedef enum { - OC_TOKEN_MODE_NONE, - OC_TOKEN_MODE_STOKEN, - OC_TOKEN_MODE_TOTP, - OC_TOKEN_MODE_HOTP, - OC_TOKEN_MODE_YUBIOATH, - OC_TOKEN_MODE_OIDC, + OC_TOKEN_MODE_NONE, + OC_TOKEN_MODE_STOKEN, + OC_TOKEN_MODE_TOTP, + OC_TOKEN_MODE_HOTP, + OC_TOKEN_MODE_YUBIOATH, + OC_TOKEN_MODE_OIDC, } oc_token_mode_t; typedef enum { - OC_COMPRESSION_MODE_NONE, - OC_COMPRESSION_MODE_STATELESS, - OC_COMPRESSION_MODE_ALL, + OC_COMPRESSION_MODE_NONE, + OC_COMPRESSION_MODE_STATELESS, + OC_COMPRESSION_MODE_ALL, } oc_compression_mode_t; /* All strings are UTF-8. If operating in a legacy environment where @@ -383,7 +382,7 @@ typedef enum { environment, call with name==NULL. */ int openconnect_set_csd_environ(struct openconnect_info *vpninfo, - const char *name, const char *value); + const char *name, const char *value); /* This string is static, valid only while the connection lasts. If you * are going to cache this to remember which certs the user has accepted, @@ -403,7 +402,7 @@ const char *openconnect_get_peer_cert_hash(struct openconnect_info *vpninfo); * a different hash function today. This function will get it right. * Returns 0 on match; 1 on mismatch, -errno on failure. */ int openconnect_check_peer_cert_hash(struct openconnect_info *vpninfo, - const char *old_hash); + const char *old_hash); /* The buffers returned by these two functions must be freed with openconnect_free_cert_info(), especially on Windows. */ @@ -412,27 +411,27 @@ char *openconnect_get_peer_cert_details(struct openconnect_info *vpninfo); /* Returns the length of the created DER output, in a newly-allocated buffer that will need to be freed by openconnect_free_cert_info(). */ int openconnect_get_peer_cert_DER(struct openconnect_info *vpninfo, - unsigned char **buf); + unsigned char **buf); void openconnect_free_cert_info(struct openconnect_info *vpninfo, - void *buf); + void *buf); /* Creates a list of all certs in the peer's chain, returning the number of certs in the chain (or <0 on error). Only valid inside the validate_peer_cert callback. The caller should free the chain, but should not modify the contents. */ int openconnect_get_peer_cert_chain(struct openconnect_info *vpninfo, - struct oc_cert **chain); + struct oc_cert **chain); void openconnect_free_peer_cert_chain(struct openconnect_info *vpninfo, - struct oc_cert *chain); + struct oc_cert *chain); /* Contains a comma-separated list of authentication methods to enabled. Currently supported: Negotiate,NTLM,Digest,Basic */ int openconnect_set_http_auth(struct openconnect_info *vpninfo, - const char *methods); + const char *methods); int openconnect_set_proxy_auth(struct openconnect_info *vpninfo, - const char *methods); + const char *methods); int openconnect_set_http_proxy(struct openconnect_info *vpninfo, - const char *proxy); + const char *proxy); int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo); int openconnect_obtain_cookie(struct openconnect_info *vpninfo); int openconnect_init_ssl(void); @@ -488,16 +487,16 @@ int openconnect_set_localname(struct openconnect_info *, const char *); typedef int (*openconnect_lock_token_vfn)(void *tokdata); typedef int (*openconnect_unlock_token_vfn)(void *tokdata, const char *new_tok); int openconnect_set_token_callbacks(struct openconnect_info *, void *tokdata, - openconnect_lock_token_vfn, - openconnect_unlock_token_vfn); + openconnect_lock_token_vfn, + openconnect_unlock_token_vfn); int openconnect_set_token_mode(struct openconnect_info *, - oc_token_mode_t, const char *token_str); + oc_token_mode_t, const char *token_str); /* Legacy stoken-only function; do not use */ int openconnect_set_stoken_mode(struct openconnect_info *, int, const char *); int openconnect_set_compression_mode(struct openconnect_info *, - oc_compression_mode_t); + oc_compression_mode_t); /* The size must be 41 bytes, since that's the size of a 20-byte SHA1 represented as hex with a trailing NUL. */ @@ -521,13 +520,13 @@ void openconnect_set_xmlpost(struct openconnect_info *, int enable); int openconnect_set_reported_os(struct openconnect_info *, const char *os); int openconnect_set_version_string(struct openconnect_info *vpninfo, - const char *version_string); + const char *version_string); int openconnect_set_mobile_info(struct openconnect_info *vpninfo, - const char *mobile_platform_version, - const char *mobile_device_type, - const char *mobile_device_uniqueid); + const char *mobile_platform_version, + const char *mobile_device_type, + const char *mobile_device_uniqueid); int openconnect_set_client_cert(struct openconnect_info *, const char *cert, - const char *sslkey); + const char *sslkey); int openconnect_set_key_password(struct openconnect_info *vpninfo, const char *pass); const char *openconnect_get_ifname(struct openconnect_info *); void openconnect_set_reqmtu(struct openconnect_info *, int reqmtu); @@ -541,9 +540,9 @@ time_t openconnect_get_auth_expiration(struct openconnect_info *); pointers are no longer valid. For similar reasons, it is unsafe to call this function from another thread. */ int openconnect_get_ip_info(struct openconnect_info *, - const struct oc_ip_info **info, - const struct oc_vpn_option **cstp_options, - const struct oc_vpn_option **dtls_options); + const struct oc_ip_info **info, + const struct oc_vpn_option **cstp_options, + const struct oc_vpn_option **dtls_options); int openconnect_get_port(struct openconnect_info *); const char *openconnect_get_cookie(struct openconnect_info *); @@ -554,7 +553,7 @@ void openconnect_disable_ipv6(struct openconnect_info *vpninfo); void openconnect_reset_ssl(struct openconnect_info *vpninfo); int openconnect_parse_url(struct openconnect_info *vpninfo, const char *url); void openconnect_set_cert_expiry_warning(struct openconnect_info *vpninfo, - int seconds); + int seconds); void openconnect_set_pfs(struct openconnect_info *vpninfo, unsigned val); int openconnect_set_allow_insecure_crypto(struct openconnect_info *vpninfo, unsigned val); @@ -588,11 +587,11 @@ int openconnect_make_cstp_connection(struct openconnect_info *vpninfo); /* Create a tun device through the OS kernel (typical use case). Both strings are optional and can be NULL if desired. */ int openconnect_setup_tun_device(struct openconnect_info *vpninfo, - const char *vpnc_script, const char *ifname); + const char *vpnc_script, const char *ifname); /* Pass traffic to a script program (no tun device). */ int openconnect_setup_tun_script(struct openconnect_info *vpninfo, - const char *tun_script); + const char *tun_script); #ifdef _WIN32 /* Caller will provide an overlap-capable handle for the tunnel traffic. */ @@ -607,8 +606,8 @@ int openconnect_setup_dtls(struct openconnect_info *vpninfo, int dtls_attempt_pe /* Start the main loop; exits if OC_CMD_CANCEL is received on cmd_fd or the remote site aborts. */ int openconnect_mainloop(struct openconnect_info *vpninfo, - int reconnect_timeout, - int reconnect_interval); + int reconnect_timeout, + int reconnect_interval); /* The first (privdata) argument to each of these functions is either the privdata argument provided to openconnect_vpninfo_new_with_cbdata(), @@ -622,8 +621,8 @@ int openconnect_mainloop(struct openconnect_info *vpninfo, in OpenConnect and *is* translated). The function shall return zero if the certificate is (or has in the past been) explicitly accepted by the user, and non-zero to abort the connection. */ -typedef int (*openconnect_validate_peer_cert_vfn) (void *privdata, - const char *reason); +typedef int (*openconnect_validate_peer_cert_vfn)(void *privdata, + const char *reason); /* On a successful connection, the server may provide us with a new XML configuration file. This contains the list of servers that can be chosen by the user to connect to, amongst other stuff that we mostly @@ -631,34 +630,34 @@ typedef int (*openconnect_validate_peer_cert_vfn) (void *privdata, not match the SHA1 set with the openconnect_set_xmlsha1() above. If they don't match, or openconnect_set_xmlsha1() has not been called, then the new XML is downloaded and this function is invoked. */ -typedef int (*openconnect_write_new_config_vfn) (void *privdata, const char *buf, - int buflen); +typedef int (*openconnect_write_new_config_vfn)(void *privdata, const char *buf, + int buflen); /* Handle an authentication form, requesting input from the user. * Return value: * < 0, on error * = 0, when form was parsed and POST required * = 1, when response was cancelled by user */ -typedef int (*openconnect_process_auth_form_vfn) (void *privdata, - struct oc_auth_form *form); +typedef int (*openconnect_process_auth_form_vfn)(void *privdata, + struct oc_auth_form *form); /* Logging output which the user *may* want to see. */ typedef void __attribute__ ((format(printf, 3, 4))) - (*openconnect_progress_vfn) (void *privdata, int level, - const char *fmt, ...); +(*openconnect_progress_vfn)(void *privdata, int level, + const char *fmt, ...); struct openconnect_info *openconnect_vpninfo_new(const char *useragent, - openconnect_validate_peer_cert_vfn, - openconnect_write_new_config_vfn, - openconnect_process_auth_form_vfn, - openconnect_progress_vfn, - void *privdata); + openconnect_validate_peer_cert_vfn, + openconnect_write_new_config_vfn, + openconnect_process_auth_form_vfn, + openconnect_progress_vfn, + void *privdata); void openconnect_vpninfo_free(struct openconnect_info *vpninfo); /* Callback to allow binding a newly created socket's file descriptor to a specific interface, e.g. with SO_BINDTODEVICE. This tells the kernel not to route the traffic in question over the VPN tunnel. */ -typedef void (*openconnect_protect_socket_vfn) (void *privdata, int fd); +typedef void (*openconnect_protect_socket_vfn)(void *privdata, int fd); void openconnect_set_protect_socket_handler(struct openconnect_info *vpninfo, - openconnect_protect_socket_vfn protect_socket); + openconnect_protect_socket_vfn protect_socket); void openconnect_set_loglevel(struct openconnect_info *vpninfo, int level); @@ -666,9 +665,9 @@ void openconnect_set_pass_tos(struct openconnect_info *vpninfo, int enable); /* Callback for obtaining traffic stats via OC_CMD_STATS. */ -typedef void (*openconnect_stats_vfn) (void *privdata, const struct oc_stats *stats); +typedef void (*openconnect_stats_vfn)(void *privdata, const struct oc_stats *stats); void openconnect_set_stats_handler(struct openconnect_info *vpninfo, - openconnect_stats_vfn stats_handler); + openconnect_stats_vfn stats_handler); /* SSL certificate capabilities. openconnect_has_pkcs11_support() means that we can accept PKCS#11 URLs in place of filenames, for the certificate and key. */ @@ -692,22 +691,22 @@ const char *openconnect_get_protocol(struct openconnect_info *vpninfo); int openconnect_set_protocol(struct openconnect_info *vpninfo, const char *protocol); struct addrinfo; -typedef int (*openconnect_getaddrinfo_vfn) (void *privdata, const char *node, const char *service, - const struct addrinfo *hints, struct addrinfo **res); +typedef int (*openconnect_getaddrinfo_vfn)(void *privdata, const char *node, const char *service, + const struct addrinfo *hints, struct addrinfo **res); void openconnect_override_getaddrinfo(struct openconnect_info *vpninfo, openconnect_getaddrinfo_vfn gai_fn); /* Callback for configuring the interface after tunnel is fully up. */ -typedef void (*openconnect_setup_tun_vfn) (void *privdata); +typedef void (*openconnect_setup_tun_vfn)(void *privdata); void openconnect_set_setup_tun_handler(struct openconnect_info *vpninfo, - openconnect_setup_tun_vfn setup_tun); + openconnect_setup_tun_vfn setup_tun); /* Callback for indicating that a TCP reconnection succeeded. */ -typedef void (*openconnect_reconnected_vfn) (void *privdata); +typedef void (*openconnect_reconnected_vfn)(void *privdata); void openconnect_set_reconnected_handler(struct openconnect_info *vpninfo, - openconnect_reconnected_vfn reconnected_fn); + openconnect_reconnected_vfn reconnected_fn); #ifdef __cplusplus } #endif -#endif /* __OPENCONNECT_H__ */ +#endif // SRC_OPENCONNECT_H_ diff --git a/src/openconnectmanager.cpp b/src/openconnectmanager.cpp index b1ed360a799b0cd801a942ce87e87dcc566ef5c7..05a1df5d1f40e5b59ece7eaa64a9c845514784ef 100644 --- a/src/openconnectmanager.cpp +++ b/src/openconnectmanager.cpp @@ -15,342 +15,199 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "openconnectmanager.h" +#include "src/openconnectmanager.h" -#include <utility> +#include "src/openconnectwidget.h" +#include "src/openconnectwindow.h" -#include "openconnectwidget.h" -#include "openconnectwindow.h" - -static int ValidatePeerCertificate(void *private_data, const char *reason) { - // if the certificate is valid ignore if the certificate has changed -> otherwise every 90 days warning (lets encrypt) - return 0; +OpenconnectManager::OpenconnectManager(std::string hostname, QWidget *managing_widget) : + openconnect_info_(nullptr), + managing_widget_(dynamic_cast<OpenconnectWidget *>(managing_widget)), + health_probe_(this), + connection_status_(OpenconnectManager::Status::kDisconnected), + hostname_(std::move(hostname)), + username_(), + password_(), + first_auth_attempt_(true), + command_pipe_file_descriptor_(INVALID_SOCKET) { + qRegisterMetaType<OpenconnectManager::Status>("OpenconnectManager::Status"); + + connect(&health_probe_, &HealthProbe::SignalHealthCheckFailed, this, + &OpenconnectManager::SlotOpenconnectDisconnect); + connect(managing_widget, SIGNAL(SignalOpenconnectConnect()), this, SLOT(SlotOpenconnectConnect()), + Qt::QueuedConnection); + connect(managing_widget, SIGNAL(SignalOpenconnectDisconnect()), this, SLOT(SlotOpenconnectDisconnect()), + Qt::QueuedConnection); } -static int ProcessAuthForm(void *private_data, struct oc_auth_form *form) { - auto openconnect_manager = (OpenconnectManager *) (private_data); - - if (form->banner) { - Logger::Instance()->warn("[{}] {}", Logger::Component::kOpenconnect, std::string(form->banner)); - } else if (form->message) { - Logger::Instance()->warn("[{}] {}", Logger::Component::kOpenconnect, std::string(form->message)); - } else if (form->error) { - Logger::Instance()->warn("[{}] {}", Logger::Component::kOpenconnect, std::string(form->error)); - } - - for (auto option = form->opts; option; option = option->next) { - if (option->flags & OC_FORM_OPT_IGNORE) { - continue; - } - - if (!openconnect_manager->HandleAuthFormOption(option)) { - return OC_FORM_RESULT_CANCELLED; - } - } - - return OC_FORM_RESULT_OK; +OpenconnectManager::~OpenconnectManager() { + thread()->quit(); } -static void ProgressHandler(void *private_data, int level, const char *format, ...) { - char buffer[512]; - size_t buffer_length; - va_list argument_list; +bool OpenconnectManager::HandleAuthFormOption(oc_form_opt *form_option) { + if (form_option->type == OC_FORM_OPT_TEXT || form_option->type == OC_FORM_OPT_PASSWORD) { + if (!first_auth_attempt_) { + emit SignalPopupCreation("Invalid Username or Password"); - // don't spam - if (level == PRG_TRACE) { - return; + return false; } - buffer[0] = 0; - va_start(argument_list, format); - vsnprintf(buffer, sizeof(buffer), format, argument_list); - va_end(argument_list); - - buffer_length = strlen(buffer); - if (buffer[buffer_length - 1] == '\n') { - buffer[buffer_length - 1] = 0; + if (form_option->type == OC_FORM_OPT_TEXT) { + openconnect_set_option_value(form_option, username_.c_str()); + } else { + openconnect_set_option_value(form_option, password_.c_str()); + first_auth_attempt_ = false; } - Logger::Instance()->info("[{}] {}", Logger::Component::kOpenconnect, std::string(buffer)); -} - -static void StatsHandler(void *private_data, const struct oc_stats *stats) { - auto openconnect_manager = (OpenconnectManager *) (private_data); + } else { + Logger::Instance()->warn("[{}] Unknown form type: {}", Logger::Component::kOpenconnect, + std::to_string(form_option->type)); + } - Logger::Instance()->info("[{}] {} {} {}", Logger::Component::kOpenconnect, std::to_string(stats->tx_bytes), - std::to_string(stats->rx_bytes), - std::string(openconnect_get_dtls_cipher(openconnect_manager->GetVpnInfo()))); + return true; } -static int LockToken(void *private_data) { - auto openconnect_manager = (OpenconnectManager *) (private_data); - - return openconnect_set_token_mode(openconnect_manager->GetVpnInfo(), - (oc_token_mode_t) (openconnect_manager->GetTokenType()), - openconnect_manager->GetTokenString().c_str()); +void OpenconnectManager::SetUsername(const std::string &username) { + username_ = username; } -static int UnlockToken(void *private_data, const char *newToken) { - auto openconnect_manager = (OpenconnectManager *) (private_data); - - openconnect_manager->SetTokenString(newToken); - return 0; +void OpenconnectManager::SetPassword(const std::string &password) { + password_ = password; } -static void SetupTunnel(void *private_data) { - auto openconnect_manager = (OpenconnectManager *) (private_data); - -#ifdef _WIN32 - std::string vpnc_script_path = GetApplicationDirectory() + "/resources/win/vpnc-script-win.js"; +void OpenconnectManager::SetCommandPipeFileDescriptor( +#ifdef __WIN32 + SOCKET file_descriptor #elif __linux - std::string vpnc_script_path = - GetParentDirectory(GetApplicationDirectory()) + - "/share/openconnect-hda/resources/linux/split-tunneling-vpnc"; + int file_descriptor #endif - if (!fs::exists(vpnc_script_path) || - openconnect_setup_tun_device(openconnect_manager->GetVpnInfo(), vpnc_script_path.c_str(), nullptr) != 0) { - Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, "failed to Setup tunnel"); - - if (!fs::exists(vpnc_script_path)) { - Logger::Instance()->critical("[{}] no vpnc script found at: {}", Logger::Component::kOpenconnect, - vpnc_script_path); - } - - emit openconnect_manager->SignalPopupCreation("Failed to Setup tunnel."); - return; - } - - openconnect_manager->SetConnectionStatus(OpenconnectManager::Status::kConnected); +) { + command_pipe_file_descriptor_ = file_descriptor; } -static void MainLoop(OpenconnectManager *openconnect_manager) { - while (openconnect_mainloop(openconnect_manager->GetVpnInfo(), 100, RECONNECT_INTERVAL_MIN) != 0) { - Logger::Instance()->info("[{}] {}", Logger::Component::kOpenconnect, "disconnected"); - - openconnect_manager->SetCommandPipeFileDescriptor(INVALID_SOCKET); - openconnect_manager->SetConnectionStatus(OpenconnectManager::Status::kDisconnected); - - emit openconnect_manager->SignalWidgetDisconnect(); - break; - } +void OpenconnectManager::SetConnectionStatus(OpenconnectManager::Status status) { + connection_status_ = status; + emit SignalStatusChanged(connection_status_); } -OpenconnectManager::OpenconnectManager(std::string hostname, QWidget *managing_widget) : - vpn_info_(nullptr), - managing_widget_(dynamic_cast<OpenconnectWidget *>(managing_widget)), - health_probe_(this), - connection_status_(OpenconnectManager::Status::kDisconnected), - hostname_(std::move(hostname)), - username_(), - password_(), - token_string_(), - first_auth_attempt_(true), - command_pipe_file_descriptor_(INVALID_SOCKET), - token_type_() { - qRegisterMetaType<OpenconnectManager::Status>("OpenconnectManager::Status"); - - connect(&health_probe_, &HealthProbe::SignalHealthCheckFailed, this, - &OpenconnectManager::SlotOpenconnectDisconnect); - connect(managing_widget, SIGNAL(SignalOpenconnectConnect()), this, SLOT(SlotOpenconnectConnect()), - Qt::QueuedConnection); - connect(managing_widget, SIGNAL(SignalOpenconnectDisconnect()), this, SLOT(SlotOpenconnectDisconnect()), - Qt::QueuedConnection); +OpenconnectManager::Status OpenconnectManager::GetConnectionStatus() { + return connection_status_; } -OpenconnectManager::~OpenconnectManager() { - thread()->quit(); +struct openconnect_info *OpenconnectManager::GetOpenconnectInfo() { + return openconnect_info_; } void OpenconnectManager::SlotOpenconnectConnect() { - int return_value = OpenconnectConnect(); - if (return_value != 0) { - if (!managing_widget_->GetUiParent()->CloseEventOngoing() && return_value != OC_FORM_RESULT_CANCELLED) { - emit SignalPopupCreation("Setting up connection failed."); - } - } else { - QtConcurrent::run(MainLoop, this); + int return_value = OpenconnectConnect(); + if (return_value != 0) { + if (!managing_widget_->GetUiParent()->CloseEventOngoing() && return_value != OC_FORM_RESULT_CANCELLED) { + emit SignalPopupCreation("Setting up connection failed."); } + } else { + QtConcurrent::run(MainLoop, this); + } - first_auth_attempt_ = true; + first_auth_attempt_ = true; } void OpenconnectManager::SlotOpenconnectDisconnect() { - if (connection_status_ == OpenconnectManager::Status::kConnected) { - SetConnectionStatus(OpenconnectManager::Status::kDisconnecting); - health_probe_.SetMonitoringState(HealthProbe::MonitoringStates::kDisconnected); - - char oc_command = OC_CMD_CANCEL; + if (connection_status_ == OpenconnectManager::Status::kConnected) { + SetConnectionStatus(OpenconnectManager::Status::kDisconnecting); + health_probe_.SetMonitoringState(HealthProbe::MonitoringStates::kDisconnected); - while (command_pipe_file_descriptor_ != INVALID_SOCKET) { - if (int returnValue = PIPE_WRITE(command_pipe_file_descriptor_, &oc_command, 1) < 0) { - Logger::Instance()->critical("[{}] IPC error: {}", Logger::Component::kOpenconnect, - std::to_string(returnValue)); - } + char oc_command = OC_CMD_CANCEL; - usleep(1000); - } + while (command_pipe_file_descriptor_ != INVALID_SOCKET) { + if (int returnValue = PIPE_WRITE(command_pipe_file_descriptor_, &oc_command, 1) < 0) { + Logger::Instance()->critical("[{}] IPC error: {}", Logger::Component::kOpenconnect, + std::to_string(returnValue)); + } - openconnect_vpninfo_free(vpn_info_); - -#ifdef _WIN32 - WSACleanup(); -#endif + usleep(1000); } -} - -bool OpenconnectManager::HandleAuthFormOption(oc_form_opt *form_option) { - if (form_option->type == OC_FORM_OPT_TEXT || form_option->type == OC_FORM_OPT_PASSWORD) { - if (!first_auth_attempt_) { - emit SignalPopupCreation("Invalid Username or Password"); - return false; - } + openconnect_vpninfo_free(openconnect_info_); - if (form_option->type == OC_FORM_OPT_TEXT) { - openconnect_set_option_value(form_option, username_.c_str()); - } else { - openconnect_set_option_value(form_option, password_.c_str()); - first_auth_attempt_ = false; - } - - } else { - Logger::Instance()->warn("[{}] Unknown form type: {}", Logger::Component::kOpenconnect, - std::to_string(form_option->type)); - } - - return true; -} - -void OpenconnectManager::SetUsername(const std::string &username) { - username_ = username; -} - -void OpenconnectManager::SetPassword(const std::string &password) { - password_ = password; -} - -void OpenconnectManager::SetTokenString(const std::string &token_string) { - token_string_ = token_string; -} - -void OpenconnectManager::SetCommandPipeFileDescriptor( -#ifdef __WIN32 - SOCKET file_descriptor -#elif __linux - int file_descriptor +#ifdef _WIN32 + WSACleanup(); #endif -) { - command_pipe_file_descriptor_ = file_descriptor; -} - -void OpenconnectManager::SetConnectionStatus(OpenconnectManager::Status status) { - connection_status_ = status; - emit SignalStatusChanged(connection_status_); -} - -OpenconnectManager::Status OpenconnectManager::GetConnectionStatus() { - return connection_status_; -} - -struct openconnect_info *OpenconnectManager::GetVpnInfo() { - return vpn_info_; -} - -int OpenconnectManager::GetTokenType() const { - return token_type_; -} - -const std::string &OpenconnectManager::GetTokenString() const { - return token_string_; + } } int OpenconnectManager::OpenconnectConnect() { #ifdef __WIN32 - WSADATA data; - WSAStartup(MAKEWORD(1, 1), &data); + WSADATA data; + WSAStartup(MAKEWORD(1, 1), &data); #endif #ifdef _WIN32 - std::string os_name = "win"; + std::string os_name = "win"; #elif __linux - std::string os_name = "linux"; + std::string os_name = "linux"; #ifndef __i368__ - os_name += "-64"; + os_name += "-64"; #endif #else #error Define OS string of other platforms ... #endif - vpn_info_ = openconnect_vpninfo_new("OpenConnect-GUI VPN Client", ValidatePeerCertificate, nullptr, - ProcessAuthForm, ProgressHandler, this); + openconnect_info_ = openconnect_vpninfo_new("OpenConnect-GUI VPN Client", ValidatePeerCertificate, nullptr, + ProcessAuthForm, ProgressHandler, this); - if (vpn_info_ == nullptr) { - Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, "initial Setup fails"); - return -1; - } + if (openconnect_info_ == nullptr) { + Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, "initial Setup fails"); + return -1; + } - if ((command_pipe_file_descriptor_ = openconnect_setup_cmd_pipe(vpn_info_)) == INVALID_SOCKET) { - Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, "pipe Setup failed"); - return -1; - } + if ((command_pipe_file_descriptor_ = openconnect_setup_cmd_pipe(openconnect_info_)) == INVALID_SOCKET) { + Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, "pipe Setup failed"); + return -1; + } -#ifdef __WIN32 - if (BlockSocket(command_pipe_file_descriptor_) != 0) { -#elif __linux - if (BlockSocket(command_pipe_file_descriptor_) == -1) { -#endif - Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, "blocking socket failed"); - return -1; - } - - openconnect_set_stats_handler(vpn_info_, StatsHandler); - - if (!token_string_.empty()) { - openconnect_set_token_callbacks(vpn_info_, this, LockToken, UnlockToken); - openconnect_set_token_mode(vpn_info_, (oc_token_mode_t) token_type_, token_string_.c_str()); - } + openconnect_set_stats_handler(openconnect_info_, StatsHandler); - int return_code; - if ((return_code = openconnect_set_protocol(vpn_info_, "gp")) != 0) { - Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, "setting protocol failed"); - return return_code; - } + int return_code; + if ((return_code = openconnect_set_protocol(openconnect_info_, "gp")) != 0) { + Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, "setting protocol failed"); + return return_code; + } - openconnect_set_setup_tun_handler(vpn_info_, SetupTunnel); + openconnect_set_setup_tun_handler(openconnect_info_, SetupTunnel); - if ((return_code = openconnect_parse_url(vpn_info_, hostname_.c_str())) != 0) { - Logger::Instance()->critical("[{}] parsing url failed: {}", Logger::Component::kOpenconnect, hostname_); - return return_code; - } + if ((return_code = openconnect_parse_url(openconnect_info_, hostname_.c_str())) != 0) { + Logger::Instance()->critical("[{}] parsing url failed: {}", Logger::Component::kOpenconnect, hostname_); + return return_code; + } - if ((return_code = openconnect_set_reported_os(vpn_info_, os_name.c_str())) != 0) { - Logger::Instance()->critical("[{}] setting os failed: {}", Logger::Component::kOpenconnect, os_name); - return return_code; - } + if ((return_code = openconnect_set_reported_os(openconnect_info_, os_name.c_str())) != 0) { + Logger::Instance()->critical("[{}] setting os failed: {}", Logger::Component::kOpenconnect, os_name); + return return_code; + } - if ((return_code = openconnect_obtain_cookie(vpn_info_)) != 0) { - if (return_code != OC_FORM_RESULT_CANCELLED) { - Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, - "Authentication error cannot obtain cookie"); - } - return return_code; + if ((return_code = openconnect_obtain_cookie(openconnect_info_)) != 0) { + if (return_code != OC_FORM_RESULT_CANCELLED) { + Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, + "Authentication error cannot obtain cookie"); } + return return_code; + } - SetConnectionStatus(OpenconnectManager::Status::kConnecting); + SetConnectionStatus(OpenconnectManager::Status::kConnecting); - if ((return_code = openconnect_make_cstp_connection(vpn_info_)) != 0) { - Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, - "Error establishing the CSTP channel"); - return return_code; - } + if ((return_code = openconnect_make_cstp_connection(openconnect_info_)) != 0) { + Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, + "Error establishing the CSTP channel"); + return return_code; + } - if ((return_code = openconnect_setup_dtls(vpn_info_, 100)) != 0) { - Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, - "Set up UDP failed; using SSL instead"); - return return_code; - } + if ((return_code = openconnect_setup_dtls(openconnect_info_, 100)) != 0) { + Logger::Instance()->critical("[{}] {}", Logger::Component::kOpenconnect, + "Set up UDP failed; using SSL instead"); + return return_code; + } - health_probe_.SetMonitoringState(HealthProbe::MonitoringStates::kStartup); + health_probe_.SetMonitoringState(HealthProbe::MonitoringStates::kStartup); - return 0; + return 0; } diff --git a/src/openconnectmanager.h b/src/openconnectmanager.h index 38ae7faae615535665dd4ce690061c3adec5510c..afc7f9c6fcda68b918320ab9629adc2e20bbd8f4 100644 --- a/src/openconnectmanager.h +++ b/src/openconnectmanager.h @@ -15,8 +15,12 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef OPENCONNECT_GUI_C_VPNCONFIG_H -#define OPENCONNECT_GUI_C_VPNCONFIG_H +#ifndef SRC_OPENCONNECTMANAGER_H_ +#define SRC_OPENCONNECTMANAGER_H_ + +#include <QObject> +#include <QtConcurrent/QtConcurrent> +#include <QtConcurrent/QtConcurrentRun> #include <stdexcept> #include <iostream> @@ -24,17 +28,13 @@ #include <algorithm> #include <cstring> #include <cstdarg> +#include <utility> -#include <QObject> -#include <QtConcurrent/QtConcurrent> -#include <QtConcurrent/QtConcurrentRun> - -#include "openconnect.h" - -#include "popupinfo.h" -#include "healthprobe.h" -#include "utils.h" -#include "logger.h" +#include "src/openconnect.h" +#include "src/popupinfo.h" +#include "src/healthprobe.h" +#include "src/utils.h" +#include "src/logger.h" #ifdef __linux #define INVALID_SOCKET (-1) @@ -45,156 +45,254 @@ class OpenconnectWindow; class OpenconnectWidget; class OpenconnectManager : public QObject { -Q_OBJECT - -public: - enum Status { - kDisconnected, kDisconnecting, kConnected, kConnecting - }; - - explicit OpenconnectManager(std::string hostname, QWidget *managing_widget = nullptr); - - ~OpenconnectManager() override; - - /** - * Handle authentication-form requests form the server - * - * @param form_option struct that represents the form -> see openconnect library - */ - bool HandleAuthFormOption(oc_form_opt *form_option); - - /** - * Set the username - * - * @param username string containing the username - */ - void SetUsername(const std::string &username); - - /** - * Set the password - * - * @param password string containing the password - */ - void SetPassword(const std::string &password); - - /** - * Set the token string - * - * @param token_string string containing the string representation of the token - */ - void SetTokenString(const std::string &token_string); - - /** - * Set the command pipe file descriptor - * - * @param file_descriptor SOCKET / int containing the file descriptor - */ - void SetCommandPipeFileDescriptor( + Q_OBJECT + + public: + enum Status { + kDisconnected, kDisconnecting, kConnected, kConnecting + }; + + explicit OpenconnectManager(std::string hostname, QWidget *managing_widget = nullptr); + + ~OpenconnectManager() override; + + /** + * Handle authentication-form requests form the server + * + * @param form_option struct that represents the form -> see openconnect library + */ + bool HandleAuthFormOption(oc_form_opt *form_option); + + /** + * Set the username + * + * @param username string containing the username + */ + void SetUsername(const std::string &username); + + /** + * Set the password + * + * @param password string containing the password + */ + void SetPassword(const std::string &password); + + /** + * Set the command pipe file descriptor + * + * @param file_descriptor SOCKET / int containing the file descriptor + */ + void SetCommandPipeFileDescriptor( #ifdef __WIN32 - SOCKET file_descriptor + SOCKET file_descriptor); #elif __linux - int file_descriptor + int file_descriptor); #endif - ); - - /** - * Set the connection status - * - * @param status represented by the OpenconnectManager::Status enum - */ - void SetConnectionStatus(OpenconnectManager::Status status); - - /** - * Get the current connection status -> see OpenconnectManager::Status enum - * - * @return status representing the current connection status - */ - [[nodiscard]] OpenconnectManager::Status GetConnectionStatus(); - - /** - * Get the openconnect_info struct -> see openconnect library - * - * @return pointer to openconnect_info struct - */ - [[nodiscard]] struct openconnect_info *GetVpnInfo(); - - /** - * Get the current token type - * - * @return int representing oc_token_mode_t enum -> see openconnect library - */ - [[nodiscard]] int GetTokenType() const; - - /** - * Get the current token string - * - * @return string containing the token - */ - [[nodiscard]] const std::string &GetTokenString() const; - -signals: - - /** - * Signal to show that a disconnect should happen - */ - void SignalWidgetDisconnect(); - - /** - * Signal change in the connection status - * - * @param status representing the changed connection status -> see OpenconnectManager::Status enum - */ - void SignalStatusChanged(OpenconnectManager::Status status); - - /** - * Signal that can be used to create a popup in the ui_ thread from another thread - * - * @param info_message message inside the popup - */ - void SignalPopupCreation(QString info_message); - -public slots: - - /** - * Slot to handle openconnect connect request - */ - void SlotOpenconnectConnect(); - - /** - * Slot to handle openconnect disconnect request - */ - void SlotOpenconnectDisconnect(); - -private: - /** - * Perform openconnect connect - * - * @return int representing return status - */ - int OpenconnectConnect(); - - struct openconnect_info *vpn_info_{}; - - OpenconnectWidget *managing_widget_; - - HealthProbe health_probe_; - - OpenconnectManager::Status connection_status_; - - std::string hostname_; - std::string username_; - std::string password_; - std::string token_string_; - - bool first_auth_attempt_; + + /** + * Set the connection status + * + * @param status represented by the OpenconnectManager::Status enum + */ + void SetConnectionStatus(OpenconnectManager::Status status); + + /** + * Get the current connection status -> see OpenconnectManager::Status enum + * + * @return status representing the current connection status + */ + [[nodiscard]] OpenconnectManager::Status GetConnectionStatus(); + + /** + * Get the openconnect_info struct -> see openconnect library + * + * @return pointer to openconnect_info struct + */ + [[nodiscard]] struct openconnect_info *GetOpenconnectInfo(); + + signals: + + /** + * Signal to show that a disconnect should happen + */ + void SignalWidgetDisconnect(); + + /** + * Signal change in the connection status + * + * @param status representing the changed connection status -> see OpenconnectManager::Status enum + */ + void SignalStatusChanged(OpenconnectManager::Status status); + + /** + * Signal that can be used to create a popup in the ui_ thread from another thread + * + * @param info_message message inside the popup + */ + void SignalPopupCreation(QString info_message); + + public slots: + + /** + * Slot to handle openconnect connect request + */ + void SlotOpenconnectConnect(); + + /** + * Slot to handle openconnect disconnect request + */ + void SlotOpenconnectDisconnect(); + + private: + /** + * Perform openconnect connect + * + * @return int representing return status + */ + int OpenconnectConnect(); + + struct openconnect_info *openconnect_info_; + + OpenconnectWidget *managing_widget_; + + HealthProbe health_probe_; + + OpenconnectManager::Status connection_status_; + + std::string hostname_; + std::string username_; + std::string password_; + + bool first_auth_attempt_; #ifdef __WIN32 - SOCKET + SOCKET #else - int + int #endif - command_pipe_file_descriptor_; - int token_type_; + command_pipe_file_descriptor_; }; -#endif //OPENCONNECT_GUI_C_VPNCONFIG_H +static int ValidatePeerCertificate(void *private_data, const char *reason) { + // if the certificate is valid ignore if the certificate has changed + // -> otherwise every 90 days warning (lets encrypt) + return 0; +} + +static int ProcessAuthForm(void *private_data, struct oc_auth_form *form) { + auto openconnect_manager = + reinterpret_cast<OpenconnectManager *>(private_data); + + if (form->banner) { + Logger::Instance()->warn("[{}] {}", + Logger::Component::kOpenconnect, + std::string(form->banner)); + } else if (form->message) { + Logger::Instance()->warn("[{}] {}", + Logger::Component::kOpenconnect, + std::string(form->message)); + } else if (form->error) { + Logger::Instance()->warn("[{}] {}", + Logger::Component::kOpenconnect, + std::string(form->error)); + } + + for (auto option = form->opts; option; option = option->next) { + if (option->flags & OC_FORM_OPT_IGNORE) { + continue; + } + + if (!openconnect_manager->HandleAuthFormOption(option)) { + return OC_FORM_RESULT_CANCELLED; + } + } + + return OC_FORM_RESULT_OK; +} + +static void ProgressHandler(void *private_data, + int level, + const char *format, + ...) { + char buffer[512]; + size_t buffer_length; + va_list argument_list; + + buffer[0] = 0; + va_start(argument_list, format); + vsnprintf(buffer, sizeof(buffer), format, argument_list); + va_end(argument_list); + + buffer_length = strlen(buffer); + if (buffer[buffer_length - 1] == '\n') { + buffer[buffer_length - 1] = 0; + } + + Logger::Instance()->info("[{}] {}", Logger::Component::kOpenconnect, std::string(buffer)); +} + +static void StatsHandler(void *private_data, const struct oc_stats *stats) { + auto openconnect_manager = + reinterpret_cast<OpenconnectManager *>(private_data); + + Logger::Instance()->info("[{}] {} {} {}", + Logger::Component::kOpenconnect, + std::to_string(stats->tx_bytes), + std::to_string(stats->rx_bytes), + std::string(openconnect_get_dtls_cipher( + openconnect_manager->GetOpenconnectInfo()))); +} + +static void SetupTunnel(void *private_data) { + auto openconnect_manager = + reinterpret_cast<OpenconnectManager *>(private_data); + +#ifdef _WIN32 + std::string vpnc_script_path = GetApplicationDirectory() + + "/resources/win/vpnc-script-win.js"; +#elif __linux + std::string vpnc_script_path = + GetParentDirectory(GetApplicationDirectory()) + + "/share/openconnect-hda/resources/linux/split-tunneling-vpnc"; +#endif + if (!fs::exists(vpnc_script_path) || + openconnect_setup_tun_device(openconnect_manager->GetOpenconnectInfo(), + vpnc_script_path.c_str(), + nullptr) != + 0) { + Logger::Instance()->critical("[{}] {}", + Logger::Component::kOpenconnect, + "failed to Setup tunnel"); + + if (!fs::exists(vpnc_script_path)) { + Logger::Instance()->critical("[{}] no vpnc script found at: {}", + Logger::Component::kOpenconnect, + vpnc_script_path); + } + + emit openconnect_manager->SignalPopupCreation("Failed to Setup tunnel."); + return; + } + + openconnect_manager->SetConnectionStatus( + OpenconnectManager::Status::kConnected); +} + +static void MainLoop(OpenconnectManager *openconnect_manager) { + while (openconnect_mainloop(openconnect_manager->GetOpenconnectInfo(), + 100, + RECONNECT_INTERVAL_MIN) != 0) { + Logger::Instance()->info("[{}] {}", + Logger::Component::kOpenconnect, + "disconnected"); + + openconnect_manager->SetCommandPipeFileDescriptor(INVALID_SOCKET); + openconnect_manager->SetConnectionStatus( + OpenconnectManager::Status::kDisconnected); + + emit openconnect_manager->SignalWidgetDisconnect(); + break; + } +} + +#endif // SRC_OPENCONNECTMANAGER_H_ diff --git a/src/openconnectwidget.cpp b/src/openconnectwidget.cpp index 593d033a0ace3818faaa8bc684438fc63905f8e6..1c610e5c5773143633cd86bc2d5bb7ead8c3b457 100644 --- a/src/openconnectwidget.cpp +++ b/src/openconnectwidget.cpp @@ -15,106 +15,103 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "openconnectwidget.h" - -#include "openconnectwindow.h" +#include "src/openconnectwidget.h" +#include "src/openconnectwindow.h" OpenconnectWidget::OpenconnectWidget(QWidget *parent) : QWidget(parent), ui_(new Ui::OpenconnectWidget), parent_(dynamic_cast<OpenconnectWindow *>(parent)), openconnect_manager_( - new OpenconnectManager("vpn.fbi.h-da.de", this)), + new OpenconnectManager("vpn.fbi.h-da.de", this)), openconnect_manager_thread_() { - ui_->setupUi(this); + ui_->setupUi(this); - openconnect_manager_->moveToThread(&openconnect_manager_thread_); - openconnect_manager_thread_.start(); + openconnect_manager_->moveToThread(&openconnect_manager_thread_); + openconnect_manager_thread_.start(); #ifdef __WIN32 - busy_movie_ = new QMovie(QString::fromStdString(GetApplicationDirectory() + "/resources/busy_symbol.gif")); + busy_movie_ = new QMovie(QString::fromStdString(GetApplicationDirectory() + "/resources/busy_symbol.gif")); #elif __linux - busy_movie_ = new QMovie( - QString::fromStdString( - GetParentDirectory(GetApplicationDirectory()) + "/share/openconnect-hda/resources/busy_symbol.gif")); + busy_movie_ = new QMovie( + QString::fromStdString( + GetParentDirectory(GetApplicationDirectory()) + "/share/openconnect-hda/resources/busy_symbol.gif")); #endif - busy_movie_->start(); - - ui_->busy_animation_->setMovie(busy_movie_); - ui_->busy_animation_->hide(); - - connect(parent_, &OpenconnectWindow::SignalTopLevelCloseEvent, this, &OpenconnectWidget::SlotCloseEvent); - connect(ui_->connect_button_, SIGNAL(clicked()), this, SLOT(SlotConnectClicked()), Qt::QueuedConnection); - connect(ui_->disconnect_button_, SIGNAL(clicked()), this, SLOT(SlotDisconnectClicked()), Qt::QueuedConnection); - connect(openconnect_manager_, SIGNAL(SignalWidgetDisconnect()), this, SLOT(SlotWidgetDisconnect())); - connect(openconnect_manager_, SIGNAL(SignalStatusChanged(OpenconnectManager::Status)), this, - SLOT(SlotStatusChanged(const OpenconnectManager::Status &))); - connect(openconnect_manager_, SIGNAL(SignalPopupCreation(QString)), this, SLOT(SlotCreatePopup(const QString &))); + busy_movie_->start(); + + ui_->busy_animation_->setMovie(busy_movie_); + ui_->busy_animation_->hide(); + + connect(parent_, &OpenconnectWindow::SignalTopLevelCloseEvent, this, &OpenconnectWidget::SlotCloseEvent); + connect(ui_->connect_button_, SIGNAL(clicked()), this, SLOT(SlotConnectClicked()), Qt::QueuedConnection); + connect(ui_->disconnect_button_, SIGNAL(clicked()), this, SLOT(SlotDisconnectClicked()), Qt::QueuedConnection); + connect(openconnect_manager_, SIGNAL(SignalWidgetDisconnect()), this, SLOT(SlotWidgetDisconnect())); + connect(openconnect_manager_, SIGNAL(SignalStatusChanged(OpenconnectManager::Status)), this, + SLOT(SlotStatusChanged(const OpenconnectManager::Status &))); + connect(openconnect_manager_, SIGNAL(SignalPopupCreation(QString)), this, SLOT(SlotCreatePopup(const QString &))); } OpenconnectWidget::~OpenconnectWidget() { - openconnect_manager_->deleteLater(); - openconnect_manager_thread_.wait(); + openconnect_manager_->deleteLater(); + openconnect_manager_thread_.wait(); - busy_movie_->stop(); - delete busy_movie_; + busy_movie_->stop(); + delete busy_movie_; - delete ui_; + delete ui_; } OpenconnectWindow *OpenconnectWidget::GetUiParent() { - return parent_; + return parent_; } void OpenconnectWidget::SlotDisconnectClicked() { - emit SignalOpenconnectDisconnect(); + emit SignalOpenconnectDisconnect(); } void OpenconnectWidget::SlotWidgetDisconnect() { - if (parent_->CloseEventOngoing()) { - emit SignalFinishedDisconnect(); - } + if (parent_->CloseEventOngoing()) { + emit SignalFinishedDisconnect(); + } } void OpenconnectWidget::SlotCloseEvent() { - if (openconnect_manager_->GetConnectionStatus() == OpenconnectManager::Status::kConnected) { - SlotDisconnectClicked(); - } else { - SlotWidgetDisconnect(); - } + if (openconnect_manager_->GetConnectionStatus() == OpenconnectManager::Status::kConnected) { + SlotDisconnectClicked(); + } else { + SlotWidgetDisconnect(); + } } void OpenconnectWidget::SlotConnectClicked() { - if (openconnect_manager_->GetConnectionStatus() == OpenconnectManager::Status::kDisconnected) { - openconnect_manager_->SetUsername(ui_->username_field_->text().toStdString()); - openconnect_manager_->SetPassword(ui_->password_field_->text().toStdString()); + if (openconnect_manager_->GetConnectionStatus() == OpenconnectManager::Status::kDisconnected) { + openconnect_manager_->SetUsername(ui_->username_field_->text().toStdString()); + openconnect_manager_->SetPassword(ui_->password_field_->text().toStdString()); - emit SignalOpenconnectConnect(); - } + emit SignalOpenconnectConnect(); + } } void OpenconnectWidget::SlotStatusChanged(const OpenconnectManager::Status &status) { - switch (status) { - case OpenconnectManager::kDisconnected: { - ui_->connection_status_->setText(tr("disconnected")); - ui_->busy_animation_->hide(); - break; - } - case OpenconnectManager::kConnected: { - ui_->connection_status_->setText(tr("connected")); - ui_->busy_animation_->hide(); - break; - } - case OpenconnectManager::kDisconnecting: - ui_->connection_status_->setText(tr("disconnecting")); - ui_->busy_animation_->show(); - break; - case OpenconnectManager::kConnecting: - ui_->connection_status_->setText(tr("connecting")); - ui_->busy_animation_->show(); - break; + switch (status) { + case OpenconnectManager::kDisconnected: { + ui_->connection_status_->setText(tr("disconnected")); + ui_->busy_animation_->hide(); + break; + } + case OpenconnectManager::kConnected: { + ui_->connection_status_->setText(tr("connected")); + ui_->busy_animation_->hide(); + break; } + case OpenconnectManager::kDisconnecting:ui_->connection_status_->setText(tr("disconnecting")); + ui_->busy_animation_->show(); + break; + case OpenconnectManager::kConnecting:ui_->connection_status_->setText(tr("connecting")); + ui_->busy_animation_->show(); + break; + } } void OpenconnectWidget::SlotCreatePopup(const QString &info_message) { - PopupInfo info(info_message.toStdString(), parent_); - info.ShowAndWaitForReturn(); + PopupInfo info(info_message.toStdString(), parent_); + info.ShowAndWaitForReturn(); } diff --git a/src/openconnectwidget.h b/src/openconnectwidget.h index c0a98071b7c973fa9eab4cd50b83b71664a66f7f..e6f75cc6ea40ec53f6965a7fbf126d31e52456d4 100644 --- a/src/openconnectwidget.h +++ b/src/openconnectwidget.h @@ -15,14 +15,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef OPENCONNECT_GUI_OPENCONNECTFRAME_H -#define OPENCONNECT_GUI_OPENCONNECTFRAME_H +#ifndef SRC_OPENCONNECTWIDGET_H_ +#define SRC_OPENCONNECTWIDGET_H_ #include <QMovie> -#include "ui_openconnectwidget.h" - -#include "openconnectmanager.h" +#include "autogen/include/ui_openconnectwidget.h" +#include "src/openconnectmanager.h" class OpenconnectWindow; @@ -31,85 +30,85 @@ namespace Ui { class OpenconnectWidget; } QT_END_NAMESPACE class OpenconnectWidget : public QWidget { -Q_OBJECT + Q_OBJECT -public: - explicit OpenconnectWidget(QWidget *parent = nullptr); + public: + explicit OpenconnectWidget(QWidget *parent = nullptr); - ~OpenconnectWidget() override; + ~OpenconnectWidget() override; - /** - * Get pointer to ui parent - * - * @return pointer to OpenconnectWindow - */ - [[nodiscard]] OpenconnectWindow *GetUiParent(); + /** + * Get pointer to ui parent + * + * @return pointer to OpenconnectWindow + */ + [[nodiscard]] OpenconnectWindow *GetUiParent(); -public slots: + public slots: - /** - * Slot to handle a hit of the SlotWidgetDisconnect button - */ - void SlotDisconnectClicked(); + /** + * Slot to handle a hit of the SlotWidgetDisconnect button + */ + void SlotDisconnectClicked(); -signals: + signals: - /** - * Signal used to show that the disconnect has finished - */ - void SignalFinishedDisconnect(); + /** + * Signal used to show that the disconnect has finished + */ + void SignalFinishedDisconnect(); - /** - * Signal openconnect connect - */ - void SignalOpenconnectConnect(); + /** + * Signal openconnect connect + */ + void SignalOpenconnectConnect(); - /** - * Signal openconnect disconnect - */ - void SignalOpenconnectDisconnect(); + /** + * Signal openconnect disconnect + */ + void SignalOpenconnectDisconnect(); -private slots: + private slots: - /** - * Slot to perform a complete disconnect - */ - void SlotWidgetDisconnect(); + /** + * Slot to perform a complete disconnect + */ + void SlotWidgetDisconnect(); - /** - * Slot to handle top level close event - */ - void SlotCloseEvent(); + /** + * Slot to handle top level close event + */ + void SlotCloseEvent(); - /** - * Slot to handle a hit of the connection button - */ - void SlotConnectClicked(); + /** + * Slot to handle a hit of the connection button + */ + void SlotConnectClicked(); - /** - * Slot to handle changed status - * - * @param status current status -> see OpenconnectManager::Status enum - */ - void SlotStatusChanged(const OpenconnectManager::Status &status); + /** + * Slot to handle changed status + * + * @param status current status -> see OpenconnectManager::Status enum + */ + void SlotStatusChanged(const OpenconnectManager::Status &status); - /** - * Slot to create a popup - * - * @param info_message message inside the popup - */ - void SlotCreatePopup(const QString &info_message); + /** + * Slot to create a popup + * + * @param info_message message inside the popup + */ + void SlotCreatePopup(const QString &info_message); -private: - Ui::OpenconnectWidget *ui_; + private: + Ui::OpenconnectWidget *ui_; - OpenconnectWindow *parent_; + OpenconnectWindow *parent_; - OpenconnectManager *openconnect_manager_; + OpenconnectManager *openconnect_manager_; - QThread openconnect_manager_thread_; + QThread openconnect_manager_thread_; - QMovie *busy_movie_; + QMovie *busy_movie_; }; -#endif //OPENCONNECT_GUI_OPENCONNECTFRAME_H +#endif // SRC_OPENCONNECTWIDGET_H_ diff --git a/src/openconnectwindow.cpp b/src/openconnectwindow.cpp index 7aa9d2b9cc3dda122872cfb08a738ca0ba99b633..e26b05427f3a62b91cea3abea59c3fc1cbee7459 100644 --- a/src/openconnectwindow.cpp +++ b/src/openconnectwindow.cpp @@ -15,152 +15,152 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "openconnectwindow.h" +#include "src/openconnectwindow.h" OpenconnectWindow::OpenconnectWindow(QWidget *ui_parent) : - QMainWindow(ui_parent), ui_(new Ui::OpenconnectWindow), - system_tray_icon_available_(QSystemTrayIcon::isSystemTrayAvailable()), ongoing_close_event_(false) { - ui_->setupUi(this); + QMainWindow(ui_parent), ui_(new Ui::OpenconnectWindow), + system_tray_icon_available_(QSystemTrayIcon::isSystemTrayAvailable()), ongoing_close_event_(false) { + ui_->setupUi(this); - openconnect_widget_ = new OpenconnectWidget(this); - setCentralWidget(openconnect_widget_); + openconnect_widget_ = new OpenconnectWidget(this); + setCentralWidget(openconnect_widget_); - // set size to fit around widget - resize(openconnect_widget_->width(), openconnect_widget_->height() + STATUSBAR_OFFSET); - layout()->setSizeConstraint(QLayout::SetFixedSize); + // set size to fit around widget + resize(openconnect_widget_->width(), openconnect_widget_->height() + STATUSBAR_OFFSET); + layout()->setSizeConstraint(QLayout::SetFixedSize); - // move window to cursor location on startup - QPoint global_cursor_pos = QCursor::pos(); - QPoint local_cursor_pos = global_cursor_pos - QApplication::desktop()->geometry().topLeft(); - move(qRound(local_cursor_pos.x() - width() * 0.5), qRound(global_cursor_pos.y() - height() * 0.5)); + // move window to cursor location on startup + QPoint global_cursor_pos = QCursor::pos(); + QPoint local_cursor_pos = global_cursor_pos - QApplication::desktop()->geometry().topLeft(); + move(qRound(local_cursor_pos.x() - width() * 0.5), qRound(global_cursor_pos.y() - height() * 0.5)); #ifdef __WIN32 - QIcon application_icon = QIcon(QString::fromStdString(GetApplicationDirectory() + "/resources/logo.png")); + QIcon application_icon = QIcon(QString::fromStdString(GetApplicationDirectory() + "/resources/logo.png")); #elif __linux - QIcon application_icon = QIcon(QString::fromStdString( - GetParentDirectory(GetApplicationDirectory()) + "/share/openconnect-hda/resources/logo.png")); + QIcon application_icon = QIcon(QString::fromStdString( + GetParentDirectory(GetApplicationDirectory()) + "/share/openconnect-hda/resources/logo.png")); #endif - setWindowIcon(application_icon); - - if (system_tray_icon_available_) { - tray_icon_ = new QSystemTrayIcon(this); - tray_icon_->setIcon(application_icon); - - tray_menu_ = new QMenu(this); - tray_maximize_action_ = new QAction(tr("maximize"), this); - tray_disconnect_action_ = new QAction(tr("disconnect"), this); - tray_exit_action_ = new QAction(tr("exit"), this); - - tray_menu_->addAction(tray_maximize_action_); - tray_menu_->addAction(tray_disconnect_action_); - tray_menu_->addAction(tray_exit_action_); - - tray_icon_->setContextMenu(tray_menu_); - tray_icon_->show(); - - connect(tray_maximize_action_, SIGNAL(triggered()), this, SLOT(SlotShowWindow())); - connect(tray_disconnect_action_, &QAction::triggered, openconnect_widget_, - &OpenconnectWidget::SlotDisconnectClicked); - connect(tray_exit_action_, SIGNAL(triggered()), this, SLOT(close())); - connect(tray_icon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, SLOT(SlotShowWindow(QSystemTrayIcon::ActivationReason))); - } - - license_action_ = new QAction(tr("&License Information"), this); - license_action_->setStatusTip(tr("Show license for application")); - - about_qt_action_ = new QAction(tr("About &Qt"), this); - about_qt_action_->setStatusTip(tr("Show the Qt library information")); - - help_menu_ = menuBar()->addMenu(tr("&Help")); - help_menu_->addAction(license_action_); - help_menu_->addAction(about_qt_action_); - - statusBar()->showMessage( - tr("This window can be minimized, it will continue to run. (system tray or task bar)")); - - connect(license_action_, &QAction::triggered, this, &OpenconnectWindow::SlotLicenseInformation); - connect(about_qt_action_, &QAction::triggered, (QApplication *) QCoreApplication::instance(), - &QApplication::aboutQt); - connect(statusBar(), &QStatusBar::messageChanged, this, &OpenconnectWindow::SlotStatusBarMessageChanged); - connect(openconnect_widget_, &OpenconnectWidget::SignalFinishedDisconnect, this, &QApplication::quit); + setWindowIcon(application_icon); + + if (system_tray_icon_available_) { + tray_icon_ = new QSystemTrayIcon(this); + tray_icon_->setIcon(application_icon); + + tray_menu_ = new QMenu(this); + tray_maximize_action_ = new QAction(tr("maximize"), this); + tray_disconnect_action_ = new QAction(tr("disconnect"), this); + tray_exit_action_ = new QAction(tr("exit"), this); + + tray_menu_->addAction(tray_maximize_action_); + tray_menu_->addAction(tray_disconnect_action_); + tray_menu_->addAction(tray_exit_action_); + + tray_icon_->setContextMenu(tray_menu_); + tray_icon_->show(); + + connect(tray_maximize_action_, SIGNAL(triggered()), this, SLOT(SlotShowWindow())); + connect(tray_disconnect_action_, &QAction::triggered, openconnect_widget_, + &OpenconnectWidget::SlotDisconnectClicked); + connect(tray_exit_action_, SIGNAL(triggered()), this, SLOT(close())); + connect(tray_icon_, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(SlotShowWindow(QSystemTrayIcon::ActivationReason))); + } + + license_action_ = new QAction(tr("&License Information"), this); + license_action_->setStatusTip(tr("Show license for application")); + + about_qt_action_ = new QAction(tr("About &Qt"), this); + about_qt_action_->setStatusTip(tr("Show the Qt library information")); + + help_menu_ = menuBar()->addMenu(tr("&Help")); + help_menu_->addAction(license_action_); + help_menu_->addAction(about_qt_action_); + + statusBar()->showMessage( + tr("This window can be minimized, it will continue to run. (system tray or task bar)")); + + connect(license_action_, &QAction::triggered, this, &OpenconnectWindow::SlotLicenseInformation); + connect(about_qt_action_, &QAction::triggered, reinterpret_cast<QApplication *>(QCoreApplication::instance()), + &QApplication::aboutQt); + connect(statusBar(), &QStatusBar::messageChanged, this, &OpenconnectWindow::SlotStatusBarMessageChanged); + connect(openconnect_widget_, &OpenconnectWidget::SignalFinishedDisconnect, this, &QApplication::quit); } OpenconnectWindow::~OpenconnectWindow() { - if (system_tray_icon_available_) { - delete tray_disconnect_action_; - delete tray_exit_action_; - delete tray_menu_; - delete tray_icon_; - } - delete openconnect_widget_; - delete license_action_; - delete about_qt_action_; - delete ui_; + if (system_tray_icon_available_) { + delete tray_disconnect_action_; + delete tray_exit_action_; + delete tray_menu_; + delete tray_icon_; + } + delete openconnect_widget_; + delete license_action_; + delete about_qt_action_; + delete ui_; } bool OpenconnectWindow::CloseEventOngoing() const { - return ongoing_close_event_; + return ongoing_close_event_; } void OpenconnectWindow::SlotShowWindow(QSystemTrayIcon::ActivationReason reason) { - if (reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::DoubleClick || - reason == QSystemTrayIcon::Unknown) { - if (isHidden()) { - showNormal(); - } + if (reason == QSystemTrayIcon::Trigger || reason == QSystemTrayIcon::DoubleClick || + reason == QSystemTrayIcon::Unknown) { + if (isHidden()) { + showNormal(); } + } } void OpenconnectWindow::SlotLicenseInformation() { - QMessageBox::about(this, tr("license information"), - tr("openconnect-hda Copyright (C) 2021 Lukas Koenen\n" - "This program comes with ABSOLUTELY NO WARRANTY This is free software, " - "and you are welcome to redistribute it under certain condition\n\n" - "THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY" - "APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT" - "HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY" - "OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, " - "THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR" - "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM" - "IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF" - "ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n" - "This program is free software: you can redistribute it and/or modify" - "it under the terms of the GNU General Public License as published by" - "the Free Software Foundation, either version 3 of the License, or" - "(at your license_option) any later version.")); + QMessageBox::about(this, tr("license information"), + tr("openconnect-hda Copyright (C) 2021 Lukas Koenen\n" + "This program comes with ABSOLUTELY NO WARRANTY This is free software, " + "and you are welcome to redistribute it under certain condition\n\n" + "THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY" + "APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT" + "HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY" + "OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, " + "THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR" + "PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM" + "IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF" + "ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n" + "This program is free software: you can redistribute it and/or modify" + "it under the terms of the GNU General Public License as published by" + "the Free Software Foundation, either version 3 of the License, or" + "(at your license_option) any later version.")); } void OpenconnectWindow::SlotStatusBarMessageChanged() { - // if messageChanged is emitted and the status bar is still visible restore text - if (statusBar()->isVisible()) { - statusBar()->showMessage( - tr("This window can be minimized, it will continue to run. (system tray or task bar)")); - } + // if messageChanged is emitted and the status bar is still visible restore text + if (statusBar()->isVisible()) { + statusBar()->showMessage( + tr("This window can be minimized, it will continue to run. (system tray or task bar)")); + } } void OpenconnectWindow::closeEvent(QCloseEvent *event) { - if (!ongoing_close_event_) { - ongoing_close_event_ = true; + if (!ongoing_close_event_) { + ongoing_close_event_ = true; - if (system_tray_icon_available_) { - if (tray_icon_->isVisible()) { - tray_icon_->hide(); - } - } - - event->ignore(); - emit SignalTopLevelCloseEvent(); + if (system_tray_icon_available_) { + if (tray_icon_->isVisible()) { + tray_icon_->hide(); + } } + + event->ignore(); + emit SignalTopLevelCloseEvent(); + } } void OpenconnectWindow::hideEvent(QHideEvent *event) { - // on first hide event remove info text - if (statusBar()->isVisible()) { - statusBar()->hide(); - } - - if (system_tray_icon_available_) { - hide(); - } + // on first hide event remove info text + if (statusBar()->isVisible()) { + statusBar()->hide(); + } + + if (system_tray_icon_available_) { + hide(); + } } diff --git a/src/openconnectwindow.h b/src/openconnectwindow.h index c2181aeb0a635e6bd13e60cc455c10b9f22a186c..ee42405f2975e538ae69da5e2654b177f883129f 100644 --- a/src/openconnectwindow.h +++ b/src/openconnectwindow.h @@ -15,8 +15,8 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef OPENCONNECT_HDA_OPENCONNECTWINDOW_H -#define OPENCONNECT_HDA_OPENCONNECTWINDOW_H +#ifndef SRC_OPENCONNECTWINDOW_H_ +#define SRC_OPENCONNECTWINDOW_H_ #include <QSystemTrayIcon> #include <QMenu> @@ -26,9 +26,10 @@ #include <QMenuBar> #include <QCloseEvent> -#include "ui_openconnectwindow.h" +#include <utility> -#include "openconnectwidget.h" +#include "autogen/include/ui_openconnectwindow.h" +#include "src/openconnectwidget.h" #define STATUSBAR_OFFSET 10 @@ -37,68 +38,68 @@ namespace Ui { class OpenconnectWindow; } QT_END_NAMESPACE class OpenconnectWindow : public QMainWindow { -Q_OBJECT + Q_OBJECT -public: - explicit OpenconnectWindow(QWidget *ui_parent = nullptr); + public: + explicit OpenconnectWindow(QWidget *ui_parent = nullptr); - ~OpenconnectWindow() override; + ~OpenconnectWindow() override; - /** - * Get if there is a ongoing close event - * - * @return bool that represents if there is an ongoing close event - */ - [[nodiscard]] bool CloseEventOngoing() const; + /** + * Get if there is a ongoing close event + * + * @return bool that represents if there is an ongoing close event + */ + [[nodiscard]] bool CloseEventOngoing() const; -signals: + signals: - /** - * Signal to show that a close event has occurred - */ - void SignalTopLevelCloseEvent(); + /** + * Signal to show that a close event has occurred + */ + void SignalTopLevelCloseEvent(); -private slots: + private slots: - /** - * Slot that handles any event that requires the window to be shown - * - * @param reason behind the activation -> see ActivationReason enum - */ - void SlotShowWindow(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown); + /** + * Slot that handles any event that requires the window to be shown + * + * @param reason behind the activation -> see ActivationReason enum + */ + void SlotShowWindow(QSystemTrayIcon::ActivationReason reason = QSystemTrayIcon::Unknown); - /** - * Slot to handle printing license information - */ - void SlotLicenseInformation(); + /** + * Slot to handle printing license information + */ + void SlotLicenseInformation(); - /** - * Slot that handles messageChanged signal of status bar - */ - void SlotStatusBarMessageChanged(); + /** + * Slot that handles messageChanged signal of status bar + */ + void SlotStatusBarMessageChanged(); -private: - void closeEvent(QCloseEvent *event) override; + private: + void closeEvent(QCloseEvent *event) override; - void hideEvent(QHideEvent *event) override; + void hideEvent(QHideEvent *event) override; - Ui::OpenconnectWindow *ui_; + Ui::OpenconnectWindow *ui_; - OpenconnectWidget *openconnect_widget_; + OpenconnectWidget *openconnect_widget_; - QSystemTrayIcon *tray_icon_; + QSystemTrayIcon *tray_icon_; - QMenu *tray_menu_; - QMenu *help_menu_; + QMenu *tray_menu_; + QMenu *help_menu_; - QAction *tray_maximize_action_; - QAction *tray_disconnect_action_; - QAction *tray_exit_action_; - QAction *license_action_; - QAction *about_qt_action_; + QAction *tray_maximize_action_; + QAction *tray_disconnect_action_; + QAction *tray_exit_action_; + QAction *license_action_; + QAction *about_qt_action_; - bool system_tray_icon_available_; - bool ongoing_close_event_; + bool system_tray_icon_available_; + bool ongoing_close_event_; }; -#endif //OPENCONNECT_HDA_OPENCONNECTWINDOW_H +#endif // SRC_OPENCONNECTWINDOW_H_ diff --git a/src/popupinfo.cpp b/src/popupinfo.cpp index 302a6f6dfb432fc00b4b1a57c9c7e4313f5083cd..62df37e97f73b50e72aa61b79ef700640b53833c 100644 --- a/src/popupinfo.cpp +++ b/src/popupinfo.cpp @@ -15,74 +15,74 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "popupinfo.h" +#include "src/popupinfo.h" -#include "openconnectwindow.h" +#include "src/openconnectwindow.h" PopupInfo::PopupInfo(const std::string &info_text, QWidget *parent) : - QWidget(nullptr), ui_(new Ui::PopupInfo), ui_parent_(dynamic_cast<OpenconnectWindow *>(parent)) { - ui_->setupUi(this); + QWidget(nullptr), ui_(new Ui::PopupInfo), ui_parent_(dynamic_cast<OpenconnectWindow *>(parent)) { + ui_->setupUi(this); #ifdef __WIN32 - QIcon application_icon = QIcon(QString::fromStdString(GetApplicationDirectory() + "/resources/logo.png")); + QIcon application_icon = QIcon(QString::fromStdString(GetApplicationDirectory() + "/resources/logo.png")); #elif __linux - QIcon application_icon = QIcon( - QString::fromStdString( - GetParentDirectory(GetApplicationDirectory()) + "/share/openconnect-hda/resources/logo.png")); + QIcon application_icon = QIcon( + QString::fromStdString( + GetParentDirectory(GetApplicationDirectory()) + "/share/openconnect-hda/resources/logo.png")); #endif - setWindowIcon(application_icon); + setWindowIcon(application_icon); - if (ui_parent_) { - QPoint ui_parent_pos = ui_parent_->pos(); - move(qRound(ui_parent_pos.x() + (ui_parent_->width() - width()) * 0.5), ui_parent_pos.y()); - } else { - // center the QWidget Window on the Desktop - QRect desktop_geometry = QApplication::desktop()->availableGeometry(this); - QPoint center = desktop_geometry.center(); + if (ui_parent_) { + QPoint ui_parent_pos = ui_parent_->pos(); + move(qRound(ui_parent_pos.x() + (ui_parent_->width() - width()) * 0.5), ui_parent_pos.y()); + } else { + // center the QWidget Window on the Desktop + QRect desktop_geometry = QApplication::desktop()->availableGeometry(this); + QPoint center = desktop_geometry.center(); - move(qRound(center.x() - width() * 0.5), qRound(center.y() - height() * 0.5)); - } + move(qRound(center.x() - width() * 0.5), qRound(center.y() - height() * 0.5)); + } - ui_->info_label_->setText(tr(info_text.c_str())); + ui_->info_label_->setText(tr(info_text.c_str())); #ifdef __WIN32 - ui_->warning_symbol_->setPixmap( - QPixmap(QString::fromStdString(GetApplicationDirectory() + "/resources/warning_symbol.png"))); + ui_->warning_symbol_->setPixmap( + QPixmap(QString::fromStdString(GetApplicationDirectory() + "/resources/warning_symbol.png"))); #elif __linux - ui_->warning_symbol_->setPixmap( - QPixmap(QString::fromStdString( - GetParentDirectory(GetApplicationDirectory()) + - "/share/openconnect-hda/resources/warning_symbol.png"))); + ui_->warning_symbol_->setPixmap( + QPixmap(QString::fromStdString( + GetParentDirectory(GetApplicationDirectory()) + + "/share/openconnect-hda/resources/warning_symbol.png"))); #endif - connect(ui_->accept_button_, SIGNAL(clicked()), this, SLOT(SlotAcceptClicked())); + connect(ui_->accept_button_, SIGNAL(clicked()), this, SLOT(SlotAcceptClicked())); } PopupInfo::~PopupInfo() { - delete ui_; + delete ui_; } void PopupInfo::ShowAndWaitForReturn() { - show(); + show(); - QEventLoop waiting_loop; + QEventLoop waiting_loop; - if (ui_parent_) { - QObject::connect(ui_parent_, &OpenconnectWindow::SignalTopLevelCloseEvent, &waiting_loop, - &QEventLoop::quit); - } + if (ui_parent_) { + QObject::connect(ui_parent_, &OpenconnectWindow::SignalTopLevelCloseEvent, &waiting_loop, + &QEventLoop::quit); + } - QObject::connect(this, &PopupInfo::SignalAcceptOrCloseEvent, &waiting_loop, &QEventLoop::quit); - waiting_loop.exec(); + QObject::connect(this, &PopupInfo::SignalAcceptOrCloseEvent, &waiting_loop, &QEventLoop::quit); + waiting_loop.exec(); - destroy(); + destroy(); } void PopupInfo::SlotAcceptClicked() { - emit SignalAcceptOrCloseEvent(); + emit SignalAcceptOrCloseEvent(); } void PopupInfo::closeEvent(QCloseEvent *event) { - emit SignalAcceptOrCloseEvent(); - event->ignore(); + emit SignalAcceptOrCloseEvent(); + event->ignore(); } diff --git a/src/popupinfo.h b/src/popupinfo.h index e60dff1130bf93c5345b85704df7283516c236b8..cdc4ae97e9660ea0000916b6a9ceb8a465681da4 100644 --- a/src/popupinfo.h +++ b/src/popupinfo.h @@ -15,16 +15,16 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef OPENCONNECT_GUI_POPUPINFO_H -#define OPENCONNECT_GUI_POPUPINFO_H - -#include <string> +#ifndef SRC_POPUPINFO_H_ +#define SRC_POPUPINFO_H_ #include <QDesktopWidget> -#include "ui_popupinfo.h" +#include <string> +#include <utility> -#include "utils.h" +#include "autogen/include/ui_popupinfo.h" +#include "src/utils.h" class OpenconnectWindow; @@ -33,39 +33,39 @@ namespace Ui { class PopupInfo; } QT_END_NAMESPACE class PopupInfo : public QWidget { -Q_OBJECT + Q_OBJECT -public: - explicit PopupInfo(const std::string &info_text, QWidget *parent = nullptr); + public: + explicit PopupInfo(const std::string &info_text, QWidget *parent = nullptr); - ~PopupInfo() override; + ~PopupInfo() override; - /** - * Blocks until the user has entered an input - * - */ - void ShowAndWaitForReturn(); + /** + * Blocks until the user has entered an input + * + */ + void ShowAndWaitForReturn(); -signals: + signals: - /** - * Signal to represents an acknowledgement or a close event (interrupt) - */ - void SignalAcceptOrCloseEvent(); + /** + * Signal to represents an acknowledgement or a close event (interrupt) + */ + void SignalAcceptOrCloseEvent(); -private slots: + private slots: - /** - * Slot that handles hit of accept button - */ - void SlotAcceptClicked(); + /** + * Slot that handles hit of accept button + */ + void SlotAcceptClicked(); -private: - Ui::PopupInfo *ui_; + private: + Ui::PopupInfo *ui_; - OpenconnectWindow *ui_parent_; + OpenconnectWindow *ui_parent_; - void closeEvent(QCloseEvent *event) override; + void closeEvent(QCloseEvent *event) override; }; -#endif //OPENCONNECT_GUI_POPUPINFO_H +#endif // SRC_POPUPINFO_H_ diff --git a/src/utils.cpp b/src/utils.cpp index fac785fa745790c8308010b0a39248731c8cf124..50ec5441854a3b038979058bb1acf40c12bf8b6d 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -15,61 +15,46 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "utils.h" +#include "src/utils.h" std::string GetApplicationDirectory() { - char directory_buffer[256]; - ssize_t buffer_size = sizeof(directory_buffer); + char directory_buffer[256]; + ssize_t buffer_size = sizeof(directory_buffer); #ifdef __WIN32 - GetModuleFileName(nullptr, directory_buffer, buffer_size); - std::string application_path = std::string(directory_buffer); - return application_path.substr(0, application_path.find_last_of('\\')); + GetModuleFileName(nullptr, directory_buffer, buffer_size); + std::string application_path = std::string(directory_buffer); + return application_path.substr(0, application_path.find_last_of('\\')); #elif __linux - int number_of_bytes = std::min(readlink("/proc/self/exe", directory_buffer, buffer_size), buffer_size - 1); - if (number_of_bytes >= 0) - directory_buffer[number_of_bytes] = '\0'; + int number_of_bytes = std::min(readlink("/proc/self/exe", directory_buffer, buffer_size), buffer_size - 1); + if (number_of_bytes >= 0) + directory_buffer[number_of_bytes] = '\0'; - std::string application_path = std::string(directory_buffer); - return application_path.substr(0, application_path.find_last_of('/')); + std::string application_path = std::string(directory_buffer); + return application_path.substr(0, application_path.find_last_of('/')); #endif } #ifdef __linux std::string GetParentDirectory(const std::string &path) { - return std::filesystem::path(path).parent_path().string(); + return fs::path(path).parent_path().string(); } int RelaunchAsRoot(int argc, const char **argv) { - if (system("command -v pkexec > /dev/null") == 0) { - std::string program_arguments; - for (int i = 1; i < argc; ++i) { - program_arguments += argv[i]; - } - - return system(std::string( - "pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY XDG_RUNTIME_DIR=/run/user/$USER " + - GetApplicationDirectory() + "/openconnect-hda" + " " + program_arguments).c_str()); + if (system("command -v pkexec > /dev/null") == 0) { + std::string program_arguments; + for (int i = 1; i < argc; ++i) { + program_arguments += argv[i]; } - PopupInfo info("Application requires root privileges", nullptr); + return system(std::string( + "pkexec env DISPLAY=$DISPLAY XAUTHORITY=$XAUTHORITY XDG_RUNTIME_DIR=/run/user/$USER " + + GetApplicationDirectory() + "/openconnect-hda" + " " + program_arguments).c_str()); + } - return 1; -} + PopupInfo info("Application requires root privileges", nullptr); -#endif + return 1; +} -int BlockSocket( -#ifdef __WIN32 - SOCKET file_descriptor -#elif __linux - int file_descriptor #endif -) { -#ifdef __WIN32 - unsigned long mode = 0; - return ioctlsocket(file_descriptor, FIONBIO, &mode); -#elif __linux - return fcntl(file_descriptor, F_SETFL, fcntl(file_descriptor, F_GETFL) & ~O_NONBLOCK); -#endif -} diff --git a/src/utils.h b/src/utils.h index 685481b6bfc57e217c00c6268754016c9fe7043f..7aff339181bbd3b3540e443716cdc01c289d3b31 100644 --- a/src/utils.h +++ b/src/utils.h @@ -15,15 +15,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef OPENCONNECT_GUI_C_UTILS_H -#define OPENCONNECT_GUI_C_UTILS_H +#ifndef SRC_UTILS_H_ +#define SRC_UTILS_H_ #include <unistd.h> #include <climits> #include <string> -#include "popupinfo.h" - #ifdef _WIN32 #include <winsock2.h> @@ -37,6 +35,10 @@ #endif +#include "src/popupinfo.h" + +namespace fs = std::filesystem; + /** * Get the directory of the application * @@ -65,24 +67,10 @@ int RelaunchAsRoot(int argc, const char **argv); #endif -/** - * Block a socket based on it's file descriptor - * - * @param file_descriptor the file_descriptor as an int - * @return int indicating success (0) - */ -int BlockSocket( -#ifdef __WIN32 - SOCKET file_descriptor -#elif __linux - int file_descriptor -#endif -); - #ifdef _WIN32 #define PIPE_WRITE(x, y, z) send(x, y, z, 0) #else #define PIPE_WRITE(x, y, z) write(x, y, z) #endif -#endif //OPENCONNECT_GUI_C_UTILS_H +#endif // SRC_UTILS_H_