diff --git a/lab1/login_linux.c b/lab1/login_linux.c index b97f329..2520b2d 100755 --- a/lab1/login_linux.c +++ b/lab1/login_linux.c @@ -2,6 +2,10 @@ /* gcc -std=gnu99 -Wall -g -o mylogin login_linux.c -lcrypt */ +/* Note, makepass.c is first used to create hashed password + then, info is manually saved in file passdb */ + + #include #include #include @@ -12,6 +16,8 @@ #include #include #include "pwent.h" /* Step 2 */ +#include +#include #define TRUE 1 #define FALSE 0 @@ -24,15 +30,14 @@ void sighandler() { signal(SIGINT, SIG_IGN); /* This will catch ctrl+c and ignore it*/ //signal(SIGTSTP, SIG_IGN); /* This will catch ctrl+z and ignore it*/ - /* add signalhandling routines here */ - /* see 'man 2 signal' */ + //signal(SIGTERM,SIG_IGN); //TODO block termios kanske... } + int main(int argc, char *argv[]) { //struct passwd *passwddata /* Step 1 */ mypwent *passwddata; /* Step 2 */ - /* see pwent.h */ char important1[LENGTH] = "**IMPORTANT 1**"; @@ -40,9 +45,10 @@ int main(int argc, char *argv[]) { char important2[LENGTH] = "**IMPORTANT 2**"; - //char *c_pass; //you might want to use this variable later... - char prompt[] = "password: "; - char *user_pass; + //char *c_pass; //you might want to use this variable later... TODO + //char prompt[] = "password: "; + //char *user_pass; + char user_pass[LENGTH]; // TODO la till denna sighandler(); @@ -53,68 +59,132 @@ int main(int argc, char *argv[]) { printf("Value of variable 'important2' before input of login name: %s\n", important2); + ////////////////////////////////////////////////////////////////////////////////////////// + printf("login: "); fflush(NULL); /* Flush all output buffers */ __fpurge(stdin); /* Purge any data in stdin buffer */ + bool okusername = true; + /* using fgets instead of gets to avoid buffer overflow attacks*/ if (fgets(user,sizeof(user),stdin) == NULL ) { - clearerr(stdin); //if EOF only, clear error - continue; ///* overflow attacks. */ + // if error or EOF (ctrl+d) + // TODO need for more error handling ? + clearerr(stdin); + okusername = false; } - user[strlen(user)-1] = '\0'; //replacing \n with \0 + if (strlen(user) == sizeof(user)-1 || strlen(user) == 1){ + // too long username or no username was entered + okusername = false; + } + else{ + // replacing \n with \0 + user[strcspn(user,"\n")] = '\0'; + } + + ////////////////////////////////////////////////////////////////////////////////////////// + /* check to see if important variable is intact after input of login name - do not remove */ printf("Value of variable 'important 1' after input of login name: %*.*s\n", LENGTH - 1, LENGTH - 1, important1); printf("Value of variable 'important 2' after input of login name: %*.*s\n", LENGTH - 1, LENGTH - 1, important2); - // using makepass.c to create hashed password -> saving it manually in passdb + ////////////////////////////////////////////////////////////////////////////////////////// + + // using termios instead of the outdated getpass + // user_pass = getpass(prompt); - user_pass = getpass(prompt); //enter password using deprecated function :/ - passwddata = mygetpwnam(user); //get user info from passdb + struct termios old_term_flags, new_term_flags; + /* Turn echoing off so password will not be shown in terminal */ + if (tcgetattr(fileno(stdin), &old_term_flags) != 0){ + perror("Error"); + exit(EXIT_FAILURE); + } + new_term_flags = old_term_flags; + new_term_flags.c_lflag &= ~ECHO; + if (tcsetattr(fileno(stdin), TCSAFLUSH, &new_term_flags) != 0) { + perror("Error"); + exit(EXIT_FAILURE); + } + + bool okpassword = true; + printf("password: "); + if (fgets(user_pass,sizeof(user_pass),stdin) == NULL ) { + clearerr(stdin); + okpassword = false; + } + if (strlen(user_pass) == sizeof(user_pass)-1 || strlen(user_pass) == 1){ + okpassword = false; + } + + /* Restore terminal */ + if (tcsetattr(fileno(stdin), TCSAFLUSH, &old_term_flags) != 0) { + perror("Error");exit(EXIT_FAILURE); + } + + if (!okpassword || !okusername){ + printf("\nLogin Incorrect \n \n"); + continue; + } + user_pass[strcspn(user_pass, "\n")] = '\0'; // replacing \n with \0 + + ////////////////////////////////////////////////////////////////////////////////////////// + + //get user info from passdb + passwddata = mygetpwnam(user); + if (passwddata != NULL) { - /* You have to encrypt user_pass for this to work */ - /* Don't forget to include the salt */ + + if (passwddata->pwfailed >= 10) { + printf("\nToo many failed login attempts. Your account has been locked.\nContact and Admin to unlock your account.\n"); + continue; + } - + /* Encryp user_pass with salt included */ char *user_pass_encrypted = crypt(user_pass, passwddata->passwd_salt); - if (&user_pass_encrypted == NULL) { + if (user_pass_encrypted == NULL) { perror("Error");exit(EXIT_FAILURE); } - printf("encryption of typed pass: %s \n", user_pass_encrypted); - if (passwddata->pwfailed >= 10) { - printf("Too many failed login attempts. Your account has been locked.\nContact and Admin to unlock your account.\n"); - } else if (!strcmp(user_pass_encrypted, passwddata->passwd)) { - printf(" You're in !\n"); + if (!strcmp(user_pass_encrypted, passwddata->passwd)) { + // successfull login passwddata->pwfailed = 0; passwddata->pwage = passwddata->pwage + 1; - if (mysetpwent(user, passwddata) < 0) { /* execute the command */ + + if (mysetpwent(user, passwddata) < 0) { perror("Error");exit(EXIT_FAILURE); } if (passwddata->pwage > 100) { printf(" Your password is OLD!!!!\n"); + // TODO } + + /* check UID, see setuid(2) */ - if (setuid(passwddata->uid) < 0) { /* execute the command */ + if (setuid(passwddata->uid) < 0) { + printf(" always here !\n"); perror("Error");exit(EXIT_FAILURE); } + printf(" cant get here !\n"); /* start a shell, use execve(2) */ - if (execve("/bin/bash",NULL,NULL) < 0) { /* execute the command */ + if (execve("/bin/bash",NULL,NULL) < 0) { perror("Error");exit(EXIT_FAILURE); } - } else { + } + else { + // user name exists but password does not match passwddata->pwfailed = passwddata->pwfailed + 1; - if (mysetpwent(user, passwddata) < 0) { /* execute the command */ + if (mysetpwent(user, passwddata) < 0) { perror("Error");exit(EXIT_FAILURE); } } } - printf("Login Incorrect \n"); + printf("\nLogin Incorrect \n \n"); } return 0; }