This commit is contained in:
asivery
2025-10-08 18:47:53 +02:00
parent b8f0b6dd6b
commit d5696ed758
14 changed files with 152 additions and 377 deletions

8
.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
xovi-websocket.cpp
xovi-websocket.h
xovi-networkaccess.h
xovi-networkaccess.cpp
xovi-tokenstore.h
xovi-tokenstore.cpp
*.o
*.so

33
Makefile Normal file
View File

@@ -0,0 +1,33 @@
CC += -D_GNU_SOURCE -fPIC
CXX += -D_GNU_SOURCE -fPIC
CXXFLAGS=$(shell pkg-config --cflags --libs Qt6Network Qt6WebSockets)
VPATH = src
all: rmfakecloud_ns rmfakecloud_ws rmfakecloud_ts
objects_networkaccess = networkaccess-part.o xovi-networkaccess.o
rmfakecloud_ns : $(objects_networkaccess)
${CC} ${CFLAGS} -shared -o rmfakecloud_ns.so $(objects_networkaccess)
xovi-networkaccess.cpp xovi-networkaccess.h &: rmfakecloud-networkaccess.xovi
python3 ${XOVI_REPO}/util/xovigen.py -o xovi-networkaccess.cpp -H xovi-networkaccess.h rmfakecloud-networkaccess.xovi
networkaccess-part.o : xovi-networkaccess.h src/networkaccess-part.cpp src/commons.cpp
objects_websocket = websocket-part.o xovi-websocket.o
rmfakecloud_ws : $(objects_websocket)
${CC} ${CFLAGS} -shared -o rmfakecloud_ws.so $(objects_websocket)
xovi-websocket.cpp xovi-websocket.h &: rmfakecloud-websocket.xovi
python3 ${XOVI_REPO}/util/xovigen.py -o xovi-websocket.cpp -H xovi-websocket.h rmfakecloud-websocket.xovi
websocket-part.o : xovi-websocket.h src/websocket-part.cpp src/commons.cpp
objects_tokenstore = tokenstore-part.o xovi-tokenstore.o
rmfakecloud_ts : $(objects_tokenstore)
${CC} ${CFLAGS} -shared -o rmfakecloud_ts.so $(objects_tokenstore)
xovi-tokenstore.cpp xovi-tokenstore.h &: rmfakecloud-tokenstore.xovi
python3 ${XOVI_REPO}/util/xovigen.py -o xovi-tokenstore.cpp -H xovi-tokenstore.h rmfakecloud-tokenstore.xovi
tokenstore-part.o : xovi-tokenstore.h src/tokenstore-part.cpp
.PHONY : clean
clean :
rm -f rmfakecloud_ns.so rmfakecloud_ws.so rmfakecloud_ts.so $(objects_networkaccess) $(objects_websocket) $(objects_tokenstore) xovi-*.cpp xovi-*.h

View File

@@ -1,6 +0,0 @@
set -euxo pipefail
python3 ../xovi/util/xovigen.py -o xovi.c -H xovi.h rmfakecloud.xovi
python3 ../xovi/util/xovigen.py -o websocket-xovi.c -H websocket-xovi.h websocket.xovi
$CC -shared -fPIC main.cpp xovi.c `pkg-config --cflags --libs Qt6Network` -o rmfakecloud.so
$CC -shared -fPIC websocket.cpp websocket-xovi.c `pkg-config --cflags --libs Qt6Network Qt6WebSockets` -o rmfakecloud-websocket.so

View File

@@ -1,4 +1,5 @@
version 1.0.1
version 1.1.0
import? _ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice
override _ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice

View File

@@ -0,0 +1,8 @@
version 1.1.0
import? _ZNK9QSettings5valueE14QAnyStringViewRK8QVariant>QVariant
override _ZNK9QSettings5valueE14QAnyStringViewRK8QVariant
import? _ZNK9QSettings5valueE14QAnyStringView>QVariant
override _ZNK9QSettings5valueE14QAnyStringView
import? _ZN9QSettings8setValueE14QAnyStringViewRK8QVariant
override _ZN9QSettings8setValueE14QAnyStringViewRK8QVariant

View File

@@ -1,4 +1,4 @@
version 1.0.1
version 1.1.0
import? _ZN10QWebSocket4openERK15QNetworkRequest
override _ZN10QWebSocket4openERK15QNetworkRequest

45
src/commons.cpp Normal file
View File

