Detect tails, support data persistence

Co-authored-by: Thotbot <thotbot@protonmail.com>
Co-authored-by: Selsta <selsta@sent.at>
This commit is contained in:
dsc
2019-07-03 05:13:51 +02:00
parent cfec9dde96
commit 0b61328971
13 changed files with 277 additions and 123 deletions

100
src/qt/TailsOS.cpp Normal file
View File

@@ -0,0 +1,100 @@
#include <QRegExp>
#include <QMessageBox>
#include <QPixmap>
#include <QTranslator>
#include "TailsOS.h"
#include "utils.h"
bool TailsOS::usePersistence = false;
QString TailsOS::tailsPathData = QString("/live/persistence/TailsData_unlocked/");
bool TailsOS::detect()
{
if (!fileExists("/etc/os-release"))
return false;
QByteArray data = fileOpen("/etc/os-release");
QRegularExpression re("TAILS_PRODUCT_NAME=\"Tails\"");
QRegularExpressionMatch os_match = re.match(data);
bool matched = os_match.hasMatch();
#ifdef QT_DEBUG
if (matched)
qDebug() << "Tails OS detected";
#endif
return matched;
}
bool TailsOS::detectDataPersistence()
{
return QDir(QDir::homePath() + "/Persistent").exists();
}
bool TailsOS::detectDotPersistence()
{
return QDir(tailsPathData + "dotfiles").exists();
}
void TailsOS::showDataPersistenceDisabledWarning()
{
QMessageBox msgBox;
msgBox.setText(QObject::tr("Warning: persistence disabled"));
msgBox.setWindowTitle(QObject::tr("Warning: persistence disabled"));
msgBox.setInformativeText(
QObject::tr("Monero GUI has detected that Tails persistence is "
"currently disabled. Any configurations you make inside "
"the Monero GUI will not be saved."
"\n\n"
"In addition, make sure to not save your wallet on the "
"filesystem, as it will be lost at shutdown."
"\n\n"
"To enable Tails persistence, setup an encrypted volume "
"and restart Tails. To gain a startup menu item, "
"enable the Tails \"dotfiles\" feature."));
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setDefaultButton(QMessageBox::Ok);
msgBox.setIconPixmap(QPixmap(":/images/tails-grey.png"));
msgBox.exec();
}
void TailsOS::askPersistence()
{
QMessageBox msgBox;
msgBox.setWindowTitle(QObject::tr("Monero GUI"));
msgBox.setText(QObject::tr("Use Tails persistence?"));
msgBox.setInformativeText(
QObject::tr("Persist wallet files and configuration on the encrypted volume?"
"\n\n"
"In addition, you can enable Tails dotfiles persistence "
"to gain a start menu entry.\n"));
msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
msgBox.setDefaultButton(QMessageBox::Yes);
msgBox.setIconPixmap(QPixmap(":/images/tails-grey.png"));
TailsOS::usePersistence = (msgBox.exec() == QMessageBox::Yes);
}
void TailsOS::persistXdgMime(QString filePath, QString data)
{
QFileInfo file(filePath);
QString tailsPath = tailsPathData + "dotfiles/.local/share/applications/";
// write to persistent volume
#ifdef QT_DEBUG
qDebug() << "Writing xdg mime: " << tailsPath + file.fileName();
#endif
QDir().mkpath(tailsPath); // ensure directory exists
fileWrite(tailsPath + file.fileName(), data);
// write to current session
#ifdef QT_DEBUG
qDebug() << "Writing xdg mime: " << file.filePath();
#endif
QDir().mkpath(file.path()); // ensure directory exists
fileWrite(file.filePath(), data);
}

23
src/qt/TailsOS.h Normal file
View File

@@ -0,0 +1,23 @@
#ifndef TAILSOS_H
#define TAILSOS_H
#include <QApplication>
class TailsOS
{
public:
TailsOS();
static bool detect();
static bool detectDataPersistence();
static bool detectDotPersistence();
static void showDataPersistenceDisabledWarning();
static void askPersistence();
static void persistXdgMime(QString filePath, QString data);
static bool usePersistence;
static QString tailsPathData;
};
#endif // TAILSOS_H

View File

