gets vs fgets for overflow in program - c

i have the following c program. when i enter input as bytebyte it is giving the wrong input due to buffer overflow.
this is the program
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void) {
// Use a struct to force local variable memory ordering
struct {
char buff[5];
char perf;
} localinfo;
localinfo.perf = 0;
if(strcmp(localinfo.perf, "byte")){
printf ("\n Wrong Password \n");
}
else {
printf ("\n wrong Password\n");
localinfo.perf = 1; // Set a flag denoting correct password
}
//IF password matches
// GIVE root or admin rights to user
if(localinfo.pass){
printf ("\n Congratulations! Root privileges given to the user!\n");
}
return 0;
}
The correct password is byte, if enter byte it works fine.
if i enter bytebyte due to bufferoverflow the pass is modified as 1. and user is getting admin privileges.
if enter bytebyte as input output is
wrong password

Simply never use gets function, It is dangerous and obsolete.
Use fgets instead
fgets(localinfo.buff, sizeof(localinfo.buff), stdin);
To be sure that the whole line was read check if the last character is '\n'. If not assume that something is wrong and wrong password was entered.

Try this
#include <stdio.h>
#include <string.h>
int main(void) {
struct {
char buff[10];
char pass;
}
localinfo;
localinfo.pass = 0;
printf("\n Enter the password:\n");
scanf("%[^\n]s", localinfo.buff);
if (strcmp(localinfo.buff, "byte")) {
printf("\n Wrong Password \n");
} else {
printf("\n Correct Password\n");
localinfo.pass = 1;
}
if (localinfo.pass) {
printf("\n Congratulations! Root privileges given to the user!\n");
}
return 0;
}

Related

How can I check the password until it is correct?

I'm writing a program to read a password until it is correct. I'm confused about how to use the loop in this.
#include <stdio.h>
#include <cs50.h> //cs library Harvard for getting input of string from the user
#include <string.h>
int main(void)
{
string first="hello";
string check = get_string("Hello! \n, enter password ,"); //gets the string, input from the user.
if (strcmp(first, check) == 0)
{
printf("Welcome \n");
}
else
{
printf("\n wrong pwd, good bye \n");
}//I want to put this part in loop until the correct pwd is entered.
}
Your problem will be solved using an infinite loop that will run until the user enters the correct password.
So, for this task enclose your if-else statements and print inside the infinite while loop, which will break once a user gets the password right.
#include <stdio.h>
#include <cs50.h>
#include <string.h>
int main(void)
{
string first="hello";
while(1)
{
string check = get_string("Hello! \n, enter password ,");
if (strcmp(first, check) == 0)
{
printf("Welcome \n");
break;
}
else
{
printf("\n wrong pwd, good bye \n");
}
}
}

C Program suddenly exits after first input when using printf()

I tried this code but after entering the first input it exits. This code works fine though when the printf("hello world"); is commented out or deleted. The compiler doesn't explain anything and it doesn't show any error so I dont know the solution. What is the reason behind this?
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <stdbool.h>
bool login(bool logStatus) // takes in loggedIn value
{
char correctUsername[16] = "admin";
char correctPassword[16] = "admin123";
char *inputUsername;
char *inputPassword;
int i, checkUsername, checkPassword;
printf("Enter your username : \n");
fgets(inputUsername, 16, stdin); /* Get user input for username */
inputUsername[strlen(inputUsername) - 1] = '\0';
// scanf("%s", &inputUsername);
printf("Enter your password : \n");
fgets(inputPassword, 16, stdin); /* Get user input for password */
inputPassword[strlen(inputPassword) - 1] = '\0';
// scanf("%s", &inputPassword);
/* Check username and password */
checkUsername = strcmp(correctUsername, inputUsername);
checkPassword = strcmp(correctPassword, inputPassword);
printf("%d %d", checkUsername, checkPassword);
if (checkUsername == 0 && checkPassword == 0)
{
printf("\n\nLogged In Successful");
logStatus = true;
return logStatus;
}
else
{
printf("\n\nIncorrect username or password\n");
printf("Enter any key to continue...");
getch();
system("cls");
}
}
int main()
{
int input;
int choice;
bool loggedIn = false;
printf("hello world");
login(loggedIn);
return 0;
}
inputUsername and inputPassword are uninitialized pointers. You then pass them to fgets which attempts to dereference those invalid pointers. Doing so invokes undefined behavior.
Make them arrays like the username/password you're checking against.
char inputUsername[16];
char inputPassword[16];

