From f8dd93020d6ede8e90d3e633af0c428002bb761c Mon Sep 17 00:00:00 2001 From: Your Name Date: Sun, 14 Jan 2024 01:18:21 +0300 Subject: [PATCH] login add --- TODO | 5 +- build.sh | 2 +- include/libmu/get_string.h | 21 ++++++++ include/libmu/pw_check.h | 30 +++++++++++ src/coreutils/cp/cp.c | 8 +-- src/loginutils/login/build.sh | 3 ++ src/loginutils/login/login.c | 94 +++++++++++++++++++++++++++++++++++ src/miscutils/spark/build.sh | 2 +- 8 files changed, 155 insertions(+), 10 deletions(-) create mode 100644 include/libmu/get_string.h create mode 100644 include/libmu/pw_check.h create mode 100755 src/loginutils/login/build.sh create mode 100644 src/loginutils/login/login.c diff --git a/TODO b/TODO index acb8339..34ed47e 100644 --- a/TODO +++ b/TODO @@ -46,7 +46,7 @@ Loginutils: getty Modutils (linux only): - modprobe + insmod rmmod lsmod @@ -54,9 +54,6 @@ Findutils: grep find -Shell: - rc - run command (1 2 3 ~ | <> <<>> & * " parsing) (sig handler) - BUGS: ls (unicode strlen, -l flag col) xargs (getopt with glibc) diff --git a/build.sh b/build.sh index b3941b1..dd79d62 100755 --- a/build.sh +++ b/build.sh @@ -26,7 +26,7 @@ for project in $projects; do cd $PROJECT_DIR/$i echo " * Compile" $i chmod -v +x build.sh - env CC=$CC CFLAGS="$CFLAGS -I$PROJECT_DIR -I$PROJECT_DIR/include/libmu -lm" OUTPUT="$PROJECT_DIR"/bin/ ./build.sh + env CC=$CC CFLAGS="$CFLAGS -I$PROJECT_DIR -I$PROJECT_DIR/include/libmu" OUTPUT="$PROJECT_DIR"/bin/ ./build.sh cd $PROJECT_DIR done echo diff --git a/include/libmu/get_string.h b/include/libmu/get_string.h new file mode 100644 index 0000000..639d51c --- /dev/null +++ b/include/libmu/get_string.h @@ -0,0 +1,21 @@ +#ifndef _GET_STRING_H +#define _GET_STRING_H +#include +#include +#include + +int mu_get_string(const char *prog_name, char *buf, const size_t len) { + off_t rbytes = read(STDIN_FILENO, buf, len); + + if (rbytes <= 0) { + fprintf(stderr, "%s: %s\n", prog_name, strerror(errno)); + return 1; + } + + if (rbytes > 1) + buf[rbytes - 1] = '\0'; + + return 0; +} + +#endif diff --git a/include/libmu/pw_check.h b/include/libmu/pw_check.h new file mode 100644 index 0000000..8405de6 --- /dev/null +++ b/include/libmu/pw_check.h @@ -0,0 +1,30 @@ +#ifndef _PW_CHECK_H +#define _PW_CHECK_H + +#include +#include +#include +#include + +int pw_check(const char *prog_name, const struct passwd *pw, const char *pass) { + if (pw->pw_passwd[0] == '\0' || pass[0] == '\0') { + fprintf(stderr, "%s: Incorrect password\n", prog_name); + return 1; + } + + if (pw->pw_passwd[0] == '!' || pw->pw_passwd[0] == '*') { + fprintf(stderr, "%s: Denied\n", prog_name); + return 1; + } + + char *cryptpass = crypt(pass, pw->pw_passwd); + if (cryptpass == NULL) + return 1; + + if (!strcmp(pw->pw_passwd, cryptpass)) + return 0; + + return 1; +} + +#endif diff --git a/src/coreutils/cp/cp.c b/src/coreutils/cp/cp.c index 47f534d..ab16e40 100644 --- a/src/coreutils/cp/cp.c +++ b/src/coreutils/cp/cp.c @@ -179,14 +179,14 @@ int main(int argc, char **argv) { } } - if (argv[optind] == NULL) { + argv += optind; + argc -= optind; + + if (argc < 2) { fprintf(stderr, "cp: missing operand\n"); return 1; } - argv += optind; - argc -= optind; - int ret = 0; if (argc == 2) ret = cptree(argv[0], argv[argc - 1]); diff --git a/src/loginutils/login/build.sh b/src/loginutils/login/build.sh new file mode 100755 index 0000000..1029f41 --- /dev/null +++ b/src/loginutils/login/build.sh @@ -0,0 +1,3 @@ +#!/bin/sh +project_dir=$(pwd) +echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) -lcrypt | xargs $CC diff --git a/src/loginutils/login/login.c b/src/loginutils/login/login.c new file mode 100644 index 0000000..474d35a --- /dev/null +++ b/src/loginutils/login/login.c @@ -0,0 +1,94 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "get_string.h" +#include "pw_check.h" + +void login(const struct passwd *pw) { + char *shell = pw->pw_shell[0] == '\0' ? "/bin/sh" : pw->pw_shell; + + setenv("HOME", pw->pw_dir, 1); + setenv("SHELL", shell, 1); + setenv("USER", pw->pw_name, 1); + setenv("LOGNAME", pw->pw_name, 1); + + if (chdir(pw->pw_dir) < 0) { + fprintf(stderr, "login: %s\n", strerror(errno)); + return; + } + + execlp(shell, shell, "-l", NULL); +} + +struct passwd *proccess_input(char *hostname) { + static char user[512]; + static char psswd[512]; + + /* Username */ + printf("Login on %s:\n", hostname); + if (mu_get_string("login", user, sizeof(user))) + return NULL; + + struct passwd *pw = getpwnam(user); + if (!pw) { + fprintf(stderr, "login: Incorrent username\n"); + return NULL; + } + + + /* Password */ + printf("\nPassword:\n"); + if (mu_get_string("login", psswd, sizeof(psswd))) + return NULL; + + if (pw_check("login", pw, psswd)) { + memset(psswd, '\0', sizeof(psswd)); + return NULL; + } + + + memset(psswd, '\0', sizeof(psswd)); + return pw; +} + +int main(void) { + if ((!isatty(STDIN_FILENO) || !isatty(STDOUT_FILENO))) { + fprintf(stderr, "login: no tty\n"); + return 1; + } + + /* For prompt */ + char hostname[HOST_NAME_MAX + 1]; + if (gethostname(hostname, sizeof(hostname)) < 0) { + fprintf(stderr, "login: %s\n", strerror(errno)); + return 1; + } + + signal(SIGQUIT, SIG_IGN); + signal(SIGINT, SIG_IGN); + signal(SIGHUP, SIG_IGN); + + + struct passwd *pw = proccess_input(hostname); + if (!pw) + return 1; + + /* Start */ + if (setgid(pw->pw_gid) < 0) { + fprintf(stderr, "login: %s\n", strerror(errno)); + return 1; + } + + if (setuid(pw->pw_uid) < 0) { + fprintf(stderr, "login: %s\n", strerror(errno)); + return 1; + } + + login(pw); + return 0; +} diff --git a/src/miscutils/spark/build.sh b/src/miscutils/spark/build.sh index 6d8974b..0ea3f65 100755 --- a/src/miscutils/spark/build.sh +++ b/src/miscutils/spark/build.sh @@ -1,3 +1,3 @@ #!/bin/sh project_dir=$(pwd) -echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) | xargs $CC +echo ./*.c $CFLAGS -o $OUTPUT$(basename $project_dir) -lm | xargs $CC