This commit is contained in:
Ivan 2015-05-12 11:03:48 -07:00
commit 33ed4fd7cf
19 changed files with 111 additions and 86 deletions

View File

@ -23,6 +23,13 @@ The following libraries are required:
* zlib
* libmicrohttpd
* QJSON
* libxtst (optional for auto-type on X11)
On Debian you can install them with:
```bash
sudo apt-get install build-essential cmake libqt4-dev libgcrypt11-dev zlib1g-dev
```
#### Build Steps

View File

@ -20,12 +20,12 @@ file(GLOB DATABASE_ICONS icons/database/*.png)
install(FILES ${DATABASE_ICONS} DESTINATION ${DATA_INSTALL_DIR}/icons/database)
if(UNIX AND NOT APPLE)
install(DIRECTORY icons/application/ DESTINATION share/icons/hicolor
install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor
FILES_MATCHING PATTERN "keepassx.png" PATTERN "keepassx.svgz")
install(DIRECTORY icons/application/ DESTINATION share/icons/hicolor
install(DIRECTORY icons/application/ DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor
FILES_MATCHING PATTERN "application-x-keepassx.png" PATTERN "application-x-keepassx.svgz")
install(FILES linux/keepassx.desktop DESTINATION share/applications)
install(FILES linux/keepassx.xml DESTINATION share/mime/packages)
install(FILES linux/keepassx.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications)
install(FILES linux/keepassx.xml DESTINATION ${CMAKE_INSTALL_DATADIR}/mime/packages)
endif(UNIX AND NOT APPLE)
if(APPLE)

View File

@ -89,6 +89,7 @@ void Config::init(const QString& fileName)
m_settings.reset(new QSettings(fileName, QSettings::IniFormat));
m_defaults.insert("RememberLastDatabases", true);
m_defaults.insert("RememberLastKeyFiles", true);
m_defaults.insert("OpenPreviousDatabasesOnStartup", true);
m_defaults.insert("AutoSaveAfterEveryChange", false);
m_defaults.insert("AutoSaveOnExit", false);

View File

@ -69,7 +69,7 @@ public:
* Sets group as the root group and takes ownership of it.
* Warning: Be careful when calling this method as it doesn't
* emit any notifications so e.g. models aren't updated.
* The caller is responsible for cleaning up the pervious
* The caller is responsible for cleaning up the previous
root group.
*/
void setRootGroup(Group* group);

View File

@ -173,6 +173,24 @@ bool Crypto::selfTest()
return false;
}
// Twofish
cipherText = QByteArray::fromHex("e0227c3cc80f3cb1b2ed847cc6f57d3c");
cipherText.append(QByteArray::fromHex("657b1e7960b30fb7c8d62e72ae37c3a0"));
SymmetricCipher twofishEncrypt(SymmetricCipher::Twofish, SymmetricCipher::Cbc, SymmetricCipher::Encrypt, key, iv);
if (twofishEncrypt.process(plainText) != cipherText) {
m_errorStr = "Twofish encryption mismatch.";
qWarning("Crypto::selfTest: %s", qPrintable(m_errorStr));
return false;
}
SymmetricCipher twofishDecrypt(SymmetricCipher::Twofish, SymmetricCipher::Cbc, SymmetricCipher::Decrypt, key, iv);
if (twofishDecrypt.process(cipherText) != plainText) {
m_errorStr = "Twofish decryption mismatch.";
qWarning("Crypto::selfTest: %s", qPrintable(m_errorStr));
return false;
}
QByteArray salsa20Key = QByteArray::fromHex("F3F4F5F6F7F8F9FAFBFCFDFEFF000102030405060708090A0B0C0D0E0F101112");
QByteArray salsa20iv = QByteArray::fromHex("0000000000000000");
QByteArray salsa20Plain = QByteArray::fromHex("00000000000000000000000000000000");

View File