why my email checker in C is not working?(I use an ispunct to detect that there are # on the email or not, but it seems not working)

I just recently starts learning C and found a problem. So here is my code:
#include <stdio.h>
#include <ctype.h>
int main()
{
char email[100];
int i;
printf("Input username (email) :");
scanf("%s", email);
for (i = 0; email[i] != '\0'; ++i)
{
if(!ispunct(email[i]))
{
printf("Please input a correct username (email) :");
scanf("%s", email);
}
}
return 0;
}
So, the program somehow only finished if I only input 1 character like # or other punctuation, but if I add alphabet like jack#gmail.com it will loop forever until I input only 1 punctuation. so can somebody please tell me whats wrong? I am trying to make a program that will only loop if I only input alphabet and didn't input punctuation like # or . in my email.
There are couple of suggestion:
use strchr() to find a particular charcater.
Loop over the same input instruction until you find a satisfactory input.
A modified version of your code can be
#include <stdio.h>
#include <string.h>
int main(void)
{
char email[100];
char toBeFound = '#'; // instead of any punctuation, make your search precise
while (1){ // go for a loop till the valid input is received.
printf("Input username (email) :\n");
scanf("%99s", email); //length limit the input, to avoid buffer overflow problem.
if (strchr (email, toBeFound)){ // search whether the required character is there
//in the input or not
printf ("%s is a valid email address\n", email);
break;
}
printf ("The input %s is not valid\n", email); // for debug, can be removed.
}
return 0;
}
Your program start the loop with i = 0 and test the first character in email. If this first character is not a punctuation, your program asks for a new email. So your program keeps testing only the first character and it requires that it’s a punctuation.
You should accumulate the result of the ispunct test and test the result.
#include <stdio.h>
#include <ctype.h>
int main()
{
char email[100];
int i;
printf("Input username (email) :");
scanf("%s", email);
for () {
int done = 0;
for (i = 0; email[i] != '\0'; ++i)
done |= ispunct(email[i]);
if (done != 0)
break;
printf("Please input a correct username (email) :");
scanf("%s", email);
}
return 0;
}

Segmentation Fault Error for a simple program in main() function

I just started teaching myself C, and wanted to write a basic program in main() that would take user input for a password, check it with the correct password, and have an appropriate output. However, the program started running and it read user input, but then it suddenly terminated under the error Segmentation Fault (code dumped). What's wrong with the code that's causing the error?
#include <stdio.h>
int main(void)
{
printf("Enter the password\n");
char guess;
scanf(" %c", &guess);
char password[] = "Hello123";
int correct = 0;
while (correct != 1){
if(strncmp(password,guess)==0){
printf("Success! You have logged in with your password
%c\n",guess);
correct +=1;
}
else
{
printf("Incorrect password. Try again\n");
}
}
}
Hey I took a privilege of recoding your code
#include <stdio.h>
#include <string.h>
int main(void)
{
char *guess;
const char password[] = "Hello123";
int correct = 0;
while (correct != 1){
/*
* Include the input prompt inside while loop
*/
if (correct == 0){
printf("Enter the password\n");
scanf(" %s", guess);
}
if(strncmp(password,guess, 10)==0){ //strncmp accept 3 params, set length e.g 10
printf("Success! You have logged in with your password %s\n",guess);
correct = 1;
}
else
{
printf("Incorrect password. Try again\n");
correct = 0;
}
}
}

How do I properly utilize fgets() and strncmp() functions?

I am trying to secure some C code by utilizing the fgets() and strncmp() functions. The program runs fine, however, if I enter the correct password ("password") more than once it still indicates a correct password. Also, even when using fgets() the results (if longer than the 9 indicated in the buffer) still appear in the output. Any help would be greatly appreciated.
#include <stdio.h>
#include <string.h>
int main(void)
{
char buffer[9];
int pass = 0;
char password[] = "password";
printf("\n Enter your password : \n");
fgets(buffer, 9, stdin);
if(strcmp(buffer, password))
{
printf ("\n Incorrect Password \n");
}
else
{
printf ("\n Correct Password \n");
pass = 1;
}
if(pass)
{
printf ("\n Root privileges authorized \n");
}
return 0;
}
The problem with your code is that fgets is taking the first 8 characters off the input and ignoring the rest. Obviously, if you are inviting a password you don't want to ignore any input! You might want to do something a little more fancy to ensure that you capture the full input.
My first two tries at answering this were wrong. Thanks to wildplasser for holding my feet to the fire.
So, the hack answer is: use a really big buffer. fgets is probably your easier solution there.
Alternatively, you could allocate memory dynamically as your input string exceeds your buffer.
But, just for fun, here is an implementation that breaks us out of the "line buffer" trap that I wasn't aware getchar was in.
For this, I leveraged a very beautiful comment here: getchar() and stdin
PS: Ok, Ok, I tested it this time. It works. On my Mac.
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <termios.h>
int main(void)
{
int c, i;
char buffer[9];
struct termios tty_opts_default, tty_opts_raw;
if (!isatty(STDIN_FILENO)) {
printf("Error: stdin is not a TTY\n");
return 1;
}
/* save tty settings for later. */
tcgetattr(STDIN_FILENO, &tty_opts_default);
/* put tty settings into raw mode. */
cfmakeraw(&tty_opts_raw);
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_raw);
/* NOW we can grab the input one character at a time. */
c = getchar();
while (i < 8 && c != EOF && c != '\n' && c != '\r') {
/* Since we are collecting a pwd, we might want to enforce other
password logic here, such as no control characters! */
putchar('*');
buffer[i++] = c;
c = getchar();
}
buffer[i] = '\0';
/* Restore default TTY settings */
tcsetattr(STDIN_FILENO, TCSANOW, &tty_opts_default);
/* Report results to user. */
printf("\nPassword received.\n");
printf("(It was '%s' -- don't tell anyone! Quick! Hide the terminal!)\n", buffer);
return 0;
}
fgets()reads the (CR+)LF too, and stores it into the buffer.
But only if there is sufficient place!
Otherwise, your buffer will contain the first n-1 characters, plus a NUL character.
So: allocate a large-enough buffer, and strip the CR/LF:
#include <stdio.h>
#include <string.h>
int main(void)
{
int pass = 0;
char password[] = "password";
char buffer[3+ sizeof password];
printf("\n Enter your password : \n");
fgets(buffer, sizeof buffer, stdin);
buffer[strcspn(buffer,"\r\n")]=0;
if(strcmp(buffer, password))
{
printf ("\n Incorrect Password \n");
}
else
{
printf ("\n Correct Password \n");
pass = 1;
}
if(pass)
{
printf ("\n Root privileges authorized \n");
}
return 0;
}

Resources