new-dialogue #8
@@ -1,20 +1,86 @@
 | 
				
			|||||||
 | 
					#include <dirent.h>
 | 
				
			||||||
 | 
					#include <errno.h>
 | 
				
			||||||
#include <fcntl.h>
 | 
					#include <fcntl.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <string.h>
 | 
				
			||||||
 | 
					#include <sys/stat.h>
 | 
				
			||||||
 | 
					#include <sys/types.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define PATH_MAX 4096
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int main(int argc, char *argv[]) {
 | 
					int main(int argc, char *argv[]) {
 | 
				
			||||||
 | 
					  // Check for correct usage
 | 
				
			||||||
  if (argc != 2) {
 | 
					  if (argc != 2) {
 | 
				
			||||||
    fprintf(stderr, "Usage: ./opener [FILENAME]");
 | 
					    fprintf(stderr, "Usage: %s <pathname>\n", argv[0]);
 | 
				
			||||||
    return 1;
 | 
					    return 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  int fd = open(argv[1], O_RDWR | O_CREAT);
 | 
					  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;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Case 1: The path is not a directory
 | 
				
			||||||
 | 
					  if (!S_ISDIR(statbuf.st_mode)) {
 | 
				
			||||||
 | 
					    int fd = open(path, O_RDONLY);
 | 
				
			||||||
    if (fd == -1) {
 | 
					    if (fd == -1) {
 | 
				
			||||||
    perror("Cannot open file");
 | 
					      perror("open");
 | 
				
			||||||
      return 1;
 | 
					      return 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    close(fd);
 | 
					    close(fd);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    return 0;
 | 
					    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);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -160,27 +160,54 @@ openers/symlinked_opener2 ./protected/motto >/dev/null 2>/dev/null &&
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# test permission globbing
 | 
					# 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 yes_perm
 | 
				
			||||||
icfs_dialogue --set-fake-response-filename "/"
 | 
					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]: 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
 | 
					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]: 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
 | 
					# test database access
 | 
				
			||||||
 | 
					if [[ $1 == '--setuid' ]]; then
 | 
				
			||||||
  if [[ -r "./.pt.db" || -w "./.pt.db" ]]; then
 | 
					  if [[ -r "./.pt.db" || -w "./.pt.db" ]]; then
 | 
				
			||||||
    echo "[ICFS-TEST]: permanent permissions database is accessible!"
 | 
					    echo "[ICFS-TEST]: permanent permissions database is accessible!"
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    echo "[ICFS-TEST]: OK"
 | 
					    echo "[ICFS-TEST]: OK"
 | 
				
			||||||
  fi
 | 
					  fi
 | 
				
			||||||
 | 
					else
 | 
				
			||||||
 | 
					  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
 | 
					# unmount
 | 
				
			||||||
 | 
					
 | 
				
			||||||
sleep 0.5
 | 
					sleep 0.5
 | 
				
			||||||
#lsof +f -- $(realpath ./protected)
 | 
					#lsof +f -- $(realpath ./protected)
 | 
				
			||||||
umount $(realpath ./protected)
 | 
					umount "$(realpath ./protected)"
 | 
				
			||||||
sleep 0.5
 | 
					sleep 0.5
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user