v0.2.0-rc - implement basic integrity checking framework

This commit is contained in:
2025-03-22 11:19:41 -04:00
parent 25a55609ec
commit 0b03b9b954
7 changed files with 473 additions and 156 deletions

View File

@@ -1,5 +1,5 @@
/*
* config.h - Function declarations for libglacier
* config.h - Config loading for Glacier
*
* This file is part of Glacier.
*
@@ -18,83 +18,75 @@
#ifndef GLACIERCONFIG_H_
#define GLACIERCONFIG_H_
#include <libconfig.h>
/* Constants */
#ifndef LG_VERBOSE
#define LG_VERBOSE 0
#endif
/*
* init_config
* DESCRIPTION: Init_config initializes the libconfig library, so it can read the required runtime files
* PARAMETERS:
* None. (void)
* RETURN VAUES:
* 0 on success, EXIT_FAILURE on failure
* CAVEATS:
* None.
* EXAMPLE:
* // It is best practice to check for ALL non-zero return values, rather than specific ones,
* // as init_config() returns EXIT_FAILURE
*
* if (init_config() != 0) {
* errlog("Failed to initialize libconfig");
* return(EXIT_FAILURE); // fatal error requiring termination of program execution
* }
* else {
* successlog("Initialized libconfig"); // output automatically if LG_VERBOSE = 1
* }
* DESCRIPTION: Initialize libconfig with required configs
* PARAMETERS:
* None.
* RETURN VALUES:
* 0 on success, 1 on failure
* CAVEATS:
* This MUST be called before ANY other config function is.
* EXAMPLE:
* init_config();
*/
int init_config(void);
/**************************************************************************************************************/
/*
* die_config
* DESCRPTION: Die_config destroys the loaded libconfig library.
* PARAMETERS:
* None. (void)
* RETURN VALUES:
* EXIT_SUCCESS on success
* CAVEATS:
* None.
* EXAMPLE:
* // die_config() is unlikely to fail unless you tried to destroy an invalid object,
* // so checking for non-zero return values is unnecessary
*
* DESCRIPTION: Die_config brings down libconfig gracefully.
* PARAMETERS:
* None.
* RETURN VALUES:
* 0 on success, 1 on failure
* CAVEATS:
* This MUST be called after ALL other config functions have completed.
* EXAMPLE:
* die_config();
*/
int die_config(void);
/**************************************************************************************************************/
/*
* load_all_from_config
* DESCRIPTION: Initialize all settings from glacier.cfg.
*
* DESCRIPTION: load_all_from_config loads all settings from the config file.
* PARAMETERS:
* None. (void)
* None.
* RETURN VALUES:
* 0 on success, 1 on file does not exist, 2 on library error
* 0 on success, 1 on failure
* CAVEATS:
* None.
* EXAMPLE:
* load_all_from_config();
*/
int load_all_from_config();
/**************************************************************************************************************/
int load_all_from_config(void);
/*
* [[[ DEPRECATED ]]]
* load_setting_from_config
* DESCRIPTION: Initialize a specified from glacier.cfg.
* load_all_from_profile
*
* DESCRIPTION: load_all_from_profile loads all settings from the profile file.
* PARAMETERS:
* char SETTING[] -> The setting to initialize
* None.
* RETURN VALUES:
* 0 on success, 1 on setting not found, 2 on file does not exist, 3 on library error
* 0 on success, 1 on failure
* CAVEATS:
* None.
* EXAMPLE:
* load_setting_from_config();
* load_all_from_profile();
*/
/* int load_setting_from_config(char SETTING[]); */
int load_all_from_profile(void);
#endif

View File

@@ -20,6 +20,21 @@
#include <stdbool.h>
/* Maximum number of children a node can have */
#define MAX_CHILDREN 64
/* Maximum recursion depth for tree operations */
#define MAX_RECURSION_DEPTH 100
/* Node structure definition */
struct node {
char *data;
struct node *children[MAX_CHILDREN];
int numChildren;
struct node *left;
struct node *right;
};
/*
* create_node
*
@@ -27,16 +42,30 @@
* PARAMETERS:
* char *data -> The name of the node to create
* RETURN VALUES:
* None.
* A pointer to the created node on success, NULL on failure
* CAVEATS:
* None.
* Caller must free the node using free_node when done
* EXAMPLE:
* struct node package = create_node("Package");
* struct node *package = create_node("Package");
*/
struct node *create_node(char *data);
/**************************************************************************************************************/
/*
* free_node
*
* DESCRIPTION: Free_node recursively frees all memory allocated for a node and its children.
* PARAMETERS:
* struct node *root -> The root node to free
* RETURN VALUES:
* None.
* CAVEATS:
* Will free all child nodes recursively.
* EXAMPLE:
* free_node(package);
*/
void free_node(struct node *root);
/*
* add_child
@@ -46,16 +75,14 @@ struct node *create_node(char *data);
* struct node *parent -> The parent node which the child will be added to
* struct node *child -> The child node which will be added to the parent node
* RETURN VALUES:
* 1 on maximum children exceeded
* 0 on success, 1-3 for different error conditions
* CAVEATS:
* None.
* EXAMPLE:
* add_child(package, dep1);
*/
void add_child(struct node *parent, struct node *child);
/**************************************************************************************************************/
int add_child(struct node *parent, struct node *child);
/*
* print_tree
@@ -65,13 +92,13 @@ void add_child(struct node *parent, struct node *child);
* struct node *root -> The tree to print
* int level -> The number of levels to descend
* RETURN VALUES:
* None.
* 0 on success, non-zero on error
* CAVEATS:
* None.
* EXAMPLE:
* print_tree(package, 0);
*/
void print_tree(struct node *root, int level);
int print_tree(struct node *root, int level);
#endif

