Comparar commits

...

39 Commits

Autor SHA1 Mensagem Data
Björn Schießle fbdfebac3b allow user to change key password 2012-09-13 18:59:22 +02:00
Bjoern Schiessle f06206e9db make strings translatable 2012-09-05 16:35:06 +02:00
Bjoern Schiessle f14ed691d5 catch network errors 2012-09-05 13:50:04 +02:00
Bjoern Schiessle b49d45c859 don't call function twice 2012-09-05 13:27:39 +02:00
Bjoern Schiessle 16ef78305c catch possible errors during key generation/download 2012-09-05 12:38:53 +02:00
Bjoern Schiessle 74854e80df extended encryption class and generic password dialog to allow user to change
the key password
2012-09-04 15:37:32 +02:00
Bjoern Schiessle 8e1d57569f switch to new key format 2012-08-29 13:10:22 +02:00
Bjoern Schiessle 22ea63a89e retrieve rsa key from server 2012-08-27 15:50:31 +02:00
Bjoern Schiessle 5277ac9681 keymanager class added 2012-08-25 09:34:13 +02:00
Bjoern Schiessle a4cbf792d7 some code cleanup 2012-08-24 11:18:59 +02:00
Bjoern Schiessle d3ff0a9db1 rebase files_encryption branch to master 2012-08-23 16:34:06 +02:00
Bjoern Schiessle 2fb4eb5d15 merged with master 2012-08-23 16:27:42 +02:00
Bjoern Schiessle dcd7593b1e generate RSA keys and send them to the ownCloud server 2012-08-23 16:04:30 +02:00
Bjoern Schiessle 252f68efdf generate RSA private/public key 2012-08-23 16:04:29 +02:00
Bjoern Schiessle b686cdcd37 upload encryption keys to server 2012-08-23 16:04:29 +02:00
Bjoern Schiessle 70badb2f76 added TODO 2012-08-23 16:04:29 +02:00
Bjoern Schiessle 808b5f2d5b added dialog to generate key password 2012-08-23 16:04:29 +02:00
Bjoern Schiessle feeea57e37 write encryption setting to the config file 2012-08-23 16:00:46 +02:00
Bjoern Schiessle edfb67800a - let user enable client side encryption in setup wizard
- Encryption class introduced to get/set keys, parse xml, etc.
2012-08-23 15:57:52 +02:00
Bjoern Schiessle efa5a7f7cd add checkbox for client side encryption to setup wizard 2012-08-23 15:49:11 +02:00
Bjoern Schiessle 606f987c67 added dialog to generate key password 2012-08-23 15:44:13 +02:00
Bjoern Schiessle 6ebbb5e04d write encryption setting to the config file 2012-08-23 15:44:12 +02:00
Bjoern Schiessle 8737ad4bf8 - let user enable client side encryption in setup wizard
- Encryption class introduced to get/set keys, parse xml, etc.
2012-08-23 15:37:25 +02:00
Bjoern Schiessle f8c8d5d948 add checkbox for client side encryption to setup wizard 2012-08-23 15:37:25 +02:00
Bjoern Schiessle 7f9a0f1163 generate RSA keys and send them to the ownCloud server 2012-08-23 15:20:19 +02:00
Bjoern Schiessle 0b16026da6 generate RSA private/public key 2012-08-16 17:54:30 +02:00
Bjoern Schiessle 8bf0ba4480 upload encryption keys to server 2012-08-16 13:23:49 +02:00
Bjoern Schiessle 2b1fdddaed added TODO 2012-08-15 18:08:10 +02:00
Bjoern Schiessle 3efec87b8c Merge branch 'files_encryption' of gitorious.org:owncloud/mirall into files_encryption 2012-08-15 18:06:42 +02:00
Bjoern Schiessle bebf02a280 added dialog to generate key password 2012-08-15 18:05:58 +02:00
Bjoern Schiessle 198daccb36 write encryption setting to the config file 2012-08-15 18:05:58 +02:00
Bjoern Schiessle f1d85e1057 - let user enable client side encryption in setup wizard
- Encryption class introduced to get/set keys, parse xml, etc.
2012-08-15 18:05:58 +02:00
Bjoern Schiessle e26ebf9a2b add checkbox for client side encryption to setup wizard 2012-08-15 18:05:58 +02:00
Bjoern Schiessle 624c152107 added dialog to generate key password 2012-08-15 18:03:08 +02:00
Bjoern Schiessle 97c1c0b489 write encryption setting to the config file 2012-08-15 15:13:23 +02:00
Bjoern Schiessle c94888b725 - let user enable client side encryption in setup wizard
- Encryption class introduced to get/set keys, parse xml, etc.
2012-08-15 12:49:01 +02:00
Bjoern Schiessle 7300688767 Merge branch 'files_encryption' of gitorious.org:owncloud/mirall into files_encryption 2012-08-14 13:43:26 +02:00
Bjoern Schiessle a117525ce7 add checkbox for client side encryption to setup wizard 2012-08-14 13:42:56 +02:00
Bjoern Schiessle 5ee100603f add checkbox for client side encryption to setup wizard 2012-08-14 13:31:45 +02:00
14 arquivos alterados com 1189 adições e 33 exclusões
+7
Ver Arquivo
@@ -18,6 +18,7 @@ mirall/owncloudwizardresultpage.ui
mirall/owncloudcredentialspage.ui
mirall/sslerrorsdialog.ui
mirall/proxydialog.ui
mirall/passworddialog.ui
)
set(3rdparty_SRC
@@ -115,6 +116,9 @@ set(mirall_SRCS
mirall/sslerrordialog.cpp
mirall/logbrowser.cpp
mirall/proxydialog.cpp
mirall/encryption.cpp
mirall/keymanager.cpp
mirall/passworddialog.cpp
)
set(mirall_HEADERS
@@ -128,6 +132,9 @@ set(mirall_HEADERS
mirall/sslerrordialog.h
mirall/logbrowser.h
mirall/proxydialog.h
mirall/encryption.h
mirall/keymanager.h
mirall/passworddialog.h
)
if( UNIX AND NOT APPLE)
+262
Ver Arquivo
@@ -0,0 +1,262 @@
/*
* Copyright (C) 2012 Bjoern Schiessle <schiessle@owncloud.com>
*
* 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 2 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.
*/
#include "encryption.h"
#include "keymanager.h"
#include <QMap>
#include <iostream>
#include <QtNetwork>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QAuthenticator>
#include <QDomDocument>
#include <QFile>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <openssl/evp.h>
#include <openssl/bio.h>
#include <openssl/err.h>
#include <stdio.h>
Encryption::Encryption(QString baseurl, QString username, QString password, QObject *parent) :
QObject(parent)
{
setBaseUrl(baseurl);
setAuthCredentials(username, password);
_nam = new QNetworkAccessManager(this);
connect( _nam, SIGNAL(finished(QNetworkReply*)),this,SLOT(slotHttpRequestResults(QNetworkReply*)));
connect( _nam, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), this, SLOT(slotHttpAuth(QNetworkReply*,QAuthenticator*)));
}
void Encryption::setBaseUrl(QString baseurl)
{
_baseurl = baseurl;
}
void Encryption::setAuthCredentials(QString username, QString password) {
_username = username;
_password = password;
}
void Encryption::getUserKeys(QString password)
{
QNetworkReply *reply = _nam->get(QNetworkRequest(QUrl(_baseurl + "/ocs/v1.php/cloud/userkeys")));
_directories[reply] = Encryption::GetUserKeys;
_data[reply].insert("password", password);
}
void Encryption::generateUserKeys(QString password)
{
RSA *rsa;
int bits = 1024; // 512, 1024, 2048, 4096
unsigned long exp = RSA_F4; // RSA_3
if ( (rsa = RSA_generate_key(bits, exp, NULL, NULL)) == NULL) {
qDebug() << "Couldn't generate RSA Key";
return;
}
Keymanager::Instance()->setRSAkey(rsa);
sendUserKeys(key2pem(password), Encryption::SetUserKeys);
}
void Encryption::changeUserKeyPassword(QString oldpasswd, QString newpasswd)
{
QNetworkReply *reply = _nam->get(QNetworkRequest(QUrl(_baseurl + "/ocs/v1.php/cloud/userkeys")));
_directories[reply] = Encryption::ChangeKeyPassword;
_data[reply].insert("oldpassword", oldpasswd);
_data[reply].insert("newpassword", newpasswd);
_data[reply].insert("step", "import");
}
void Encryption::sendUserKeys(QMap<QString, QString> keypair, OCSCalls operation)
{
QUrl postData;
postData.addQueryItem("privatekey", QUrl::toPercentEncoding(keypair["privatekey"]));
postData.addQueryItem("publickey", QUrl::toPercentEncoding(keypair["publickey"]));
QNetworkRequest req;
req.setUrl(QUrl(_baseurl + "/ocs/v1.php/cloud/userkeys"));
req.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QNetworkReply *reply = _nam->post(req, postData.encodedQuery());
_directories[reply] = operation;
QEventLoop eventLoop;
// stay here until request is finished to avoid losing postData to early
connect(_nam, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec();
}
QMap<QString, QString> Encryption::key2pem(QString password)
{
QMap<QString, QString> keypair;
BUF_MEM *bptr;
BIO *pubBio = BIO_new(BIO_s_mem());
BIO *privBio = BIO_new(BIO_s_mem());
EVP_PKEY *pkey;
pkey = EVP_PKEY_new();
EVP_PKEY_assign_RSA(pkey, Keymanager::Instance()->getRSAkey());
PEM_write_bio_RSA_PUBKEY(pubBio, Keymanager::Instance()->getRSAkey());
PEM_write_bio_PKCS8PrivateKey(privBio, pkey, EVP_aes_128_cfb(), NULL, 0, 0, password.toLocal8Bit().data());
BIO_get_mem_ptr(pubBio, &bptr);
keypair["publickey"] = QString::fromAscii(bptr->data, bptr->length);
BIO_get_mem_ptr(privBio, &bptr);
keypair["privatekey"] = QString::fromAscii(bptr->data, bptr->length);
BIO_free_all(pubBio);
BIO_free_all(privBio);
EVP_PKEY_free(pkey);
return keypair;
}
bool Encryption::pem2key(QString privatekey, QString password)
{
QByteArray ba = privatekey.toLocal8Bit();
char *c_privatekey = ba.data();
BIO *privBio = BIO_new_mem_buf(c_privatekey, -1);
RSA *rsa = RSA_new();
if (PEM_read_bio_RSAPrivateKey(privBio, &rsa, 0, password.toLocal8Bit().data()) == NULL) {
return false;
}
Keymanager::Instance()->setRSAkey(rsa);
BIO_free_all(privBio);
return true;
}
/**
* Qt slots
*/
void Encryption::slotHttpRequestResults(QNetworkReply *reply)
{
OCSCalls call = _directories.value(reply);
QMap<QString, QString> result;
QList<QString> returnValues;
if(reply->error() == QNetworkReply::NoError) {
QString xml = reply->readAll();
switch (call)
{
case Encryption::GetUserKeys:
returnValues << "statuscode" << "publickey" << "privatekey";
result = parseXML(xml, returnValues);
if (result["statuscode"] == "100") {
if (!pem2key( result["privatekey"], _data.value(reply).value("password"))) {
result["statuscode"] = "-1";
}
}
emit ocsGetUserKeysResults(result);
break;
case Encryption::SetUserKeys:
returnValues << "statuscode";
result = parseXML(xml, returnValues);
emit ocsSetUserKeysResults(result);
break;
case Encryption::ChangeKeyPassword:
if (_data.value(reply).constFind("step") != _data.value(reply).constEnd()) { // get key and check old password before setting the new one
returnValues << "statuscode" << "privatekey";
result = parseXML(xml, returnValues);
if (result["statuscode"] == "100") {
if (!pem2key(result["privatekey"], _data.value(reply).value("oldpassword"))) {
result["statuscode"] = "-1";
emit ocsChangePasswordResult(result);
break;
}
sendUserKeys(key2pem(_data.value(reply).value("newpassword")), Encryption::ChangeKeyPassword);
}
} else { //check if key was uploaded successfully
returnValues << "statuscode";
result = parseXML(xml, returnValues);
emit ocsChangePasswordResult(result);
}
break;
default :
qDebug() << "Something went wrong!";
}
} else {
onError(reply);
qDebug() << reply->errorString();
}
_directories.remove(reply);
_data.remove(reply);
}
void Encryption::onError(QNetworkReply *reply)
{
OCSCalls call = _directories.value(reply);
QMap<QString, QString> result;
result.insert("statuscode", "-10");
switch (call)
{
case Encryption::GetUserKeys:
emit ocsGetUserKeysResults(result);
break;
case Encryption::SetUserKeys:
emit ocsSetUserKeysResults(result);
break;
case Encryption::ChangeKeyPassword:
emit ocsChangePasswordResult(result);
break;
default :
qDebug() << "Something went wrong!";
}
}
void Encryption::slotHttpAuth(QNetworkReply *reply, QAuthenticator *auth)
{
auth->setUser(_username);
auth->setPassword(_password);
}
/**
* some helper functions
*/
QMap<QString, QString> Encryption::parseXML(QString xml, QList<QString> tags)
{
QMap<QString, QString> result;
QDomDocument doc("results");
doc.setContent(xml);
for (int i = 0; i < tags.size(); ++i) {
QString tag = tags.at(i);
QDomNodeList elements = doc.elementsByTagName(tag);
if (elements.size() == 1 ) {
result[tag] = elements.at(0).toElement().text();
}
}
return result;
}
+67
Ver Arquivo
@@ -0,0 +1,67 @@
#ifndef ENCRYPTION_H
#define ENCRYPTION_H
/*
* Copyright (C) 2012 Bjoern Schiessle <schiessle@owncloud.com>
*
* 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 2 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.
*/
#include <QObject>
#include <QList>
#include <QMap>
#include <QHash>
#include <openssl/rsa.h>
class QNetworkAccessManager;
class QNetworkReply;
class QAuthenticator;
class Encryption : public QObject
{
Q_OBJECT
public:
explicit Encryption(QString baseurl = "", QString username = "", QString password = "", QObject *parent = 0);
void setBaseUrl(QString baseurl);
void setAuthCredentials(QString username, QString password);
void getUserKeys(QString password);
void generateUserKeys(QString password);
void changeUserKeyPassword(QString oldpasswd, QString newpasswd);
private:
enum OCSCalls { SetUserKeys,
GetUserKeys,
ChangeKeyPassword };
QString _baseurl;
QString _username;
QString _password;
QNetworkAccessManager *_nam;
QHash<QNetworkReply*, OCSCalls> _directories;
QHash<QNetworkReply*, QHash<QString, QString> > _data;
QMap<QString, QString> parseXML(QString xml, QList<QString> tags);
QMap<QString, QString> key2pem(QString password);
bool pem2key(QString privatekey, QString password);
void sendUserKeys(QMap<QString, QString> keypair, OCSCalls operation);
void onError(QNetworkReply *reply);
signals:
void ocsGetUserKeysResults(QMap<QString, QString>);
void ocsSetUserKeysResults(QMap<QString, QString>);
void ocsChangePasswordResult(QMap<QString, QString>);
protected slots:
void slotHttpRequestResults(QNetworkReply*);
void slotHttpAuth(QNetworkReply*,QAuthenticator*);
};
#endif // ENCRYPTION_H
+23
Ver Arquivo
@@ -0,0 +1,23 @@
#include "keymanager.h"
Keymanager* Keymanager::_Instance = NULL;
Keymanager* Keymanager::Instance()
{
if (!_Instance) {
_Instance = new Keymanager();
}
return _Instance;
}
RSA* Keymanager::getRSAkey()
{
return this->rsa;
}
void Keymanager::setRSAkey(RSA *rsa)
{
this->rsa = rsa;
}
+23
Ver Arquivo
@@ -0,0 +1,23 @@
#ifndef KEYMANAGER_H
#define KEYMANAGER_H
#include <openssl/rsa.h>
class Keymanager
{
public:
static Keymanager* Instance();
RSA* getRSAkey();
void setRSAkey(RSA *rsa);
private:
RSA *rsa;
Keymanager() {};
Keymanager(Keymanager const&){};
Keymanager& operator=(Keymanager const&){};
static Keymanager* _Instance;
};
#endif // KEYMANAGER_H
+16 -1
Ver Arquivo
@@ -18,6 +18,7 @@
#include <QtCore>
#include <QtGui>
#include <iostream>
#define DEFAULT_REMOTE_POLL_INTERVAL 30000 // default remote poll time in milliseconds
#define DEFAULT_LOCAL_POLL_INTERVAL 10000 // default local poll time in milliseconds
@@ -123,7 +124,8 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
const QString& url,
const QString& user,
const QString& passwd,
bool skipPwd )
bool skipPwd,
bool enc)
{
const QString file = configFile();
qDebug() << "*** writing mirall config to " << file << " Skippwd: " << skipPwd;
@@ -139,6 +141,8 @@ void MirallConfigFile::writeOwncloudConfig( const QString& connection,
settings.beginGroup( connection );
settings.setValue( QLatin1String("url"), cloudsUrl );
settings.setValue( QLatin1String("user"), user );
settings.setValue( QLatin1String("encryption"), QVariant(enc) );
if( skipPwd ) {
pwd.clear();
}
@@ -236,6 +240,17 @@ QString MirallConfigFile::ownCloudUrl( const QString& connection, bool webdav )
return url;
}
bool MirallConfigFile::ownCloudEncryption(const QString& connection) const
{
QString con(connection);
if( connection.isEmpty() ) con = defaultConnection();
QSettings settings( configFile(), QSettings::IniFormat );
settings.setIniCodec( "UTF-8" );
settings.beginGroup( con );
return ( settings.value( QLatin1String("encryption")).toBool() );
}
QString MirallConfigFile::ownCloudUser( const QString& connection ) const
{
QString con( connection );
+5 -1
Ver Arquivo
@@ -47,7 +47,9 @@ public:
void writeOwncloudConfig( const QString& connection,
const QString& url,
const QString& user,
const QString& passwd, bool skipPwd );
const QString& passwd,
bool skipPwd,
bool enc);
void removeConnection( const QString& connection = QString() );
@@ -66,6 +68,8 @@ public:
QString ownCloudVersion() const;
void setOwnCloudVersion( const QString& );
bool ownCloudEncryption(const QString &connection = QString()) const;
QVariant customMedia( customMediaType );
// max count of lines in the log window
+85 -28
Ver Arquivo
@@ -6,15 +6,28 @@
<rect>
<x>0</x>
<y>0</y>
<width>480</width>
<height>271</height>
<width>689</width>
<height>354</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0" colspan="2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="topLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QSplitter" name="splitter_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
@@ -33,7 +46,7 @@
</widget>
</widget>
</item>
<item row="2" column="0">
<item>
<widget class="QLabel" name="serverAddressLabel">
<property name="text">
<string>Server &amp;address:</string>
@@ -43,7 +56,7 @@
</property>
</widget>
</item>
<item row="3" column="0" colspan="2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="protocolLabel">
@@ -61,7 +74,7 @@
</item>
</layout>
</item>
<item row="4" column="0" colspan="2">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
@@ -135,6 +148,63 @@
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QCheckBox" name="cbEncryption">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Use client side encryption</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="keyStatusLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbGetEncKeys">
<property name="enabled">
<bool>false</bool>
</property>
<property name="toolTip">
<string>Get Keys from your ownCloud server</string>
</property>
<property name="text">
<string>Get Keys</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbGenEncKeys">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Generate Keys</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pbChangeKeyPassword">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Change Key Password</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QCheckBox" name="cbNoPasswordStore">
<property name="toolTip">
@@ -156,7 +226,14 @@
</item>
</layout>
</item>
<item row="6" column="1">
<item>
<widget class="QLabel" name="bottomLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
@@ -169,26 +246,6 @@
</property>
</spacer>
</item>
<item row="0" column="0" colspan="2">
<widget class="QLabel" name="topLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
<item row="5" column="0" colspan="2">
<widget class="QLabel" name="bottomLabel">
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
+9 -1
Ver Arquivo
@@ -21,6 +21,7 @@
#include <QProcess>
#include <QMessageBox>
#include <QDesktopServices>
#include <iostream>
namespace Mirall {
@@ -142,7 +143,8 @@ void OwncloudSetupWizard::testOwnCloudConnect()
_ocWizard->field(QLatin1String("OCUrl")).toString(),
_ocWizard->field(QLatin1String("OCUser")).toString(),
_ocWizard->field(QLatin1String("OCPasswd")).toString(),
_ocWizard->field(QLatin1String("PwdNoLocalStore")).toBool() );
_ocWizard->field(QLatin1String("PwdNoLocalStore")).toBool(),
_ocWizard->field(QLatin1String("Encryption")).toBool());
// now start ownCloudInfo to check the connection.
ownCloudInfo::instance()->setCustomConfigHandle( _configHandle );
@@ -330,6 +332,12 @@ void OwncloudSetupWizard::startWizard()
if( !url.isEmpty() ) {
_ocWizard->setOCUrl( url );
}
bool encryption = cfgFile.ownCloudEncryption();
if (encryption) {
_ocWizard->setOCEncryption( encryption );
}
_ocWizard->restart();
_ocWizard->show();
}
+241 -1
Ver Arquivo
@@ -14,6 +14,8 @@
*/
#include "mirall/owncloudwizard.h"
#include "mirall/mirallconfigfile.h"
#include "mirall/encryption.h"
#include "mirall/passworddialog.h"
#include <QDebug>
#include <QDesktopServices>
@@ -23,8 +25,10 @@
#include <QValidator>
#include <QWizardPage>
#include <QDir>
#include <QMap>
#include <QScrollBar>
#include <QMessageBox>
#include <iostream>
#include <stdlib.h>
namespace Mirall
@@ -62,13 +66,30 @@ OwncloudSetupPage::OwncloudSetupPage()
registerField( QLatin1String("connectMyOC"), _ui.cbConnectOC );
registerField( QLatin1String("secureConnect"), _ui.cbSecureConnect );
registerField( QLatin1String("PwdNoLocalStore"), _ui.cbNoPasswordStore );
registerField( QLatin1String("Encryption"), _ui.cbEncryption );
_enc = new Encryption();
connect( _ui.lePassword, SIGNAL(textChanged(QString)), this, SIGNAL(completeChanged()));
connect( _ui.cbNoPasswordStore, SIGNAL(stateChanged(int)), this, SLOT(slotPwdStoreChanged(int)));
connect( _ui.cbSecureConnect, SIGNAL(stateChanged(int)), this, SLOT(slotSecureConChanged(int)));
connect( _ui.cbEncryption, SIGNAL(stateChanged(int)), this, SLOT(slotEncryptionChanged(int)));
connect( _ui.leUrl, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged()));
connect( _ui.leUsername, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged()));
connect( _ui.lePassword, SIGNAL(textChanged(QString)), this, SLOT(slotTextChanged()));
connect( _ui.pbGenEncKeys, SIGNAL(clicked()), this, SLOT(slotGenEncKeysButtonClicked()));
connect( _ui.pbGetEncKeys, SIGNAL(clicked()), this, SLOT(slotGetEncKeysButtonClicked()));
connect( _ui.pbChangeKeyPassword, SIGNAL(clicked()), this, SLOT(slotChangeKeyPasswordClicked()));
connect( _enc, SIGNAL(ocsGetUserKeysResults(QMap<QString,QString>)), this, SLOT(slotGetEncryptionKeysResult(QMap<QString, QString>)));
connect( _enc, SIGNAL(ocsSetUserKeysResults(QMap<QString,QString>)), this, SLOT(slotSetEncryptionKeysResult(QMap<QString, QString>)));
connect( _enc, SIGNAL(ocsChangePasswordResult(QMap<QString,QString>)), this, SLOT(slotChangeKeyPasswordResult(QMap<QString, QString>)));
_ui.keyStatusLabel->hide();
_ui.cbConnectOC->hide();
_ui.pbChangeKeyPassword->hide();
setupCustomization();
#if QT_VERSION >= 0x040700
@@ -100,6 +121,29 @@ void OwncloudSetupPage::setOCUrl( const QString& newUrl )
_ui.leUrl->setText( url );
}
void OwncloudSetupPage::setOCEncryption(const bool enc)
{
_ui.cbEncryption->setChecked(enc);
_ui.cbEncryption->setEnabled(true);
if (enc) {
_ui.pbGetEncKeys->show();
_ui.pbGetEncKeys->setEnabled(true);
_ui.pbGenEncKeys->show();
_ui.pbGenEncKeys->setEnabled(true);
_ui.pbGenEncKeys->setText("Generate new Keys");
_ui.pbChangeKeyPassword->show();
_ui.pbChangeKeyPassword->setEnabled(true);
_ui.cbEncryption->setEnabled(true);
} else {
_ui.pbGetEncKeys->show();
_ui.pbGetEncKeys->setEnabled(true);
_ui.pbGenEncKeys->show();
_ui.pbGenEncKeys->setEnabled(true);
_ui.pbChangeKeyPassword->hide();
_ui.cbEncryption->setEnabled(true);
}
}
void OwncloudSetupPage::setupCustomization()
{
// set defaults for the customize labels.
@@ -144,6 +188,190 @@ void OwncloudSetupPage::slotSecureConChanged( int state )
}
}
void OwncloudSetupPage::slotGetEncKeysButtonClicked()
{
PasswordDialog *pd = new PasswordDialog();
pd->setOperation(PasswordDialog::GetKeyPasswd);
connect( pd, SIGNAL(privateKeyPassword(QString)), this, SLOT(slotGetPrivateKeyPassword(QString)));
pd->show();
}
void OwncloudSetupPage::slotGetPrivateKeyPassword(QString password)
{
_enc->setBaseUrl(_ui.protocolLabel->text() + _ui.leUrl->text());
_enc->setAuthCredentials(_ui.leUsername->text(), _ui.lePassword->text());
_enc->getUserKeys(password);
}
void OwncloudSetupPage::slotGetEncryptionKeysResult(QMap<QString, QString> result)
{
if (!result.isEmpty()) {
switch (result["statuscode"].toInt()) {
case 100:
_ui.keyStatusLabel->setTextFormat(Qt::RichText);
_ui.keyStatusLabel->setText("<font color=\"green\">keys successfully downloaded</font>");
_ui.keyStatusLabel->show();
break;
case 300:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Client side encryption not enabled, please check your server configuration."),
QMessageBox::Ok);
break;
case 404:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("No keys found. If you use the encryption system for tge first time you havr to generate the keys first."),
QMessageBox::Ok);
break;
case -1:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Can't import key probably due a wrong key format. Key expected in PEM format."),
QMessageBox::Ok);
break;
case -10:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Can't connect to your ownCloud. Please check the URL, the username and the password."),
QMessageBox::Ok);
break;
default:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Unknown error (") + result["statuscode"].toInt() + ")",
QMessageBox::Ok);
}
}
}
void OwncloudSetupPage::slotGenEncKeysButtonClicked()
{
PasswordDialog *pd = new PasswordDialog();
pd->setOperation(PasswordDialog::GenRSAKey);
connect( pd, SIGNAL(privateKeyPassword(QString)), this, SLOT(slotSetPrivateKeyPassword(QString)));
pd->show();
}
void OwncloudSetupPage::slotSetPrivateKeyPassword(QString password)
{
_enc->setBaseUrl(_ui.protocolLabel->text() + _ui.leUrl->text());
_enc->setAuthCredentials(_ui.leUsername->text(), _ui.lePassword->text());
_enc->generateUserKeys(password);
}
void OwncloudSetupPage::slotSetEncryptionKeysResult(QMap<QString, QString> result)
{
if (!result.isEmpty()) {
switch (result["statuscode"].toInt()) {
case 100:
_ui.keyStatusLabel->setTextFormat(Qt::RichText);
_ui.keyStatusLabel->setText("<font color=\"green\">keys successfully generated</font>");
_ui.keyStatusLabel->show();
break;
case 300:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Client side encryption not enabled, please check your server configuration."),
QMessageBox::Ok);
break;
case 404:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Server could not write your key to the keyring."),
QMessageBox::Ok);
break;
case -10:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Can't connect to your ownCloud. Please check the URL, the username and the password."),
QMessageBox::Ok);
break;
default:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Unknown error during key generation (") + result["statuscode"].toInt() + ")",
QMessageBox::Ok);
}
}
}
void OwncloudSetupPage::slotChangeKeyPasswordClicked()
{
PasswordDialog *pd = new PasswordDialog();
pd->setOperation(PasswordDialog::ChangeKeyPasswd);
connect( pd, SIGNAL(changePrivateKeyPassword(QString,QString)), this, SLOT(slotChangeKeyPassword(QString,QString)));
pd->show();
}
void OwncloudSetupPage::slotChangeKeyPassword(QString oldpasswd, QString newpasswd)
{
_enc->setBaseUrl(_ui.protocolLabel->text() + _ui.leUrl->text());
_enc->setAuthCredentials(_ui.leUsername->text(), _ui.lePassword->text());
_enc->changeUserKeyPassword(oldpasswd, newpasswd);
}
void OwncloudSetupPage::slotChangeKeyPasswordResult(QMap<QString, QString> result)
{
if (!result.isEmpty()) {
switch (result["statuscode"].toInt()) {
case 100:
_ui.keyStatusLabel->setTextFormat(Qt::RichText);
_ui.keyStatusLabel->setText("<font color=\"green\">keys successfully generated</font>");
_ui.keyStatusLabel->show();
break;
case 300:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Client side encryption not enabled, please check your server configuration."),
QMessageBox::Ok);
break;
case 404:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Server could not write your key to the keyring."),
QMessageBox::Ok);
break;
case -10:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Can't connect to your ownCloud. Please check the URL, the username and the password."),
QMessageBox::Ok);
break;
default:
_ui.cbEncryption->setChecked(false);
QMessageBox::critical(this, tr("ownCloud Client"),
tr("Unknown error during key generation (") + result["statuscode"].toInt() + ")",
QMessageBox::Ok);
}
}
}
void OwncloudSetupPage::slotEncryptionChanged( int state )
{
if ( state == Qt::Checked){
_ui.pbGetEncKeys->setEnabled(true);
_ui.pbGenEncKeys->setEnabled(true);
} else {
_ui.pbGetEncKeys->setEnabled(false);
_ui.pbGenEncKeys->setEnabled(false);
_ui.keyStatusLabel->hide();
}
}
void OwncloudSetupPage::slotTextChanged( )
{
if ( !(_ui.leUsername->text().isEmpty() || _ui.lePassword->text().isEmpty() || _ui.leUrl->text().isEmpty()) ) {
_ui.cbEncryption->setEnabled(true);
} else {
_ui.cbEncryption->setEnabled(false);
}
}
bool OwncloudSetupPage::isComplete() const
{
if( _ui.leUrl->text().isEmpty() ) return false;
@@ -535,4 +763,16 @@ void OwncloudWizard::setOCUrl( const QString& url )
}
void OwncloudWizard::setOCEncryption(const bool enc)
{
#ifdef OWNCLOUD_CLIENT
_oCEncEnabled = enc;
OwncloudSetupPage *p = static_cast<OwncloudSetupPage*>(page(Page_oCSetup));
if( p )
p->setOCEncryption( enc );
#endif
}
} // end namespace
+20 -1
Ver Arquivo
@@ -25,8 +25,12 @@
#include "ui_owncloudcredentialspage.h"
#include "ui_owncloudsetuppage.h"
#include <QMap>
class QLabel;
class QVariant;
class Encryption;
class GenEncKeys;
namespace Mirall {
@@ -41,13 +45,26 @@ public:
virtual void initializePage();
virtual int nextId() const;
void setOCUrl( const QString& );
void setOCEncryption( const bool enc );
protected slots:
void slotPwdStoreChanged( int );
void slotSecureConChanged( int );
void slotEncryptionChanged( int );
void slotGetEncryptionKeysResult(QMap<QString, QString>);
void slotSetEncryptionKeysResult(QMap<QString, QString>);
void slotSetPrivateKeyPassword(QString);
void slotGetPrivateKeyPassword(QString);
void slotGenEncKeysButtonClicked();
void slotGetEncKeysButtonClicked();
void slotChangeKeyPasswordClicked();
void slotChangeKeyPassword(QString oldpasswd, QString newpasswd);
void slotChangeKeyPasswordResult(QMap<QString, QString>);
void slotTextChanged();
void setupCustomization();
private:
Ui_OwncloudSetupPage _ui;
Encryption *_enc;
};
@@ -74,6 +91,8 @@ public:
void setOCUrl( const QString& );
void setOCEncryption( const bool enc );
void setupCustomMedia( QVariant, QLabel* );
QString ocUrl() const;
@@ -82,7 +101,6 @@ public slots:
void slotCurrentPageChanged( int );
void showOCUrlLabel( bool );
signals:
void connectToOCUrl( const QString& );
void installOCServer();
@@ -91,6 +109,7 @@ signals:
private:
QString _configFile;
QString _oCUrl;
bool _oCEncEnabled;
};
/**
+106
Ver Arquivo
@@ -0,0 +1,106 @@
/*
* Copyright (C) 2012 Bjoern Schiessle <schiessle@owncloud.com>
*
* 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 2 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.
*/
#include "passworddialog.h"
#include "ui_passworddialog.h"
#include "mirall/encryption.h"
#include <iostream>
PasswordDialog::PasswordDialog(QWidget *parent) :
QDialog(parent),
_ui(new Ui::PasswordDialogUi)
{
_ui->setupUi(this);
connect( _ui->bbFinishSetup, SIGNAL(accepted()), this, SLOT(slotAccept()));
connect( _ui->bbFinishSetup, SIGNAL(rejected()), this, SLOT(slotReject()));
}
PasswordDialog::~PasswordDialog()
{
delete _ui;
}
void PasswordDialog::setOperation(Operations op)
{
_operation = op;
updateDialog();
}
void PasswordDialog::updateDialog()
{
switch (_operation)
{
case PasswordDialog::GenRSAKey:
_ui->gbInstructions->setTitle(tr("Provide Encryption Key Password"));
_ui->instructionsLabel->setText(tr("Please enter the password you want to use to secure your encryption key.\n\n"
"The password has to different to your ownCloud password."));
_ui->lePassword->show();
_ui->PasswordLabel->show();
_ui->lePasswordRepeated->show();
_ui->RepeatPasswordLabel->show();
_ui->OldPasswordLabel->hide();
_ui->leOldPassword->hide();
break;
case PasswordDialog::GetKeyPasswd:
_ui->gbInstructions->setTitle(tr("Provide Encryption Key Password"));
_ui->instructionsLabel->setText(tr("Please enter the password for your encryption key."));
_ui->lePassword->show();
_ui->PasswordLabel->show();
_ui->lePasswordRepeated->hide();
_ui->RepeatPasswordLabel->hide();
_ui->OldPasswordLabel->hide();
_ui->leOldPassword->hide();
break;
case PasswordDialog::ChangeKeyPasswd:
_ui->gbInstructions->setTitle(tr("Change Encryption Key Password"));
_ui->instructionsLabel->setText(tr("Please enter the old and the new password for your encryption key."));
_ui->PasswordLabel->setText(tr("New password"));
_ui->RepeatPasswordLabel->setText(tr("Repeat new password"));
_ui->lePassword->show();
_ui->PasswordLabel->show();
_ui->lePasswordRepeated->show();
_ui->RepeatPasswordLabel->show();
_ui->OldPasswordLabel->show();
_ui->leOldPassword->show();
break;
}
}
void PasswordDialog::slotAccept()
{
switch (_operation)
{
case PasswordDialog::GenRSAKey:
if ( QString::compare(_ui->lePassword->text(), _ui->lePasswordRepeated->text(), Qt::CaseSensitive) == 0 ) {
emit privateKeyPassword(_ui->lePassword->text());
}
break;
case PasswordDialog::GetKeyPasswd:
emit privateKeyPassword(_ui->lePassword->text());
break;
case PasswordDialog::ChangeKeyPasswd:
if ( QString::compare(_ui->lePassword->text(), _ui->lePasswordRepeated->text(), Qt::CaseSensitive) == 0 ) {
emit changePrivateKeyPassword(_ui->leOldPassword->text(), _ui->lePassword->text());
}
break;
}
}
void PasswordDialog::slotReject()
{
std::cout << "rejected" << std::endl << std::flush;
}
+55
Ver Arquivo
@@ -0,0 +1,55 @@
/*
* Copyright (C) 2012 Bjoern Schiessle <schiessle@owncloud.com>
*
* 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 2 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.
*/
#ifndef ENCRYPTIONPASSWDDIALOG_H
#define ENCRYPTIONPASSWDDIALOG_H
#include <QDialog>
class Encryption;
namespace Ui {
class PasswordDialogUi;
}
class PasswordDialog : public QDialog
{
Q_OBJECT
public:
enum Operations { GenRSAKey,
ChangeKeyPasswd,
GetKeyPasswd};
PasswordDialog(QWidget *parent = 0);
void setOperation(Operations op);
~PasswordDialog();
private:
Operations _operation;
void updateDialog();
private slots:
void slotAccept();
void slotReject();
signals:
void privateKeyPassword(QString);
void changePrivateKeyPassword(QString oldpasswd, QString newpasswd);
private:
Ui::PasswordDialogUi *_ui;
};
#endif // ENCRYPTIONPASSWDDIALOG_H
+270
Ver Arquivo
@@ -0,0 +1,270 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PasswordDialogUi</class>
<widget class="QDialog" name="PasswordDialogUi">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>353</width>
<height>345</height>
</rect>
</property>
<property name="windowTitle">
<string>Generate Encryption Keys</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_3">
<property name="font">
<font>
<pointsize>14</pointsize>
<weight>50</weight>
<bold>false</bold>
</font>
</property>
<property name="text">
<string>ownCloud Client-Side Encryption</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item>
<widget class="QGroupBox" name="gbInstructions">
<property name="title">
<string>Provide Encryption Key Credentials</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QLabel" name="instructionsLabel">
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Droid Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans Serif'; font-size:11pt; color:#585858;&quot;&gt;Please enter the password you want to use to secure your encryption key. &lt;/span&gt;&lt;/p&gt;
&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:11pt; color:#585858;&quot;&gt;&lt;br /&gt;&lt;/p&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-family:'Sans Serif'; font-size:11pt; color:#585858;&quot;&gt;Please choose a strong passwort which is different to your ownCloud password.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::AutoText</enum>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="openExternalLinks">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="OldPasswordLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Old password</string>
</property>
</widget>
</item>
<item row="0" column="1">
<spacer name="horizontalSpacer_4">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="0" column="2">
<widget class="QLineEdit" name="leOldPassword">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="PasswordLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Password</string>
</property>
</widget>
</item>
<item row="1" column="1">
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Minimum</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="2">
<widget class="QLineEdit" name="lePassword">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
<item row="2" column="0" colspan="2">
<widget class="QLabel" name="RepeatPasswordLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>Repeat password</string>
</property>
</widget>
</item>
<item row="2" column="2">
<widget class="QLineEdit" name="lePasswordRepeated">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>23</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QDialogButtonBox" name="bbFinishSetup">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources/>
<connections>
<connection>
<sender>bbFinishSetup</sender>
<signal>accepted()</signal>
<receiver>PasswordDialogUi</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>bbFinishSetup</sender>
<signal>rejected()</signal>
<receiver>PasswordDialogUi</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>