Merge pull request #196 from keepassxreboot/hotfix/147-keepasshttp

KeePassHTTP hotfix, resolves #147 and slightly increases security.
This commit is contained in:
Jonathan White 2017-01-24 19:12:04 -05:00 committed by GitHub
commit fe9bcc254a
7 changed files with 110 additions and 141 deletions

View File

@ -174,7 +174,9 @@ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS_NONE QT_NO_DEBUG)
find_package(Gcrypt 1.6.0 REQUIRED)
find_package(LibMicroHTTPD REQUIRED)
if (WITH_XC_HTTP)
find_package(LibMicroHTTPD REQUIRED)
endif(WITH_XC_HTTP)
find_package(ZLIB REQUIRED)

View File

@ -3,57 +3,63 @@
[![Travis Build Status](https://travis-ci.org/keepassxreboot/keepassxc.svg?branch=develop)](https://travis-ci.org/keepassxreboot/keepassxc) [![Coverage Status](https://coveralls.io/repos/github/keepassxreboot/keepassxc/badge.svg)](https://coveralls.io/github/keepassxreboot/keepassxc)
## About
Fork of [KeePassX](https://www.keepassx.org/) that [aims to incorporate stalled Pull Requests, features, and bug fixes that are not being incorporated into the main KeePassX baseline](https://github.com/keepassxreboot/keepassx/issues/43).
KeePassXC is a fork of [KeePassX](https://www.keepassx.org/) that [aims to incorporate stalled pull requests, features, and bug fixes that have never made it into the main KeePassX repository](https://github.com/keepassxreboot/keepassx/issues/43).
#### Additional Reboot Features
- keepasshttp support for use with [PassIFox](https://addons.mozilla.org/en-us/firefox/addon/passifox/) for Mozilla Firefox and [chromeIPass](https://chrome.google.com/webstore/detail/chromeipass/ompiailgknfdndiefoaoiligalphfdae) for Google Chrome.
## Additional features compared to KeePassX
- Autotype on all three major platforms (Linux, Windows, OS X)
- Stand-alone password generator
- Password strength meter
- Use website's favicons as entry icons
- Merging of databases
- Automatic reload when the database changed on disk
- KeePassHTTP support for use with [PassIFox](https://addons.mozilla.org/en-us/firefox/addon/passifox/) in Mozilla Firefox and [chromeIPass](https://chrome.google.com/webstore/detail/chromeipass/ompiailgknfdndiefoaoiligalphfdae) in Google Chrome or Chromium.
KeePassHttp implementation has been forked from jdachtera's repository, which in turn was based on code from code with Francois Ferrand's [keepassx-http](https://gitorious.org/keepassx/keepassx-http/source/master) repository.
This is a rebuild from [denk-mal's keepasshttp](https://github.com/denk-mal/keepassx.git) that brings it forward to Qt5 and KeePassX v2.x.
For a full list of features and changes, read the [CHANGELOG](CHANGELOG) document.
### Note about KeePassHTTP
KeePassHTTP is not a highly secure protocol and has certain flaw which allow an attacker to decrypt your passwords when they manage to intercept communication between a KeePassHTTP server and PassIFox/chromeIPass over a network connection (see [here](https://github.com/pfn/keepasshttp/issues/258) and [here](https://github.com/keepassxreboot/keepassxc/issues/147)). KeePassXC therefore strictly limits communication between itself and the browser plugin to your local computer. As long as your computer is not compromised, your passwords are fairly safe that way, but still use it at your own risk!
### Installation
Pre-compiled binaries can be found on the [downloads page](https://keepassxc.org/download). Additionally, individual Linux distributions may ship their own versions, so please check out your distribution's package list to see if KeePassXC is available.
Right now KeePassXC does not have a precompiled executable or an installation package.<br/>
So you must install it from its source code.
### Building KeePassXC yourself
**More detailed instructions are available in the INSTALL file or at the [Wiki page](https://github.com/keepassxreboot/keepassx/wiki/Install-Instruction-from-Source).**
*More detailed instructions are available in the INSTALL file or on the [Wiki page](https://github.com/keepassxreboot/keepassx/wiki/Install-Instruction-from-Source).*
First you must download the KeePassXC source code as ZIP file or with Git.
First, you must download the KeePassXC [source tarball](https://keepassxc.org/download#source) or check out the latest version from our [Git repository](https://github.com/keepassxreboot/keepassxc).
Generally you can build and install KeePassXC with the following commands from a Terminal in the KeePassXC folder
```
mkdir build
cd build
cmake -DWITH_TESTS=OFF ..
make
sudo make install
```
### Clone Repository
Clone the repository to a suitable location where you can extend and build this project.
To clone the project from Git, `cd` to a suitable location and run
```bash
git clone https://github.com/keepassxreboot/keepassxc.git
```
**Note:** This will clone the entire contents of the repository at the HEAD revision.
This will clone the entire contents of the repository and check out the current `develop` branch.
To update the project from within the project's folder you can run the following command:
To update the project from within the project's folder, you can run the following command:
```bash
git pull
```
Once you have downloaded the source code, you can `cd` into the source code directory and build and install KeePassXC with
```
mkdir build
cd build
cmake -DWITH_TESTS=OFF ..
make -j8
sudo make install
```
To enable autotype, add `-DWITH_XC_AUTOTYPE=ON` to the `cmake` command. KeePassHTTP support is compiled in by adding `-DWITH_XC_HTTP=ON`. If these options are not specified, KeePassXC will be built without these plugins.
### Contributing
We're always looking for suggestions to improve our application. If you have a suggestion for improving an existing feature,
or would like to suggest a completely new feature for KeePassX Reboot, please use the [Issues](https://github.com/keepassxreboot/keepassxc/issues) section or our [Google Groups](https://groups.google.com/forum/#!forum/keepassx-reboot) forum.
We are always looking for suggestions how to improve our application. If you find any bugs or have an idea for a new feature, please let us know by opening a report in our [issue tracker](https://github.com/keepassxreboot/keepassxc/issues) on GitHub or write to our [Google Groups](https://groups.google.com/forum/#!forum/keepassx-reboot) forum.
Please review the [CONTRIBUTING](.github/CONTRIBUTING.md) document for further information.
You can of course also directly contribute your own code. We are happy to accept your pull requests.
Please read the [CONTRIBUTING](.github/CONTRIBUTING.md) document for further information.

View File

@ -18,7 +18,7 @@ PasswordGenerator HttpSettings::m_generator;
bool HttpSettings::isEnabled()
{
return config()->get("Http/Enabled", true).toBool();
return config()->get("Http/Enabled", false).toBool();
}
void HttpSettings::setEnabled(bool enabled)
@ -126,18 +126,6 @@ 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;

View File

@ -42,8 +42,6 @@ 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);

View File

@ -15,6 +15,8 @@
#include "ui_OptionDialog.h"
#include "HttpSettings.h"
#include <QMessageBox>
OptionDialog::OptionDialog(QWidget *parent) :
QWidget(parent),
ui(new Ui::OptionDialog())
@ -41,7 +43,6 @@ void OptionDialog::loadSettings()
ui->sortByUsername->setChecked(true);
else
ui->sortByTitle->setChecked(true);
ui->httpHost->setText(settings.httpHost());
ui->httpPort->setText(QString::number(settings.httpPort()));
/*
@ -70,8 +71,14 @@ 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());
int port = ui->httpPort->text().toInt();
if (port < 1024) {
QMessageBox::warning(this, tr("Cannot bind to privileged ports"),
tr("Cannot bind to privileged ports below 1024!\nUsing default port 19455."));
port = 19455;
}
settings.setHttpPort(port);
/*
settings.setPasswordUseLowercase(ui->checkBoxLower->isChecked());

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>605</width>
<height>389</height>
<height>429</height>
</rect>
</property>
<property name="windowTitle">
@ -17,7 +17,7 @@
<item>
<widget class="QCheckBox" name="enableHttpServer">
<property name="text">
<string>Enable KeepassXC Http protocol
<string>Enable KeepassXC HTTP protocol
This is required for accessing your databases from ChromeIPass or PassIFox</string>
</property>
</widget>
@ -28,7 +28,7 @@ This is required for accessing your databases from ChromeIPass or PassIFox</stri
<enum>QTabWidget::Rounded</enum>
</property>
<property name="currentIndex">
<number>0</number>
<number>2</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@ -201,32 +201,41 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_1">
<item>
<widget class="QLabel" name="label_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>HTTP Host:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="httpHost">
<property name="placeholderText">
<string>Default host: localhost</string>
</property>
</widget>
</item>
</layout>
<spacer name="verticalSpacer_4">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="1">
<widget class="QLineEdit" name="httpPort">
<property name="inputMask">
<string notr="true">d0000</string>
</property>
<property name="placeholderText">
<string>Default port: 19455</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QLabel" name="label_5">
<property name="text">
<string>KeePassXC will listen to this port on 127.0.0.1</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
@ -237,15 +246,8 @@ Only entries with the same scheme (http://, https://, ftp://, ...) are returned<
<property name="text">
<string>HTTP Port:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="httpPort">
<property name="inputMask">
<string notr="true">d0000</string>
</property>
<property name="placeholderText">
<string>Default port: 19455</string>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>

View File

@ -331,68 +331,34 @@ void Server::start(void)
if (m_started)
return;
bool nohost = true;
// local loopback hardcoded, since KeePassHTTP handshake
// is not safe against interception
QHostAddress address("127.0.0.1");
int port = HttpSettings::httpPort();
void* addrx = NULL;
unsigned int flags = MHD_USE_SELECT_INTERNALLY;
QHostInfo info = QHostInfo::fromName(HttpSettings::httpHost());
if (!info.addresses().isEmpty()) {
void* addrx = NULL;
unsigned int flags = MHD_USE_SELECT_INTERNALLY;
QHostAddress address = info.addresses().first();
struct sockaddr_in *addr = static_cast<struct sockaddr_in*>(calloc(1, sizeof(struct sockaddr_in)));
addrx = static_cast<void*>(addr);
addr->sin_family = AF_INET;
addr->sin_port = htons(port);
addr->sin_addr.s_addr = htonl(address.toIPv4Address());
if (address.protocol() == QAbstractSocket::IPv4Protocol) {
struct sockaddr_in *addr = static_cast<struct sockaddr_in*>(calloc(1, sizeof(struct sockaddr_in)));
addrx = static_cast<void*>(addr);
addr->sin_family = AF_INET;
addr->sin_port = htons(HttpSettings::httpPort());
addr->sin_addr.s_addr = htonl(address.toIPv4Address());
nohost = false;
} else {
struct sockaddr_in6 *addr = static_cast<struct sockaddr_in6*>(calloc(1, sizeof(struct sockaddr_in6)));
addrx = static_cast<void*>(addr);
addr->sin6_family = AF_INET6;
addr->sin6_port = htons(HttpSettings::httpPort());
memcpy(&addr->sin6_addr, address.toIPv6Address().c, 16);
nohost = false;
flags |= MHD_USE_IPv6;
}
if (nohost) {
qWarning("HTTPPlugin: Faled to get configured host!");
} else {
if (NULL == (daemon = MHD_start_daemon(flags, port, NULL, NULL,
&this->request_handler_wrapper, this,
MHD_OPTION_NOTIFY_COMPLETED,
this->request_completed, NULL,
MHD_OPTION_SOCK_ADDR,
addrx,
MHD_OPTION_END))) {
nohost = true;
qWarning("HTTPPlugin: Failed to bind to configured host!");
} else {
nohost = false;
//qWarning("HTTPPlugin: Binded to configured host.");
}
}
if (addrx != NULL)
free(addrx);
if (NULL == (daemon = MHD_start_daemon(flags, port, NULL, NULL,
&this->request_handler_wrapper, this,
MHD_OPTION_NOTIFY_COMPLETED,
this->request_completed, NULL,
MHD_OPTION_SOCK_ADDR,
addrx,
MHD_OPTION_END))) {
qWarning("HTTPPlugin: Failed to bind to localhost!");
} else {
m_started = true;
}
if (nohost) {
if (NULL == (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))) {
qWarning("HTTPPlugin: Fatal! Failed to bind to both configured and default hosts!");
} else {
qWarning("HTTPPlugin: Bound to fallback address 0.0.0.0/:::!");
}
}
m_started = true;
if (addrx != NULL)
free(addrx);
}