diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1d8608e7..79cf2293 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -153,6 +153,7 @@ find_package(Qt5Concurrent 5.2 REQUIRED)
find_package(Qt5Widgets 5.2 REQUIRED)
find_package(Qt5Test 5.2 REQUIRED)
find_package(Qt5LinguistTools 5.2 REQUIRED)
+find_package(Qt5Network 5.2 REQUIRED)
set(CMAKE_AUTOMOC ON)
# Debian sets the the build type to None for package builds.
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2ef1d77d..c7d8cbf3 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -174,7 +174,7 @@ qt5_wrap_ui(keepassx_SOURCES ${keepassx_FORMS})
add_library(keepassx_core STATIC ${keepassx_SOURCES})
set_target_properties(keepassx_core PROPERTIES COMPILE_DEFINITIONS KEEPASSX_BUILDING_CORE)
-target_link_libraries(keepassx_core Qt5::Core Qt5::Concurrent Qt5::Widgets)
+target_link_libraries(keepassx_core Qt5::Core Qt5::Concurrent Qt5::Widgets Qt5::Network)
add_executable(${PROGNAME} WIN32 MACOSX_BUNDLE ${keepassx_SOURCES_MAINEXE})
target_link_libraries(${PROGNAME}
@@ -183,6 +183,7 @@ target_link_libraries(${PROGNAME}
Qt5::Core
Qt5::Concurrent
Qt5::Widgets
+ Qt5::Network
${GCRYPT_LIBRARIES}
${ZLIB_LIBRARIES})
diff --git a/src/http/HttpSettings.cpp b/src/http/HttpSettings.cpp
index f9cf6c59..dd0dd00f 100644
--- a/src/http/HttpSettings.cpp
+++ b/src/http/HttpSettings.cpp
@@ -126,6 +126,18 @@ void HttpSettings::setSupportKphFields(bool supportKphFields)
config()->set("Http/SupportKphFields", supportKphFields);
}
+QString HttpSettings::httpHost()
+{
+ static const QString host = "localhost";
+
+ return config()->get("Http/Host", host).toString().toUtf8();
+}
+
+void HttpSettings::setHttpHost(QString host)
+{
+ config()->set("Http/Host", host);
+}
+
int HttpSettings::httpPort()
{
static const int PORT = 19455;
diff --git a/src/http/HttpSettings.h b/src/http/HttpSettings.h
index bea5648c..c1987f7e 100644
--- a/src/http/HttpSettings.h
+++ b/src/http/HttpSettings.h
@@ -42,6 +42,8 @@ public:
static void setSearchInAllDatabases(bool searchInAllDatabases);
static bool supportKphFields();
static void setSupportKphFields(bool supportKphFields);
+ static QString httpHost();
+ static void setHttpHost(QString host);
static int httpPort();
static void setHttpPort(int port);
diff --git a/src/http/OptionDialog.cpp b/src/http/OptionDialog.cpp
index 357a3cd7..4d9d1f6c 100644
--- a/src/http/OptionDialog.cpp
+++ b/src/http/OptionDialog.cpp
@@ -41,6 +41,7 @@ void OptionDialog::loadSettings()
ui->sortByUsername->setChecked(true);
else
ui->sortByTitle->setChecked(true);
+ ui->httpHost->setText(settings.httpHost());
ui->httpPort->setText(QString::number(settings.httpPort()));
/*
@@ -68,6 +69,7 @@ void OptionDialog::saveSettings()
settings.setUnlockDatabase(ui->unlockDatabase->isChecked());
settings.setMatchUrlScheme(ui->matchUrlScheme->isChecked());
settings.setSortByUsername(ui->sortByUsername->isChecked());
+ settings.setHttpHost(ui->httpHost->text());
settings.setHttpPort(ui->httpPort->text().toInt());
/*
diff --git a/src/http/OptionDialog.ui b/src/http/OptionDialog.ui
index c925d7ad..a230f2ad 100644
--- a/src/http/OptionDialog.ui
+++ b/src/http/OptionDialog.ui
@@ -28,7 +28,7 @@ This is required for accessing keypass database from ChromeIPass or PassIfoxQTabWidget::Rounded
- 2
+ 0
@@ -200,6 +200,30 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
+ -
+
+
-
+
+
+
+ 0
+ 0
+
+
+
+ HTTP Host:
+
+
+
+ -
+
+
+ Default host: localhost
+
+
+
+
+
-
-
diff --git a/src/http/Protocol.cpp b/src/http/Protocol.cpp
index 4650937e..40a1445c 100644
--- a/src/http/Protocol.cpp
+++ b/src/http/Protocol.cpp
@@ -27,7 +27,7 @@ static const char * const STR_SET_LOGIN = "set-login";
static const char * const STR_ASSOCIATE = "associate";
static const char * const STR_TEST_ASSOCIATE = "test-associate";
static const char * const STR_GENERATE_PASSWORD = "generate-password";
-static const char * const STR_VERSION = "1.8.4.1"; // TODO: not true, need to incorporate change of listener host
+static const char * const STR_VERSION = "1.8.4.1";
}/*namespace KeepassHttpProtocol*/
diff --git a/src/http/Server.cpp b/src/http/Server.cpp
index 2056464a..e54a9995 100644
--- a/src/http/Server.cpp
+++ b/src/http/Server.cpp
@@ -20,6 +20,9 @@
#include
#include
#include
+#include
+#include
+#include
using namespace KeepassHttpProtocol;
@@ -324,11 +327,49 @@ void Server::start(void)
int port = HttpSettings::httpPort();
- daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL, NULL,
- &this->request_handler_wrapper, this,
- MHD_OPTION_NOTIFY_COMPLETED,
- this->request_completed, NULL,
- MHD_OPTION_END);
+ struct sockaddr_in as;
+ struct sockaddr_in *ss = &as;
+ bool nohost = true;
+
+ QHostInfo info = QHostInfo::fromName(HttpSettings::httpHost());
+ if (!info.addresses().isEmpty()) {
+ QHostAddress address = info.addresses().first();
+
+ if (address.protocol() == QAbstractSocket::IPv4Protocol) {
+ struct sockaddr_in* addr = ss;
+ memset(addr, 0, sizeof(struct sockaddr_in));
+ addr->sin_family = AF_INET;
+ addr->sin_port = htons(HttpSettings::httpPort());
+ addr->sin_addr.s_addr = htonl(address.toIPv4Address());
+ nohost = false;
+#ifdef MHD_USE_IPv6
+ } else {
+ struct sockaddr_in6* addr = (sockaddr_in6*)ss;
+ memset(addr, 0, sizeof(struct sockaddr_in6));
+ addr->sin6_family = AF_INET6;
+ addr->sin6_port = htons(HttpSettings::httpPort());
+ memcpy(&addr->sin6_addr, address.toIPv6Address().c, 16);
+ nohost = false;
+#endif
+ }
+
+ daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL, NULL,
+ &this->request_handler_wrapper, this,
+ MHD_OPTION_NOTIFY_COMPLETED,
+ this->request_completed, NULL,
+ MHD_OPTION_SOCK_ADDR,
+ ss,
+ MHD_OPTION_END);
+ }
+
+ if (nohost) {
+ daemon = MHD_start_daemon(MHD_USE_SELECT_INTERNALLY, port, NULL, NULL,
+ &this->request_handler_wrapper, this,
+ MHD_OPTION_NOTIFY_COMPLETED,
+ this->request_completed, NULL,
+ MHD_OPTION_END);
+ }
+
m_started = true;
}