@ -9,50 +9,13 @@
/* Guess the endianness of the target architecture. */
/*
* The LITTLE endian machines:
*/
#if defined(__ultrix) /* Older MIPS */
#define ECRYPT_LITTLE_ENDIAN
#elif defined(__alpha) /* Alpha */
#define ECRYPT_LITTLE_ENDIAN
#elif defined(i386) /* x86 (gcc) */
#define ECRYPT_LITTLE_ENDIAN
#elif defined(__i386) /* x86 (gcc) */
#define ECRYPT_LITTLE_ENDIAN
#elif defined(__x86_64) /* x86_64 (gcc) */
#define ECRYPT_LITTLE_ENDIAN
#elif defined(_M_IX86) /* x86 (MSC, Borland) */
#define ECRYPT_LITTLE_ENDIAN
#elif defined(_MSC_VER) /* x86 (surely MSC) */
#define ECRYPT_LITTLE_ENDIAN
#elif defined(__INTEL_COMPILER) /* x86 (surely Intel compiler icl.exe) */
#define ECRYPT_LITTLE_ENDIAN
#include <QtGlobal>
/*
* The BIG endian machines:
*/
#elif defined(__sparc) /* Newer Sparc's */
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
#define ECRYPT_LITTLE_ENDIAN
#elif Q_BYTE_ORDER == Q_BIG_ENDIAN
#define ECRYPT_BIG_ENDIAN
#elif defined(__powerpc__) /* PowerPC */
#define ECRYPT_BIG_ENDIAN
#elif defined(__ppc__) /* PowerPC */
#define ECRYPT_BIG_ENDIAN
#elif defined(__hppa) /* HP-PA */
#define ECRYPT_BIG_ENDIAN
/*
* Finally machines with UNKNOWN endianness:
*/
#elif defined (_AIX) /* RS6000 */
#define ECRYPT_UNKNOWN
#elif defined(__aux) /* 68K */
#define ECRYPT_UNKNOWN
#elif defined(__dgux) /* 88K (but P6 in latest boxes) */
#define ECRYPT_UNKNOWN
#elif defined(__sgi) /* Newer MIPS */
#define ECRYPT_UNKNOWN
#else /* Any other processor */
#else
#define ECRYPT_UNKNOWN
#endif

View File

@ -699,7 +699,7 @@ Entry* KeePass2XmlReader::parseEntry(bool history)
int iconId = readNumber();
if (iconId < 0) {
if (m_strictMode) {
raiseError("Invalud entry icon number");
raiseError("Invalid entry icon number");
}
}
else {
@ -862,7 +862,7 @@ QPair<QString, QString> KeePass2XmlReader::parseEntryBinary(Entry* entry)
m_xml.skipCurrentElement();
}
else {
// format compatbility
// format compatibility
value = readBinary();
bool isProtected = attr.hasAttribute("Protected")
&& (attr.value("Protected") == "True");

View File

@ -67,10 +67,12 @@ void DatabaseOpenWidget::load(const QString& filename)
m_ui->labelFilename->setText(filename);
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
if (lastKeyFiles.contains(m_filename)) {
m_ui->checkKeyFile->setChecked(true);
m_ui->comboKeyFile->addItem(lastKeyFiles[m_filename].toString());
if (config()->get("RememberLastKeyFiles").toBool()) {
QHash<QString, QVariant> lastKeyFiles = config()->get("LastKeyFiles").toHash();
if (lastKeyFiles.contains(m_filename)) {
m_ui->checkKeyFile->setChecked(true);
m_ui->comboKeyFile->addItem(lastKeyFiles[m_filename].toString());
}
}
m_ui->editPassword->setFocus();
@ -148,7 +150,9 @@ CompositeKey DatabaseOpenWidget::databaseKey()
lastKeyFiles.remove(m_filename);
}
config()->set("LastKeyFiles", lastKeyFiles);
if (config()->get("RememberLastKeyFiles").toBool()) {
config()->set("LastKeyFiles", lastKeyFiles);
}
return masterKey;
}

View File

