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

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];

Related

gets vs fgets for overflow in program

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;
}

How to get integer and string input using scanf?

I have a problem in C language
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char usrname[17] = "nsa-secret-agent";
char password[9] = "marshal41";
char usr[512], pass[512];
printf("username: ");
scanf("%[^\n]%*c", usr);
printf("password: ");
scanf("%[^\n]%*c", pass);
printf("%s\n", usr);
printf("%s\n", pass);
if (strcmp(usrname, usr) == 0 && strcmp(password, pass) == 0){
printf("You Have Successfully Logged In!\n");
}
else{
printf("username or password not found!\n");
exit(0);
}
return 0;
}
When I run this code it runs without any errors but when give input like below:
username: nsa-secret-agent
password: marshal41
nsa-secret-agent
marshal41
username or password not found!
I am giving correct credentials but still it's showing error
Your arrays for usrname and password are off by one:
char usrname[17] = "nsa-secret-agent";
char password[9] = "marshal41";
These are short one byte for the zero terminator which makes the comparison later fail. Either add one or just use
char usrname[] = "nsa-secret-agent";
char password[] = "marshal41";
or you could even use
char *usrname = "nsa-secret-agent";
char *password = "marshal41";
since the strings are not modified.

An unusual behaviour when using printf() after scanf()

I am using scanf() to get the password from the user and store it in password variable which has a size of 20 bytes. I check the entered password against the the correctPassword and if they match, boolean variable pass will be changed to true.
So, when I enter a password which is longer than 20 chars, a buffer overflow happens and the value of pass becomes non-zero (ie true). However, when I use printf() to print the address of variable pass no buffer overflow happens even-though I use a password which is longer than 20 chars.
here is the code that leads to overflow:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int main (int argc, char *argv[]) {
char password[20];
char correctPassword[] = "random";
bool pass = false;
printf("enter your password: ");
scanf("%s", password);
if (strcmp(password, correctPassword) == 0) {
// compare the two strings,strcmp() returns 0 if two strings values are the same.
pass = true;
}
if (pass) {
printf("Connecting you to the central system...\n");
} else {
printf("Password is wrong! entry denied\n");
}
printf("%d\n", pass);
return 0;
}
when password entered is in this case 40 chars long(ASCII value of a is 97), value of pass changes to 97(true).
enter your password: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Connecting you to the central system...
97
here is the same code but with one extra line at the end to print the address of variable pass:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
#include <string.h>
int main (int argc, char *argv[]) {
char password[20];
char correctPassword[] = "random";
bool pass = false;
printf("enter your password: ");
scanf("%s", password);
if (strcmp(password, correctPassword) == 0) {
// compare the two strings,strcmp() returns 0 if two strings values are the same.
pass = true;
}
if (pass) {
printf("Connecting you to the central system...\n");
} else {
printf("Password is wrong! entry denied\n");
}
printf("%d\n", pass);
printf("%x\n", &pass);
return 0;
}
In this case password entered is 40 chars long but pass is still 0 (false).
enter your password: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Password is wrong! entry denied
0
61fec4
So, my question is how could adding only
printf("%x\n", &pass);
leads to no buffer-overflow as expected?
scanf("%s", password) is a security flaw: any input word longer than 19 bytes will cause scanf() to write beyond the end of the array, triggering undefined behavior.
Undefined behavior can have unpredictable side effects, which can be visible or not. The output of 97 is a mild side effect, but a long enough input will corrupt the return address and cause a segmentation fault upon returning from main() and a cleverly constructed input might allow an attacker to execute arbitrary code. Changing the program likely changes the side effects as the allocation of the local variables may be different for example when you take the address of &pass. None of this is predictable.
Note also that printf("%x\n", &pass); has undefined behavior too because %x expects an unsigned int, not a bool *, you should write printf("%p\n", (void *)&pass);
There is a simple way to prevent this by passing a length field to scanf():
scanf("%19s", password);
Note however that you should also check the return value to detect premature end of file and you should also flush the rest of the input line.
Here is a modified version:
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main (int argc, char *argv[]) {
char password[20];
char correctPassword[] = "random";
bool pass = false;
int c;
printf("enter your password: ");
if (scanf("%19s", password) != 1) {
printf("invalid input\n");
return 1;
}
/* read and discard the rest of the line */
while ((c = getchar()) != EOF && c != '\n')
continue;
if (strcmp(password, correctPassword) == 0) {
// compare the two strings,strcmp() returns 0 if two strings values are the same.
pass = true;
}
if (pass) {
printf("Connecting you to the central system...\n");
} else {
printf("Password is wrong! entry denied\n");
}
printf("%d\n", pass);
return 0;
}

Encryption in C using a Caesar Cipher

I have been asked to create a program where I have to encrypt multiple pieces of information using a Caesar Cipher. I understand the concept behind it but what I'm having trouble visually is how to enter pieces of data within the function. For example, I have encrypted passwords saved in a file ("hrkk1" meaning "pass1" and so on). I have to create a cipher function to read the input from a scanf and strcmp so it matches what's in the file allowing the user to login.
Whats the best way to validate the user input and make "pass1" turn into "hrkk1" so it matches what's in the file and allows user login?
Thank you
This is the code I have so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <windows.h>
void checkValid(void);
void loginDetails(char username[5][6], char password[5][9]);
void encryption(char username[5][6], char password[5][9]);
int main(void)
{
FILE *EP;
FILE *UN;
char username[5][6];
char password [5][9], ch, key;
EP = fopen("encrypted_passwords.txt", "r");
fscanf(EP, "%s %s %s %s %s", password[0], password[1],
password[2], password[3], password[4]);
fclose(EP);
UN = fopen("username.txt", "r");
fscanf(UN, "%s %s %s %s %s", username[0], username[1], username[2],
username[3], username[4]);
fclose(UN);
printf("Welcome.");
loginDetails(username, password);
return 0;
}
void loginDetails(char username[5][6], char password[5][9])
{
int i;
char nurseUsername[6];
char nursePassword[6];
bool useValid = 0;
bool passValid = 0;
printf("Please Enter your username: \n");
scanf("%s", nurseUsername);
for (i = 0; i < 5; i++)
{
if(strcmp(nurseUsername, username[i]) == 0)
{
useValid = 1;
}
}
if(useValid != 1)
{
printf("\nError. Invalid Username. Returning to menu.\n");
Sleep(1000);
system("cls");
main();
}
else
{
printf("\nPlease enter your password: \n");
scanf("%s", nursePassword);
}
for(i = 0; i < 5; i++)
{
if((strcmp(nurseUsername, username[i]) == 0) &&
(strcmp(nursePassword, password[i]) == 0))
{
passValid = 1;
}
if(passValid != 1)
{
printf ("Error. Invalid Password. Returning to menu.\n");
Sleep(1000);
system("cls");
main();
}
else
{
printf("\nLogin Successful. Loading menu.\n");
Sleep(1000);
system("cls");
patientEntry();
}
}
}
You need to use the shifting of the character in c. This is possibile with a simple addition( or subtraction) on a char value.
Pay attention your example doesn't shift the number character and maybe also the character doesn't go out the alphabet, and it take in consideration also the capital letters. So pay attention when you do the addition to not exceed the range of capital or non capital letter. My suggestion is to use ascii table.

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;
}
}
}

Resources