@@ -0,0 +1,45 @@
#pragma once
#include <QSettings>
#include <QFile>
#include <QVariant>
#include <iostream>
#define NAME "rmfakecloud"
static QString newRMFCHostName = NULL;
static int newRMFCPort;
extern "C" void _xovi_construct() {
char *configRoot = Environment->getExtensionDirectory(NAME);
// Load the config file and read the host.
QString configFile(configRoot);
configFile += "config.conf";
QSettings extensionConfig(configFile, QSettings::IniFormat);
QString newRMFCHostNameQStr = extensionConfig.value("host").toString();
if (newRMFCHostNameQStr == "") {
std::cerr << "[" << NAME << "] No host defined in the config file!";
abort();
}
std::cerr << "[" << NAME << "] New host set to: " << newRMFCHostNameQStr.toStdString();
newRMFCHostName = newRMFCHostNameQStr;
bool ok;
newRMFCPort = extensionConfig.value("port").toInt(&ok);
if(!ok) newRMFCPort = -1; // Default.
// Load our CA to the global cert store.
QString caCertFileName(configRoot);
caCertFileName += "ca.pem";
QFile caFile(caCertFileName);
if (caFile.open(QIODevice::ReadOnly)) {
const QByteArray caBytes = caFile.readAll();
const QSslCertificate certificate(caBytes);
QSslConfiguration config = QSslConfiguration::defaultConfiguration();
auto globalCerts = config.caCertificates();
globalCerts.append(certificate);
config.setCaCertificates(globalCerts);
QSslConfiguration::setDefaultConfiguration(config);
} else {
std::cerr << "[" << NAME << "] Failed to open CA file!";
}
free(configRoot);
}

View File

