From 253e48af77129cded4919c734e3f990cb80861c7 Mon Sep 17 00:00:00 2001 From: xSlendiX Date: Wed, 8 Sep 2021 01:07:21 +0300 Subject: [PATCH] Add formatter and pipe support --- .clang-format | 14 ++ Makefile | 2 +- sus.c | 440 ++++++++++++++++++++++++++------------------------ 3 files changed, 242 insertions(+), 214 deletions(-) create mode 100644 .clang-format diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..f2bab91 --- /dev/null +++ b/.clang-format @@ -0,0 +1,14 @@ +--- +Language: Cpp +BasedOnStyle: WebKit +SpaceAfterTemplateKeyword: false +AlignEscapedNewlines: true +AlignTrailingComments: true +BreakBeforeInheritanceComma: true +BreakConstructorInitializers: BeforeComma +IndentPPDirectives: AfterHash +BreakBeforeBraces: Custom +BraceWrapping: + AfterFunction: true +NamespaceIndentation: None + diff --git a/Makefile b/Makefile index acf070a..3214fe8 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ build: - cc -lcrypt -I. sus.c -o sus + cc -Wall -lcrypt -I. sus.c -o sus all: build install diff --git a/sus.c b/sus.c index 756c366..651ee18 100644 --- a/sus.c +++ b/sus.c @@ -9,31 +9,31 @@ #define _XOPEN_SOURCE +#include +#include +#include +#include #include #include -#include -#include -#include #include #define MAX_PASSWORD 3 -// TODO: Add pipe support +void get_password(char* password); -void get_password(char *password); - -void cats(char **str, const char *str2); +void cats(char** str, const char* str2); int CheckIfInGroup(const char* string); int GetUID(const char* username, uid_t* uid); -void PrintHelp(); void CreatePasswordMessage(); +void PrintHelp(); +void CreatePasswordMessage(); int CheckPassword(char* password); int AskPassword(); -int uid = 0; +uid_t uid = 0; int command_start = 1; @@ -41,211 +41,225 @@ char* command_name; struct termios old_terminal; -void intHandler(int dummy) { - tcsetattr(STDIN_FILENO, TCSANOW, &old_terminal); - puts("Cancelled."); - exit(0); -} +void getln(int, char*, size_t); -int main(int argc, char** argv) { - struct rule *rule; - char **envp; - - if (CheckIfInGroup("wheel") != 1) { - puts("ERROR: Not in the wheel group."); - return 0; - } - - tcgetattr(STDIN_FILENO, &old_terminal); - - signal(SIGINT, intHandler); - - command_name = malloc((1 + strlen(argv[0])) * sizeof(char)); - strcpy(command_name, argv[0]); - - if (argc < 2) { - PrintHelp(); - return 0; - } - - if (AskPassword() != 1) { - puts("ERROR: Too many attempts."); - return 1; - } - - char username[32]; - username[0] = '\0'; - - if (argv[1][0] == '-') { - // - specified. Check if user is in next argument or - // in the same argument as the switch. - if (strlen(argv[1]) > 1) { - if (strlen(argv[1]) > 34) { - puts("ERROR: Username limit reached!"); - return 1; - } - strcpy(username, argv[1]); - command_start = 2; - } else { - if (strlen(argv[2]) > 33) { - puts("ERROR: Username limit reached!"); - return 1; - } - strcpy(username, argv[2]); - command_start = 3; - } - - if (username[0] == '-') - memmove(username, username+1, strlen(username)); - - } - - char* command = ""; - for (int i = command_start; i < argc; i++) { - cats(&command, argv[i]); - cats(&command, " "); - } - - command[strlen(command)-1] = '\0'; - - if (username[0] == '\0') - uid = 0; - else - if (GetUID(username, &uid) == -1) { - printf("ERROR: Could not find username: %s", username); - return 1; - } - - if (fork() == 0) { - setuid(uid); - system(command); - } - - return 0; -} - -int GetUID(const char* username, uid_t* uid) { struct passwd *pw; pw = getpwnam(username); if (pw != NULL) { *uid = pw->pw_uid; - return 1; - } - - return -1; -} - -int CheckIfInGroup(const char* string) { - int ngroups_max; - ngroups_max = sysconf(_SC_NGROUPS_MAX); - - int groups = getgroups(0, NULL); - - gid_t list[groups]; - - int ngroups = getgroups(groups, list); - - if (ngroups < 0) - return -1; - - for (int i = 0; i < groups; i++) { - struct group *grp; - grp = getgrgid(list[i]); - if (grp == NULL) - return -1; - if (strcmp(grp->gr_name, "wheel") == 0) - return 1; - - } - - return -1; -} - -void PrintHelp() { - printf("Usage: %s [- user] command\n", command_name); -} - -int AskPassword() { - for (int i=0; ipw_name); - if (shadow_entry == NULL) - return 2; - correct = shadow_entry->sp_pwdp; - salt = strdup(correct); - if (salt == NULL) - return 3; - p = strchr(salt + 1, '$'); - if (p == NULL) - return 4; - p = strchr(p + 1, '$'); - if (p == NULL) - return 5; - p[1] = 0; - - supplied = crypt(password, salt); - if (supplied == NULL) - return 6; - return !!strcmp(supplied, correct); -} - -void CreatePasswordMessage() { - puts("Incorrect password! Try again."); -} - -void cats(char **str, const char *str2) { - char *tmp = NULL; - - // Reset *str - if ( *str != NULL && str2 == NULL ) { - free(*str); - *str = NULL; - return; - } - - // Initial copy - if (*str == NULL) { - *str = calloc( strlen(str2)+1, sizeof(char) ); - memcpy( *str, str2, strlen(str2) ); - } - else { // Append - tmp = calloc( strlen(*str)+1, sizeof(char) ); - memcpy( tmp, *str, strlen(*str) ); - *str = calloc( strlen(*str)+strlen(str2)+1, sizeof(char) ); - memcpy( *str, tmp, strlen(tmp) ); - memcpy( *str + strlen(*str), str2, strlen(str2) ); - free(tmp); - } - -} - -void get_password(char *password) +void intHandler(int dummy) { - static struct termios new_terminal; - - new_terminal = old_terminal; - new_terminal.c_lflag &= ~(ECHO); - - tcsetattr(STDIN_FILENO, TCSANOW, &new_terminal); - - if (fgets(password, BUFSIZ, stdin) == NULL) - password[0] = '\0'; - else - password[strlen(password)-1] = '\0'; - - putchar('\n'); - - tcsetattr(STDIN_FILENO, TCSANOW, &old_terminal); + tcsetattr(STDIN_FILENO, TCSANOW, &old_terminal); + puts("Cancelled."); + exit(0); } +int main(int argc, char** argv) +{ + if (CheckIfInGroup("wheel") != 1) { + puts("ERROR: Not in the wheel group."); + return 0; + } + + signal(SIGINT, intHandler); + + command_name = malloc((1 + strlen(argv[0])) * sizeof(char)); + strcpy(command_name, argv[0]); + + if (argc < 2) { + PrintHelp(); + return 0; + } + + if (AskPassword() != 1) { + puts("ERROR: Too many attempts."); + return 1; + } + + char username[32]; + username[0] = '\0'; + + if (argv[1][0] == '-') { + // - specified. Check if user is in next argument or + // in the same argument as the switch. + if (strlen(argv[1]) > 1) { + if (strlen(argv[1]) > 34) { + puts("ERROR: Username limit reached!"); + return 1; + } + strcpy(username, argv[1]); + command_start = 2; + } else { + if (strlen(argv[2]) > 33) { + puts("ERROR: Username limit reached!"); + return 1; + } + strcpy(username, argv[2]); + command_start = 3; + } + + if (username[0] == '-') + memmove(username, username + 1, strlen(username)); + } + + char* command = ""; + for (int i = command_start; i < argc; i++) { + cats(&command, argv[i]); + cats(&command, " "); + } + + command[strlen(command) - 1] = '\0'; + + if (username[0] == '\0') + uid = 0; + else if (GetUID(username, &uid) == -1) { + printf("ERROR: Could not find username: %s", username); + return 1; + } + + if (fork() == 0) { + setuid(uid); + system(command); + } + + return 0; +} + +int GetUID(const char* username, uid_t* uid) +{ + struct passwd* pw; + pw = getpwnam(username); + if (pw != NULL) { + *uid = pw->pw_uid; + return 1; + } + + return -1; +} + +int CheckIfInGroup(const char* string) +{ + int groups = getgroups(0, NULL); + + gid_t list[groups]; + + int ngroups = getgroups(groups, list); + + if (ngroups < 0) + return -1; + + for (int i = 0; i < groups; i++) { + struct group* grp; + grp = getgrgid(list[i]); + if (grp == NULL) + return -1; + if (strcmp(grp->gr_name, "wheel") == 0) + return 1; + } + + return -1; +} + +void PrintHelp() { printf("Usage: %s [- user] command\n", command_name); } + +int AskPassword() +{ + for (int i = 0; i < MAX_PASSWORD; i++) { + char password[BUFSIZ]; + get_password(password); + + int res = CheckPassword(password); + if (res == 0) + return 1; + else + CreatePasswordMessage(); + sleep(1); + } + + return 0; +} + +int CheckPassword(char* password) +{ + struct spwd* shadow_entry; + struct passwd* pa = getpwuid(getuid()); + char *p, *correct, *supplied, *salt; + shadow_entry = getspnam(pa->pw_name); + if (shadow_entry == NULL) + return 2; + correct = shadow_entry->sp_pwdp; + salt = strdup(correct); + if (salt == NULL) + return 3; + p = strchr(salt + 1, '$'); + if (p == NULL) + return 4; + p = strchr(p + 1, '$'); + if (p == NULL) + return 5; + p[1] = 0; + + supplied = crypt(password, salt); + if (supplied == NULL) + return 6; + return !!strcmp(supplied, correct); +} + +void CreatePasswordMessage() { puts("Incorrect password! Try again."); } + +void cats(char** str, const char* str2) +{ + char* tmp = NULL; + + // Reset *str + if (*str != NULL && str2 == NULL) { + free(*str); + *str = NULL; + return; + } + + // Initial copy + if (*str == NULL) { + *str = calloc(strlen(str2) + 1, sizeof(char)); + memcpy(*str, str2, strlen(str2)); + } else { // Append + tmp = calloc(strlen(*str) + 1, sizeof(char)); + memcpy(tmp, *str, strlen(*str)); + *str = calloc(strlen(*str) + strlen(str2) + 1, sizeof(char)); + memcpy(*str, tmp, strlen(tmp)); + memcpy(*str + strlen(*str), str2, strlen(str2)); + free(tmp); + } +} + +void get_password(char* password) +{ + static struct termios new_terminal; + + int ttyfd = open("/dev/tty", O_RDWR); + + tcgetattr(ttyfd, &old_terminal); + + new_terminal = old_terminal; + new_terminal.c_lflag &= ~(ECHO); + + tcsetattr(ttyfd, TCSAFLUSH, &new_terminal); + + write(ttyfd, "Password: ", 11); + + getln(ttyfd, password, sizeof(password)); + + tcsetattr(ttyfd, TCSAFLUSH, &old_terminal); + + close(ttyfd); + + putchar('\n'); +} + +void getln(int fd, char* buf, size_t bufsiz) +{ + ssize_t nr = -1; + char ch; + while ((nr = read(fd, &ch, 1)) == 1 && ch != '\n' && ch != '\r') { + if (buf < buf + bufsiz - 1) { + *buf++ = ch; + } + } + *buf = '\0'; +}