GUI: Begin IPC mechanism to open files despite sandboxing
This commit is contained in:
parent
3e387b99f8
commit
890925929a
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
#-------------------------------------------------
|
#-------------------------------------------------
|
||||||
|
|
||||||
QT += core concurrent gui
|
QT += core concurrent gui network
|
||||||
|
|
||||||
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
|
||||||
CONFIG += c++17
|
CONFIG += c++17
|
||||||
@ -23,6 +23,8 @@ DEFINES += QT_DEPRECATED_WARNINGS
|
|||||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||||
|
|
||||||
SOURCES += \
|
SOURCES += \
|
||||||
|
ipcclient.cpp \
|
||||||
|
ipcserver.cpp \
|
||||||
main.cpp \
|
main.cpp \
|
||||||
mainwindow.cpp \
|
mainwindow.cpp \
|
||||||
pdfworker.cpp \
|
pdfworker.cpp \
|
||||||
@ -30,6 +32,9 @@ SOURCES += \
|
|||||||
clicklabel.cpp
|
clicklabel.cpp
|
||||||
|
|
||||||
HEADERS += \
|
HEADERS += \
|
||||||
|
ipc.h \
|
||||||
|
ipcclient.h \
|
||||||
|
ipcserver.h \
|
||||||
mainwindow.h \
|
mainwindow.h \
|
||||||
pdfworker.h \
|
pdfworker.h \
|
||||||
pdfpreview.h \
|
pdfpreview.h \
|
||||||
|
9
gui/ipc.h
Normal file
9
gui/ipc.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef IPC_H
|
||||||
|
#define IPC_H
|
||||||
|
|
||||||
|
enum IPCCommand
|
||||||
|
{
|
||||||
|
DocOpen,
|
||||||
|
FileOpen
|
||||||
|
};
|
||||||
|
#endif // IPC_H
|
27
gui/ipcclient.cpp
Normal file
27
gui/ipcclient.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include <QDataStream>
|
||||||
|
#include "ipcclient.h"
|
||||||
|
|
||||||
|
IPCClient::IPCClient(QString socketPath)
|
||||||
|
{
|
||||||
|
this->socketPath = socketPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IPCClient::sendCommand(IPCCommand command, QStringList args)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
QLocalSocket socket;
|
||||||
|
socket.connectToServer(socketPath);
|
||||||
|
if(socket.isOpen() && socket.isWritable())
|
||||||
|
{
|
||||||
|
QDataStream stream(&socket);
|
||||||
|
stream << command;
|
||||||
|
stream << args;
|
||||||
|
socket.flush();
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
qDebug() << "Not connected to IPC server";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
18
gui/ipcclient.h
Normal file
18
gui/ipcclient.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef IPCCLIENT_H
|
||||||
|
#define IPCCLIENT_H
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QString>
|
||||||
|
#include <QStringList>
|
||||||
|
#include "ipc.h"
|
||||||
|
|
||||||
|
class IPCClient
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
QString socketPath;
|
||||||
|
|
||||||
|
public:
|
||||||
|
IPCClient(QString socketPath);
|
||||||
|
bool sendCommand(IPCCommand command, QStringList args);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IPCCLIENT_H
|
88
gui/ipcserver.cpp
Normal file
88
gui/ipcserver.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include <QFile>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QProcess>
|
||||||
|
#include <QUrl>
|
||||||
|
#include <QLocalSocket>
|
||||||
|
#include <QDataStream>
|
||||||
|
#include "ipcserver.h"
|
||||||
|
|
||||||
|
IpcServer::IpcServer()
|
||||||
|
{
|
||||||
|
connect(&this->spawningServer, &QLocalServer::newConnection, this, &IpcServer::spawnerNewConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IpcServer::startSpawner(QString socketPath)
|
||||||
|
{
|
||||||
|
QFile::remove(socketPath);
|
||||||
|
return this->spawningServer.listen(socketPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IpcServer::docOpen(QString path, int pagenum)
|
||||||
|
{
|
||||||
|
QSettings settings;
|
||||||
|
QString command = settings.value("pdfviewer").toString();
|
||||||
|
if(command != "" && command.contains("%p") && command.contains("%f"))
|
||||||
|
{
|
||||||
|
QStringList splitted = command.split(" ");
|
||||||
|
if(splitted.size() > 1)
|
||||||
|
{
|
||||||
|
QString cmd = splitted[0];
|
||||||
|
QStringList args = splitted.mid(1);
|
||||||
|
args.replaceInStrings("%f", path);
|
||||||
|
args.replaceInStrings("%p", QString::number(pagenum));
|
||||||
|
|
||||||
|
QProcess::startDetached(cmd, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IpcServer::fileOpen(QString path)
|
||||||
|
{
|
||||||
|
return QDesktopServices::openUrl(QUrl::fromLocalFile(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
void IpcServer::spawnerNewConnection()
|
||||||
|
{
|
||||||
|
QScopedPointer<QLocalSocket> socket{this->spawningServer.nextPendingConnection()};
|
||||||
|
if(!socket.isNull())
|
||||||
|
{
|
||||||
|
if(!socket->waitForReadyRead())
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QDataStream stream(socket.get());
|
||||||
|
IPCCommand command;
|
||||||
|
QStringList args;
|
||||||
|
stream >> command;
|
||||||
|
stream >> args;
|
||||||
|
if(args.size() < 1)
|
||||||
|
{
|
||||||
|
stream << "invalid";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(command == DocOpen)
|
||||||
|
{
|
||||||
|
if(args.size() < 2)
|
||||||
|
{
|
||||||
|
stream << "invalid";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
docOpen(args[0], args[2].toInt());
|
||||||
|
}
|
||||||
|
if(command == FileOpen)
|
||||||
|
{
|
||||||
|
if(args.size() < 1)
|
||||||
|
{
|
||||||
|
stream << "invalid";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fileOpen(args[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
21
gui/ipcserver.h
Normal file
21
gui/ipcserver.h
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
#ifndef IPCSERVER_H
|
||||||
|
#define IPCSERVER_H
|
||||||
|
#include <QString>
|
||||||
|
#include <QLocalServer>
|
||||||
|
#include "ipc.h"
|
||||||
|
class IpcServer : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
private:
|
||||||
|
QLocalServer spawningServer;
|
||||||
|
bool docOpen(QString path, int pagenum);
|
||||||
|
bool fileOpen(QString path);
|
||||||
|
private slots:
|
||||||
|
void spawnerNewConnection();
|
||||||
|
|
||||||
|
public:
|
||||||
|
IpcServer();
|
||||||
|
bool startSpawner(QString socketPath);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // IPCSERVER_H
|
38
gui/main.cpp
38
gui/main.cpp
@ -2,19 +2,51 @@
|
|||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QStandardPaths>
|
#include <QStandardPaths>
|
||||||
|
#include <QProcess>
|
||||||
|
|
||||||
#include "mainwindow.h"
|
#include "mainwindow.h"
|
||||||
#include "searchresult.h"
|
#include "searchresult.h"
|
||||||
#include "pdfpreview.h"
|
#include "pdfpreview.h"
|
||||||
#include "../shared/common.h"
|
#include "../shared/common.h"
|
||||||
#include "../submodules/qssb.h/qssb.h"
|
#include "../submodules/qssb.h/qssb.h"
|
||||||
|
#include "ipcserver.h"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
QString socketPath = "/tmp/looqs-spawner";
|
||||||
|
if(argc > 1)
|
||||||
|
{
|
||||||
|
QApplication a(argc, argv);
|
||||||
|
QString arg = argv[1];
|
||||||
|
if(arg == "ipc")
|
||||||
|
{
|
||||||
|
IpcServer *ipcserver = new IpcServer();
|
||||||
|
qDebug() << "Launching ipc";
|
||||||
|
if(!ipcserver->startSpawner(socketPath))
|
||||||
|
{
|
||||||
|
qDebug() << "Error failed to spawn";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
qDebug() << "Launched";
|
||||||
|
}
|
||||||
|
return a.exec();
|
||||||
|
}
|
||||||
|
QProcess process;
|
||||||
|
QStringList args;
|
||||||
|
args << "ipc";
|
||||||
|
if(!process.startDetached("/proc/self/exe", args))
|
||||||
|
{
|
||||||
|
QString errorMsg = "Failed to start IPC server";
|
||||||
|
qDebug() << errorMsg;
|
||||||
|
QMessageBox::critical(nullptr, "Error", errorMsg);
|
||||||
|
}
|
||||||
|
|
||||||
struct qssb_policy *policy = qssb_init_policy();
|
struct qssb_policy *policy = qssb_init_policy();
|
||||||
std::string appDataLocation = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation).toStdString();
|
std::string appDataLocation = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation).toStdString();
|
||||||
std::string cacheDataLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation).toStdString();
|
std::string cacheDataLocation = QStandardPaths::writableLocation(QStandardPaths::CacheLocation).toStdString();
|
||||||
|
std::string sockPath = socketPath.toStdString();
|
||||||
policy->namespace_options = QSSB_UNSHARE_NETWORK | QSSB_UNSHARE_USER;
|
policy->namespace_options = QSSB_UNSHARE_NETWORK | QSSB_UNSHARE_USER;
|
||||||
|
|
||||||
qssb_append_path_policy(policy, QSSB_FS_ALLOW_READ | QSSB_FS_ALLOW_REMOVE_FILE, "/");
|
qssb_append_path_policy(policy, QSSB_FS_ALLOW_READ | QSSB_FS_ALLOW_REMOVE_FILE, "/");
|
||||||
qssb_append_path_policy(policy, QSSB_FS_ALLOW_READ | QSSB_FS_ALLOW_REMOVE_FILE | QSSB_FS_ALLOW_WRITE,
|
qssb_append_path_policy(policy, QSSB_FS_ALLOW_READ | QSSB_FS_ALLOW_REMOVE_FILE | QSSB_FS_ALLOW_WRITE,
|
||||||
appDataLocation.c_str());
|
appDataLocation.c_str());
|
||||||
@ -44,7 +76,9 @@ int main(int argc, char *argv[])
|
|||||||
qRegisterMetaType<QVector<SearchResult>>("QVector<SearchResult>");
|
qRegisterMetaType<QVector<SearchResult>>("QVector<SearchResult>");
|
||||||
qRegisterMetaType<QVector<PdfPreview>>("QVector<PdfPreview>");
|
qRegisterMetaType<QVector<PdfPreview>>("QVector<PdfPreview>");
|
||||||
qRegisterMetaType<PdfPreview>("PdfPreview");
|
qRegisterMetaType<PdfPreview>("PdfPreview");
|
||||||
MainWindow w;
|
|
||||||
|
IPCClient client{socketPath};
|
||||||
|
MainWindow w{0, client};
|
||||||
w.showMaximized();
|
w.showMaximized();
|
||||||
|
|
||||||
return a.exec();
|
return a.exec();
|
||||||
|
@ -18,10 +18,11 @@
|
|||||||
#include "../shared/looqsgeneralexception.h"
|
#include "../shared/looqsgeneralexception.h"
|
||||||
#include "../shared/common.h"
|
#include "../shared/common.h"
|
||||||
|
|
||||||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
|
MainWindow::MainWindow(QWidget *parent, IPCClient &client) : QMainWindow(parent), ui(new Ui::MainWindow)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
setWindowTitle(QCoreApplication::applicationName());
|
setWindowTitle(QCoreApplication::applicationName());
|
||||||
|
this->ipcClient = &client;
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
|
|
||||||
db = QSqlDatabase::addDatabase("QSQLITE");
|
db = QSqlDatabase::addDatabase("QSQLITE");
|
||||||
@ -136,29 +137,7 @@ void MainWindow::pdfPreviewReceived(PdfPreview preview)
|
|||||||
label->setPixmap(QPixmap::fromImage(preview.previewImage));
|
label->setPixmap(QPixmap::fromImage(preview.previewImage));
|
||||||
label->setToolTip(preview.documentPath);
|
label->setToolTip(preview.documentPath);
|
||||||
ui->scrollAreaWidgetContents->layout()->addWidget(label);
|
ui->scrollAreaWidgetContents->layout()->addWidget(label);
|
||||||
connect(label, &ClickLabel::leftClick,
|
connect(label, &ClickLabel::leftClick, [this, docPath, previewPage]() { ipcDocOpen(docPath, previewPage); });
|
||||||
[docPath, previewPage]()
|
|
||||||
{
|
|
||||||
QSettings settings;
|
|
||||||
QString command = settings.value("pdfviewer").toString();
|
|
||||||
if(command != "" && command.contains("%p") && command.contains("%f"))
|
|
||||||
{
|
|
||||||
QStringList splitted = command.split(" ");
|
|
||||||
if(splitted.size() > 1)
|
|
||||||
{
|
|
||||||
QString cmd = splitted[0];
|
|
||||||
QStringList args = splitted.mid(1);
|
|
||||||
args.replaceInStrings("%f", docPath);
|
|
||||||
args.replaceInStrings("%p", QString::number(previewPage));
|
|
||||||
|
|
||||||
QProcess::startDetached(cmd, args);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(docPath));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
connect(label, &ClickLabel::rightClick,
|
connect(label, &ClickLabel::rightClick,
|
||||||
[this, docPath, previewPage]()
|
[this, docPath, previewPage]()
|
||||||
{
|
{
|
||||||
@ -301,17 +280,27 @@ void MainWindow::createSearchResutlMenu(QMenu &menu, const QFileInfo &fileInfo)
|
|||||||
[&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.fileName()); });
|
[&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.fileName()); });
|
||||||
menu.addAction("Copy full path to clipboard",
|
menu.addAction("Copy full path to clipboard",
|
||||||
[&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.absoluteFilePath()); });
|
[&fileInfo] { QGuiApplication::clipboard()->setText(fileInfo.absoluteFilePath()); });
|
||||||
menu.addAction("Open containing folder",
|
menu.addAction("Open containing folder", [this, &fileInfo] { this->ipcFileOpen(fileInfo.absolutePath()); });
|
||||||
[&fileInfo]
|
}
|
||||||
{
|
|
||||||
QString dir = fileInfo.absolutePath();
|
void MainWindow::ipcDocOpen(QString path, int num)
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
|
{
|
||||||
});
|
QStringList args;
|
||||||
|
args << path;
|
||||||
|
args << QString::number(num);
|
||||||
|
this->ipcClient->sendCommand(DocOpen, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MainWindow::ipcFileOpen(QString path)
|
||||||
|
{
|
||||||
|
QStringList args;
|
||||||
|
args << path;
|
||||||
|
this->ipcClient->sendCommand(FileOpen, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::treeSearchItemActivated(QTreeWidgetItem *item, int i)
|
void MainWindow::treeSearchItemActivated(QTreeWidgetItem *item, int i)
|
||||||
{
|
{
|
||||||
QDesktopServices::openUrl(QUrl::fromLocalFile(item->text(1)));
|
ipcFileOpen(item->text(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::showSearchResultsContextMenu(const QPoint &point)
|
void MainWindow::showSearchResultsContextMenu(const QPoint &point)
|
||||||
|
@ -8,8 +8,10 @@
|
|||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
#include <QFutureWatcher>
|
#include <QFutureWatcher>
|
||||||
#include <QSqlDatabase>
|
#include <QSqlDatabase>
|
||||||
|
#include <QLocalSocket>
|
||||||
#include "pdfworker.h"
|
#include "pdfworker.h"
|
||||||
#include "../shared/looqsquery.h"
|
#include "../shared/looqsquery.h"
|
||||||
|
#include "ipcclient.h"
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
@ -20,7 +22,7 @@ class MainWindow : public QMainWindow
|
|||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MainWindow(QWidget *parent = 0);
|
explicit MainWindow(QWidget *parent, IPCClient &client);
|
||||||
~MainWindow();
|
~MainWindow();
|
||||||
signals:
|
signals:
|
||||||
void beginSearch(const QString &query);
|
void beginSearch(const QString &query);
|
||||||
@ -28,6 +30,7 @@ class MainWindow : public QMainWindow
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
Ui::MainWindow *ui;
|
Ui::MainWindow *ui;
|
||||||
|
IPCClient *ipcClient;
|
||||||
QFileIconProvider iconProvider;
|
QFileIconProvider iconProvider;
|
||||||
bool pdfDirty;
|
bool pdfDirty;
|
||||||
QSqlDatabase db;
|
QSqlDatabase db;
|
||||||
@ -45,6 +48,9 @@ class MainWindow : public QMainWindow
|
|||||||
LooqsQuery currentQuery;
|
LooqsQuery currentQuery;
|
||||||
int pdfPreviewsPerPage;
|
int pdfPreviewsPerPage;
|
||||||
void createSearchResutlMenu(QMenu &menu, const QFileInfo &fileInfo);
|
void createSearchResutlMenu(QMenu &menu, const QFileInfo &fileInfo);
|
||||||
|
void ipcDocOpen(QString path, int num);
|
||||||
|
void ipcFileOpen(QString path);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void lineEditReturnPressed();
|
void lineEditReturnPressed();
|
||||||
void treeSearchItemActivated(QTreeWidgetItem *item, int i);
|
void treeSearchItemActivated(QTreeWidgetItem *item, int i);
|
||||||
|
@ -13,6 +13,8 @@ TEMPLATE = lib
|
|||||||
CONFIG += staticlib
|
CONFIG += staticlib
|
||||||
CONFIG += c++17
|
CONFIG += c++17
|
||||||
|
|
||||||
|
INCLUDEPATH += $$PWD/../sandbox/qssb.h/
|
||||||
|
|
||||||
# The following define makes your compiler emit warnings if you use
|
# The following define makes your compiler emit warnings if you use
|
||||||
# any feature of Qt which has been marked as deprecated (the exact warnings
|
# any feature of Qt which has been marked as deprecated (the exact warnings
|
||||||
# depend on your compiler). Please consult the documentation of the
|
# depend on your compiler). Please consult the documentation of the
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 75f607bc350354ed31fd0977311917e13241e703
|
Subproject commit 692c9b54b7b5fdca6a416d91d3f34d15af185c33
|
Loading…
Reference in New Issue
Block a user