@@ -1,70 +0,0 @@
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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
// THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 PROFITS; 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 <QtCore>
#include <QApplication>
#include <QFile>
#include <QTextStream>
#include "mime.h"
#include "utils.h"
void registerXdgMime(QApplication &app){
// MacOS handled via Info.plist
// Windows handled in the installer by rbrunner7
QString xdg = QString(
"[Desktop Entry]\n"
"Name=Monero GUI\n"
"GenericName=Monero-GUI\n"
"X-GNOME-FullName=Monero-GUI\n"
"Comment=Monero GUI\n"
"Keywords=Monero;\n"
"Exec=%1 %u\n"
"Terminal=false\n"
"Type=Application\n"
"Icon=monero\n"
"Categories=Network;GNOME;Qt;\n"
"MimeType=x-scheme-handler/monero;x-scheme-handler/moneroseed\n"
"StartupNotify=true\n"
"X-GNOME-Bugzilla-Bugzilla=GNOME\n"
"X-GNOME-UsesNotifications=true\n"
).arg(app.applicationFilePath());
QString appPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
QString filePath = QString("%1/monero-gui.desktop").arg(appPath);
qDebug() << QString("Writing %1").arg(filePath);
QFile file(filePath);
if(file.open(QIODevice::WriteOnly)){
QTextStream out(&file); out << xdg << endl;
file.close();
}
else
file.close();
}

View File

@@ -1,36 +0,0 @@
// Copyright (c) 2014-2019, The Monero Project
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are
// permitted provided that the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// 2. 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.
//
// 3. Neither the name of the copyright holder 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
// THE COPYRIGHT HOLDER OR CONTRIBUTORS 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 PROFITS; 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 MIME_H
#define MIME_H
#include <QApplication>
void registerXdgMime(QApplication &app);
#endif // MIME_H

View File

@@ -27,15 +27,35 @@
// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <QtCore>
#include <QApplication>
#include "src/qt/TailsOS.h"
#include "utils.h"
bool fileExists(QString path) {
QFileInfo check_file(path);
if (check_file.exists() && check_file.isFile())
return check_file.exists() && check_file.isFile();
}
QByteArray fileOpen(QString path) {
QFile file(path);
if(!file.open(QFile::ReadOnly | QFile::Text))
return QByteArray();
QByteArray data = file.readAll();
file.close();
return data;
}
bool fileWrite(QString path, QString data) {
QFile file(path);
if(file.open(QIODevice::WriteOnly)){
QTextStream out(&file); out << data << endl;
file.close();
return true;
else
return false;
}
return false;
}
QString getAccountName(){
@@ -47,6 +67,53 @@ QString getAccountName(){
return accountName;
}
QString xdgMime(QApplication &app){
return QString(
"[Desktop Entry]\n"
"Name=Monero GUI\n"
"GenericName=Monero-GUI\n"
"X-GNOME-FullName=Monero-GUI\n"
"Comment=Monero GUI\n"
"Keywords=Monero;\n"
"Exec=%1 %u\n"
"Terminal=false\n"
"Type=Application\n"
"Icon=monero\n"
"Categories=Network;GNOME;Qt;\n"
"MimeType=x-scheme-handler/monero;x-scheme-handler/moneroseed\n"
"StartupNotify=true\n"
"X-GNOME-Bugzilla-Bugzilla=GNOME\n"
"X-GNOME-UsesNotifications=true\n"
).arg(app.applicationFilePath());
}
void registerXdgMime(QApplication &app){
#ifdef Q_OS_LINUX
// Register desktop entry
// - MacOS handled via Info.plist
// - Windows handled in the installer by rbrunner7
// - Linux written to `QStandardPaths::ApplicationsLocation`
// - Tails written to persistent dotfiles
QString mime = xdgMime(app);
QString appPath = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation);
QString filePath = QString("%1/monero-gui.desktop").arg(appPath);
if (TailsOS::detect() && TailsOS::detectDotPersistence() && TailsOS::usePersistence) {
TailsOS::persistXdgMime(filePath, mime);
return;
}
QFileInfo file(filePath);
QDir().mkpath(file.path()); // ensure directory exists
#ifdef QT_DEBUG
qDebug() << "Writing xdg mime: " << filePath;
#endif
fileWrite(filePath, mime);
#endif
}
QString randomUserAgent(){
QStringList urand;
urand << "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.1"

View File

@@ -31,9 +31,14 @@
#include <QtCore>
#include <QRegExp>
#include <QApplication>
bool fileExists(QString path);
QByteArray fileOpen(QString path);
bool fileWrite(QString path, QString data);
QString getAccountName();
QString xdgMime(QApplication &app);
void registerXdgMime(QApplication &app);
const static QRegExp reURI = QRegExp("^\\w+:\\/\\/([\\w+\\-?\\-_\\-=\\-&]+)");
QString randomUserAgent();