diff --git a/.gitignore b/.gitignore index 0d22fd3..8a10fb8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ build/* .clang-tidy .cache +test/protected/* diff --git a/Makefile b/Makefile index 96d7890..8ffddeb 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,34 @@ SHELL=/bin/bash +# configurable options + +SOURCES_DIR := ./src +TESTS_DIR := ./tests +BUILD_DIR := ./build + CC := gcc CXX := g++ -CFLAGS := -I/usr/include/fuse -D_FILE_OFFSET_BITS=64 -LDFLAGS := -lfuse3 -pthread -ifdef DEBUG - CFLAGS += -O0 -pedantic -Wall -Wextra -Wcast-align \ +# dependencies + +PACKAGE_NAMES := fuse3 + +ifeq ($(TEST), 1) + # PACKAGE_NAMES += check # TODO: use check? +endif + + +# set up cflags and libs + +CFLAGS := -D_FILE_OFFSET_BITS=64 +LDFLAGS := + +CFLAGS += $(shell pkg-config --cflags $(PACKAGE_NAMES)) +LDFLAGS += $(shell pkg-config --libs $(PACKAGE_NAMES)) + +ifeq ($(DEBUG),1) + CFLAGS += -O0 -pedantic -g -Wall -Wextra -Wcast-align \ -Wcast-qual -Wdisabled-optimization -Wformat=2 \ -Winit-self -Wlogical-op -Wmissing-declarations \ -Wmissing-include-dirs -Wredundant-decls -Wshadow \ @@ -19,12 +40,32 @@ else LDFLAGS += endif -SOURCES_DIR := ./src -BUILD_DIR := ./build -build: $(BUILD_DIR)/main.o $(BUILD_DIR)/fuse_operations.o $(BUILD_DIR)/sourcefs.o $(BUILD_DIR)/ui-socket.o +# set up targets + +TARGETS := icfs + +ifeq ($(TEST), 1) + TARGETS += icfs_test +endif + + +# build! + +default: $(TARGETS) + +.PHONY: clean + +icfs: $(BUILD_DIR)/main.o $(BUILD_DIR)/fuse_operations.o $(BUILD_DIR)/sourcefs.o $(BUILD_DIR)/ui-socket.o $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $(BUILD_DIR)/icfs +icfs_test: $(BUILD_DIR)/main.o $(BUILD_DIR)/fuse_operations.o $(BUILD_DIR)/sourcefs.o $(BUILD_DIR)/ui-socket.o + $(CC) $(CFLAGS) $^ $(LDFLAGS) -o $(BUILD_DIR)/icfs_test + # $(BUILD_DIR)/icfs_test # TODO: implement testing + +$(BUILD_DIR)/test_access_control.o: $(TESTS_DIR)/test_access_control.c + $(CC) $(CFLAGS) -c $< $(LDFLAGS) -o $@ + $(BUILD_DIR)/main.o: $(SOURCES_DIR)/main.c $(CC) $(CFLAGS) -c $< $(LDFLAGS) -o $(BUILD_DIR)/main.o @@ -38,4 +79,4 @@ $(BUILD_DIR)/ui-socket.o: $(SOURCES_DIR)/ui-socket.c $(SOURCES_DIR)/ui-socket.h $(CC) $(CFLAGS) -c $< $(LDFLAGS) -o $@ clean: - rm $(BUILD_DIR)/* + rm $(BUILD_DIR)/*.o $(BUILD_DIR)/icfs* diff --git a/README.md b/README.md index db45191..bf66d92 100644 --- a/README.md +++ b/README.md @@ -12,15 +12,17 @@ Traditional access control mechanisms in operating systems allow the same level ## Building -* Install dependencies - + fuse, libfuse (v3 or later) - - Debian: `sudo apt install fuse3 libfuse3-dev` - + zenity - - Debian: `sudo apt install zenity` -* Build using `make`: - + In the project directory: `make` - + Use `make DEBUG=1` for testing. -* Resulting binaries should appear in the `build` directory. +- Install dependencies + - libfuse3 + - Debian: `sudo apt install fuse3 libfuse3-dev` + - zenity + - Debian: `sudo apt install zenity` + - Build tools + - Debian: `sudo apt install gcc make pkg-config` +- Build using `make`: + - In the project directory: `make` + - Use `make DEBUG=1` for testing. +- Resulting binaries should appear in the `build` directory. ## Usage diff --git a/test/mock/zenity b/test/mock/zenity new file mode 100755 index 0000000..be62934 --- /dev/null +++ b/test/mock/zenity @@ -0,0 +1,23 @@ +#!/bin/bash + +# fake-zenity: script that mocks the behavior of zenity based on the ./.fake-zenity-response file + +if [[ $1 == "--set-fake-response" ]]; then + #someone knows we are fake :) + echo $2 >~/.fake_zenity_response +else + if [ -f ~/.fake_zenity_response ]; then + FAKE_ZENITY_RESPONSE=$(cat ~/.fake_zenity_response) + + if [[ $FAKE_ZENITY_RESPONSE == "yes_tmp" ]]; then + printf "Allow this time\n" + exit 1 + elif [[ $FAKE_ZENITY_RESPONSE == "no" ]]; then + exit 1 + elif [[ $FAKE_ZENITY_RESPONSE == "yes" ]]; then + exit 0 + fi + fi +fi + +exit -1 # TODO: call actual zenity here diff --git a/test/test.bash b/test/test.bash new file mode 100755 index 0000000..3cfc42e --- /dev/null +++ b/test/test.bash @@ -0,0 +1,73 @@ +#!/bin/bash + +# clean what was left from previous tests + +rm -rf ./protected +mkdir protected +touch ./protected/do-not-remove ./protected/should-be-removed +echo "Free code, free world." >./protected/this-only + +# set up the fake-zenity + +PATH="$(realpath ./mock/):$PATH" + +# mount the filesystem + +echo "Run $(date -u +%Y-%m-%dT%H:%M:%S) " +valgrind -s ../build/icfs -o default_permissions ./protected & + +sleep 1 + +# Try to touch files in the directory + +#echo \"manual\" >./protected/manual + +zenity --set-fake-response no +echo "first" >./protected/first 2>/dev/null && + echo "[ICFS-TEST]: echo can create protected/first despite access being denied!" || + echo "[ICFS-TEST]: OK" # EACCESS + +zenity --set-fake-response yes_tmp +echo "second" >./protected/second 2>/dev/null && + echo "[ICFS-TEST]: OK" || + echo "[ICFS-TEST]: echo cannot create protected/second despite access being permitted!" # OK + +# Test whether permissons work + +zenity --set-fake-response yes_tmp +cat ./protected/first >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: cat can read a non-existant file ./protected/first!" || + echo "[ICFS-TEST]: OK" # ENOENT + +zenity --set-fake-response yes_tmp +cat ./protected/second >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: OK" || + echo "[ICFS-TEST]: cat cannot open protected/second despite access being permitted!" # "second" + +zenity --set-fake-response yes_tmp +cat ./protected/this-only >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: OK" || + echo "[ICFS-TEST]: echo cannot create protected/second despite access being permitted!" # "Free code, free world." + +#parallel ::: "cat ./protected/sudo-only > /dev/null 2> /dev/null \ +# && echo \"[ICFS-TEST]: cat can access files owned by root!\" \ +# || echo \"[ICFS-TEST]: OK\"" # EACCESS + +# test the removal + +zenity --set-fake-response no +rm ./protected/do-not-remove >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: rm can unlink protected/do-not-remove despite access being denied!" || + echo "[ICFS-TEST]: OK" # EACCESS + +zenity --set-fake-response yes_tmp +rm ./protected/should-be-removed >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: OK" || + echo "[ICFS-TEST]: rm cannot unlink protected/should-be-removed despite access being permitted!" # OK + +# unmount + +sleep 0.5 +#lsof +f -- $(realpath ./protected) +umount $(realpath ./protected) +sleep 0.5