@@ -3,7 +3,8 @@
#include <QNetworkReply>
#include <QDebug>
#include <QIODevice>
#include "xovi.h"
#include "../xovi-networkaccess.h"
#include "commons.cpp"
extern "C" QNetworkReply* override$_ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice(
QNetworkAccessManager* self,
@@ -11,17 +12,16 @@ extern "C" QNetworkReply* override$_ZN21QNetworkAccessManager13createRequestENS_
const QNetworkRequest& req,
QIODevice* outgoingData
) {
const char* host = std::getenv("RMFAKECLOUD_HOST");
// set new url
QUrl newUrl = req.url();
newUrl.setHost(QString(host));
newUrl.setHost(newRMFCHostName);
newUrl.setPort(newRMFCPort);
// create a new request, so we don't have to modify the original request
QNetworkRequest newReq(req);
newReq.setUrl(newUrl);
// get original function signature
// get original function signature
using CreateFn = QNetworkReply*(*)(QNetworkAccessManager*,
QNetworkAccessManager::Operation,
const QNetworkRequest&,
@@ -33,13 +33,3 @@ extern "C" QNetworkReply* override$_ZN21QNetworkAccessManager13createRequestENS_
// call original function, and return the result
return orig(self, op, newReq, outgoingData);
}
extern "C" void _xovi_construct() {
const char* host = std::getenv("RMFAKECLOUD_HOST");
if (host == NULL) {
qCritical() << "[rmfakecloud] Environment variable \"RMFAKECLOUD_HOST\" not set!";
abort();
}
qDebug() << "Loading rmfakecloud by Tiebe. Using host " << host;
}

46
src/tokenstore-part.cpp Normal file
View File

@@ -0,0 +1,46 @@
#define NAME "rmfakecloud"
#include <QSettings>
#include <QFile>
#include <QVariant>
#include <iostream>
#include "../xovi-tokenstore.h"
extern "C" {
static QSettings *tokenStorage;
void _xovi_construct() {
char *configRoot = Environment->getExtensionDirectory(NAME);
// Prepare the token storage (leak object)
QString tokenFile(configRoot);
tokenFile += "tokens.conf";
tokenStorage = new QSettings(tokenFile, QSettings::IniFormat);
free(configRoot);
}
static inline bool checkKey(void **that, QAnyStringView &key) {
if(key == "devicetoken" || key == "UserToken") {
*that = tokenStorage;
return true;
}
return false;
}
QVariant override$_ZNK9QSettings5valueE14QAnyStringView(void *that, QAnyStringView key) {
checkKey(&that, key);
return $_ZNK9QSettings5valueE14QAnyStringView(that, key);
}
QVariant override$_ZNK9QSettings5valueE14QAnyStringViewRK8QVariant(void *that, QAnyStringView key, const QVariant &defaultValue) {
checkKey(&that, key);
return $_ZNK9QSettings5valueE14QAnyStringViewRK8QVariant(that, key, defaultValue);
}
void override$_ZN9QSettings8setValueE14QAnyStringViewRK8QVariant(void *that, QAnyStringView key, const QVariant &value) {
bool sync = checkKey(&that, key);
$_ZN9QSettings8setValueE14QAnyStringViewRK8QVariant(that, key, value);
if(sync) {
tokenStorage->sync();
}
}
}

View File

@@ -4,17 +4,17 @@
#include <QDebug>
#include <QIODevice>
#include <QWebSocket>
#include "websocket-xovi.h"
#include "../xovi-websocket.h"
#include "commons.cpp"
extern "C" void override$_ZN10QWebSocket4openERK15QNetworkRequest(
QWebSocket* self,
const QNetworkRequest& req
) {
const char* host = std::getenv("RMFAKECLOUD_HOST");
// set new url
QUrl newUrl = req.url();
newUrl.setHost(QString(host));
newUrl.setHost(newRMFCHostName);
newUrl.setPort(newRMFCPort);
// create a new request, so we don't have to modify the original request
QNetworkRequest newReq(req);
@@ -30,13 +30,3 @@ extern "C" void override$_ZN10QWebSocket4openERK15QNetworkRequest(
// call original function, and return the result
orig(self, newReq);
}
extern "C" void _xovi_construct() {
const char* host = std::getenv("RMFAKECLOUD_HOST");
if (host == NULL) {
qCritical() << "[rmfakecloud-websocket] Environment variable \"RMFAKECLOUD_HOST\" not set!";
abort();
}
qDebug() << "Loading rmfakecloud-websocket by Tiebe. Using host " << host;
}

View File

@@ -1,92 +0,0 @@
// This file is autogenerated. Please do not alter it manually and instead run xovigen.py.
// XOVI extension / module base file
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XOVI_PUBLIC_API
#define XOVI_PUBLIC_API
#define XOVI_VERSION "0.2.0"
#include <stdbool.h>
#define LP1_F_TYPE_EXPORT 1
#define LP1_F_TYPE_IMPORT 2
#define LP1_F_TYPE_OVERRIDE 3
#define LP1_F_TYPE_CONDITION 4
#define METADATA_TYPE_INT 1
#define METADATA_TYPE_BOOL 2
#define METADATA_TYPE_STRING 3
typedef union {
int i;
bool b;
struct {
int sLength;
const char *s;
};
} XoviMetadataValue;
struct XoviMetadataEntry {
const char *name;
char type;
XoviMetadataValue value;
};
// Public version of the metadata iterator.
struct ExtensionMetadataIterator {
const char *extensionName;
const char *functionName;
void *functionAddress;
char OPAQUE[sizeof(void *) * 4 + sizeof(bool)];
};
struct XoViEnvironment {
char *(*getExtensionDirectory)(const char *family);
void (*requireExtension)(const char *name, unsigned char major, unsigned char minor, unsigned char patch);
// 0.2.0 API - metadata:
int (*getExtensionCount)();
int (*getExtensionNames)(const char **table, int maxCount);
int (*getExtensionFunctionCount)(const char *key);
int (*getExtensionFunctionNames)(const char *extension, const char **table, int maxCount);
int (*getMetadataEntriesCountForFunction)(const char *extension, const char *function, int functionType);
struct XoviMetadataEntry **(*getMetadataChainForFunction)(const char *extension, const char *function, int functionType);
struct XoviMetadataEntry *(*getMetadataEntryForFunction)(const char *extension, const char *function, int functionType, const char *metadataEntryName);
void (*createMetadataSearchingIterator)(struct ExtensionMetadataIterator *iterator, const char *metadataEntryName);
struct XoviMetadataEntry *(*nextFunctionMetadataEntry)(struct ExtensionMetadataIterator *iterator);
};
#endif
// Deps
extern void override$_ZN10QWebSocket4openERK15QNetworkRequest();
// XOVI metadata
__attribute__((section(".xovi"))) const char *LINKTABLENAMES = "C_ZN10QWebSocket4openERK15QNetworkRequest\0I_ZN10QWebSocket4openERK15QNetworkRequest\0O_ZN10QWebSocket4openERK15QNetworkRequest\0\0";
__attribute__((section(".xovi"))) const void *LINKTABLEVALUES[] = { (void *) 3, (void *) 0, (void *) 0, (void *) override$_ZN10QWebSocket4openERK15QNetworkRequest };
__attribute__((section(".xovi"))) const void *Environment = 0;
__attribute__((section(".xovi_info"))) const int EXTENSIONVERSION = 65537;
__attribute__((section(".xovi_info"))) const char __XOVIMETADATANAMES[] = "";
// Raw Metadata Entries
// Metadata Chains
// Main metadata list
__attribute__((section(".xovi"))) const struct XoviMetadataEntry **METADATAVALUES[] = {
(const struct XoviMetadataEntry **) 0,
(const struct XoviMetadataEntry **) 0,
(const struct XoviMetadataEntry **) 0,
(const struct XoviMetadataEntry **) 0, (const struct XoviMetadataEntry **) 1
};
// Resources
#ifdef __cplusplus
}
#endif

View File

@@ -1,78 +0,0 @@
// XOVI project import / resource header file. This file is autogenerated. Do not edit.
#ifndef _XOVIGEN
#define _XOVIGEN
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XOVI_PUBLIC_API
#define XOVI_PUBLIC_API
#define XOVI_VERSION "0.2.0"
#include <stdbool.h>
#define LP1_F_TYPE_EXPORT 1
#define LP1_F_TYPE_IMPORT 2
#define LP1_F_TYPE_OVERRIDE 3
#define LP1_F_TYPE_CONDITION 4
#define METADATA_TYPE_INT 1
#define METADATA_TYPE_BOOL 2
#define METADATA_TYPE_STRING 3
typedef union {
int i;
bool b;
struct {
int sLength;
const char *s;
};
} XoviMetadataValue;
struct XoviMetadataEntry {
const char *name;
char type;
XoviMetadataValue value;
};
// Public version of the metadata iterator.
struct ExtensionMetadataIterator {
const char *extensionName;
const char *functionName;
void *functionAddress;
char OPAQUE[sizeof(void *) * 4 + sizeof(bool)];
};
struct XoViEnvironment {
char *(*getExtensionDirectory)(const char *family);
void (*requireExtension)(const char *name, unsigned char major, unsigned char minor, unsigned char patch);
// 0.2.0 API - metadata:
int (*getExtensionCount)();
int (*getExtensionNames)(const char **table, int maxCount);
int (*getExtensionFunctionCount)(const char *key);
int (*getExtensionFunctionNames)(const char *extension, const char **table, int maxCount);
int (*getMetadataEntriesCountForFunction)(const char *extension, const char *function, int functionType);
struct XoviMetadataEntry **(*getMetadataChainForFunction)(const char *extension, const char *function, int functionType);
struct XoviMetadataEntry *(*getMetadataEntryForFunction)(const char *extension, const char *function, int functionType, const char *metadataEntryName);
void (*createMetadataSearchingIterator)(struct ExtensionMetadataIterator *iterator, const char *metadataEntryName);
struct XoviMetadataEntry *(*nextFunctionMetadataEntry)(struct ExtensionMetadataIterator *iterator);
};
#endif
extern const void *LINKTABLEVALUES[];
// Imports
#define $_ZN10QWebSocket4openERK15QNetworkRequest ((unsigned long long int (*)()) LINKTABLEVALUES[2])
// Resources
// Environment
extern const struct XoViEnvironment *Environment;
#ifdef __cplusplus
}
#endif
#endif

