diff --git a/test/opener/opener.c b/test/opener/opener.c index 1cd4fb5..51ce934 100644 --- a/test/opener/opener.c +++ b/test/opener/opener.c @@ -1,20 +1,86 @@ - - +#include +#include #include #include +#include +#include +#include +#include #include + +#define PATH_MAX 4096 + int main(int argc, char *argv[]) { + // Check for correct usage if (argc != 2) { - fprintf(stderr, "Usage: ./opener [FILENAME]"); + fprintf(stderr, "Usage: %s \n", argv[0]); return 1; } - int fd = open(argv[1], O_RDWR | O_CREAT); - if (fd == -1) { - perror("Cannot open file"); + const char *path = argv[1]; + struct stat statbuf; + + // Stat the given path to determine if it's a directory + if (lstat(path, &statbuf) == -1) { + perror("lstat"); return 1; } - close(fd); - return 0; + // Case 1: The path is not a directory + if (!S_ISDIR(statbuf.st_mode)) { + int fd = open(path, O_RDONLY); + if (fd == -1) { + perror("open"); + return 1; + } + close(fd); + return 0; + } + + // Case 2: The path is a directory + DIR *dirp = opendir(path); + if (dirp == NULL) { + perror("opendir"); + return 1; + } + + struct dirent *entry; + int success = 1; + + while ((entry = readdir(dirp)) != NULL) { + // Skip . and .. + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { + continue; + } + + // Construct the full path + char fullpath[PATH_MAX]; + snprintf(fullpath, PATH_MAX, "%s/%s", path, entry->d_name); + + // Stat the entry to check if it's a regular file + struct stat entry_stat; + if (lstat(fullpath, &entry_stat) == -1) { + perror("lstat"); + success = 0; + break; + } + + // Only process regular files + if (!S_ISREG(entry_stat.st_mode)) { + continue; + } + + // Try to open and immediately close the file + int fd = open(fullpath, O_RDONLY); + if (fd == -1) { + perror("open"); + success = 0; + break; + } + close(fd); + } + + closedir(dirp); + + return (success ? 0 : 1); } diff --git a/test/test.bash b/test/test.bash index ba0d9c8..e287240 100755 --- a/test/test.bash +++ b/test/test.bash @@ -160,27 +160,54 @@ openers/symlinked_opener2 ./protected/motto >/dev/null 2>/dev/null && # test permission globbing +icfs_dialogue --set-fake-response yes +icfs_dialogue --set-fake-response-filename "/" +openers/opener3 ./protected/haystack >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: OK" || + echo "[ICFS-TEST]: openers/opener3 cannot read protected/haystack/needle despite access being permitted!" # OK + +icfs_dialogue --set-fake-response no +icfs_dialogue --set-fake-response-filename "/" +openers/opener4 ./protected/haystack >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: openers/opener4 can read files in protected/haystack despite access being denied!" || + echo "[ICFS-TEST]: OK" # EACCESS + icfs_dialogue --set-fake-response yes_perm icfs_dialogue --set-fake-response-filename "/" -grep 'Liberty' ./protected/haystack/needle >/dev/null && +openers/opener5 ./protected/haystack/needle >/dev/null 2>/dev/null && echo "[ICFS-TEST]: OK" || - echo "[ICFS-TEST]: grep cannot read protected/motto despite access being permitted!" # OK + echo "[ICFS-TEST]: openers/opener5 cannot read protected/haystack/needle despite access being permitted!" # OK icfs_dialogue --set-fake-response no # this should be ignored -grep "Liberty" ./protected/haystack/* >/dev/null && +openers/opener5 ./protected/haystack >/dev/null 2>/dev/null && echo "[ICFS-TEST]: OK" || - echo "[ICFS-TEST]: grep cannot read protected/motto despite access being permitted!" # OK + echo "[ICFS-TEST]: openers/opener5 cannot read files in protected/haystack despite access being permitted!" # OK + +icfs_dialogue --set-fake-response no_perm +icfs_dialogue --set-fake-response-filename "/" +openers/opener6 ./protected/haystack/needle >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: openers/opener6 can read protected/haystack/needle despite access being denied!" || + echo "[ICFS-TEST]: OK" # EACCESS + +icfs_dialogue --set-fake-response yes # this should be ignored +openers/opener6 ./protected/haystack >/dev/null 2>/dev/null && + echo "[ICFS-TEST]: openers/opener6 can read files in protected/haystack despite access being denied!" || + echo "[ICFS-TEST]: OK" # EACCESS # test database access -if [[ -r "./.pt.db" || -w "./.pt.db" ]]; then - echo "[ICFS-TEST]: permanent permissions database is accessible!" +if [[ $1 == '--setuid' ]]; then + if [[ -r "./.pt.db" || -w "./.pt.db" ]]; then + echo "[ICFS-TEST]: permanent permissions database is accessible!" + else + echo "[ICFS-TEST]: OK" + fi else - echo "[ICFS-TEST]: OK" + echo "[ICFS-TEST]: permanent permissions database access was not tested due to the lack of seuid bit setting capabilites. To test this, run the script with '--setuid' flag" fi # unmount sleep 0.5 #lsof +f -- $(realpath ./protected) -umount $(realpath ./protected) +umount "$(realpath ./protected)" sleep 0.5