#include "sandbox.h" #include "entry.h" #include #include #include #include #include #include Command COMMANDS[] = { {CommandHelp, "help", "[command]", "Prints this help message.", "TODO: Add details."}, {CommandVersion, "version", NULL, "Prints the version of the program.", "TODO: Add details."}, {}, {CommandAddEntry, "add-entry", "", "Adds a new entry to the sandbox.", "TODO: Add details."}, {CommandRemoveEntry, "remove-entry", "", "Removes an entry from the sandbox.", "TODO: Add details."}, {CommandListEntries, "list-entries", NULL, "Lists all the entries in the sandbox.", "TODO: Add details."}, {CommandClearEntries, "clear-entries", NULL, "Clears all the entries from the sandbox.", "TODO: Add details."}, }; int main(int argc, char* argv[]) { struct passwd* pw = getpwnam(SANDBOX_USER); if (pw == NULL) { Log(LOG_LEVEL_ERROR, "Failed to get the 'sandbox' user (%s).", strerror(errno)); return EXIT_FAILURE; } // Check if the current user is root or the 'sandbox' user if (getuid() != 0 && getuid() != pw->pw_uid) { Log(LOG_LEVEL_ERROR, "You must be root or the 'sandbox' user to use this program."); return EXIT_FAILURE; } // Try and switch to the 'sandbox' user if we are root if (geteuid() == 0) { if (setregid(pw->pw_gid, pw->pw_gid) == -1) { Log(LOG_LEVEL_ERROR, "Failed to set the real and effective group ID to the 'sandbox' user (%s).", strerror(errno)); return EXIT_FAILURE; } if (setreuid(pw->pw_uid, pw->pw_uid) == -1) { Log(LOG_LEVEL_ERROR, "Failed to set the real and effective user ID to the 'sandbox' user (%s).", strerror(errno)); return EXIT_FAILURE; } } // If there are no arguments, print the help message if (argc == 1) return CommandHelp(0, NULL); const char* input = argv[1]; size_t input_length = strlen(input); const Command* command = NULL; for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) { if (COMMANDS[i].name == NULL) continue; if (input_length > strlen(COMMANDS[i].name)) continue; if (strncmp(input, COMMANDS[i].name, input_length) == 0) { if (command != NULL) { Log(LOG_LEVEL_ERROR, "Ambiguous command '%s'.", input); return EXIT_FAILURE; } command = &COMMANDS[i]; } } if (command == NULL) { Log(LOG_LEVEL_ERROR, "Unknown command '%s'.", input); return EXIT_FAILURE; } return command->handler(argc - 2, argv + 2); } int CommandHelp(int argc, char* argv[]) { if (argc == 0) { fprintf(stdout, "Usage: sandbox [arguments] [options]\n"); fprintf(stdout, "\n"); fprintf(stdout, "Commands:\n"); for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) { if (COMMANDS[i].name == NULL) { fprintf(stdout, "\n"); continue; } fprintf(stdout, " %s", COMMANDS[i].name); if (COMMANDS[i].arguments != NULL) fprintf(stdout, " %s", COMMANDS[i].arguments); fprintf(stdout, " - %s\n", COMMANDS[i].description); } fprintf(stdout, "\nFor more information, run 'sandbox help '.\n"); return EXIT_SUCCESS; } else if (argc == 1) { const char* input = argv[0]; for (size_t i = 0; i < sizeof(COMMANDS) / sizeof(COMMANDS[0]); i++) { if (COMMANDS[i].name == NULL) continue; if (strcmp(input, COMMANDS[i].name) == 0) { fprintf(stdout, "Usage: sandbox %s", COMMANDS[i].name); if (COMMANDS[i].arguments != NULL) fprintf(stdout, " %s", COMMANDS[i].arguments); fprintf(stdout, "\n %s\n\n %s\n", COMMANDS[i].description, COMMANDS[i].details); return EXIT_SUCCESS; } } Log(LOG_LEVEL_ERROR, "Unknown command '%s'.", input); return EXIT_FAILURE; } else { Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'help'."); return EXIT_FAILURE; } return EXIT_SUCCESS; } int CommandVersion(int argc, char* argv[]) { fprintf(stdout, "Sandbox utility v%s\n", VERSION); return EXIT_SUCCESS; } int CommandAddEntry(int argc, char* argv[]) { if (argc < 1) { Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'add-entry'."); return EXIT_FAILURE; } else if (argc > 1) { Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'add-entry'."); return EXIT_FAILURE; } return AddEntry(argv[0]); } int CommandRemoveEntry(int argc, char* argv[]) { if (argc < 1) { Log(LOG_LEVEL_ERROR, "Too few arguments supplied to 'remove-entry'."); return EXIT_FAILURE; } else if (argc > 1) { Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'remove-entry'."); return EXIT_FAILURE; } return RemoveEntry(argv[0]); } int CommandListEntries(int argc, char* argv[]) { if (argc > 0) { Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'list-entries'."); return EXIT_FAILURE; } char** entries = NULL; Status status = ListEntries(&entries); if (status != SUCCESS) return status; for (size_t i = 0; entries[i] != NULL; i++) fprintf(stdout, "%s\n", entries[i]); for (size_t i = 0; entries[i] != NULL; i++) free(entries[i]); free(entries); return EXIT_SUCCESS; } int CommandClearEntries(int argc, char* argv[]) { if (argc > 0) { Log(LOG_LEVEL_ERROR, "Too many arguments supplied to 'clear-entries'."); return EXIT_FAILURE; } return ClearEntries(); }