@ -563,7 +563,7 @@ void DatabaseTabWidget::lockDatabases()
QMessageBox::StandardButton result =
MessageBox::question(
this, tr("Lock database"),
tr("This database has never been saved.\nYou can save the dabatase or stop locking it."),
tr("This database has never been saved.\nYou can save the database or stop locking it."),
QMessageBox::Save | QMessageBox::Cancel, QMessageBox::Cancel);
if (result == QMessageBox::Save) {
if (!saveDatabase(db)) {

View File

@ -46,7 +46,9 @@ void DialogyWidget::keyPressEvent(QKeyEvent* e)
break;
case Qt::Key_Escape:
if (!clickButton(QDialogButtonBox::Cancel)) {
e->ignore();
if (!clickButton(QDialogButtonBox::Close)) {
e->ignore();
}
}
break;
default:

View File

@ -23,6 +23,7 @@ EditWidget::EditWidget(QWidget* parent)
, m_ui(new Ui::EditWidget())
{
m_ui->setupUi(this);
setReadOnly(false);
QFont headerLabelFont = m_ui->headerLabel->font();
headerLabelFont.setBold(true);
@ -68,3 +69,20 @@ QLabel* EditWidget::headlineLabel()
{
return m_ui->headerLabel;
}
void EditWidget::setReadOnly(bool readOnly)
{
m_readOnly = readOnly;
if (readOnly) {
m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Close);
}
else {
m_ui->buttonBox->setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
}
}
bool EditWidget::readOnly() const
{
return m_readOnly;
}

View File

@ -41,6 +41,8 @@ public:
void setCurrentRow(int index);
void setHeadline(const QString& text);
QLabel* headlineLabel();
void setReadOnly(bool readOnly);
bool readOnly() const;
Q_SIGNALS:
void accepted();
@ -48,6 +50,7 @@ Q_SIGNALS:
private:
const QScopedPointer<Ui::EditWidget> m_ui;
bool m_readOnly;
Q_DISABLE_COPY(EditWidget)
};

View File

@ -105,6 +105,8 @@ MainWindow::MainWindow()
autoType()->registerGlobalShortcut(globalAutoTypeKey, globalAutoTypeModifiers);
}
m_ui->actionEntryAutoType->setVisible(autoType()->isAvailable());
m_inactivityTimer = new InactivityTimer(this);
connect(m_inactivityTimer, SIGNAL(inactivityDetected()),
m_ui->tabWidget, SLOT(lockDatabases()));

View File

