Added permanent permissions
Finally implemented the permanent permission tables using sqlite3. For now, performance wasn't a consideration. There are a lot of optimizations that could be made, like having prepared queries. The code remains fairly untested.
This commit is contained in:
parent
4ce97555e4
commit
7e111b16b7
8
Makefile
8
Makefile
@ -12,7 +12,7 @@ CXX := g++
|
|||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
|
|
||||||
PACKAGE_NAMES := fuse3
|
PACKAGE_NAMES := fuse3 sqlite3
|
||||||
|
|
||||||
ifeq ($(TEST), 1)
|
ifeq ($(TEST), 1)
|
||||||
# PACKAGE_NAMES += check # TODO: use check?
|
# PACKAGE_NAMES += check # TODO: use check?
|
||||||
@ -56,7 +56,7 @@ default: $(TARGETS)
|
|||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
|
|
||||||
$(BUILD_DIR)/icfs: $(BUILD_DIR)/main.o $(BUILD_DIR)/fuse_operations.o $(BUILD_DIR)/sourcefs.o $(BUILD_DIR)/ui-socket.o $(BUILD_DIR)/temp_permissions_table.o
|
$(BUILD_DIR)/icfs: $(BUILD_DIR)/main.o $(BUILD_DIR)/fuse_operations.o $(BUILD_DIR)/sourcefs.o $(BUILD_DIR)/ui-socket.o $(BUILD_DIR)/temp_permissions_table.o $(BUILD_DIR)/perm_permissions_table.o
|
||||||
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $(BUILD_DIR)/icfs
|
$(CC) $(CFLAGS) $^ $(LDFLAGS) -o $(BUILD_DIR)/icfs
|
||||||
|
|
||||||
icfs_test: $(BUILD_DIR)/icfs
|
icfs_test: $(BUILD_DIR)/icfs
|
||||||
@ -80,5 +80,9 @@ $(BUILD_DIR)/ui-socket.o: $(SOURCES_DIR)/ui-socket.c $(SOURCES_DIR)/ui-socket.h
|
|||||||
$(BUILD_DIR)/temp_permissions_table.o: $(SOURCES_DIR)/temp_permissions_table.c $(SOURCES_DIR)/temp_permissions_table.h
|
$(BUILD_DIR)/temp_permissions_table.o: $(SOURCES_DIR)/temp_permissions_table.c $(SOURCES_DIR)/temp_permissions_table.h
|
||||||
$(CC) $(CFLAGS) -c $< $(LDFLAGS) -o $@
|
$(CC) $(CFLAGS) -c $< $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/perm_permissions_table.o: $(SOURCES_DIR)/perm_permissions_table.c $(SOURCES_DIR)/perm_permissions_table.h
|
||||||
|
$(CC) $(CFLAGS) -c $< $(LDFLAGS) -o $@
|
||||||
|
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm $(BUILD_DIR)/*.o $(BUILD_DIR)/icfs*
|
rm $(BUILD_DIR)/*.o $(BUILD_DIR)/icfs*
|
||||||
|
@ -38,7 +38,7 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
ret = init_ui_socket();
|
ret = init_ui_socket();
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
perror("init_ui_socket");
|
fprintf(stderr, "Could not initalize ui-socket.\n");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
192
src/perm_permissions_table.c
Normal file
192
src/perm_permissions_table.c
Normal file
@ -0,0 +1,192 @@
|
|||||||
|
#include "perm_permissions_table.h"
|
||||||
|
#include "process_info.h"
|
||||||
|
#include <sqlite3.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
sqlite3 *perm_database = NULL;
|
||||||
|
const char *const table_name = "permissions";
|
||||||
|
// one row corresponds to a permission to access one file for one executable
|
||||||
|
const int column_count = 2;
|
||||||
|
const char *const schema[] = {"executable", "filename"};
|
||||||
|
const char *const types[] = {"TEXT", "TEXT"};
|
||||||
|
|
||||||
|
static int check_table_col_schema(void *notused, int argc, char **argv,
|
||||||
|
char **colname) {
|
||||||
|
(void)notused;
|
||||||
|
(void)colname;
|
||||||
|
if (argc < 3) {
|
||||||
|
fprintf(stderr, "Unexpected amount of arguments given to the callback.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int i = atoi(argv[0]);
|
||||||
|
if (i >= column_count) {
|
||||||
|
fprintf(stderr, "Table contains more columns than expected.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (strcmp(schema[i], argv[1]) == 0 && strcmp(types[i], argv[2]) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "Column %d does not conform to the schema.\n", i);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_flag(void *flag, int argc, char **argv, char **colname) {
|
||||||
|
(void)argc;
|
||||||
|
(void)argv;
|
||||||
|
(void)colname;
|
||||||
|
*(int *)flag = 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int create_database_schema() {
|
||||||
|
fprintf(stderr, "Creating table 'permissions'.\n");
|
||||||
|
const char *create_query = "CREATE TABLE permissions(executable TEXT NOT "
|
||||||
|
"NULL, filename TEXT NOT NULL);";
|
||||||
|
char *err = NULL;
|
||||||
|
int ret = sqlite3_exec(perm_database, create_query, NULL, NULL, &err);
|
||||||
|
|
||||||
|
if (ret != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "sqlite3 error: %s\n", err);
|
||||||
|
sqlite3_free(err);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Database created successfully\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that the database schema is correct.
|
||||||
|
*
|
||||||
|
* @return: 0 if the schema is correct, 1 if the schema could not be corrected.
|
||||||
|
*/
|
||||||
|
int ensure_database_schema() {
|
||||||
|
// Check for the table.
|
||||||
|
int result = sqlite3_table_column_metadata(
|
||||||
|
perm_database, NULL, table_name, NULL, NULL, NULL, NULL, NULL, NULL);
|
||||||
|
if (result == SQLITE_ERROR) {
|
||||||
|
fprintf(stderr, "Table '%s' does not exist.\n", table_name);
|
||||||
|
if (create_database_schema()) {
|
||||||
|
fprintf(stderr, "Table could not be created.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
} else if (result != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "Database metadata could not be retrieved.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *pragma = "PRAGMA table_info(permissions);";
|
||||||
|
char *err = NULL;
|
||||||
|
int ret =
|
||||||
|
sqlite3_exec(perm_database, pragma, check_table_col_schema, NULL, &err);
|
||||||
|
|
||||||
|
if (ret != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "sqlite3 error: %s\n", err);
|
||||||
|
sqlite3_free(err);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "Schema is correct.\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the permanent permissions table.
|
||||||
|
*
|
||||||
|
* @param db_filename: The filename of the permissions sqlite3 database
|
||||||
|
* @return: 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int init_perm_permissions_table(const char *db_filename) {
|
||||||
|
if (sqlite3_open(db_filename, &perm_database)) {
|
||||||
|
perror("Can't open permanent permissions database:");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (ensure_database_schema()) {
|
||||||
|
fprintf(stderr, "Database schema is not correct.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the permanent permissions table.
|
||||||
|
*/
|
||||||
|
void destroy_perm_permissions_table() { sqlite3_close(perm_database); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the process has a permanent access to the file.
|
||||||
|
*
|
||||||
|
* @param filename: The file that the process is trying to access
|
||||||
|
* @pram pi: The process information
|
||||||
|
* @return: 0 if access is denied, 1 if access is allowed
|
||||||
|
*/
|
||||||
|
int check_perm_access(const char *filename, struct process_info pi) {
|
||||||
|
size_t query_len =
|
||||||
|
56 + strlen(table_name) + strlen(filename) + strlen(pi.name);
|
||||||
|
const char *query = malloc(query_len);
|
||||||
|
size_t should_be_written = snprintf(
|
||||||
|
query, query_len,
|
||||||
|
"SELECT * FROM %s WHERE executable = \'%s\' AND filename = \'%s\';",
|
||||||
|
table_name, pi.name, filename);
|
||||||
|
// -1 for the \0
|
||||||
|
if (should_be_written != query_len - 1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Unexpected query size while permanent access rule check: "
|
||||||
|
"Expected %lu, but snprintf returned %lu. The query: %s\n",
|
||||||
|
query_len, should_be_written, query);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *sqlite_error = NULL;
|
||||||
|
int flag = 0;
|
||||||
|
int ret = sqlite3_exec(perm_database, query, set_flag, &flag, &sqlite_error);
|
||||||
|
if (ret != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "SQLite returned an error: %s\n", sqlite_error);
|
||||||
|
sqlite3_free(sqlite_error);
|
||||||
|
free(query);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(query);
|
||||||
|
return flag;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives permanent access to the process to the file.
|
||||||
|
*
|
||||||
|
* @param filename: The file that the process is trying to access
|
||||||
|
* @param pi: The process information
|
||||||
|
* @return: 0 on success, 1 on failure
|
||||||
|
*/
|
||||||
|
int give_perm_access(const char *filename, struct process_info pi) {
|
||||||
|
size_t query_len =
|
||||||
|
30 + strlen(table_name) + strlen(filename) + strlen(pi.name);
|
||||||
|
const char *query = malloc(query_len);
|
||||||
|
size_t should_be_written =
|
||||||
|
snprintf(query, query_len, "INSERT INTO %s VALUES (\'%s\', \'%s\');",
|
||||||
|
table_name, pi.name, filename);
|
||||||
|
// -1 for the \0
|
||||||
|
if (should_be_written != query_len - 1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Unexpected query size while permanent access rule insertion: "
|
||||||
|
"Expected %lu, but snprintf returned %lu\n",
|
||||||
|
query_len, should_be_written);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *sqlite_error = NULL;
|
||||||
|
int ret = sqlite3_exec(perm_database, query, NULL, NULL, &sqlite_error);
|
||||||
|
if (ret != SQLITE_OK) {
|
||||||
|
fprintf(stderr, "SQLite returned an error: %s\n", sqlite_error);
|
||||||
|
sqlite3_free(sqlite_error);
|
||||||
|
free(query);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(query);
|
||||||
|
return 0;
|
||||||
|
}
|
38
src/perm_permissions_table.h
Normal file
38
src/perm_permissions_table.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
|
||||||
|
#ifndef PERM_PERMISSION_TABLE_H
|
||||||
|
#define PERM_PERMISSION_TABLE_H
|
||||||
|
|
||||||
|
#include "process_info.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the permanent permissions table.
|
||||||
|
*
|
||||||
|
* @param db_filename: The filename of the permissions sqlite3 database
|
||||||
|
* @return: 0 on success, -1 on failure (e.g. ENOMEM)
|
||||||
|
*/
|
||||||
|
int init_perm_permissions_table(const char *db_filename);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the permanent permissions table.
|
||||||
|
*/
|
||||||
|
void destroy_perm_permissions_table();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the process has a permanent access to the file.
|
||||||
|
*
|
||||||
|
* @param filename: The file that the process is trying to access
|
||||||
|
* @pram pi: The process information
|
||||||
|
* @return: 0 if access is denied, 1 if access is allowed
|
||||||
|
*/
|
||||||
|
int check_perm_access(const char *filename, struct process_info pi);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gives permanent access to the process to the file.
|
||||||
|
*
|
||||||
|
* @param filename: The file that the process is trying to access
|
||||||
|
* @param pi: The process information
|
||||||
|
* @return: 0 on success, -1 on failure
|
||||||
|
*/
|
||||||
|
int give_perm_access(const char *filename, struct process_info pi);
|
||||||
|
|
||||||
|
#endif // #ifdef PERM_PERMISSION_TABLE_H
|
@ -11,6 +11,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#define _GNU_SOURCE
|
#define _GNU_SOURCE
|
||||||
#include "cc.h"
|
#include "cc.h"
|
||||||
|
#include "perm_permissions_table.h"
|
||||||
#include "temp_permissions_table.h"
|
#include "temp_permissions_table.h"
|
||||||
#include "ui-socket.h"
|
#include "ui-socket.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
@ -26,7 +27,16 @@ int init_ui_socket() {
|
|||||||
char line[256];
|
char line[256];
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
init_temp_permissions_table();
|
if (init_temp_permissions_table()) {
|
||||||
|
fprintf(stderr, "Could not initialize temporary permissions table.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (init_perm_permissions_table(
|
||||||
|
"/home/fedir/Developement/uni/ICFS/test/.pt.db")) {
|
||||||
|
fprintf(stderr, "Could not initialize permanent permissions table.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Test if Zenity is installed (get version)
|
// Test if Zenity is installed (get version)
|
||||||
fp = popen("zenity --version", "r");
|
fp = popen("zenity --version", "r");
|
||||||
@ -41,7 +51,10 @@ int init_ui_socket() {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void destroy_ui_socket() { destroy_temp_permissions_table(); }
|
void destroy_ui_socket() {
|
||||||
|
destroy_temp_permissions_table();
|
||||||
|
destroy_perm_permissions_table();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Asks the user if the process should be allowed to access the file using the
|
* Asks the user if the process should be allowed to access the file using the
|
||||||
@ -53,7 +66,6 @@ void destroy_ui_socket() { destroy_temp_permissions_table(); }
|
|||||||
* for the runtime of the process
|
* for the runtime of the process
|
||||||
*/
|
*/
|
||||||
int ask_access(const char *filename, struct process_info pi) {
|
int ask_access(const char *filename, struct process_info pi) {
|
||||||
|
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
size_t command_len =
|
size_t command_len =
|
||||||
139 + sizeof(pid_t) * 8 + strlen(pi.name) + strlen(filename);
|
139 + sizeof(pid_t) * 8 + strlen(pi.name) + strlen(filename);
|
||||||
@ -86,6 +98,7 @@ int ask_access(const char *filename, struct process_info pi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int zenity_exit_code = WEXITSTATUS(pclose(fp));
|
int zenity_exit_code = WEXITSTATUS(pclose(fp));
|
||||||
|
fprintf(stderr, "zenity returned %d\n", zenity_exit_code);
|
||||||
// zenity returns 1 on "No" >:(
|
// zenity returns 1 on "No" >:(
|
||||||
if (zenity_exit_code == 0) {
|
if (zenity_exit_code == 0) {
|
||||||
return 1;
|
return 1;
|
||||||
@ -94,22 +107,6 @@ int ask_access(const char *filename, struct process_info pi) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the process has a permanent access to the file.
|
|
||||||
*
|
|
||||||
* @param filename: The file that the process is trying to access
|
|
||||||
* @pram pi: The process information
|
|
||||||
* @return: 0 if access is denied, 1 if access is allowed
|
|
||||||
*/
|
|
||||||
int check_perm_access(const char *filename, struct process_info pi) {
|
|
||||||
perror("Not implemented");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
int give_perm_access(const char *filename, struct process_info pi) {
|
|
||||||
perror("Not implemented");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check access according to:
|
* Check access according to:
|
||||||
* 1. temp permission table
|
* 1. temp permission table
|
||||||
|
Loading…
x
Reference in New Issue
Block a user