commit d13e5016f63cf7e49318759b36f96bc10fa7ecf8 Author: uvos Date: Mon Sep 20 18:06:17 2021 +0200 inial version diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..1392043 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,13 @@ +cmake_minimum_required(VERSION 2.4) + +project(securex) + +set(SRC_FILES main.c) + +add_executable(${PROJECT_NAME} ${SRC_FILES}) + +add_definitions("-Wall -Os") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s") + +set(CMAKE_INSTALL_PREFIX "/usr") +install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION bin) diff --git a/main.c b/main.c new file mode 100644 index 0000000..5ca5ab7 --- /dev/null +++ b/main.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +const char run_user_default[] = "securex"; +const char secure_cookie[] = ".Xauthority-secure"; + +void usage(char* progname) +{ + printf("Usage %s -u [user] [PROGRAM]\n", progname); + exit(0); +} + +int main(int argc, char** argv) +{ + size_t progVstart = 1; + const char *run_user = run_user_default; + + if(argc < 2) + usage(argv[0]); + + uid_t user_uid = getuid(); + if(user_uid == 0) + { + printf("Do not run this programm as root\n"); + return -1; + } + + uid_t euid = geteuid(); + if(euid != 0) + { + printf("This programm must be setuid as root\n"); + return -1; + } + + const char* display = getenv("DISPLAY"); + if(display == NULL) + { + printf("DSIPLAY must be set\n"); + return -1; + } + + if(strcmp(argv[1], "-u") == 0) + { + if(argc < 3) + usage(argv[0]); + progVstart+=1; + run_user = getlogin(); + } + + struct passwd *securex_user = getpwnam(run_user); + if(securex_user == NULL) + { + printf("user %s must exist\n", run_user); + return -1; + } + + char secure_cookie_filename[80]; + + snprintf(secure_cookie_filename, sizeof(secure_cookie_filename), + "%s/%s", getenv("HOME") ?: "/root/", secure_cookie); + + if(access(secure_cookie_filename, F_OK) == 0) + remove(secure_cookie_filename); + + pid_t pid = fork(); + if(pid == 0) + { + printf("Createing %s\n", secure_cookie_filename); + if(setgid(securex_user->pw_gid) < 0) + { + printf("setgid failure\n"); + return -1; + } + if(setuid(user_uid) < 0) + { + printf("setuid failure\n"); + return -1; + } + + int fd = open(secure_cookie_filename, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + if(fd < 0) + { + printf("can not create %s: %s\n", secure_cookie_filename, strerror(errno)); + return -1; + } + close(fd); + execlp("xauth", "xauth", "-f", secure_cookie_filename, "generate", display, "MIT-MAGIC-COOKIE-1", "untrusted", (char*) NULL); + printf("failed to exec xauth\n"); + return -1; + } + else if(pid == -1) + { + printf("fork() failure\n"); + return -1; + } + else + { + int retval; + waitpid(pid, &retval, 0); + if(retval != 0) + { + printf("xauth failure\n"); + return -1; + } + + chmod(secure_cookie_filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP); + } + + pid = fork(); + if(pid == 0) + { + printf("Executeing %s\n", argv[progVstart]); + if(setgid(securex_user->pw_gid) < 0) + { + printf("setgid failure\n"); + return -1; + } + if(setuid(securex_user->pw_uid) < 0) + { + printf("setuid failure\n"); + return -1; + } + if(setenv("XAUTHORITY", secure_cookie_filename, 1) < 0) + { + printf("can not setenv XAUTHORITY=%s: %s\n", secure_cookie_filename, strerror(errno)); + return -1; + } + execvp(argv[progVstart], &(argv[progVstart])); + printf("failed to exec %s: %s\n", argv[progVstart], strerror(errno)); + return -1; + } + else if(pid == -1) + { + printf("fork() failure\n"); + return -1; + } + else + { + int retval; + waitpid(pid, &retval, 0); + return retval; + } + + return -1; +}