@ -96,6 +96,7 @@ void SettingsWidget::addSettingsPage(ISettingsPage *page)
void SettingsWidget::loadSettings()
{
m_generalUi->rememberLastDatabasesCheckBox->setChecked(config()->get("RememberLastDatabases").toBool());
m_generalUi->rememberLastKeyFilesCheckBox->setChecked(config()->get("RememberLastKeyFiles").toBool());
m_generalUi->openPreviousDatabasesOnStartupCheckBox->setChecked(
config()->get("OpenPreviousDatabasesOnStartup").toBool());
m_generalUi->autoSaveAfterEveryChangeCheckBox->setChecked(config()->get("AutoSaveAfterEveryChange").toBool());
@ -144,6 +145,7 @@ void SettingsWidget::loadSettings()
void SettingsWidget::saveSettings()
{
config()->set("RememberLastDatabases", m_generalUi->rememberLastDatabasesCheckBox->isChecked());
config()->set("RememberLastKeyFiles", m_generalUi->rememberLastKeyFilesCheckBox->isChecked());
config()->set("OpenPreviousDatabasesOnStartup",
m_generalUi->openPreviousDatabasesOnStartupCheckBox->isChecked());
config()->set("AutoSaveAfterEveryChange",

View File

@ -25,75 +25,85 @@
</widget>
</item>
<item row="1" column="0">
<widget class="QCheckBox" name="rememberLastKeyFilesCheckBox">
<property name="text">
<string>Remember last key files</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QCheckBox" name="openPreviousDatabasesOnStartupCheckBox">
<property name="text">
<string>Open previous databases on startup</string>
</property>
</widget>
</item>
<item row="2" column="0">
<item row="3" column="0">
<widget class="QCheckBox" name="autoSaveOnExitCheckBox">
<property name="text">
<string>Automatically save on exit</string>
</property>
</widget>
</item>
<item row="3" column="0">
<item row="4" column="0">
<widget class="QCheckBox" name="autoSaveAfterEveryChangeCheckBox">
<property name="text">
<string>Automatically save after every change</string>
</property>
</widget>
</item>
<item row="4" column="0">
<item row="5" column="0">
<widget class="QCheckBox" name="minimizeOnCopyCheckBox">
<property name="text">
<string>Minimize when copying to clipboard</string>
</property>
</widget>
</item>
<item row="5" column="0">
<item row="6" column="0">
<widget class="QCheckBox" name="useGroupIconOnEntryCreationCheckBox">
<property name="text">
<string>Use group icon on entry creation</string>
</property>
</widget>
</item>
<item row="6" column="0">
<item row="7" column="0">
<widget class="QLabel" name="autoTypeShortcutLabel">
<property name="text">
<string>Global Auto-Type shortcut</string>
</property>
</widget>
</item>
<item row="6" column="1">
<item row="7" column="1">
<widget class="ShortcutWidget" name="autoTypeShortcutWidget"/>
</item>
<item row="7" column="0">
<item row="8" column="0">
<widget class="QCheckBox" name="autoTypeEntryTitleMatchCheckBox">
<property name="text">
<string>Use entry title to match windows for global auto-type</string>
</property>
</widget>
</item>
<item row="8" column="0">
<item row="9" column="0">
<widget class="QLabel" name="languageLabel">
<property name="text">
<string>Language</string>
</property>
</widget>
</item>
<item row="8" column="1">
<item row="9" column="1">
<widget class="QComboBox" name="languageComboBox"/>
</item>
<item row="9" column="0">
<item row="10" column="0">
<widget class="QCheckBox" name="systrayShowCheckBox">
<property name="text">
<string>Show a system tray icon</string>
</property>
</widget>
</item>
<item row="10" column="0">
<item row="11" column="0">
<widget class="QCheckBox" name="systrayMinimizeToTrayCheckBox">
<property name="enabled">
<bool>false</bool>
@ -114,6 +124,7 @@
</customwidgets>
<tabstops>
<tabstop>rememberLastDatabasesCheckBox</tabstop>
<tabstop>rememberLastKeyFilesCheckBox</tabstop>
<tabstop>openPreviousDatabasesOnStartupCheckBox</tabstop>
<tabstop>autoSaveOnExitCheckBox</tabstop>
<tabstop>autoSaveAfterEveryChangeCheckBox</tabstop>

View File

@ -277,6 +277,7 @@ void EditEntryWidget::loadEntry(Entry* entry, bool create, bool history, const Q
}
setForms(entry);
setReadOnly(m_history);
setCurrentRow(0);
setRowHidden(m_historyWidget, m_history);
@ -384,10 +385,7 @@ void EditEntryWidget::setForms(const Entry* entry, bool restore)
void EditEntryWidget::saveEntry()
{
if (m_history) {
m_entry = Q_NULLPTR;
m_database = Q_NULLPTR;
m_entryAttributes->clear();
m_entryAttachments->clear();
clear();
Q_EMIT editFinished(false);
return;
}
@ -463,6 +461,7 @@ void EditEntryWidget::cancel()
if (m_history) {
clear();
Q_EMIT editFinished(false);
return;
}
if (!m_entry->iconUuid().isNull() &&

View File

@ -147,7 +147,7 @@ void QtIOCompressorPrivate::flushZlib(int flushMode)
/*!
\internal
Writes outputSize bytes from buffer to the inderlying device.
Writes outputSize bytes from buffer to the underlying device.
*/
bool QtIOCompressorPrivate::writeBytes(ZlibByte *buffer, ZlibSize outputSize)
{
@ -192,7 +192,7 @@ void QtIOCompressorPrivate::setZlibError(const QString &errorMessage, int zlibEr
A QtIOCompressor object is constructed with a pointer to an
underlying QIODevice. Data written to the QtIOCompressor object
will be compressed before it is written to the underlying
QIODevice. Similary, if you read from the QtIOCompressor object,
QIODevice. Similarly, if you read from the QtIOCompressor object,
the data will be read from the underlying device and then
decompressed.
@ -251,14 +251,14 @@ void QtIOCompressorPrivate::setZlibError(const QString &errorMessage, int zlibEr
\a bufferSize specifies the size of the internal buffer used when reading from and writing to the
underlying device. The default value is 65KB. Using a larger value allows for faster compression and
deompression at the expense of memory usage.
decompression at the expense of memory usage.
*/
QtIOCompressor::QtIOCompressor(QIODevice *device, int compressionLevel, int bufferSize)
:d_ptr(new QtIOCompressorPrivate(this, device, compressionLevel, bufferSize))
{}
/*!
Destroys the QtIOCompressor, closing it if neccesary.
Destroys the QtIOCompressor, closing it if necessary.
*/
QtIOCompressor::~QtIOCompressor()
{
@ -313,12 +313,12 @@ bool QtIOCompressor::isSequential() const
/*!
Opens the QtIOCompressor in \a mode. Only ReadOnly and WriteOnly is supported.
This functon will return false if you try to open in other modes.
This function will return false if you try to open in other modes.
If the underlying device is not opened, this function will open it in a suitable mode. If this happens
the device will also be closed when close() is called.
If the underlying device is already opened, its openmode must be compatable with \a mode.
If the underlying device is already opened, its openmode must be compatible with \a mode.
Returns true on success, false on error.
@ -513,7 +513,7 @@ qint64 QtIOCompressor::readData(char *data, qint64 maxSize)
if (d->state == QtIOCompressorPrivate::Error)
return -1;
// We are ging to try to fill the data buffer
// We are going to try to fill the data buffer
d->zlibStream.next_out = reinterpret_cast<ZlibByte *>(data);
d->zlibStream.avail_out = maxSize;
@ -550,7 +550,7 @@ qint64 QtIOCompressor::readData(char *data, qint64 maxSize)
d->state = QtIOCompressorPrivate::Error;
d->setZlibError(QT_TRANSLATE_NOOP("QtIOCompressor", "Internal zlib error when decompressing: "), status);
return -1;
case Z_BUF_ERROR: // No more input and zlib can not privide more output - Not an error, we can try to read again when we have more input.
case Z_BUF_ERROR: // No more input and zlib can not provide more output - Not an error, we can try to read again when we have more input.
return 0;
}
// Loop util data buffer is full or we reach the end of the input stream.

View File

@ -64,12 +64,10 @@ macro(add_unit_test)
endif(NOT TEST_OUTPUT)
set(TEST_OUTPUT ${TEST_OUTPUT} CACHE STRING "The output to generate when running the QTest unit tests")
get_target_property(loc ${_test_NAME} LOCATION)
if(KDE4_TEST_OUTPUT STREQUAL "xml")
add_test(${_test_NAME} ${loc} -xml -o ${_test_NAME}.tml)
add_test(${_test_NAME} ${_test_NAME} -xml -o ${_test_NAME}.tml)
else(KDE4_TEST_OUTPUT STREQUAL "xml")
add_test(${_test_NAME} ${loc})
add_test(${_test_NAME} ${_test_NAME})
endif(KDE4_TEST_OUTPUT STREQUAL "xml")
if(NOT MSVC_IDE) #not needed for the ide

View File

@ -32,9 +32,6 @@ void TestCryptoHash::initTestCase()
void TestCryptoHash::test()
{
// TODO: move somewhere else
QVERIFY(Crypto::backendSelfTest());
CryptoHash cryptoHash1(CryptoHash::Sha256);
QCOMPARE(cryptoHash1.result(),
QByteArray::fromHex("e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"));