Crinit -- Configurable Rootfs Init
|
Implementation of the notification and service interface. More...
#include "notiserv.h"
#include <libgen.h>
#include <linux/capability.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/un.h>
#include <unistd.h>
#include "logio.h"
#include "rtimcmd.h"
#include "thrpool.h"
Classes | |
struct | crinitConnThrArgs_t |
Macros | |
#define | _GNU_SOURCE |
Needed for SCM_CREDENTIALS, struct ucred,... More... | |
#define | crinitGettid() ((pid_t)syscall(SYS_gettid)) |
#define | MAX_CONN_BACKLOG 100 |
Typedefs | |
typedef struct crinitConnThrArgs_t | crinitConnThrArgs_t |
Functions | |
static void * | crinitConnThread (void *args) |
static int | crinitCreateSockFile (int *sockFd, const char *path) |
static bool | crinitCmsgHdrCheck (const struct cmsghdr *cmh) |
static bool | crinitUcredCheckEqual (const struct ucred *a, const struct ucred *b) |
static int | crinitSendStr (int sockFd, const char *str) |
static int | crinitRecvStr (int sockFd, char **str, struct ucred *passedCreds) |
static bool | crinitCheckPerm (crinitRtimOp_t op, const struct ucred *passedCreds) |
static int | crinitProcCapget (cap_user_data_t out, pid_t pid) |
static int | crinitMkdirp (char *pathname, mode_t mode) |
int | crinitStartInterfaceServer (crinitTaskDB_t *ctx, const char *sockFile) |
Variables | |
static crinitThreadPool_t | crinitWorkers |
The worker thread pool to run connThread() in. More... | |
static crinitTaskDB_t * | crinitTdbRef |
Pointer to the crinitTaskDB_t to operate on. More... | |
Implementation of the notification and service interface.
#define _GNU_SOURCE |
Needed for SCM_CREDENTIALS, struct ucred,...
#define crinitGettid | ( | ) | ((pid_t)syscall(SYS_gettid)) |
Macro wrapper for the gettid syscall in case glibc is not new enough to contain one itself
#define MAX_CONN_BACKLOG 100 |
Maximum number of unserviced connections until the server starts refusing
typedef struct crinitConnThrArgs_t crinitConnThrArgs_t |
Helper structure defining the arguments to connThread()
|
inlinestatic |
Checks if given process credentials imply permission to execute remote command.
op | The opcode of the command the process requests to execute. |
passedCreds | The credentials of the requesting process obtained via SCM_CREDENTIALS. |
|
inlinestatic |
Checks if a received struct cmsghdr has expected length and contents.
Expected is a struct cmsghdr containing SCM_CREDENTIALS.
cmh | The header to check. |
|
static |
The worker thread function for handling a connection to a client.
Will accept connections in a loop, send RTR, handle incoming requests, and send responses. Automatically gets informed of client PID, UID, and GID through SO_PASSCRED
/SCM_CREDENTIALS
, so that permission handling is possible.
Uses crinitThreadPoolThreadAvailCallback() and crinitThreadPoolThreadBusyCallback() to signal its status to the thread pool.
The client-side equivalent connection-handling function is crinitXfer() in crinit-client.c. The following image illustrates the high level client/server protocol.
args | Arguments to the function, see crinitConnThrArgs_t. |
|
static |
Create AF_UNIX socket file, bind() and listen().
Will overwrite any exist file at path.
sockFd | Return pointer for the socket file descriptor. |
path | Path to the socket file whcih should be created. |
|
inlinestatic |
Recursive mkdir(), equivalent to mkdir -p
.
Note: Will modify the input pathname during execution to seperate paths.
pathname | The complete path to recursively generate. |
mode | The mode passed to mkdir(). |
|
inlinestatic |
Gets capabilities of process specified by PID.
out | Return pointer for capabilities. Note, that the Linux API defines cap_user_data_t as a pointer to struct __user_cap_header_struct. The given pointer needs to point to at least two elements. |
pid | PID of the process from which to get the capabilities. |
|
inlinestatic |
Receives a string from a connected client.
The low level protocol is to first wait for a size_t informing the server of the length of the following string (including the terminating zero) and then the string itself. The complementary client-side function is crinitRecv().
This function will also extract the message metadata received via SO_PASSCRED
and return the credentials of the sender via passedCreds.
This function will allocate memory for the received string using malloc(). The string should be free()'d when no longer needed.
The following image illustrates the low level send/receive protocol:
sockFd | The socket file descriptor connected to the client. |
str | Return pointer for the received string. |
passedCreds | Return pointer for SCM_CREDENTIALS metadata. |
|
inlinestatic |
Sends a string to a connected client.
The low level protocol is to first send a size_t informing the client of the length of the following string (including the terminating zero) and then the string itself. The complementary client-side function is crinitSend().
The following image illustrates the low level send/receive protocol:
sockFd | The socket file descriptor connected to the client. |
str | The string to send. |
int crinitStartInterfaceServer | ( | crinitTaskDB_t * | ctx, |
const char * | sockfile | ||
) |
Starts the Notification and Service interface socket server.
Will create the AF_UNIX socket for clients to connect to and spawn a number of worker threads to service incoming connections (see notiserv.c and thrpool.h).
ctx | Pointer to the crinitTaskDB_t which the Server should use for incoming requests. |
sockfile | Path where to create the AF_UNIX socket file. |
|
inlinestatic |
Checks if two struct ucred are equal.
Two struct ucred are equal if and only if their members pid, uid, and gid are equal with their respective counterparts.
a | First operand. |
b | Second operand. |
|
static |
Pointer to the crinitTaskDB_t to operate on.
|
static |
The worker thread pool to run connThread() in.