View File

@@ -18,22 +18,34 @@
#ifndef GLOBALS_H_
#define GLOBALS_H_
#include <libconfig.h>
#include <stdio.h>
/* Constants */
#define BUFFER_SIZE 1024
#define MAX_SIZE 256
/* libconfig context */
extern config_t cfg;
extern config_setting_t *setting;
extern const char str;
extern char GLACIER_ALLOWED_LICENSES;
/* Configuration variables */
extern int GLACIER_ALLOW_SERVICES;
extern char *GLACIER_ALLOWED_LICENSES;
extern int GLACIER_DO_INT_CHECK;
extern int GLACIER_VERBOSE;
/* Profile variables */
extern const char *GLACIER_REPO;
extern const char *GLACIER_ARCH;
extern const char *GLACIER_TARGET;
extern const char *GLACIER_LOCALDB;
extern const char *GLACIER_SYSTEM_PROFILE;
const char *runtime_files[];
/* Required runtime files */
extern const char *runtime_files[];
/* File pointers for hashing operations */
extern FILE *expected_hash;
extern FILE *pkg;

View File

@@ -18,6 +18,12 @@
#ifndef GLACIERPKGOPS_H_
#define GLACIERPKGOPS_H_
/* Permission constant for workspace directory creation */
#define DEFAULT_PERMISSIONS 0750
/* Maximum size for path buffers */
#define PATH_MAX_SIZE 512
/*
* mkworkspace
*
@@ -25,14 +31,14 @@
* PARAMETERS:
* None.
* RETURN VAUES:
* 0 on success, 2 on library error
* 0 on workspace already exists, 1 on workspace created, -1 on error
* CAVEATS:
* None.
* EXAMPLE:
* mkworkspace();
*/
int mkworkspace();
int mkworkspace(void);
/*
* prepare_pkg
@@ -41,7 +47,7 @@ int mkworkspace();
* PARAMETERS:
* char PACKAGE[] -> The package file to prepare
* RETURN VAUES:
* 0 on success, 1 on package does not exist, or error untarring
* 0 on success, 1 on package does not exist or error, other values for specific errors
* CAVEATS:
* The example presented is bad. You should be calling the system profile variable
* rather than manually specifying one.
@@ -58,7 +64,7 @@ int prepare_pkg(char PACKAGE[]);
* PARAMETERS:
* char TASK[] -> The make task to run
* RETURN VAUES:
* 0 on success, 1 on failure
* 0 on success, other values for specific errors
* CAVEATS:
* MUST be run after prepare_pkg(), or else errors will occur
* Same caveat as above. Do not manually specify the system profile, use its variable.

View File

@@ -18,6 +18,9 @@
#ifndef GLACIERSECURITY_H_
#define GLACIERSECURITY_H_
typedef unsigned int uint;
typedef unsigned char uchar;
/*
* compare_file_hash
*
@@ -35,4 +38,61 @@
/* int compare_file_hash(char ORIG_HASH[], char FILE[]); */
/*
* hash_file
*
* DESCRIPTION: Performs a hashing operation on a file and stores the result
* PARAMETERS:
* const char *filename -> The file to hash
* unsigned char *out_hash -> Buffer to store the resulting hash
* unsigned int *out_length -> Will contain the length of the hash
* RETURN VALUES:
* 0 on success, other values for specific errors
* CAVEATS:
* out_hash buffer must be large enough to hold the hash (EVP_MAX_MD_SIZE recommended)
* EXAMPLE:
* unsigned char hash[EVP_MAX_MD_SIZE];
* unsigned int hash_len;
* hash_file("file.txt", hash, &hash_len);
*/
int hash_file(const char *filename, unsigned char *out_hash, unsigned int *out_length);
/*
* print_hash
*
* DESCRIPTION: Prints a specified hash string to stdout
* PARAMETERS:
* unsigned char *hash -> The hash to print
* unsigned int length -> Length of the hash
* RETURN VALUES:
* 0 on success, 1 on error
* CAVEATS:
* None
* EXAMPLE:
* print_hash(hash, hash_len);
*/
int print_hash(uchar *hash, uint length);
/*
* stash_hash
*
* DESCRIPTION: Stores a hash inside a string as hexadecimal representation
* PARAMETERS:
* char *stored_hash -> Buffer to store the resulting hash string
* unsigned int stored_hash_size -> Size of the stored_hash buffer
* const uchar *hash -> The hash to convert to string
* uint length -> Length of the hash
* RETURN VALUES:
* 0 on success, 1 on error
* CAVEATS:
* stored_hash buffer must be at least (length*2)+1 bytes in size
* EXAMPLE:
* char hash_str[65]; // 32 bytes SHA-256 = 64 hex chars + null terminator
* stash_hash(hash_str, sizeof(hash_str), hash, hash_len);
*/
int stash_hash(char *stored_hash, unsigned int stored_hash_size, const uchar *hash, uint length);
#endif