diff options
-rw-r--r-- | CMakeLists.txt | 13 | ||||
-rw-r--r-- | src/config.c | 51 | ||||
-rw-r--r-- | src/config.h | 5 | ||||
-rw-r--r-- | src/git.c | 80 | ||||
-rw-r--r-- | src/precheck.c | 38 |
5 files changed, 22 insertions, 165 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 1483ed6..832eadd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,11 +20,6 @@ FetchContent_MakeAvailable(cjson) # CMocka find_package(cmocka REQUIRED) -# Libcap (only when building for Linux) -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - find_library(CAP_LIBRARY cap REQUIRED) -endif () - # Python find_package(Python3 REQUIRED COMPONENTS Interpreter) @@ -76,12 +71,6 @@ target_include_directories(github_mirror PRIVATE ${cjson_SOURCE_DIR} ${CMAKE_CUR add_dependencies(github_mirror generate_graphql_headers) install(TARGETS github_mirror DESTINATION bin) -# Libcap (only when building for Linux) -if (CMAKE_SYSTEM_NAME STREQUAL "Linux") - target_link_libraries(github_mirror PRIVATE ${CAP_LIBRARY}) - target_include_directories(github_mirror PRIVATE /usr/include) -endif () - # Compile Options target_compile_options(github_mirror PRIVATE -Wall @@ -125,7 +114,7 @@ set(CPACK_PACKAGE_NAME "github_mirror") set(CPACK_PACKAGE_VERSION "0.1.0") set(CPACK_PACKAGE_CONTACT "ansg191@anshulg.com") set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Anshul Gupta") -set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.28), libcurl4 (>= 7.64), libcap2 (>= 1.24)") +set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.28), libcurl4 (>= 7.64)") set(CPACK_GENERATOR "DEB") include(CPack) diff --git a/src/config.c b/src/config.c index d20f4f5..7f610a6 100644 --- a/src/config.c +++ b/src/config.c @@ -7,7 +7,6 @@ #include <ctype.h> #include <fcntl.h> #include <grp.h> -#include <pwd.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -16,11 +15,11 @@ #include <unistd.h> const char *config_locations[] = { - "/etc/github_mirror/config.ini", - "/usr/local/etc/github_mirror/config.ini", - "/usr/local/github_mirror/config.ini", - "config.ini", - NULL, + "/etc/github_mirror/config.ini", + "/usr/local/etc/github_mirror/config.ini", + "/usr/local/github_mirror/config.ini", + "config.ini", + NULL, }; enum config_section { @@ -84,10 +83,6 @@ static char *trim(char *start, char *end) static int parse_line_inner(struct config *cfg, enum config_section section, char *key, char *value) { - char *endptr; - struct passwd *pw; - struct group *gr; - switch (section) { case section_none: fprintf(stderr, @@ -113,39 +108,7 @@ static int parse_line_inner(struct config *cfg, enum config_section section, case section_git: if (!strcmp(key, "base")) cfg->git_base = value; - else if (!strcmp(key, "owner")) { - // If the value is a number, set the owner to that - // number - cfg->git_owner = strtol(value, &endptr, 10); - if (*endptr == '\0') - return 0; - - // Otherwise, convert the string into a uid - if (!((pw = getpwnam(value)))) { - fprintf(stderr, - "Error parsing config file: unknown " - "user: %s\n", - value); - return -1; - } - cfg->git_owner = pw->pw_uid; - } else if (!strcmp(key, "group")) { - // If the value is a number, set the group to that - // number - cfg->git_group = strtol(value, &endptr, 10); - if (*endptr == '\0') - return 0; - - // Otherwise, convert the string into a gid - if (!((gr = getgrnam(value)))) { - fprintf(stderr, - "Error parsing config file: unknown " - "group: %s\n", - value); - return -1; - } - cfg->git_group = gr->gr_gid; - } else { + else { fprintf(stderr, "Error parsing config file: unknown key: %s\n", key); @@ -247,8 +210,6 @@ static void config_defaults(struct config *cfg) cfg->endpoint = GH_DEFAULT_ENDPOINT; cfg->user_agent = GH_DEFAULT_USER_AGENT; cfg->git_base = "/srv/git"; - cfg->git_owner = getuid(); - cfg->git_group = getgid(); } static int config_validate(const struct config *cfg) diff --git a/src/config.h b/src/config.h index 0d7d827..2fa32d2 100644 --- a/src/config.h +++ b/src/config.h @@ -6,7 +6,6 @@ #define CONFIG_H #include <stdlib.h> -#include <sys/types.h> #define GH_DEFAULT_ENDPOINT "https://api.github.com/graphql" #define GH_DEFAULT_USER_AGENT "github_mirror/0.1" @@ -28,10 +27,6 @@ struct config { /// The filepath to the git mirrors /// Default: /srv/git const char *git_base; - /// User to give ownership of the git mirrors - uid_t git_owner; - /// Group to give ownership of the git mirrors - gid_t git_group; }; /** @@ -94,37 +94,11 @@ static char *add_url_auth(const char *url, const char *user, const char *token) } /** - * Drops the permissions of the current process to the specified user and group. - * @param ctx Repository context - * @return 0 on success, -1 on error - */ -static int drop_perms(const struct repo_ctx *ctx) -{ - // Drop supplementary groups - if (setgroups(0, NULL) != 0) { - perror("setgroups"); - return -1; - } - // Set gid - if (setgid(ctx->cfg->git_group) == -1) { - perror("setgid"); - return -1; - } - // Set uid - if (setuid(ctx->cfg->git_owner) == -1) { - perror("setuid"); - return -1; - } - return 0; -} - -/** * Checks if the git repository at the specified path is a mirror. * @param path Path to the git repository - * @param ctx Repository context * @return 1 if the repository is a mirror, 0 if not */ -static int contains_mirror(const char *path, const struct repo_ctx *ctx) +static int contains_mirror(const char *path) { const pid_t pid = fork(); if (pid < 0) { @@ -148,9 +122,7 @@ static int contains_mirror(const char *path, const struct repo_ctx *ctx) } close(devnull); - // Change uid and gid to the user specified in the config - if (drop_perms(ctx)) - _exit(127); + // Run git char *args[] = { "git", "--git-dir", (char *) path, "config", "--get", "remote.origin.mirror", @@ -201,10 +173,7 @@ static int create_mirror(const char *path, const struct repo_ctx *ctx) char *url = add_url_auth(ctx->url, ctx->username, ctx->cfg->token); - // Change uid and gid to the user specified in the config - if (drop_perms(ctx)) - _exit(127); - + // Run git char *args[] = { "git", "clone", "--mirror", url, (char *) path, NULL, @@ -247,12 +216,6 @@ static int create_git_path(const struct repo_ctx *ctx) free(owner_path); return -1; } - // Set the permissions of the owner directory to 0775 - if (chmod(owner_path, 0775) == -1) { - perror("chmod"); - free(owner_path); - return -1; - } free(owner_path); // Create repo directory if it doesn't exist @@ -265,14 +228,6 @@ static int create_git_path(const struct repo_ctx *ctx) free(repo_path); return -1; } - - // Chown the repo directory to the specified user and group - if (chown(repo_path, ctx->cfg->git_owner, ctx->cfg->git_group) == -1) { - perror("chown"); - free(repo_path); - return -1; - } - free(repo_path); return 0; } @@ -280,10 +235,9 @@ static int create_git_path(const struct repo_ctx *ctx) /** * Updates the git repository at the specified path from the remote. * @param path Full path to the git repository - * @param ctx Context containing the repository information * @return 0 on success, -1 on error */ -static int update_mirror(const char *path, const struct repo_ctx *ctx) +static int update_mirror(const char *path) { const pid_t pid = fork(); if (pid < 0) { @@ -293,10 +247,6 @@ static int update_mirror(const char *path, const struct repo_ctx *ctx) if (pid == 0) { // Child process - // Change uid and gid to the user specified in the config - if (drop_perms(ctx)) - _exit(127); - char *args[] = { "git", "--git-dir", (char *) path, "remote", "update", "--prune", NULL, @@ -324,6 +274,7 @@ static int update_mirror(const char *path, const struct repo_ctx *ctx) int git_mirror_repo(const struct repo_ctx *ctx) { + int ret = 0; char *path = get_git_path(ctx->cfg->git_base, ctx->cfg->owner, ctx->name); if (!path) { @@ -332,31 +283,30 @@ int git_mirror_repo(const struct repo_ctx *ctx) } // Check whether repo exists - if (contains_mirror(path, ctx)) { + if (contains_mirror(path)) { // Repo exists, so we can just update it printf("Repo already exists, updating...\n"); - if (update_mirror(path, ctx) == -1) { + if (update_mirror(path) == -1) { perror("update_mirror"); - free(path); - return -1; + ret = -1; + goto end; } - free(path); - return 0; + goto end; } // Repo does not exist, so we need to clone it printf("Repo does not exist, cloning...\n"); if (create_git_path(ctx) == -1) { perror("create_git_path"); - free(path); - return -1; + ret = -1; + goto end; } if (create_mirror(path, ctx) == -1) { perror("create_mirror"); - free(path); - return -1; + ret = -1; } +end: free(path); - return 0; + return ret; } diff --git a/src/precheck.c b/src/precheck.c index a9fce35..cbabd2c 100644 --- a/src/precheck.c +++ b/src/precheck.c @@ -9,9 +9,6 @@ #include <sys/stat.h> #include <sys/wait.h> #include <unistd.h> -#ifdef __linux__ -#include <sys/capability.h> -#endif /** * Check if git is installed and available in the PATH. @@ -53,39 +50,6 @@ static int has_git(void) } /** - * Check if we have CAP_CHOWN capability or if we are root. - * @return 1 if we have chown capability, 0 if not. - */ -static int has_chown(void) -{ -#ifdef __linux__ - cap_t caps = cap_get_proc(); - if (caps == NULL) { - perror("cap_get_proc"); - return 0; - } - - cap_flag_value_t cap_value; - if (cap_get_flag(caps, CAP_CHOWN, CAP_EFFECTIVE, &cap_value) == -1) { - perror("cap_get_flag"); - cap_free(caps); - return 0; - } - cap_free(caps); - - if (cap_value == CAP_SET) - return 1; // We have CAP_CHOWN capability - fprintf(stderr, "Error: CAP_CHOWN capability is not set\n"); - return 0; // We don't have CAP_CHOWN capability -#else - if (geteuid() == 0) - return 1; - fprintf(stderr, "Error: not running as root\n"); - return 0; -#endif -} - -/** * Check if the git base directory exists. * @param path Path to the directory to check * @return 1 if the directory exists, 0 if not. @@ -104,8 +68,6 @@ int precheck_self(const struct config *cfg) { if (!has_git()) return -1; - if (!has_chown()) - return -1; if (!git_base_exists(cfg->git_base)) return -1; return 0; |