92
xovi.c
View File

@@ -1,92 +0,0 @@
// This file is autogenerated. Please do not alter it manually and instead run xovigen.py.
// XOVI extension / module base file
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XOVI_PUBLIC_API
#define XOVI_PUBLIC_API
#define XOVI_VERSION "0.2.0"
#include <stdbool.h>
#define LP1_F_TYPE_EXPORT 1
#define LP1_F_TYPE_IMPORT 2
#define LP1_F_TYPE_OVERRIDE 3
#define LP1_F_TYPE_CONDITION 4
#define METADATA_TYPE_INT 1
#define METADATA_TYPE_BOOL 2
#define METADATA_TYPE_STRING 3
typedef union {
int i;
bool b;
struct {
int sLength;
const char *s;
};
} XoviMetadataValue;
struct XoviMetadataEntry {
const char *name;
char type;
XoviMetadataValue value;
};
// Public version of the metadata iterator.
struct ExtensionMetadataIterator {
const char *extensionName;
const char *functionName;
void *functionAddress;
char OPAQUE[sizeof(void *) * 4 + sizeof(bool)];
};
struct XoViEnvironment {
char *(*getExtensionDirectory)(const char *family);
void (*requireExtension)(const char *name, unsigned char major, unsigned char minor, unsigned char patch);
// 0.2.0 API - metadata:
int (*getExtensionCount)();
int (*getExtensionNames)(const char **table, int maxCount);
int (*getExtensionFunctionCount)(const char *key);
int (*getExtensionFunctionNames)(const char *extension, const char **table, int maxCount);
int (*getMetadataEntriesCountForFunction)(const char *extension, const char *function, int functionType);
struct XoviMetadataEntry **(*getMetadataChainForFunction)(const char *extension, const char *function, int functionType);
struct XoviMetadataEntry *(*getMetadataEntryForFunction)(const char *extension, const char *function, int functionType, const char *metadataEntryName);
void (*createMetadataSearchingIterator)(struct ExtensionMetadataIterator *iterator, const char *metadataEntryName);
struct XoviMetadataEntry *(*nextFunctionMetadataEntry)(struct ExtensionMetadataIterator *iterator);
};
#endif
// Deps
extern void override$_ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice();
// XOVI metadata
__attribute__((section(".xovi"))) const char *LINKTABLENAMES = "C_ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice\0I_ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice\0O_ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice\0\0";
__attribute__((section(".xovi"))) const void *LINKTABLEVALUES[] = { (void *) 3, (void *) 0, (void *) 0, (void *) override$_ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice };
__attribute__((section(".xovi"))) const void *Environment = 0;
__attribute__((section(".xovi_info"))) const int EXTENSIONVERSION = 65537;
__attribute__((section(".xovi_info"))) const char __XOVIMETADATANAMES[] = "";
// Raw Metadata Entries
// Metadata Chains
// Main metadata list
__attribute__((section(".xovi"))) const struct XoviMetadataEntry **METADATAVALUES[] = {
(const struct XoviMetadataEntry **) 0,
(const struct XoviMetadataEntry **) 0,
(const struct XoviMetadataEntry **) 0,
(const struct XoviMetadataEntry **) 0, (const struct XoviMetadataEntry **) 1
};
// Resources
#ifdef __cplusplus
}
#endif

