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.
Related
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];
I'm trying to build a program with C but I'm having trouble changing a char array into a char pointer and adjusting the program accordingly. Here's my current code that I want to change:
#include <stdio.h>
#include <string.h>
#include <unistd.h>
char username[20];
char password[20];
char username_input[20];
char password_input[20];
char user_input;
void create_account(char* usrname, char* passwd) {
printf("==================================CREATE BANK ACCOUNT==================================\n");
while(1) {
printf("Enter a username that is less than 20 characters: ");
scanf("%s", usrname);
if (strlen(usrname) <= 20)
break;
printf("That is not less than 20 characters, try again...\n");
sleep(2);
}
while(1) {
printf("Enter a password that is less than 20 characters: ");
scanf("%s", passwd);
if (strlen(passwd) <= 20) {
break;
}
printf("That is not less than 20 characters, try again... \n");
sleep(2);
}
printf("Thank you, please sign in now...\n");
sleep(2);
}
void login() {
while(1) {
printf("Enter Username: ");
scanf("%s", username_input);
printf("Enter Password: ");
scanf("%s", password_input);
if (strcmp(username, username_input) != 0 || strcmp(password, password_input) != 0) {
printf("Incorrect Username or Password. Try again...\n");
sleep(2);
}
else {
printf("Welcome %s\n", username);
sleep(2);
break;
}
}
}
On the lines at the beginning, you can see that there are 4 char array declarations. I want them to be char pointers like so:
char* username;
char* password;
char* username_input;
char* password_input;
The reason for this is because I don't want a limit in a string, but arrays need limits. Once I change that, I want to use malloc() to allocate memory for what the user inputs but I don't know how. In other words, I want to declare a char pointer that accepts user input. And I want enough memory to be allocated for that pointer so that the string that was inputted has enough space. Also I want my code to be compatible with different compilers and computers. For that I'm pretty sure that I have to multiply the malloc() function with sizeof(char) or something like that. I don't necessarily get an error, as in I don't get red lines in my IDE, but the program stops in the middle of it for no reason and gives me an exit code other than 0.
I have done something like this to alloc memory:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
void create_account(char** usrname, char** passwd);
void login(char** usrname, char** passwd, char** input_usrname, char** input_passwd);
void AllocMemory(char*** buf);
int main(){
char* username;
char* password;
char* username_input;
char* password_input;
create_account(&username, &password);
login(&username, &password, &username_input, &password_input);
free(username);
free(password);
free(username_input);
free(password_input);
return 0;
}
void create_account(char** usrname, char** passwd) {
printf("==================================CREATE BANK ACCOUNT==================================\n");
printf("Enter a Username: ");
AllocMemory(&usrname);
printf("Enter a Password: ");
AllocMemory(&passwd);
printf("Thank you, please sign in now...\n");
sleep(2);
}
void login(char** usrname, char** passwd, char** input_usrname, char** input_passwd) {
while(1) {
printf("Enter Username: ");
AllocMemory(&input_usrname);
printf("Enter Password: ");
AllocMemory(&input_passwd);
if (strcmp(*usrname, *input_usrname) != 0 || strcmp(*passwd, *input_passwd) != 0) {
printf("Incorrect Username or Password. Try again...\n");
sleep(2);
}
else {
printf("Welcome %s\n", *usrname);
sleep(2);
break;
}
}
}
void AllocMemory(char*** buf){
int bufSize = 10;
int stringSize;
**buf = calloc(bufSize, sizeof(char));
if(**buf == NULL){
printf("[ERROR] can't malloc %d bytes\n", bufSize);
exit(1);
}
char *readpos = **buf; //point to a pointer of your array!
while(1){ //looping until the alocated memory is enough to the inserted command
do{
fgets(readpos, bufSize, stdin); //reads a line from the specified stream
stringSize = strlen(**buf); //getting the size of the array
if (stringSize == 1)
{
printf("\nYou just pressed enter, pls type again: "); //checking if user just pressed enter
}
}while (stringSize == 1); //looping until user press only enter
if (readpos[strlen(readpos)-1] == '\n'){ //Search from the end as there's where the newline should be if exists, the string fits on array and doesnt need to allocate more memory
readpos[strlen(readpos)-1] = '\0'; //Remove \n from the string
break;
}
**buf = realloc(**buf, bufSize + stringSize * sizeof(char)); // Need to allocate more memory, because the before if its false
if(*buf == NULL){
printf("[ERROR] can't realloc more %d bytes\n", bufSize+1);
exit(1);
}
readpos = **buf + stringSize; // Set the pointer to next position to read into
}
}
I dont know if you are using global variables, but this dont have global variables! But if you want you can use them
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;
}
I ask for two simple user inputs, a user and a password, I then insert those into a text file, each followed by a semi colon. The semi colons save and the password saves but the username doesn't save for some odd reason.
For example if I input Joe with password 111222444555 it'll
display as ;111222444555; instead of Joe;111222444555;
Code:
int main()
{
int Number_Of_Attempts = 3;
int result = 0;
char userID[32];
printf("Please enter your user id\n");
scanf("%s", &userID);
char password[12];
printf("The user has not been found. Please enter your a password\n");
scanf("%s", &password);
printf("Username and Password has been saved");
printf("\n");
InsertIntoHash(userID, password);
return 0;
}
void InsertIntoHash(char *userID, char *hash)
{
FILE *fp;
fp = fopen("HashTable.txt", "a");
fprintf(fp, userID);
fprintf(fp,";");
fprintf(fp, hash);
fprintf(fp, ";\n");
fclose(fp);
}
You should read in the string using scanf("%31s", userID); for the userID and scanf("%11s", password); for the password.
What I think causes the problem is, that you declare and define InsertIntoHashafter the main function, without declaring a prototype at the beginning.
So the code should be the following: (I tested it and it works)
#include <stdio.h>
#include <stdlib.h>
void InsertIntoHash(char *userID, char *hash);
int main() {
int Number_Of_Attempts = 3;
int result = 0;
char userID[32];
printf("Please enter your user id\n");
scanf("%31s", userID);
char password[12];
printf("The user has not been found. Please enter your a password\n");
scanf("%11s", password);
printf("Username and Password has been saved");
printf("\n");
InsertIntoHash(userID, password);
return 0;
}
void InsertIntoHash(char *userID, char *hash) {
FILE *fp;
fp = fopen("HashTable.txt", "a");
fprintf(fp, userID);
fprintf(fp,";");
fprintf(fp, hash);
fprintf(fp, ";\n");
fclose(fp);
}
I hope I could help you! :)
Change scanf("%s", &userID); to scanf("%s", userID); as it is already an array which will be passed as a pointer. Same for password.
Note the buffer for password is too small: the password is 12 chars and the buffer too so the terminating null character is placed outside the buffer (resulting in Undefined Behavior, as you encounter).
Use "%11s" to limit the length read to the size of the buffer, leaving room for the terminating null character.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char rand(char x);
int main()
{
char input[80] = {0};
char rando[80] = {0};
char choice = 0;
char rando2[80] = {0};
if(strlen(input) >= 10 && strlen(input) <= 80); {
printf("Please enter a string with 10-80 characters: ");
scanf("%s", input);
printf("Orginal string: %s\n", input);
rando = my_rand(input);
printf("New string: %s\n", rando); }
else{
return 0; }
printf("Would you like to shuffle this string again?(y or n): ");
scanf("%c\n", &choice);
if( choice == 'y') {
rando2 = my_rand(rando);
printf("New string: %s\n", rando2);
}
else if {
printf("Would you like to shuffle another string?(y or n): ");
scanf("%c\n", &choice2); }
if(choice2 == 'y') {
printf("Please enter a string with 10-80 characters: ");
scanf("%s", input2);
printf("Original string: %s\n", input2);
char rando3 = my_rand(rando2);
printf("New string: %s\n", rando3); }
else:
return 0;
return 0;
}
Hello guys, my goal is to shuffle a user input string as many times as they would like, prompting whether to keep going or not. I am have a tough time figuring out how to shuffle the string, can anyone lend a hand?
This is the sample output:
Please enter a string with 10-80 characters:
initialnaivepassword
Original string: initialnaivepassword
New string: ntlvdiepnaaorsiiiwas
Would you like to shuffle this string again:y
New string: saiiwndrvpaiioneslat
Would you like to shuffle this string again:n
Would you like to shuffle another string? :y
Please enter a string with 10-80 characters:
anothernaivepassword
Original string: anothernaivepassword
New string: svdoanoprhsterneaaiw
Would you like to shuffle this string again:y
New string: eaapnrtwhrosvidosaen
Would you like to shuffle this string again:n
Would you like to shuffle another string? :n
Here's some code that does the shuffling, hope it's helpful:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
void shuffle(char *);
int main(int argc, char *argv[])
{
char sBuff[1024];
char sFinish[10];
srand(time(NULL));
printf("Enter a string:\n");
scanf("%s",sBuff);
do
{
shuffle(sBuff);
printf("\nShuffled string is:\n%s\n\n",sBuff);
printf("Suffle again? (y/n)\n");
scanf("%s",sFinish);
}
while (strcmp(sFinish,"y") == 0);
return 0;
}
void shuffle(char *sBuff)
{
int i, random, length = strlen(sBuff);
char temp;
for (i = length-1; i > 0; i--)
{
random = rand()%(i+1);
temp = sBuff[random];
sBuff[random] = sBuff[i];
sBuff[i] = temp;
}
}
char choice[1] = ""; //wrong declaration. You should either declare a single character or array with two characters
rando = rand(input); // you are passing string here
so the declaration of function is also wrong
char rand(char x);
if else { // you should use `else if` not `if else`
and you are using function name rand is not good practice as this is predefined function found stdlib.h.
use my_rand
This is not a solution ( but you are most welcome to upvote it :-D ), just a long comment.
Change your
1.
char input[80] = "";
char rando[80] = "";
char choice[1] = "";
char rando2[80] = "";
To
char input[80] = {0}; // Will initialize all 80 char mem to 0
char rando[80] = {0};
char choice = 0; // As you want only one char as input, no need to use an array.
// Just initialize the char to 0
char rando2[80] = {0};
2.
else: // Is not supported in C
To
else {/* code here*/}
3.
scanf("%c\n", choice);
if( choice == y)
To
scanf("%c\n", &choice); // choice is no longer an array,
// so we have to pass the address of choice
if( choice == 'y' ) // 'y' is not an int value, its a char literal
Your code is wrong on many levels (as you state already in the fact that it doesn't compile). I'll annotate what I can find:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* useless, you hide a builtin function here, without implementing anything */
char rand(char x);
int main()
{
char input[80] = "";
char rando[80] = "";
char choice[1] = "";
char rando2[80] = "";
/* 1. this is always true, as you have just filled the arrays
* 2. the semicolon after if means there is no body, so the body's scope is always executed
*/
if(strlen(input) >= 10 && strlen(input) <= 80); {
printf("Please enter a string with 10-80 characters: ");
scanf("%s", input);
printf("Orginal string: %s\n", input);
/* input is a char[], rand takes a char */
rando = rand(input);
printf("New string: %s\n", rando); }
/* you are using else as a label here, probably not allowed */
else:
return 0;
printf("Would you like to shuffle this string again?(y or n): ");
scanf("%c\n", choice);
/* y is not declared, so this results in an unknown variable, you probably mean 'y',
* then again, choice is a char[] not a char
*/
if( choice == y) {
rando2 = rand(rando);
printf("New string: %s\n", rando2);
}
/* if else is invalid */
if else {
printf("Would you like to shuffle another string?(y or n): ");
scanf("%c", choice2); }
if(choice2 == y) {
printf("Please enter a string with 10-80 characters: ");
scanf("%s", input2);
printf("Original string: %s\n", input2);
char rando3 = rand(rando2);
printf("New string: %s\n", rando3); }
else:
/* no need to return twice */
return 0;
return 0;
}
As I said in a comment. Walk through some basic C tutorials first, get to know the language and its syntax. Then come back with a compilable piece of code. Good luck!