EDGESEC
0.1.0-alpha.0+sha.ca29a8277b72f80785649ea9ef9cd7edf642d939
Secure router - reference implementation
|
File containing the definition of the os functionalities. More...
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <utarray.h>
#include "hashmap.h"
#include "log.h"
Go to the source code of this file.
Data Structures | |
struct | find_dir_type |
struct | os_time |
struct | os_reltime |
Macros | |
#define | MAX_OS_PATH_LEN 4096 |
#define | MAX_WEB_PATH_LEN 2048 |
#define | MAX_RANDOM_UUID_LEN 37 |
#define | OS_HOST_NAME_MAX 64 |
#define | BIT(x) (1U << (x)) |
#define | ARRAY_SIZE(s) (sizeof(s) / sizeof(s[0])) |
#define | BD_NO_CHDIR 01 /* Don't chdir("/") */ |
#define | BD_NO_CLOSE_FILES 02 /* Don't close all open files */ |
#define | BD_NO_REOPEN_STD_FDS |
#define | BD_NO_UMASK0 010 /* Don't do a umask(0) */ |
#define | BD_MAX_CLOSE |
#define | os_strlen(s) strlen((s)) |
#define | os_snprintf(s, maxlen, ...) snprintf((s), (maxlen), __VA_ARGS__) |
#define | os_strncmp(s1, s2, n) strncmp((s1), (s2), (n)) |
#define | os_strstr(s1, s2) strstr((s1), (s2)) |
Macro to strstr() for code taken from hostap. More... | |
#define | os_strcmp(s1, s2) strcmp((s1), (s2)) |
#define | os_strchr(s, c) strchr((s), (c)) |
Macro to strchr() for code taken from hostap. More... | |
#define | os_get_time(t) edge_os_get_time(t) |
#define | os_get_reltime(t) edge_os_get_reltime((t)) |
#define | os_get_random(buf, len) edge_os_get_random((buf), (len)) |
#define | os_strlcpy(dest, src, siz) edge_os_strlcpy((dest), (src), (siz)) |
#define | os_memcmp_const(a, b, len) edge_os_memcmp_const((a), (b), (len)) |
#define | aliasing_hide_typecast(a, t) (t *)__hide_aliasing_typecast((a)) |
Typedefs | |
typedef long | os_time_t |
typedef void(* | process_callback_fn) (void *ctx, void *buf, size_t count) |
Callback function for run_command() and similar functions. More... | |
typedef int(* | split_string_fn) (const char *, size_t, void *) |
typedef bool(* | list_dir_fn) (char *, void *args) |
Functions | |
int | become_daemon (int flags) |
Becomes a daemon. More... | |
int | edge_os_get_time (struct os_time *t) |
Get current time (sec, usec) in seconds since UNIX epoch. More... | |
int | edge_os_get_reltime (struct os_reltime *t) |
Get relative time (sec, usec) More... | |
int | os_get_timestamp (uint64_t *timestamp) |
get the timestamp in microseconds from system time More... | |
void | os_to_timestamp (struct timeval ts, uint64_t *timestamp) |
get the timestamp in microseconds from struct timeval More... | |
int | edge_os_get_random (unsigned char *buf, size_t len) |
Get cryptographically strong pseudo random data. More... | |
int | os_get_random_int_range (int low, int up) |
Return a random int from a give range. More... | |
void | os_init_random_seed (void) |
Initialises the random seed. More... | |
int | os_get_random_number_s (unsigned char *buf, size_t len) |
Get a random number string. More... | |
int8_t | hex2num (char c) |
Hex char to number. More... | |
int | edge_hexstr2bin (const char *hex, uint8_t *buf, size_t len) |
Convert ASCII hex string into binary data. More... | |
bool | is_number (const char *ptr) |
Check if a string is a number. More... | |
size_t | edge_os_strlcpy (char *restrict dest, const char *restrict src, size_t siz) |
Copy a string with size bound and NUL-termination. More... | |
size_t | os_strnlen_s (const char *str, size_t max_len) |
Returns the size of string with a give max length. More... | |
int | edge_os_memcmp_const (const void *a, const void *b, size_t len) |
Constant time memory comparison. More... | |
void * | __hide_aliasing_typecast (void *foo) |
char ** | copy_argv (const char *const argv[]) |
Makes a copy of argv. More... | |
int | run_command (char *const argv[], char *const envp[], process_callback_fn fn, void *ctx) |
Executes a command. More... | |
int | run_argv_command (const char *path, const char *const argv[], process_callback_fn fn, void *ctx) |
Executes a command with argument. More... | |
void | replace_string_char (char *s, char in, char out) |
Replace a character in a string with a given characater. More... | |
ssize_t | split_string (const char *str, char sep, split_string_fn fun, void *data) |
Splits a string into substrings (execute callback function) More... | |
ssize_t | split_string_array (const char *str, char sep, UT_array *arr) |
Splits a string into substrings (save to array) More... | |
char * | concat_paths (const char *path_left, const char *path_right) |
Concatenate two string paths. More... | |
char * | get_valid_path (const char *path) |
Get the valid path string. More... | |
char * | construct_path (const char *path_left, const char *path_right) |
Construct a valid path from two paths. More... | |
char * | get_secure_path (const UT_array *bin_path_arr, const char *filename, bool real) |
Get the secure path string of a binary. More... | |
int | list_dir (const char *dirpath, list_dir_fn fun, void *args) |
List the files in a directory. More... | |
pid_t | is_proc_app (const char *path, const char *proc_name) |
Check if the given process's basename matches proc_name. More... | |
bool | kill_process (char *proc_name) |
Kill a process by name. More... | |
bool | signal_process (const char *proc_name, int sig) |
Signal a process. More... | |
int | run_process (char *argv[], pid_t *child_pid) |
Executes a background process with an array of string arguments. More... | |
int | is_proc_running (const char *name) |
Check if a process is running. More... | |
int | make_file_exec_fd (int fd) |
Makes a file given by descriptor executable. More... | |
char * | rtrim (char *str, const char *seps) |
Right trim the string. More... | |
char * | string_array2string (const char *const strings[]) |
Concatenates an array of strings into a single string. More... | |
void | generate_radom_uuid (char rid[static MAX_RANDOM_UUID_LEN]) |
Generates a random UUID string of MAX_RANDOM_UUID_LEN - 1 characters long not including '\0'. More... | |
bool | find_dir_proc_fn (char *path, void *args) |
Callback function for list_dir function to check if process running. More... | |
int | exist_dir (const char *dirpath) |
Check if folder exists. More... | |
int | make_dirs_to_path (const char *file_path, mode_t mode) |
Recurisvely create directories to the given path. More... | |
int | create_dir (const char *dirpath, mode_t mode) |
Creates a folder recursively. More... | |
int | create_pipe_file (const char *path) |
Creates a FIFO pipe file. More... | |
int | check_file_exists (const char *path, struct stat *sb) |
Check if a file exists. More... | |
int | check_sock_file_exists (const char *path) |
Check if a socket file exists. More... | |
int | get_hostname (char buf[static OS_HOST_NAME_MAX]) |
Get the hostname of the running machine. More... | |
int | create_pid_file (const char *pid_file, int flags) |
Open/create the file named in 'pidFile', lock it, optionally set the close-on-exec flag for the file descriptor, write our PID into the file, and (in case the caller is interested) return the file descriptor referring to the locked file. The caller is responsible for deleting 'pidFile' file (just) before process termination. 'progName' should be the name of the calling program (i.e., argv[0] or similar), and is used only for diagnostic messages. If we can't open 'pidFile', or we encounter some other error, then we print an appropriate diagnostic and terminate. More... | |
ssize_t | read_file (const char *path, uint8_t **out) |
Read the entire file. More... | |
int | read_file_string (const char *path, char **out) |
Read the entire file into a string. More... | |
ssize_t | open_write_nonblock (const char *path, int *fd, const uint8_t *buffer, size_t length) |
Opens a file for writing and write a a buffer in nonblocking mode. More... | |
int | get_commands_paths (const char *commands[], const UT_array *bin_path_arr, hmap_str_keychar **hmap_bin_paths) |
Returns the absolute path of system binaries. More... | |
char * | string_append_char (const char *str, char character) |
Append a character to a string and return the new string. More... | |
File containing the definition of the os functionalities.
#define aliasing_hide_typecast | ( | a, | |
t | |||
) | (t *)__hide_aliasing_typecast((a)) |
#define ARRAY_SIZE | ( | s | ) | (sizeof(s) / sizeof(s[0])) |
#define BD_MAX_CLOSE |
#define BD_NO_CHDIR 01 /* Don't chdir("/") */ |
#define BD_NO_CLOSE_FILES 02 /* Don't close all open files */ |
#define BD_NO_REOPEN_STD_FDS |
#define BD_NO_UMASK0 010 /* Don't do a umask(0) */ |
#define BIT | ( | x | ) | (1U << (x)) |
#define MAX_OS_PATH_LEN 4096 |
#define MAX_RANDOM_UUID_LEN 37 |
#define MAX_WEB_PATH_LEN 2048 |
#define os_get_random | ( | buf, | |
len | |||
) | edge_os_get_random((buf), (len)) |
#define os_get_reltime | ( | t | ) | edge_os_get_reltime((t)) |
#define os_get_time | ( | t | ) | edge_os_get_time(t) |
#define OS_HOST_NAME_MAX 64 |
#define os_memcmp_const | ( | a, | |
b, | |||
len | |||
) | edge_os_memcmp_const((a), (b), (len)) |
#define os_snprintf | ( | s, | |
maxlen, | |||
... | |||
) | snprintf((s), (maxlen), __VA_ARGS__) |
#define os_strchr | ( | s, | |
c | |||
) | strchr((s), (c)) |
Macro to strchr() for code taken from hostap.
const char *
instead of a char *
. #define os_strcmp | ( | s1, | |
s2 | |||
) | strcmp((s1), (s2)) |
#define os_strlcpy | ( | dest, | |
src, | |||
siz | |||
) | edge_os_strlcpy((dest), (src), (siz)) |
#define os_strlen | ( | s | ) | strlen((s)) |
#define os_strncmp | ( | s1, | |
s2, | |||
n | |||
) | strncmp((s1), (s2), (n)) |
#define os_strstr | ( | s1, | |
s2 | |||
) | strstr((s1), (s2)) |
Macro to strstr() for code taken from hostap.
char *
. typedef bool(* list_dir_fn) (char *, void *args) |
typedef long os_time_t |
typedef void(* process_callback_fn) (void *ctx, void *buf, size_t count) |
Callback function for run_command() and similar functions.
ctx | - Context, passed to run_command(). |
buf | - data from stdout. Warning, if this is a string, you may have to add your own NUL-terminator. |
count | - Length of data from stdout. |
typedef int(* split_string_fn) (const char *, size_t, void *) |
void* __hide_aliasing_typecast | ( | void * | foo | ) |
int become_daemon | ( | int | flags | ) |
Becomes a daemon.
flags | Flags fpor deamon settings |
int check_file_exists | ( | const char * | path, |
struct stat * | sb | ||
) |
Check if a file exists.
[in] | path | The path to the file |
[out] | sb | If non-NULL, stores the stats of the file. |
int check_sock_file_exists | ( | const char * | path | ) |
Check if a socket file exists.
path | The path to the socket file |
char* concat_paths | ( | const char * | path_left, |
const char * | path_right | ||
) |
Concatenate two string paths.
path_left | First string path |
path_right | Second string path |
free()
the return value when done. NULL | on memory allocation error. |
char* construct_path | ( | const char * | path_left, |
const char * | path_right | ||
) |
Construct a valid path from two paths.
path_left | First path |
path_right | Second path |
NULL | on memory allocation error. |
char** copy_argv | ( | const char *const | argv[] | ) |
Makes a copy of argv.
When writing code, we normally define argv using const char *
string literals, e.g.: const char * args[] {"hello", "world", NULL};
However, the C functions (e.g. execve()) expect char * const *
, aka the strings must be mallable (unsafe with string literals).
This function makes a copy of argv so that we don't get undefined behaviour by modifing const
data.
The entire argv array (and strings) is allocated as a single malloc() so that you can use a single free() to release the memory when done.
argv | The NULL-terminated array of '\0'-terminated strings to copy. |
NULL
if malloc() failed. free()
when finished with the argv_copy
. Array of strings.
The first part of the malloc-d data hold argv, which is an array of char *
. The second part of the malloc-d data is a buffer containing all the string data (e.g. char
).
E.g., for example, a copy of
will look something like the following (for 64-bit ptrs):
Address | 0-7 | 8-15 | 16-23 | 24-29 | 30-36 |
---|---|---|---|---|---|
CType | char* | char* | char* | char[] | char[] |
Value | 24 | 30 | NULL | "Hello" | "World!" |
Pointer to beginning of string buffer within argv_copy. This is a separate variable as it's a different type to copy_argv[0]
(char vs char *), and therefore pointer arthmetic gets complicated.
int create_dir | ( | const char * | dirpath, |
mode_t | mode | ||
) |
Creates a folder recursively.
If the parent folders do not exist, creates them too.
[in] | dirpath | The folder path |
mode | The folder creation mode |
int create_pid_file | ( | const char * | pid_file, |
int | flags | ||
) |
Open/create the file named in 'pidFile', lock it, optionally set the close-on-exec flag for the file descriptor, write our PID into the file, and (in case the caller is interested) return the file descriptor referring to the locked file. The caller is responsible for deleting 'pidFile' file (just) before process termination. 'progName' should be the name of the calling program (i.e., argv[0] or similar), and is used only for diagnostic messages. If we can't open 'pidFile', or we encounter some other error, then we print an appropriate diagnostic and terminate.
pid_file | The pid file path to create |
flags | The pid file open flags |
int create_pipe_file | ( | const char * | path | ) |
Creates a FIFO pipe file.
[in] | path | The path to the pipe file |
int edge_hexstr2bin | ( | const char * | hex, |
uint8_t * | buf, | ||
size_t | len | ||
) |
Convert ASCII hex string into binary data.
hex | ASCII hex string (e.g., "01ab") |
buf | Buffer for the binary data |
len | Length of the text to convert in bytes (of buf); hex will be double this size |
int edge_os_get_random | ( | unsigned char * | buf, |
size_t | len | ||
) |
Get cryptographically strong pseudo random data.
buf | Buffer for pseudo random data. |
len | Length of the buffer. |
int edge_os_get_reltime | ( | struct os_reltime * | t | ) |
Get relative time (sec, usec)
Unlike edge_os_get_time(), the time from this function will never go backwards (e.g. due to NTP).
[out] | t | Pointer to buffer for the time. If there is a failure, may write invalid data. |
int edge_os_get_time | ( | struct os_time * | t | ) |
Get current time (sec, usec) in seconds since UNIX epoch.
[out] | t | Pointer to buffer for the time If there is a failure, may write invalid data. |
int edge_os_memcmp_const | ( | const void * | a, |
const void * | b, | ||
size_t | len | ||
) |
Constant time memory comparison.
This function is meant for comparing passwords or hash values where difference in execution time could provide external observer information about the location of the difference in the memory buffers. The return value does not behave like os_memcmp(), i.e., edge_os_memcmp_const() cannot be used to sort items into a defined order. Unlike os_memcmp(), execution time of edge_os_memcmp_const() does not depend on the contents of the compared memory buffers, but only on the total compared length.
a | First buffer to compare |
b | Second buffer to compare |
len | Number of octets to compare |
size_t edge_os_strlcpy | ( | char *restrict | dest, |
const char *restrict | src, | ||
size_t | siz | ||
) |
Copy a string with size bound and NUL-termination.
This function matches in behavior with the strlcpy(3) function in OpenBSD.
dest | Destination string |
src | Source string |
siz | Size of the target buffer |
int exist_dir | ( | const char * | dirpath | ) |
Check if folder exists.
dirpath | The folder path |
bool find_dir_proc_fn | ( | char * | path, |
void * | args | ||
) |
Callback function for list_dir function to check if process running.
[in] | path | The process path |
[in,out] | args | The callback arguments of type struct find_dir_type |
void generate_radom_uuid | ( | char | rid[static MAX_RANDOM_UUID_LEN] | ) |
Generates a random UUID string of MAX_RANDOM_UUID_LEN - 1 characters long not including '\0'.
[out] | rid | The output string of MAX_RANDOM_UUID_LEN bytes |
int get_commands_paths | ( | const char * | commands[], |
const UT_array * | bin_path_arr, | ||
hmap_str_keychar ** | hmap_bin_paths | ||
) |
Returns the absolute path of system binaries.
[in] | commands | Array of system binaries name strings. The last entry must be a NULL ptr. |
[in] | bin_path_arr | Array of system binaries default search paths |
[out] | hmap_bin_paths | The created map of system binary to absolute path. |
int get_hostname | ( | char | buf[static OS_HOST_NAME_MAX] | ) |
Get the hostname of the running machine.
[out] | buf | Buffer to store the returned hostname. Must be at least OS_HOST_NAME_MAX bytes long. Warning, this string might not be NULL-terminated if it's exactly OS_HOST_NAME_MAX bytes long. |
char* get_secure_path | ( | const UT_array * | bin_path_arr, |
const char * | filename, | ||
bool | real | ||
) |
Get the secure path string of a binary.
bin_path_arr | The path string of binary |
filename | The binary name |
real | true to return the real link |
char* get_valid_path | ( | const char * | path | ) |
Get the valid path string.
path | Input string path |
NULL | on memory allocation error. |
int8_t hex2num | ( | char | c | ) |
bool is_number | ( | const char * | ptr | ) |
Check if a string is a number.
ptr | String pointer |
pid_t is_proc_app | ( | const char * | path, |
const char * | proc_name | ||
) |
Check if the given process's basename matches proc_name.
Checks both:
/proc/[pid]/exe
), and/proc/[pid]/cmdline
).As an example, if a process was started with /usr/bin/gcc
, which is a symlink to /usr/bin/x86_64-linux-gnu-gcc-11
, then bothis_proc_app(..., "gcc")
AND is_proc_app(..., "x86_64-linux-gnu-gcc-11")
will work.
path | The /proc/[pid] folder for the process |
proc_name | The process name to search for. |
proc_name
string, or 0
if it doesn't. int is_proc_running | ( | const char * | name | ) |
Check if a process is running.
name | The process name |
bool kill_process | ( | char * | proc_name | ) |
Kill a process by name.
proc_name | The process name |
int list_dir | ( | const char * | dirpath, |
list_dir_fn | fun, | ||
void * | args | ||
) |
List the files in a directory.
dirpath | The directory path |
fun | The callback function If this function ever returns false , list_dir will return -1 . |
args | The callback function arguments |
0 | On success |
-1 | On error |
int make_dirs_to_path | ( | const char * | file_path, |
mode_t | mode | ||
) |
Recurisvely create directories to the given path.
Creates the directories recursively to the given path.
Does NOT create the final file, use create_dir() if you want if you want to create the entire path as dirs.
Example:
[in] | file_path | The directories to create to the path. |
mode | The folder create mode. |
int make_file_exec_fd | ( | int | fd | ) |
Makes a file given by descriptor executable.
fd | File descriptor |
ssize_t open_write_nonblock | ( | const char * | path, |
int * | fd, | ||
const uint8_t * | buffer, | ||
size_t | length | ||
) |
Opens a file for writing and write a a buffer in nonblocking mode.
path[in] | The file path |
fd[in,out] | The file descriptor. If this is non-0 , opens the file given by path , and sets fd to the new file descriptor. Otherwise, path is ignored, and fd is used. Please close the created fd when done with it. |
buffer[in] | The buffer to write |
length[in] | The size of the buffer |
int os_get_random_int_range | ( | int | low, |
int | up | ||
) |
Return a random int from a give range.
low | The range lower bound |
up | The range upper bound |
int os_get_random_number_s | ( | unsigned char * | buf, |
size_t | len | ||
) |
Get a random number string.
buf | Buffer for the random string. |
len | Length of the buffer. |
int os_get_timestamp | ( | uint64_t * | timestamp | ) |
get the timestamp in microseconds from system time
[out] | timestamp | The returned timestamp |
void os_init_random_seed | ( | void | ) |
Initialises the random seed.
size_t os_strnlen_s | ( | const char * | str, |
size_t | max_len | ||
) |
Returns the size of string with a give max length.
[in] | str | The string pointer |
max_len | The string max length |
max_len
if the string is longer than max_len
. void os_to_timestamp | ( | struct timeval | ts, |
uint64_t * | timestamp | ||
) |
get the timestamp in microseconds from struct timeval
[in] | ts | The input struct timeval |
[out] | timestamp | The returned timestamp |
ssize_t read_file | ( | const char * | path, |
uint8_t ** | out | ||
) |
Read the entire file.
path | The file path | |
[out] | out | Pointer to the output buffer, or NULL on error. Will be malloc() -ed, so you must free() this when done. |
int read_file_string | ( | const char * | path, |
char ** | out | ||
) |
Read the entire file into a string.
[in] | path | The file path |
[out] | out | The pointer to the output string. You must free() this variable if read_file_string() is successful. |
void replace_string_char | ( | char * | s, |
char | in, | ||
char | out | ||
) |
Replace a character in a string with a given characater.
s | The input string |
in | The character to be replaced |
out | The character to replace with |
char* rtrim | ( | char * | str, |
const char * | seps | ||
) |
Right trim the string.
str | The source string |
seps | The separator string, if NULL then the separator used is "\t\n\v\f\r " |
int run_argv_command | ( | const char * | path, |
const char *const | argv[], | ||
process_callback_fn | fn, | ||
void * | ctx | ||
) |
Executes a command with argument.
path | The command path |
argv | The command arguments without the process path |
fn | Callback function |
ctx | The callback function context |
-1 | Returns -1 on error. |
0 | Returns 0 on success. |
int run_command | ( | char *const | argv[], |
char *const | envp[], | ||
process_callback_fn | fn, | ||
void * | ctx | ||
) |
Executes a command.
argv | The command arguments including the process path |
envp | The environment variables |
fn | Callback function |
ctx | The callback function context |
int run_process | ( | char * | argv[], |
pid_t * | child_pid | ||
) |
Executes a background process with an array of string arguments.
[in] | argv | The array of string arguments terminated with NULL and the first argument is the absolute path of the process. |
[out] | child_pid | The returned child pid |
0 | The child process has been created, and is either:
|
-1 | Error, please see errno for more details. |
1-255 | The child process has exited, and the return value is this non-zero/error exit code. |
bool signal_process | ( | const char * | proc_name, |
int | sig | ||
) |
Signal a process.
[in] | proc_name | The process name |
sig | The signal value |
ssize_t split_string | ( | const char * | str, |
char | sep, | ||
split_string_fn | fun, | ||
void * | data | ||
) |
Splits a string into substrings (execute callback function)
str | String to split |
sep | String separator |
fun | Callback function |
data | Param for callback function |
ssize_t split_string_array | ( | const char * | str, |
char | sep, | ||
UT_array * | arr | ||
) |
Splits a string into substrings (save to array)
str | String to split |
sep | String separator |
arr | Array to save the substrings |
char* string_append_char | ( | const char * | str, |
char | character | ||
) |
Append a character to a string and return the new string.
The returned pointer must be passed to free()
to avoid a memory leak.
[in] | str | The string to append to |
character | The character to append |
char* string_array2string | ( | const char *const | strings[] | ) |
Concatenates an array of strings into a single string.
strings | The array of string, the last element is NULL |
free()
-ed when done, or NULL
on error.