78
xovi.h
View File

@@ -1,78 +0,0 @@
// XOVI project import / resource header file. This file is autogenerated. Do not edit.
#ifndef _XOVIGEN
#define _XOVIGEN
#ifdef __cplusplus
extern "C" {
#endif
#ifndef XOVI_PUBLIC_API
#define XOVI_PUBLIC_API
#define XOVI_VERSION "0.2.0"
#include <stdbool.h>
#define LP1_F_TYPE_EXPORT 1
#define LP1_F_TYPE_IMPORT 2
#define LP1_F_TYPE_OVERRIDE 3
#define LP1_F_TYPE_CONDITION 4
#define METADATA_TYPE_INT 1
#define METADATA_TYPE_BOOL 2
#define METADATA_TYPE_STRING 3
typedef union {
int i;
bool b;
struct {
int sLength;
const char *s;
};
} XoviMetadataValue;
struct XoviMetadataEntry {
const char *name;
char type;
XoviMetadataValue value;
};
// Public version of the metadata iterator.
struct ExtensionMetadataIterator {
const char *extensionName;
const char *functionName;
void *functionAddress;
char OPAQUE[sizeof(void *) * 4 + sizeof(bool)];
};
struct XoViEnvironment {
char *(*getExtensionDirectory)(const char *family);
void (*requireExtension)(const char *name, unsigned char major, unsigned char minor, unsigned char patch);
// 0.2.0 API - metadata:
int (*getExtensionCount)();
int (*getExtensionNames)(const char **table, int maxCount);
int (*getExtensionFunctionCount)(const char *key);
int (*getExtensionFunctionNames)(const char *extension, const char **table, int maxCount);
int (*getMetadataEntriesCountForFunction)(const char *extension, const char *function, int functionType);
struct XoviMetadataEntry **(*getMetadataChainForFunction)(const char *extension, const char *function, int functionType);
struct XoviMetadataEntry *(*getMetadataEntryForFunction)(const char *extension, const char *function, int functionType, const char *metadataEntryName);
void (*createMetadataSearchingIterator)(struct ExtensionMetadataIterator *iterator, const char *metadataEntryName);
struct XoviMetadataEntry *(*nextFunctionMetadataEntry)(struct ExtensionMetadataIterator *iterator);
};
#endif
extern const void *LINKTABLEVALUES[];
// Imports
#define $_ZN21QNetworkAccessManager13createRequestENS_9OperationERK15QNetworkRequestP9QIODevice ((unsigned long long int (*)()) LINKTABLEVALUES[2])
// Resources
// Environment
extern const struct XoViEnvironment *Environment;
#ifdef __cplusplus
}
#endif
#endif