2021-05-19 12:08:57 +02:00
|
|
|
#include "Message.h"
|
|
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <cassert>
|
|
|
|
|
|
2021-08-14 17:13:41 +02:00
|
|
|
#include <QDebug>
|
|
|
|
|
|
2021-05-19 12:08:57 +02:00
|
|
|
enum FieldType {
|
2024-02-21 11:21:37 +01:00
|
|
|
JailId = 1,
|
2021-05-19 12:08:57 +02:00
|
|
|
ExecutablePath = 10,
|
2021-08-14 22:00:42 +02:00
|
|
|
Argument,
|
2024-02-24 11:40:42 +01:00
|
|
|
InitScript,
|
2024-05-17 11:39:44 +02:00
|
|
|
JailPassword, // The jaildir is encfs encrypted. Decrypt password.
|
2021-08-14 22:00:42 +02:00
|
|
|
|
2024-02-20 19:14:25 +01:00
|
|
|
IsTry = 20, // allow next command to fail
|
|
|
|
|
RBindMountSource, // mount from an existing directory.
|
2021-08-14 22:00:42 +02:00
|
|
|
RBindMountDest,
|
2024-02-20 19:14:25 +01:00
|
|
|
UnMountDir, // unmount (remove) an existing mountpoint.
|
|
|
|
|
CreateTmpFs, // with the full path as arg
|
2024-02-16 16:54:09 +01:00
|
|
|
|
|
|
|
|
CopyFrom = 30,
|
|
|
|
|
CopyTo,
|
2024-02-17 01:03:43 +01:00
|
|
|
|
2024-02-20 19:14:25 +01:00
|
|
|
EnvironUnset = 35, // an env-var we want to filter
|
|
|
|
|
EnvironSet, // override env-var value.
|
|
|
|
|
|
|
|
|
|
DBusProxyFrom = 40, // start the xdg-dbus-proxy between from and to
|
|
|
|
|
DBusProxyTo,
|
|
|
|
|
DBusProxySystemFrom, // start the dbus proxy with system rules
|
|
|
|
|
DBusProxySystemTo,
|
2026-04-11 14:54:32 +02:00
|
|
|
|
|
|
|
|
VpnConfig = 50, // base path to vpn files (inside jail)
|
|
|
|
|
VpnHasPassFile = 51, // has a password file in the jail
|
2021-05-19 12:08:57 +02:00
|
|
|
};
|
|
|
|
|
|
2024-02-16 16:54:09 +01:00
|
|
|
// returns the length of the string, or throw if no closing zero found
|
|
|
|
|
static int stringLength(const char *from, const char *end)
|
|
|
|
|
{
|
|
|
|
|
auto at = from;
|
|
|
|
|
while (at <= end) {
|
|
|
|
|
if (*at == 0)
|
|
|
|
|
return at - from;
|
|
|
|
|
++at;
|
|
|
|
|
}
|
|
|
|
|
throw std::runtime_error("unterminated string found");
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-19 12:08:57 +02:00
|
|
|
Message::Message(int size)
|
|
|
|
|
: m_reservedSize(size)
|
|
|
|
|
{
|
|
|
|
|
assert(size > 0);
|
|
|
|
|
m_buf = std::shared_ptr<char>(new char[size], std::default_delete<char[]>());
|
|
|
|
|
m_writePtr = m_buf.get();
|
2021-08-14 22:53:51 +02:00
|
|
|
memset(m_writePtr, 0, m_reservedSize);
|
2021-05-19 12:08:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Message::Message(char *buffer, int bufferSize)
|
|
|
|
|
: m_reservedSize(bufferSize)
|
|
|
|
|
{
|
|
|
|
|
m_buf = std::shared_ptr<char>(new char[bufferSize], std::default_delete<char[]>());
|
|
|
|
|
memcpy(m_buf.get(), buffer, bufferSize);
|
2021-05-21 15:28:57 +02:00
|
|
|
buffer = m_buf.get();
|
2021-05-19 12:08:57 +02:00
|
|
|
|
|
|
|
|
const char *end = buffer + bufferSize;
|
|
|
|
|
while (buffer < end) {
|
|
|
|
|
if (*buffer == ExecutablePath) {
|
|
|
|
|
m_path = buffer + 1;
|
|
|
|
|
}
|
2021-05-21 15:28:57 +02:00
|
|
|
else if (*buffer == Argument) {
|
2021-08-14 22:00:42 +02:00
|
|
|
break;
|
2021-05-19 12:08:57 +02:00
|
|
|
}
|
2024-02-17 01:03:43 +01:00
|
|
|
const int len = ::stringLength(buffer + 1, end);
|
2021-05-19 12:08:57 +02:00
|
|
|
if (buffer + len + 2 > end) {
|
|
|
|
|
throw std::runtime_error("buffer too small");
|
|
|
|
|
}
|
|
|
|
|
buffer += len + 2;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
char *Message::path() const
|
|
|
|
|
{
|
|
|
|
|
return m_path;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Message::setPath(const std::string &path)
|
|
|
|
|
{
|
|
|
|
|
m_path = m_writePtr + 1;
|
|
|
|
|
addString(ExecutablePath, path);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-21 15:28:57 +02:00
|
|
|
void Message::addArgument(const char *string)
|
|
|
|
|
{
|
|
|
|
|
addString(Argument, string);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-14 17:13:41 +02:00
|
|
|
void Message::printFields() const
|
|
|
|
|
{
|
|
|
|
|
#ifndef NDEBUG
|
2021-08-14 22:00:42 +02:00
|
|
|
qDebug().nospace() << "Message[" << path() << "] " << size() << " bytes";
|
|
|
|
|
|
|
|
|
|
const char *buffer = m_buf.get();
|
|
|
|
|
const char *end = buffer + m_reservedSize;
|
|
|
|
|
while (buffer < end) {
|
|
|
|
|
std::string prefix;
|
|
|
|
|
const char type = *buffer;
|
2024-02-16 16:54:09 +01:00
|
|
|
if (type == Argument) {
|
2021-08-14 22:00:42 +02:00
|
|
|
prefix = "argument:";
|
|
|
|
|
}
|
|
|
|
|
else if (type == RBindMountSource) {
|
|
|
|
|
prefix = "rbind-src: ";
|
|
|
|
|
}
|
|
|
|
|
else if (type == RBindMountDest) {
|
|
|
|
|
prefix = "rbind-dst: ";
|
|
|
|
|
}
|
|
|
|
|
else if (type == UnMountDir) {
|
|
|
|
|
prefix = "umountDir: ";
|
|
|
|
|
}
|
2024-02-15 23:39:04 +01:00
|
|
|
else if (type == CreateTmpFs) {
|
|
|
|
|
prefix = "tmpFs-create: ";
|
|
|
|
|
}
|
2024-02-16 16:54:09 +01:00
|
|
|
else if (type == CopyFrom) {
|
|
|
|
|
prefix = "copyFrom: ";
|
|
|
|
|
}
|
|
|
|
|
else if (type == CopyTo) {
|
|
|
|
|
prefix = "copyTo: ";
|
|
|
|
|
}
|
2024-02-17 01:03:43 +01:00
|
|
|
else if (type == EnvironSet) {
|
|
|
|
|
prefix = "New Env: ";
|
|
|
|
|
}
|
|
|
|
|
else if (type == EnvironUnset) {
|
|
|
|
|
prefix = "Filter Env: ";
|
|
|
|
|
}
|
2024-02-20 19:14:25 +01:00
|
|
|
else if (type == DBusProxyFrom) {
|
|
|
|
|
prefix = "dbus-from: ";
|
|
|
|
|
}
|
|
|
|
|
else if (type == DBusProxySystemFrom) {
|
|
|
|
|
prefix = "dbus-system-from: ";
|
|
|
|
|
}
|
|
|
|
|
else if (type == DBusProxyTo) {
|
|
|
|
|
prefix = "dbus-to: ";
|
|
|
|
|
}
|
|
|
|
|
else if (type == DBusProxySystemTo) {
|
|
|
|
|
prefix = "dbus-system-to: ";
|
|
|
|
|
}
|
2026-04-11 14:54:32 +02:00
|
|
|
else if (type == VpnConfig) {
|
|
|
|
|
prefix = "vpn-config: ";
|
|
|
|
|
}
|
2024-02-21 11:21:37 +01:00
|
|
|
else if (type == JailId) {
|
2026-04-11 14:47:24 +02:00
|
|
|
// This only works if the source and destination have the same endian-ness
|
|
|
|
|
// as the basic design places them in the same exe just forked into two
|
|
|
|
|
// processes, this is not a concern.
|
2024-02-21 11:21:37 +01:00
|
|
|
uint32_t data = buffer[4];
|
|
|
|
|
data <<= 8;
|
|
|
|
|
data += buffer[3];
|
|
|
|
|
data <<= 8;
|
|
|
|
|
data += buffer[2];
|
|
|
|
|
data <<= 8;
|
|
|
|
|
data += buffer[1];
|
|
|
|
|
buffer += 5;
|
|
|
|
|
qDebug() << "=> JailId:" << data;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2026-04-11 14:54:32 +02:00
|
|
|
else if (type == VpnHasPassFile) { // bool
|
|
|
|
|
qDebug() << "=> hasPassFile:" << (buffer[1] != 0);
|
|
|
|
|
buffer += 2;
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2021-08-14 22:00:42 +02:00
|
|
|
else if (type == 0) {
|
|
|
|
|
qDebug() << Qt::endl;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-02-17 01:03:43 +01:00
|
|
|
const int len = ::stringLength(buffer + 1, end);
|
2021-08-14 22:00:42 +02:00
|
|
|
if (buffer + len + 2 > end) {
|
|
|
|
|
qWarning() << "buffer overrun detected, str len:" << len;
|
|
|
|
|
return;
|
|
|
|
|
}
|
2024-02-15 23:39:04 +01:00
|
|
|
if (type == IsTry) {
|
|
|
|
|
qWarning() << " try";
|
2024-02-16 09:00:15 +01:00
|
|
|
buffer += 1;
|
|
|
|
|
continue;
|
2024-02-15 23:39:04 +01:00
|
|
|
}
|
|
|
|
|
else if (type != ExecutablePath) {
|
2021-08-14 22:00:42 +02:00
|
|
|
qWarning() << " " << prefix.c_str() << QString::fromLocal8Bit(buffer + 1, len);
|
|
|
|
|
}
|
|
|
|
|
buffer += len + 2;
|
2021-08-14 17:13:41 +02:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-19 12:08:57 +02:00
|
|
|
char *Message::begin() const
|
|
|
|
|
{
|
|
|
|
|
return m_buf.get();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Message::size() const
|
|
|
|
|
{
|
|
|
|
|
if (m_writePtr)
|
|
|
|
|
return m_writePtr - m_buf.get();
|
|
|
|
|
return m_reservedSize;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-14 22:00:42 +02:00
|
|
|
void Message::addUmountPoint(const std::string &dir)
|
|
|
|
|
{
|
|
|
|
|
addString(UnMountDir, dir);
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-14 23:26:47 +02:00
|
|
|
void Message::addRemount(const std::string &source, const std::string &destination)
|
2021-08-14 22:00:42 +02:00
|
|
|
{
|
|
|
|
|
addString(RBindMountSource, source); // always first
|
|
|
|
|
addString(RBindMountDest, destination); // make sure this is last as it 'executes' the whole thing.
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-15 23:39:04 +01:00
|
|
|
void Message::setTry(bool isTry)
|
|
|
|
|
{
|
|
|
|
|
if (isTry)
|
|
|
|
|
addTag(IsTry); // always first
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 11:21:37 +01:00
|
|
|
void Message::setJailId(uint32_t jailId)
|
|
|
|
|
{
|
|
|
|
|
assert(m_writePtr);
|
|
|
|
|
if (m_buf.get() + m_reservedSize < m_writePtr + 5) {
|
|
|
|
|
throw std::runtime_error("jailId does not fit buffer");
|
|
|
|
|
}
|
2026-04-11 14:47:24 +02:00
|
|
|
// This only works if the source and destination have the same endian-ness
|
|
|
|
|
// as the basic design places them in the same exe just forked into two
|
|
|
|
|
// processes, this is not a concern.
|
2024-02-21 11:21:37 +01:00
|
|
|
m_writePtr[0] = JailId;
|
2026-04-11 14:47:24 +02:00
|
|
|
m_writePtr[1] = jailId & 0xFF;
|
|
|
|
|
m_writePtr[2] = (jailId >> 8) & 0xFF;
|
|
|
|
|
m_writePtr[3] = (jailId >> 16) & 0xFF;
|
|
|
|
|
m_writePtr[4] = (jailId >> 24) & 0xFF;
|
2024-02-21 11:21:37 +01:00
|
|
|
m_writePtr += 5;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-15 23:39:04 +01:00
|
|
|
void Message::addMountTmpDir(const std::string &dir)
|
|
|
|
|
{
|
|
|
|
|
addString(CreateTmpFs, dir);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 16:54:09 +01:00
|
|
|
void Message::addCopy(const std::string &from, const std::string &to)
|
|
|
|
|
{
|
|
|
|
|
addString(CopyFrom, from);
|
|
|
|
|
addString(CopyTo, to);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-24 11:40:42 +01:00
|
|
|
void Message::addInitSript(const std::string &text)
|
|
|
|
|
{
|
|
|
|
|
addString(InitScript, text);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-17 01:03:43 +01:00
|
|
|
void Message::addEnvToUnset(const std::string &propertyName)
|
|
|
|
|
{
|
|
|
|
|
assert(propertyName.find('=') == std::string::npos);
|
|
|
|
|
addString(EnvironUnset, propertyName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Message::addEnvToSet(const std::string &envVar)
|
|
|
|
|
{
|
|
|
|
|
assert(envVar.find('=') != std::string::npos);
|
|
|
|
|
addString(EnvironSet, envVar);
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-17 11:39:44 +02:00
|
|
|
void Message::setJailPassword(const std::string &pwd)
|
|
|
|
|
{
|
|
|
|
|
addString(JailPassword, pwd);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 19:14:25 +01:00
|
|
|
void Message::addDBusProxy(DBusType type, const std::string &from, const std::string &to)
|
|
|
|
|
{
|
|
|
|
|
addString(type == UserSessionBus ? DBusProxyFrom : DBusProxySystemFrom, from);
|
|
|
|
|
addString(type == UserSessionBus ? DBusProxyTo : DBusProxySystemTo, to);
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 14:54:32 +02:00
|
|
|
void Message::setVpnConfig(const std::string &configPath)
|
|
|
|
|
{
|
|
|
|
|
addString(VpnConfig, configPath);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Message::setHasVpnPassFile(bool yes)
|
|
|
|
|
{
|
|
|
|
|
assert(m_writePtr);
|
|
|
|
|
if (m_buf.get() + m_reservedSize < m_writePtr + 2)
|
|
|
|
|
throw std::runtime_error("Bool does not fit buffer");
|
|
|
|
|
m_writePtr[0] = VpnHasPassFile;
|
|
|
|
|
m_writePtr[1] = yes ? 1 : 0;
|
|
|
|
|
m_writePtr += 2;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-15 23:39:04 +01:00
|
|
|
void Message::addTag(char type)
|
|
|
|
|
{
|
|
|
|
|
assert(m_writePtr);
|
|
|
|
|
if (m_buf.get() + m_reservedSize < m_writePtr + 1) {
|
|
|
|
|
throw std::runtime_error("Tag does not fit buffer");
|
|
|
|
|
}
|
2024-02-16 09:00:15 +01:00
|
|
|
*m_writePtr = type;
|
2024-02-15 23:39:04 +01:00
|
|
|
++m_writePtr;
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-19 12:08:57 +02:00
|
|
|
void Message::addString(char type, const std::string &string)
|
|
|
|
|
{
|
|
|
|
|
assert(m_writePtr);
|
|
|
|
|
if (m_buf.get() + m_reservedSize < m_writePtr + string.size() + 2) {
|
|
|
|
|
// won't fit.
|
|
|
|
|
throw std::runtime_error("String does not fit buffer");
|
|
|
|
|
}
|
|
|
|
|
m_writePtr[0] = type;
|
2021-05-21 15:28:57 +02:00
|
|
|
memcpy(++m_writePtr, string.c_str(), string.size());
|
|
|
|
|
m_writePtr += string.size();
|
|
|
|
|
m_writePtr[0] = 0; // trailing zero
|
|
|
|
|
++m_writePtr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ///////////////////////////////////////////////////////////////
|
|
|
|
|
|
2021-08-14 22:00:42 +02:00
|
|
|
Message::Iterator::Iterator(const Message * const message)
|
|
|
|
|
: m_parent(message),
|
|
|
|
|
m_cur(message->begin()),
|
|
|
|
|
m_recordSize(-1)
|
2021-05-21 15:28:57 +02:00
|
|
|
{
|
2024-02-21 11:21:37 +01:00
|
|
|
next();
|
2021-05-21 15:28:57 +02:00
|
|
|
}
|
|
|
|
|
|
2021-08-14 22:00:42 +02:00
|
|
|
bool Message::Iterator::isArgument() const
|
2021-05-21 15:28:57 +02:00
|
|
|
{
|
2021-08-14 22:00:42 +02:00
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == Argument;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-17 01:03:43 +01:00
|
|
|
bool Message::Iterator::isNewEnvVar() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == EnvironSet;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Message::Iterator::isEnvVarUnset() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == EnvironUnset;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-14 22:00:42 +02:00
|
|
|
bool Message::Iterator::isUnmount() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == UnMountDir;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Message::Iterator::isRemount() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == RBindMountSource;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-15 23:39:04 +01:00
|
|
|
bool Message::Iterator::isCreateTmp() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == CreateTmpFs;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 16:54:09 +01:00
|
|
|
bool Message::Iterator::isCopy() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == CopyFrom;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 11:21:37 +01:00
|
|
|
bool Message::Iterator::isJailId() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == JailId;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-24 11:40:42 +01:00
|
|
|
bool Message::Iterator::isInitSript() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == InitScript;
|
|
|
|
|
}
|
|
|
|
|
|
2024-05-17 11:39:44 +02:00
|
|
|
bool Message::Iterator::isJailPwd() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == JailPassword;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 14:54:32 +02:00
|
|
|
bool Message::Iterator::isVpnConfig() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == VpnConfig;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool Message::Iterator::isVpnPwdBool() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
return m_cur[0] == VpnHasPassFile;
|
|
|
|
|
}
|
|
|
|
|
|
2021-08-14 22:00:42 +02:00
|
|
|
bool Message::Iterator::isValid() const
|
|
|
|
|
{
|
|
|
|
|
assert(m_parent);
|
|
|
|
|
assert(m_cur);
|
|
|
|
|
assert(m_cur >= m_parent->begin());
|
|
|
|
|
if (m_cur < m_parent->begin() + m_parent->size()) {
|
|
|
|
|
return m_cur[0] != 0;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 19:14:25 +01:00
|
|
|
bool Message::Iterator::isDBusMapping() const
|
|
|
|
|
{
|
|
|
|
|
return m_cur[0] == DBusProxyFrom || m_cur[0] == DBusProxySystemFrom;
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-11 14:54:32 +02:00
|
|
|
bool Message::Iterator::boolData() const
|
|
|
|
|
{
|
|
|
|
|
return m_cur[0] != 0;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 16:54:09 +01:00
|
|
|
CopyMessage Message::Iterator::copyData() const
|
|
|
|
|
{
|
|
|
|
|
assert(m_parent);
|
|
|
|
|
CopyMessage rc;
|
|
|
|
|
if (m_cur[0] != CopyFrom)
|
|
|
|
|
throw std::runtime_error("Not copy data");
|
|
|
|
|
|
|
|
|
|
const char *end = m_parent->m_buf.get() + m_parent->m_reservedSize;
|
2024-02-17 01:03:43 +01:00
|
|
|
auto length = ::stringLength(m_cur + 1, end);
|
2024-02-16 16:54:09 +01:00
|
|
|
rc.from = std::string(m_cur + 1, length);
|
2024-02-17 01:03:43 +01:00
|
|
|
auto length2 = ::stringLength(m_cur + 1 + length + 2, end);
|
2024-02-16 16:54:09 +01:00
|
|
|
rc.to = std::string(m_cur + 1 + length + 2, length2);
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-20 19:14:25 +01:00
|
|
|
DBusMapping Message::Iterator::dbusMapping() const
|
|
|
|
|
{
|
|
|
|
|
assert(m_parent);
|
|
|
|
|
DBusMapping rc;
|
|
|
|
|
if (m_cur[0] == DBusProxyFrom)
|
|
|
|
|
rc.systemBus = false;
|
|
|
|
|
else if (m_cur[0] == DBusProxySystemFrom)
|
|
|
|
|
rc.systemBus = true;
|
|
|
|
|
else
|
|
|
|
|
throw std::runtime_error("Not dbus-mapping data");
|
|
|
|
|
|
|
|
|
|
const char *end = m_parent->m_buf.get() + m_parent->m_reservedSize;
|
|
|
|
|
auto length = ::stringLength(m_cur + 1, end);
|
|
|
|
|
rc.from = std::string(m_cur + 1, length);
|
|
|
|
|
auto length2 = ::stringLength(m_cur + 1 + length + 2, end);
|
|
|
|
|
rc.to = std::string(m_cur + 1 + length + 2, length2);
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-21 11:21:37 +01:00
|
|
|
uint32_t Message::Iterator::jailId() const
|
|
|
|
|
{
|
2026-04-11 14:54:32 +02:00
|
|
|
assert(m_parent);
|
|
|
|
|
const char *end = m_parent->m_buf.get() + m_parent->m_reservedSize;
|
|
|
|
|
if (m_cur + 4 > end)
|
|
|
|
|
throw std::runtime_error("Not enough space in message");
|
|
|
|
|
assert(isJailId()); // check if it actually is a jailid
|
2024-02-21 11:21:37 +01:00
|
|
|
uint32_t data = m_cur[4];
|
|
|
|
|
data <<= 8;
|
|
|
|
|
data += m_cur[3];
|
|
|
|
|
data <<= 8;
|
|
|
|
|
data += m_cur[2];
|
|
|
|
|
data <<= 8;
|
|
|
|
|
data += m_cur[1];
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-17 01:03:43 +01:00
|
|
|
char *Message::Iterator::stringPtr() const
|
|
|
|
|
{
|
|
|
|
|
return m_cur + 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int Message::Iterator::stringLength() const
|
|
|
|
|
{
|
|
|
|
|
assert(isValid());
|
|
|
|
|
// not valid for one of the commands that have more than one string.
|
|
|
|
|
assert(!isRemount() && !isCopy());
|
|
|
|
|
return m_recordSize - 2;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 16:54:09 +01:00
|
|
|
MountMessage Message::Iterator::mountData() const
|
2021-08-14 22:00:42 +02:00
|
|
|
{
|
|
|
|
|
assert(m_parent);
|
|
|
|
|
MountMessage rc;
|
|
|
|
|
if (m_cur[0] == RBindMountSource)
|
|
|
|
|
rc.type = MountMessage::Remount;
|
|
|
|
|
else if (m_cur[0] == UnMountDir)
|
|
|
|
|
rc.type = MountMessage::Umount;
|
2024-02-15 23:39:04 +01:00
|
|
|
else if (m_cur[0] == CreateTmpFs)
|
|
|
|
|
rc.type = MountMessage::CreateTmpFs;
|
2021-08-14 22:00:42 +02:00
|
|
|
else
|
|
|
|
|
throw std::runtime_error("Not mount data");
|
|
|
|
|
|
2024-02-16 16:54:09 +01:00
|
|
|
const char *end = m_parent->m_buf.get() + m_parent->m_reservedSize;
|
|
|
|
|
int index = 0;
|
2021-08-14 22:00:42 +02:00
|
|
|
while (true) {
|
2024-02-16 16:54:09 +01:00
|
|
|
char t = m_cur[index];
|
|
|
|
|
const char *str = m_cur + index + 1;
|
2024-02-17 01:03:43 +01:00
|
|
|
const int strSize = ::stringLength(m_cur + index + 1, end);
|
2024-02-16 16:54:09 +01:00
|
|
|
index += strSize + 2;
|
|
|
|
|
checkAvail(index);
|
2021-08-14 22:00:42 +02:00
|
|
|
if (t == RBindMountSource) {
|
|
|
|
|
rc.src = std::string(str, strSize);
|
|
|
|
|
}
|
|
|
|
|
else if (t == RBindMountDest) {
|
|
|
|
|
rc.dst = std::string(str, strSize);
|
|
|
|
|
break; // last in the sequence
|
|
|
|
|
}
|
|
|
|
|
else if (rc.type == MountMessage::Umount) {
|
|
|
|
|
rc.src = std::string(str, strSize);
|
|
|
|
|
// only the src field is expected
|
|
|
|
|
break;
|
2021-05-21 15:28:57 +02:00
|
|
|
}
|
2024-02-15 23:39:04 +01:00
|
|
|
else if (rc.type == MountMessage::CreateTmpFs) {
|
|
|
|
|
rc.dst = std::string(str, strSize);
|
|
|
|
|
// only the dst field is expected
|
|
|
|
|
break;
|
|
|
|
|
}
|
2021-05-21 15:28:57 +02:00
|
|
|
}
|
2021-08-14 22:00:42 +02:00
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 16:54:09 +01:00
|
|
|
const char *Message::Iterator::argument() const
|
2021-08-14 22:00:42 +02:00
|
|
|
{
|
|
|
|
|
assert(m_parent);
|
|
|
|
|
assert(isArgument());
|
2024-02-16 09:00:15 +01:00
|
|
|
assert(m_recordSize != -1); // we called 'next'
|
2021-08-14 22:00:42 +02:00
|
|
|
return m_cur + 1;
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-16 09:00:15 +01:00
|
|
|
bool Message::Iterator::next()
|
2021-08-14 22:00:42 +02:00
|
|
|
{
|
|
|
|
|
assert(m_cur);
|
2024-02-16 09:00:15 +01:00
|
|
|
if (m_recordSize != -1) {
|
|
|
|
|
m_cur = m_cur + m_recordSize;
|
|
|
|
|
if (!isValid())
|
|
|
|
|
return false;
|
2021-08-14 22:00:42 +02:00
|
|
|
}
|
2024-02-16 09:00:15 +01:00
|
|
|
|
|
|
|
|
m_isTry = *m_cur == IsTry;
|
|
|
|
|
if (m_isTry)
|
|
|
|
|
m_cur += 1;
|
2024-02-16 16:54:09 +01:00
|
|
|
|
|
|
|
|
m_recordSize = 0;
|
|
|
|
|
checkAvail(2);
|
2024-02-16 09:00:15 +01:00
|
|
|
// find the string-size(s)
|
2024-02-16 16:54:09 +01:00
|
|
|
const char *end = m_parent->m_buf.get() + m_parent->m_reservedSize;
|
2024-02-16 09:00:15 +01:00
|
|
|
switch (*m_cur) {
|
|
|
|
|
case ExecutablePath: // fall through
|
|
|
|
|
case Argument: // fall through
|
|
|
|
|
case UnMountDir: // fall through
|
2024-02-17 01:03:43 +01:00
|
|
|
case EnvironSet: // fall through
|
|
|
|
|
case EnvironUnset: // fall through
|
2024-02-24 11:40:42 +01:00
|
|
|
case InitScript: // fall through
|
2024-05-17 11:39:44 +02:00
|
|
|
case JailPassword: // fall through
|
2026-04-11 14:54:32 +02:00
|
|
|
case VpnConfig: // fall through
|
2024-02-16 09:00:15 +01:00
|
|
|
case CreateTmpFs:
|
2024-02-17 01:03:43 +01:00
|
|
|
m_recordSize = ::stringLength(m_cur + 1, end) + 2;
|
2024-02-16 09:00:15 +01:00
|
|
|
break;
|
2024-02-20 19:14:25 +01:00
|
|
|
case DBusProxyFrom: // fall through
|
|
|
|
|
case DBusProxySystemFrom: // fall through
|
2024-02-16 16:54:09 +01:00
|
|
|
case RBindMountSource: // fall-through
|
|
|
|
|
case CopyFrom:
|
2024-02-20 19:14:25 +01:00
|
|
|
// these take 2 args
|
2024-02-17 01:03:43 +01:00
|
|
|
m_recordSize = ::stringLength(m_cur + 1, end) + 2;
|
|
|
|
|
m_recordSize += ::stringLength(m_cur + m_recordSize + 1, end) + 2;
|
2024-02-16 09:00:15 +01:00
|
|
|
break;
|
2024-02-21 11:21:37 +01:00
|
|
|
case JailId:
|
|
|
|
|
m_recordSize += 5;
|
|
|
|
|
break;
|
2026-04-11 14:54:32 +02:00
|
|
|
case VpnHasPassFile: // bool
|
|
|
|
|
m_recordSize += 2;
|
|
|
|
|
break;
|
2024-02-20 19:14:25 +01:00
|
|
|
case DBusProxyTo: // fall through
|
|
|
|
|
case DBusProxySystemTo: // fall through
|
2024-02-16 09:00:15 +01:00
|
|
|
case RBindMountDest:
|
|
|
|
|
assert(false);
|
|
|
|
|
default:
|
|
|
|
|
assert(false);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
2021-08-14 22:00:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void Message::Iterator::checkAvail(int bytes) const
|
|
|
|
|
{
|
|
|
|
|
if (bytes < 0 || bytes > MAX_SIZE)
|
|
|
|
|
throw std::runtime_error("Serialization failure: impossible size");
|
|
|
|
|
if (m_parent->begin() + m_parent->size() < m_cur + bytes)
|
|
|
|
|
throw std::runtime_error("Message::Iterator: out of bounds");
|
2021-05-19 12:08:57 +02:00
|
|
|
}
|