[-]
[+]
|
Changed |
_service:tar_git:harbour-maira.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira.spec
^
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -6,7 +6,7 @@
<service name="tar_git">
<param name="url">https://github.com/kimmoli/maira.git</param>
<param name="branch">master</param>
- <param name="revision">0d870a43d0996c5e25b11b6ebf554d66d553089d</param>
+ <param name="revision">2f16080cb0c5f8e636050e564b58a5f4534ce2ff</param>
<param name="token"/>
<param name="debian">N</param>
<param name="dumb">N</param>
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/maira.pro
^
|
@@ -10,7 +10,7 @@
TARGET = harbour-maira
QT += network dbus
CONFIG += sailfishapp link_pkgconfig
-PKGCONFIG += sailfishapp nemonotifications-qt5
+PKGCONFIG += sailfishapp nemonotifications-qt5 Qt5SystemInfo
DEFINES += "APPVERSION=\\\"$${SPECVERSION}\\\""
DEFINES += "APPNAME=\\\"$${TARGET}\\\""
@@ -96,7 +96,9 @@
src/notifications.cpp \
src/dbusAdaptor.cpp \
src/dbus.cpp \
- src/consolemodel.cpp
+ src/consolemodel.cpp \
+ src/simplecrypt.cpp \
+ src/crypter.cpp
HEADERS += \
src/filedownloader.h \
@@ -104,5 +106,7 @@
src/notifications.h \
src/dbusAdaptor.h \
src/dbus.h \
- src/consolemodel.h
+ src/consolemodel.h \
+ src/simplecrypt.h \
+ src/crypter.h
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/qml/maira.qml
^
|
@@ -50,7 +50,7 @@
db.transaction(function(x)
{
x.executeSql("CREATE TABLE IF NOT EXISTS accounts (id INTEGER PRIMARY KEY AUTOINCREMENT, host TEXT, auth TEXT)")
- x.executeSql("INSERT INTO accounts (host, auth) VALUES(?, ?)",[Qt.btoa("http://jiraserver:8080/"), Qt.btoa("username:password")])
+ x.executeSql("INSERT INTO accounts (host, auth) VALUES(?, ?)",[Crypter.encrypt("http://jiraserver:8080/"), Crypter.encrypt("username:password")])
})
})
@@ -65,10 +65,10 @@
links.clear()
loggedin = false
- var url = Qt.atob(accounts.current.host) + "rest/auth/1/session"
+ var url = accounts.current.host + "rest/auth/1/session"
- var content = { username: Qt.atob(accounts.current.auth).split(":")[0],
- password: Qt.atob(accounts.current.auth).split(":")[1] }
+ var content = { username: accounts.current.auth.split(":")[0],
+ password: accounts.current.auth.split(":")[1] }
post(url, JSON.stringify(content), "POST", function(o)
{
@@ -79,14 +79,14 @@
getserverinfo()
getcurrentuserinfo()
jqlsearch(0)
- activitystream.source = Qt.atob(accounts.current.host) + "activity"
+ activitystream.source = accounts.current.host + "activity"
acdata.update()
})
}
function getserverinfo()
{
- request(Qt.atob(accounts.current.host) + "rest/api/2/serverInfo", function(o)
+ request(accounts.current.host + "rest/api/2/serverInfo", function(o)
{
serverinfo = JSON.parse(o.responseText)
})
@@ -94,9 +94,9 @@
function getcurrentuserinfo()
{
- request(Qt.atob(accounts.current.host) + "rest/api/2/user?key=" + Qt.atob(accounts.current.auth).split(":")[0], function(o)
+ request(accounts.current.host + "rest/api/2/user?key=" + accounts.current.auth.split(":")[0], function(o)
{
- currentuser = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), Qt.atob(accounts.current.host)))
+ currentuser = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), accounts.current.host))
})
}
@@ -170,11 +170,14 @@
function findaccount()
{
for (var i=0 ; i<count; i++)
+ {
if (get(i).id == activeaccount.value)
{
- current = get(i)
+ var tmp = get(i)
+ current = { "id" : tmp.id, "host" : Crypter.decrypt(tmp.host), "auth" : Crypter.decrypt(tmp.auth) }
break
}
+ }
log("account " + activeaccount.value + " at index " + i)
}
@@ -187,7 +190,6 @@
var res = x.executeSql("SELECT * FROM accounts")
for(var i = 0; i < res.rows.length; i++)
{
- log(res.rows.item(i).id + " = " + res.rows.item(i).host + " - " + res.rows.item(i).auth)
append(res.rows.item(i))
}
})
@@ -243,10 +245,10 @@
clear()
if (searchtext === "")
{
- request(Qt.atob(accounts.current.host) + "rest/api/2/user/assignable/search?" + _searchterm,
+ request(accounts.current.host + "rest/api/2/user/assignable/search?" + _searchterm,
function (o)
{
- allusers = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), Qt.atob(accounts.current.host)))
+ allusers = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), accounts.current.host))
logjson(allusers, "users update()")
for (var i=0 ; i<allusers.length ; i++)
@@ -289,7 +291,7 @@
function update()
{
clear()
- request(Qt.atob(accounts.current.host) + "rest/api/2/filter/favourite",
+ request(accounts.current.host + "rest/api/2/filter/favourite",
function (o)
{
var d = JSON.parse(o.responseText)
@@ -315,10 +317,10 @@
function update()
{
clear()
- request(Qt.atob(accounts.current.host) + "rest/api/2/issue/" + currentissue.key + "/transitions?expand=transitions.fields",
+ request(accounts.current.host + "rest/api/2/issue/" + currentissue.key + "/transitions?expand=transitions.fields",
function (o)
{
- var d = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), Qt.atob(accounts.current.host)))
+ var d = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), accounts.current.host))
logjson(d, "update transitions")
for (var i=0 ; i<d.transitions.length ; i++)
@@ -367,10 +369,10 @@
function update()
{
- request(Qt.atob(accounts.current.host) + "rest/api/2/project",
+ request(accounts.current.host + "rest/api/2/project",
function (o)
{
- allprojects = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), Qt.atob(accounts.current.host)))
+ allprojects = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), accounts.current.host))
logjson(allprojects, "projects update()")
prevsearchtext = ""
sortby(sortedby)
@@ -415,7 +417,7 @@
function update()
{
- request(Qt.atob(accounts.current.host) + "rest/api/2/jql/autocompletedata",
+ request(accounts.current.host + "rest/api/2/jql/autocompletedata",
function (o)
{
allacdata = JSON.parse(o.responseText)
@@ -573,16 +575,21 @@
key = get(i-1).objecttitle
else if (get(i-1).targettitle != undefined && get(i-1).targettitle.match(/^[A-Z]+-\d+$/))
key = get(i-1).targettitle
+ var title = ""
+ title = get(i-1).title.replace(/<(?:.|\n)*?>/gm, '').replace(/[\n\r]/g, ' ').replace(/\s+/g, ' ')
- Notifications.notify(serverinfo.serverTitle,
- ((key.length > 0) ? key : serverinfo.serverTitle),
- get(i-1).title.replace(/<(?:.|\n)*?>/gm, '').replace(/[\n\r]/g, ' ').replace(/\s+/g, ' '),
- false, get(i-1).published, key)
+ Notifications.notify(serverinfo.serverTitle, ((key.length > 0) ? key : serverinfo.serverTitle), title, false, get(i-1).published, key)
newitems++
}
}
- if (newitems > 0)
+ if (newitems == 1)
+ {
+ Notifications.notify("", ((key.length > 0) ? key : serverinfo.serverTitle), title, true, "", key)
+ }
+ else if (newitems > 1)
+ {
Notifications.notify("", serverinfo.serverTitle, newitems + " new activity", true, "", "")
+ }
lastactivitystreamupdate.value = new Date().getTime()
}
}
@@ -755,10 +762,10 @@
function jqlsearch(startat)
{
- request(Qt.atob(accounts.current.host) + "rest/api/2/search?jql=" + jqlstring.value.replace(/ /g, "+") + "&startAt=" + startat + "&maxResults=10",
+ request(accounts.current.host + "rest/api/2/search?jql=" + jqlstring.value.replace(/ /g, "+") + "&startAt=" + startat + "&maxResults=10",
function (o)
{
- var d = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), Qt.atob(accounts.current.host)))
+ var d = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), accounts.current.host))
logjson(d, "jqlsearch")
if (startat === 0)
@@ -788,10 +795,10 @@
function fetchproject(projectkey)
{
- request(Qt.atob(accounts.current.host) + "rest/api/2/project/" + projectkey,
+ request(accounts.current.host + "rest/api/2/project/" + projectkey,
function (o)
{
- currentproject = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), Qt.atob(accounts.current.host)))
+ currentproject = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), accounts.current.host))
logjson(currentproject, "fetchproject")
@@ -810,16 +817,16 @@
function fetchissue(issuekey, callback)
{
- request(Qt.atob(accounts.current.host) + "rest/api/2/issue/" + issuekey,
+ request(accounts.current.host + "rest/api/2/issue/" + issuekey,
function (o)
{
- currentissue = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), Qt.atob(accounts.current.host)))
+ currentissue = JSON.parse(o.responseText.replace(new RegExp(serverinfo.baseUrl, "g"), accounts.current.host))
logjson(currentissue, "fetchissue")
customfields.clear()
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/qml/pages/ActivityStream.qml
^
|
@@ -101,8 +101,8 @@
{
source:
{
- var r = new RegExp("<img.*src=\\\"(" + Qt.atob(accounts.current.host) + ".*?)\\\"")
- var c = r.exec(content.replace(new RegExp(serverinfo.baseUrl, "g"), Qt.atob(accounts.current.host)))
+ var r = new RegExp("<img.*src=\\\"(" + accounts.current.host + ".*?)\\\"")
+ var c = r.exec(content.replace(new RegExp(serverinfo.baseUrl, "g"), accounts.current.host))
if (c && c.length > 1)
{
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/qml/pages/EditAccount.qml
^
|
@@ -21,8 +21,8 @@
{
if (result === DialogResult.Accepted)
{
- host = Qt.btoa(hosturl.text)
- auth = Qt.btoa(authusr.text + ":" + authpwd.text)
+ host = hosturl.text
+ auth = authusr.text + ":" + authpwd.text
}
}
@@ -57,7 +57,7 @@
placeholderText: "http://jiraserver:1234/"
width: parent.width
focus: false
- text: Qt.atob(accounts.current.host)
+ text: accounts.current.host
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData | Qt.ImhUrlCharactersOnly
EnterKey.iconSource: "image://theme/icon-m-enter-accept"
validator: RegExpValidator { regExp: /^https?:\/\/.*\/$/ }
@@ -73,7 +73,7 @@
placeholderText: "username"
width: parent.width
focus: false
- text: Qt.atob(accounts.current.auth).split(":")[0]
+ text: accounts.current.auth.split(":")[0]
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData
EnterKey.iconSource: "image://theme/icon-m-enter-accept"
EnterKey.onClicked:
@@ -88,7 +88,7 @@
placeholderText: "password"
width: parent.width
focus: false
- text: Qt.atob(accounts.current.auth).split(":").pop()
+ text: accounts.current.auth.split(":").pop()
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData
echoMode: TextInput.PasswordEchoOnEdit
EnterKey.iconSource: "image://theme/icon-m-enter-accept"
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/qml/pages/FilterSelector.qml
^
|
@@ -91,7 +91,7 @@
id: contextmenu
ContextMenu
{
- property bool my: Qt.atob(accounts.current.auth).split(":")[0] === owner
+ property bool my: accounts.current.auth.split(":")[0] === owner
MenuItem
{
visible: my
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/qml/pages/IssueView.qml
^
|
@@ -71,7 +71,7 @@
filePicker.selectedContentChanged.connect(function()
{
var filename = filePicker.selectedContent
- FileUploader.uploadFile(Qt.atob(accounts.current.host) + "rest/api/2/issue/" + currentissue.key + "/attachments", filename)
+ FileUploader.uploadFile(accounts.current.host + "rest/api/2/issue/" + currentissue.key + "/attachments", filename)
})
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/qml/pages/MainPage.qml
^
|
@@ -61,7 +61,11 @@
{
visible: !loggedin
text: "Retry login"
- onClicked: auth()
+ onClicked:
+ {
+ accounts.findaccount()
+ auth()
+ }
}
MenuItem
{
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/qml/pages/Settings.qml
^
|
@@ -89,7 +89,7 @@
clip: true
anchors.left: parent.left
anchors.leftMargin: Theme.paddingMedium
- text: Qt.atob(host)
+ text: Crypter.decrypt(host)
elide: Text.ElideRight
font.bold: activeaccount.value === accounts.get(index).id
}
@@ -99,7 +99,7 @@
clip: true
anchors.left: parent.left
anchors.leftMargin: Theme.paddingMedium
- text: Qt.atob(auth).split(":")[0]
+ text: Crypter.decrypt(auth).split(":")[0]
font.pixelSize: Theme.fontSizeSmall
elide: Text.ElideRight
font.bold: activeaccount.value === accounts.get(index).id
@@ -137,7 +137,7 @@
var db = opendb()
db.transaction(function(x)
{
- x.executeSql("UPDATE accounts SET host=?, auth=? WHERE id=?",[ea.host, ea.auth, activeaccount.value])
+ x.executeSql("UPDATE accounts SET host=?, auth=? WHERE id=?",[Crypter.encrypt(ea.host), Crypter.encrypt(ea.auth), activeaccount.value])
log("account updated")
})
accounts.reload()
@@ -150,7 +150,7 @@
var db = opendb()
db.transaction(function(x)
{
- x.executeSql("INSERT INTO accounts (host, auth) VALUES(?, ?)",[accounts.current.host, accounts.current.auth])
+ x.executeSql("INSERT INTO accounts (host, auth) VALUES(?, ?)",[Crypter.encrypt(accounts.current.host), Crypter.encrypt(accounts.current.auth)])
log("inserted new account")
})
accounts.reload()
|
[-]
[+]
|
Added |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/src/crypter.cpp
^
|
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2015-2017 kimmoli <kimmo.lindholm@eke.fi>
+ * All rights reserved.
+ *
+ * This file is part of Maira
+ *
+ * You may use this file under the terms of BSD license
+ */
+
+#include "crypter.h"
+
+Crypter::Crypter(quint64 key, QObject *parent) :
+ QObject(parent)
+{
+ m_simplecrypt = new SimpleCrypt(key);
+}
+
+QString Crypter::encrypt(QString input)
+{
+ return m_simplecrypt->encryptToString(input);
+}
+
+QString Crypter::decrypt(QString input)
+{
+ return m_simplecrypt->decryptToString(input);
+}
|
[-]
[+]
|
Added |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/src/crypter.h
^
|
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2015-2017 kimmoli <kimmo.lindholm@eke.fi>
+ * All rights reserved.
+ *
+ * This file is part of Maira
+ *
+ * You may use this file under the terms of BSD license
+ */
+
+#ifndef CRYPTER_H
+#define CRYPTER_H
+
+#include <QObject>
+#include "simplecrypt.h"
+
+class Crypter : public QObject
+{
+ Q_OBJECT
+public:
+ explicit Crypter(quint64 key, QObject *parent = 0);
+ Q_INVOKABLE QString encrypt(QString input);
+ Q_INVOKABLE QString decrypt(QString input);
+
+private:
+ SimpleCrypt* m_simplecrypt;
+};
+
+#endif // CRYPTER_H
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/src/main.cpp
^
|
@@ -16,11 +16,13 @@
#include <QQmlContext>
#include <QCoreApplication>
#include <QtNetwork>
+#include <QtSystemInfo/QDeviceInfo>
#include "filedownloader.h"
#include "fileuploader.h"
#include "notifications.h"
#include "dbus.h"
#include "consolemodel.h"
+#include "crypter.h"
class MyNetworkCookieJar : public QNetworkCookieJar
{
@@ -123,6 +125,11 @@
Dbus *dbus = new Dbus();
view->rootContext()->setContextProperty("Dbus", dbus);
+ QDeviceInfo *systemDeviceInfo = new QDeviceInfo();
+
+ Crypter *crypter = new Crypter(systemDeviceInfo->uniqueDeviceID().right(16).toULongLong(0, 16));
+ view->rootContext()->setContextProperty("Crypter", crypter);
+
view->setSource(SailfishApp::pathTo("qml/maira.qml"));
view->show();
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/src/notifications.cpp
^
|
@@ -25,6 +25,16 @@
notif.setPreviewSummary(summary);
notif.setPreviewBody(body);
notif.setCategory("x-harbour.maira.activity.preview");
+ if (issuekey.isEmpty())
+ {
+ remoteactions << Notification::remoteAction("default",
+ QString(),
+ "com.kimmoli.harbour.maira",
+ "/",
+ "com.kimmoli.harbour.maira",
+ "openapp",
+ QVariantList());
+ }
}
else
{
|
[-]
[+]
|
Added |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/src/simplecrypt.cpp
^
|
@@ -0,0 +1,252 @@
+/*
+Copyright (c) 2011, Andre Somers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Rathenau Instituut, Andre Somers nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR #######; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+#include "simplecrypt.h"
+#include <QByteArray>
+#include <QtDebug>
+#include <QtGlobal>
+#include <QDateTime>
+#include <QCryptographicHash>
+#include <QDataStream>
+
+SimpleCrypt::SimpleCrypt():
+ m_key(0),
+ m_compressionMode(CompressionAuto),
+ m_protectionMode(ProtectionChecksum),
+ m_lastError(ErrorNoError)
+{
+ qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF));
+}
+
+SimpleCrypt::SimpleCrypt(quint64 key):
+ m_key(key),
+ m_compressionMode(CompressionAuto),
+ m_protectionMode(ProtectionChecksum),
+ m_lastError(ErrorNoError)
+{
+ qsrand(uint(QDateTime::currentMSecsSinceEpoch() & 0xFFFF));
+ splitKey();
+}
+
+void SimpleCrypt::setKey(quint64 key)
+{
+ m_key = key;
+ splitKey();
+}
+
+void SimpleCrypt::splitKey()
+{
+ m_keyParts.clear();
+ m_keyParts.resize(8);
+ for (int i=0;i<8;i++) {
+ quint64 part = m_key;
+ for (int j=i; j>0; j--)
+ part = part >> 8;
+ part = part & 0xff;
+ m_keyParts[i] = static_cast<char>(part);
+ }
+}
+
+QByteArray SimpleCrypt::encryptToByteArray(const QString& plaintext)
+{
+ QByteArray plaintextArray = plaintext.toUtf8();
+ return encryptToByteArray(plaintextArray);
+}
+
+QByteArray SimpleCrypt::encryptToByteArray(QByteArray plaintext)
+{
+ if (m_keyParts.isEmpty()) {
+ qWarning() << "No key set.";
+ m_lastError = ErrorNoKeySet;
+ return QByteArray();
+ }
+
+
+ QByteArray ba = plaintext;
+
+ CryptoFlags flags = CryptoFlagNone;
+ if (m_compressionMode == CompressionAlways) {
+ ba = qCompress(ba, 9); //maximum compression
+ flags |= CryptoFlagCompression;
+ } else if (m_compressionMode == CompressionAuto) {
+ QByteArray compressed = qCompress(ba, 9);
+ if (compressed.count() < ba.count()) {
+ ba = compressed;
+ flags |= CryptoFlagCompression;
+ }
+ }
+
+ QByteArray integrityProtection;
+ if (m_protectionMode == ProtectionChecksum) {
+ flags |= CryptoFlagChecksum;
+ QDataStream s(&integrityProtection, QIODevice::WriteOnly);
+ s << qChecksum(ba.constData(), ba.length());
+ } else if (m_protectionMode == ProtectionHash) {
+ flags |= CryptoFlagHash;
+ QCryptographicHash hash(QCryptographicHash::Sha1);
+ hash.addData(ba);
+
+ integrityProtection += hash.result();
+ }
+
+ //prepend a random char to the string
+ char randomChar = char(qrand() & 0xFF);
+ ba = randomChar + integrityProtection + ba;
+
+ int pos(0);
+ char lastChar(0);
+
+ int cnt = ba.count();
+
+ while (pos < cnt) {
+ ba[pos] = ba.at(pos) ^ m_keyParts.at(pos % 8) ^ lastChar;
+ lastChar = ba.at(pos);
+ ++pos;
+ }
+
+ QByteArray resultArray;
+ resultArray.append(char(0x03)); //version for future updates to algorithm
+ resultArray.append(char(flags)); //encryption flags
+ resultArray.append(ba);
+
+ m_lastError = ErrorNoError;
+ return resultArray;
+}
+
+QString SimpleCrypt::encryptToString(const QString& plaintext)
+{
+ QByteArray plaintextArray = plaintext.toUtf8();
+ QByteArray cypher = encryptToByteArray(plaintextArray);
+ QString cypherString = QString::fromLatin1(cypher.toBase64());
+ return cypherString;
+}
+
+QString SimpleCrypt::encryptToString(QByteArray plaintext)
+{
+ QByteArray cypher = encryptToByteArray(plaintext);
+ QString cypherString = QString::fromLatin1(cypher.toBase64());
+ return cypherString;
+}
+
+QString SimpleCrypt::decryptToString(const QString &cyphertext)
+{
+ QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1());
+ QByteArray plaintextArray = decryptToByteArray(cyphertextArray);
+ QString plaintext = QString::fromUtf8(plaintextArray, plaintextArray.size());
+
+ return plaintext;
+}
+
+QString SimpleCrypt::decryptToString(QByteArray cypher)
+{
+ QByteArray ba = decryptToByteArray(cypher);
+ QString plaintext = QString::fromUtf8(ba, ba.size());
+
+ return plaintext;
+}
+
+QByteArray SimpleCrypt::decryptToByteArray(const QString& cyphertext)
+{
+ QByteArray cyphertextArray = QByteArray::fromBase64(cyphertext.toLatin1());
+ QByteArray ba = decryptToByteArray(cyphertextArray);
+
+ return ba;
+}
+
+QByteArray SimpleCrypt::decryptToByteArray(QByteArray cypher)
+{
+ if (m_keyParts.isEmpty()) {
+ qWarning() << "No key set.";
+ m_lastError = ErrorNoKeySet;
+ return QByteArray();
+ }
+
+ QByteArray ba = cypher;
+
+ if( cypher.count() < 3 )
+ return QByteArray();
+
+ char version = ba.at(0);
+
+ if (version !=3) { //we only work with version 3
+ m_lastError = ErrorUnknownVersion;
+ qWarning() << "Invalid version or not a cyphertext.";
+ return QByteArray();
+ }
+
|
[-]
[+]
|
Added |
_service:tar_git:harbour-maira-0.1.12.tar.bz2/src/simplecrypt.h
^
|
@@ -0,0 +1,225 @@
+/*
+Copyright (c) 2011, Andre Somers
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the Rathenau Instituut, Andre Somers nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL ANDRE SOMERS BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR #######; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#ifndef SIMPLECRYPT_H
+#define SIMPLECRYPT_H
+#include <QString>
+#include <QVector>
+#include <QFlags>
+
+/**
+ @short Simple encryption and decryption of strings and byte arrays
+
+ This class provides a simple implementation of encryption and decryption
+ of strings and byte arrays.
+
+ @warning The encryption provided by this class is NOT strong encryption. It may
+ help to shield things from curious eyes, but it will NOT stand up to someone
+ determined to break the encryption. Don't say you were not warned.
+
+ The class uses a 64 bit key. Simply create an instance of the class, set the key,
+ and use the encryptToString() method to calculate an encrypted version of the input string.
+ To decrypt that string again, use an instance of SimpleCrypt initialized with
+ the same key, and call the decryptToString() method with the encrypted string. If the key
+ matches, the decrypted version of the string will be returned again.
+
+ If you do not provide a key, or if something else is wrong, the encryption and
+ decryption function will return an empty string or will return a string containing nonsense.
+ lastError() will return a value indicating if the method was succesful, and if not, why not.
+
+ SimpleCrypt is prepared for the case that the encryption and decryption
+ algorithm is changed in a later version, by prepending a version identifier to the cypertext.
+ */
+class SimpleCrypt
+{
+public:
+ /**
+ CompressionMode describes if compression will be applied to the data to be
+ encrypted.
+ */
+ enum CompressionMode {
+ CompressionAuto, /*!< Only apply compression if that results in a shorter plaintext. */
+ CompressionAlways, /*!< Always apply compression. Note that for short inputs, a compression may result in longer data */
+ CompressionNever /*!< Never apply compression. */
+ };
+ /**
+ IntegrityProtectionMode describes measures taken to make it possible to detect problems with the data
+ or wrong decryption keys.
+
+ Measures involve adding a checksum or a cryptograhpic hash to the data to be encrypted. This
+ increases the length of the resulting cypertext, but makes it possible to check if the plaintext
+ appears to be valid after decryption.
+ */
+ enum IntegrityProtectionMode {
+ ProtectionNone, /*!< The integerity of the encrypted data is not protected. It is not really possible to detect a wrong key, for instance. */
+ ProtectionChecksum,/*!< A simple checksum is used to verify that the data is in order. If not, an empty string is returned. */
+ ProtectionHash /*!< A cryptographic hash is used to verify the integrity of the data. This method produces a much stronger, but longer check */
+ };
+ /**
+ Error describes the type of error that occured.
+ */
+ enum Error {
+ ErrorNoError, /*!< No error occurred. */
+ ErrorNoKeySet, /*!< No key was set. You can not encrypt or decrypt without a valid key. */
+ ErrorUnknownVersion, /*!< The version of this data is unknown, or the data is otherwise not valid. */
+ ErrorIntegrityFailed, /*!< The integrity check of the data failed. Perhaps the wrong key was used. */
+ };
+
+ /**
+ Constructor.
+
+ Constructs a SimpleCrypt instance without a valid key set on it.
+ */
+ SimpleCrypt();
+ /**
+ Constructor.
+
+ Constructs a SimpleCrypt instance and initializes it with the given @arg key.
+ */
+ explicit SimpleCrypt(quint64 key);
+
+ /**
+ (Re-) initializes the key with the given @arg key.
+ */
+ void setKey(quint64 key);
+ /**
+ Returns true if SimpleCrypt has been initialized with a key.
+ */
+ bool hasKey() const {return !m_keyParts.isEmpty();}
+
+ /**
+ Sets the compression mode to use when encrypting data. The default mode is Auto.
+
+ Note that decryption is not influenced by this mode, as the decryption recognizes
+ what mode was used when encrypting.
+ */
+ void setCompressionMode(CompressionMode mode) {m_compressionMode = mode;}
+ /**
+ Returns the CompressionMode that is currently in use.
+ */
+ CompressionMode compressionMode() const {return m_compressionMode;}
+
+ /**
+ Sets the integrity mode to use when encrypting data. The default mode is Checksum.
+
+ Note that decryption is not influenced by this mode, as the decryption recognizes
+ what mode was used when encrypting.
+ */
+ void setIntegrityProtectionMode(IntegrityProtectionMode mode) {m_protectionMode = mode;}
+ /**
+ Returns the IntegrityProtectionMode that is currently in use.
+ */
+ IntegrityProtectionMode integrityProtectionMode() const {return m_protectionMode;}
+
+ /**
+ Returns the last error that occurred.
+ */
+ Error lastError() const {return m_lastError;}
+
+ /**
+ Encrypts the @arg plaintext string with the key the class was initialized with, and returns
+ a cyphertext the result. The result is a base64 encoded version of the binary array that is the
+ actual result of the string, so it can be stored easily in a text format.
+ */
+ QString encryptToString(const QString& plaintext) ;
+ /**
+ Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns
+ a cyphertext the result. The result is a base64 encoded version of the binary array that is the
+ actual result of the encryption, so it can be stored easily in a text format.
+ */
+ QString encryptToString(QByteArray plaintext) ;
+ /**
+ Encrypts the @arg plaintext string with the key the class was initialized with, and returns
+ a binary cyphertext in a QByteArray the result.
+
+ This method returns a byte array, that is useable for storing a binary format. If you need
+ a string you can store in a text file, use encryptToString() instead.
+ */
+ QByteArray encryptToByteArray(const QString& plaintext) ;
+ /**
+ Encrypts the @arg plaintext QByteArray with the key the class was initialized with, and returns
+ a binary cyphertext in a QByteArray the result.
+
+ This method returns a byte array, that is useable for storing a binary format. If you need
+ a string you can store in a text file, use encryptToString() instead.
+ */
+ QByteArray encryptToByteArray(QByteArray plaintext) ;
+
+ /**
+ Decrypts a cyphertext string encrypted with this class with the set key back to the
+ plain text version.
+
+ If an error occured, such as non-matching keys between encryption and decryption,
+ an empty string or a string containing nonsense may be returned.
+ */
+ QString decryptToString(const QString& cyphertext) ;
+ /**
+ Decrypts a cyphertext string encrypted with this class with the set key back to the
+ plain text version.
+
+ If an error occured, such as non-matching keys between encryption and decryption,
+ an empty string or a string containing nonsense may be returned.
+ */
+ QByteArray decryptToByteArray(const QString& cyphertext) ;
+ /**
+ Decrypts a cyphertext binary encrypted with this class with the set key back to the
+ plain text version.
+
+ If an error occured, such as non-matching keys between encryption and decryption,
+ an empty string or a string containing nonsense may be returned.
+ */
+ QString decryptToString(QByteArray cypher) ;
+ /**
+ Decrypts a cyphertext binary encrypted with this class with the set key back to the
+ plain text version.
+
|