C password database - c

I've created a program that let's you change the password from a file if you enter the previous password that was in that file.What I want to do is to be able to create a username that's gets assigned with a password.The username and the password should be written in the file without deleting anything that was there before.The program should also be able to validate the password for the username in the file.Here is my current code,but i can't manage to write multiple things in the given file.I don't want you to give me the code for my question, only the algorythm with some tips.Thank you!
#include<stdio.h>
#include <conio.h>
#include <fstream>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *passwords;
int p='*',i,j,count,triesLeft,a,numberofTries=0;
char password[5] = {0,0,0,0,0};
char passwordCheck[5] = {0,0,0,0,0};
passwords = fopen("passwords.txt","r");
printf("You have 3 tries to enter your password!\n");
for(count=0;count<3;count++)
{
numberofTries++;
triesLeft = 3 - count;
printf("You have %d tries left!\n", triesLeft);
printf("Enter your password: ");
scanf("%s", &passwordCheck);
fscanf(passwords,"%s",&password);
if(strcmp(password, passwordCheck) == 0)
{
numberofTries--;
printf("Press 0 if you want to set up a new password, press 1 to stop the program\n");
scanf("%d", &a);
if(a==0)
{
passwords = fopen("passwords.txt","w");
printf("New password:");
for(i=0;i<5;i++)
{
password[i] = getch();
putchar(p);
}
for(j=0;j<5;j++)
{
fprintf(passwords,"%c",password[j]);
}
}
else if(a==1)
{
printf("Old password still in place");
}
break;
}
else
{
printf("Wrong password!");
}
}
if(numberofTries == 3)
{
printf("You are out tries!");
}
fclose(passwords);
}

Have a look at the fopen documentation. The magic phrase here is "access mode". As you open the file, the FILE pointer points to a certain position inside of the file. By setting the appropriate access mode, you can choose where the position pointer will be placed when the file is opened. Maybe the function fseek is interesting for you, too. It allows you to move that pointer.
A few more tips for your code:
Make sure that you don't use to many unneccessary variables, since
they make your code confusing.
When you use fopen, always check wether the pointer is set correctly
(check for NULL), otherwise your program may crash with a
segmentation fault if it is unable to find or access the file.
In C everything that differs from 0 or NULL is true. That applies for
pointers as for numeric values. Feel free to use the negation
operator "!" in combination with such tests.

Related

Segmentation error, C File handling program

Easy access program
Using linux first of all. I am trying to make a program that will first sign up a user in case he ain't got an account after that he will be directed to a login screen where he will enter his account details and then will be logged in. After that he will be given options to provide easy access to websites e.t.c. Like if the user enters 1 he will be directed to f.b, 2 for quora and so on. I successfully managed to code the program to the log in phase but i did it in a single function i.e main(), so i thought it would be nice if i had separate functions for performing specific tasks. I have coded it this time in separate functions, but i am getting segmentation error this time when i try to open FILE using fopen(). And also please tell me some way to open a website in a browser using console command. Like we have in windows (start www.facebook.com e.g). Here's the code.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct user_data {
char name[50];
unsigned long password;
};
struct user_data new_user; // Will hold the data of new
struct user_data data_ver; // Will hold the data read
void sign_up(void);
void sign_in(void);
int main(void) {
beginning: // Beginning label in case of invalid input
printf("\t\t\t\t WELCOME TO EASY ACCESS APPLICATION");
printf("\n\n\nIf you have an account press 1.\n\nPress 2 for sign up.");
char user_choice; // Wil hold the
// user_choice i.e whether he wants to sign up / sign in
user_choice = getchar();
if (user_choice == '1') {
sign_in(); // In case of 1 goto sign in page
}
else if (user_choice == '2') {
sign_up(); // Opening file);
// In case of 2 goto sign up page
}
else {
printf("Invalid input. Try again.\n\n");
puts("Press any key to continue...");
getchar();
system("clear");
goto beginning;
}
return 0;
}
void sign_up(void) {
FILE *data = fopen("data.txt", "a");
if (data == NULL) {
printf("Unable to open file.");
scanf("%c");
system("clear");
}
system("clear");
printf("\t\t----------------------------\n"
"\t\t| |\n"
"\t\t| SIGN UP PAGE |\n"
"\t\t| |\n"
"\t\t----------------------------");
printf("\n\nName:");
scanf("%c"); // Dummy scanf
gets(new_user.name); // Getting name into the struct
printf("\nPassword.");
scanf("%lu", &new_user.password); // Getting pass into the struct
fprintf(data, "%s %lu\n", new_user.name, new_user.password); //Feeding data into FILE
system("clear");
printf("\n\nSign up complete. :) ");
printf("\n\nYou will now be directed to the sign in page. ");
printf("\nPress any key to contine...");
scanf("%c");
system("clear");
fclose(data);
}
void sign_in(void) {
}
I am getting the error on the first line of sign_up function where i am opening FILE.
scanf("%c") expects a pointer where the read character will be stored. scanf() doesn't know if you provided the pointer, it just read the destination address from the expected stack location. Effectively scanf() takes a random address and writes the character there.
Use getchar(); or char Dummy; scanf("%c",&Dummy);.

Why isn't my code terminating within a loop when checking for 'exit' string?

My program is supposed to exit when the user types in exit similar to how its done in a shell. First I checked online to see if syscall could be called in a loop, but then I noticed the indices of the characters in the array are wrong. Why are these changing; when I ran the program and typed in exit I had my program shoot out the 3rd index for testing purposes and it returned 'e'. So I thought it might've been flipped and flipped all values and my exit still did not work. Any thoughts on what the underlying issue may be?
#include <stdio.h>
//Abstract: This program runs a script to emulate shell behavior
#define MAX_BIN_SIZE 100
int main() { //Memory allocation
char * entry[MAX_BIN_SIZE];
while(1)
{
printf("msh>");
fgets(entry,MAX_BIN_SIZE,stdin); //Getting user input
if(entry[0]=='t' && entry[1]=='i' && entry[2]=='x' && entry[3]=='e')
{
//printf("Exiting");
exit(0); //exit(system call)
break;
printf("Inside of exit");
}
printf("msh> you typed %s %c %c %c %c",entry,entry[3],entry[2],entry[1],entry[0]); //returning user input
}
return 0;
}
I am sorry I don't have enough reputation points to add a comment, but #lundman is correct. I don't think you need to create a pointer to entry. Also, you are checking for "exit" in the reverse order. I tried and edited the code; this seems to work:
#include <stdio.h>
//Abstract: This program runs a script to emulate shell behavior
#define MAX_BIN_SIZE 100
int main()
{ //Memory allocation
char entry[MAX_BIN_SIZE];
while(1)
{
printf("msh>");
fgets(entry,MAX_BIN_SIZE,stdin); //Getting user input
if(entry[0]=='e' && entry[1]=='x' && entry[2]=='i' && entry[3]=='t')
{
printf("Inside of exit");//printf("Exiting");
exit(0); //exit(system call)
}
printf("msh> you typed %s %c %c %c %c\n",entry,entry[3],entry[2],entry[1],entry[0]); //returning user input
}
return 0;
}

C - Price look-up program

I was asked to make a C program that act as a 'price lookup' where a user enter a product name and the program will print it's name and price which is stored in a file. If the item is not present in the file, the program will let the user know. The program will keep looping as long as the user wants to search. I did the coding using Dev C++, however after i run the code, the program got stuck after a few loops, and it's random. Could you guys detect any problem with my coding, or is it just the problem with Dev C++? I include my code below. Your help is greatly appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<ctype.h>
int main()
{
FILE *items;
char *mode="r";
char pName[50];
float pPrice;
char p1Name[50];
int value=0;
char respond='Y';
char s[50];
items=fopen("Product_Name_Price.txt", mode);
if(items==NULL)
{
fprintf(stderr, "Can't open file Product_Name_Price.txt!\n");
exit(1);
}
printf("File has been successfully opened\n");
do
{
printf("Enter the name of the product you wish to look for\n");
scanf("%s", &p1Name);
while(strcmp(p1Name, pName) !=0)
{
fscanf(items,"%s %f", pName, &pPrice);
//printf("%s\t%.2f\n", pName, pPrice);
//value=strcmp(p1Name, pName);
if(strcmp(p1Name, pName) == 0)
{
printf("%s\t%.2f\n", pName, pPrice);
}
}
/*
else
{
printf("No data in system\n");
}
*/
printf("Do you wish to look up for more item? (Y/N)\n");
scanf("%s", &respond);
}while(respond=='Y'|| respond=='y');
printf("This program is closing\n");
fclose(items);
}
Your program has undefined behaviour because your scanf("%s", &response) reads into response as if it were an array of sufficient size for the string being read — that size is at least 2 (including null terminator), but response is just one character. You blew up your stack and corrupted memory and then all bets are off.
You could write scanf("%c", &response) instead to actually read a single character, though you'd be better off switching to modern, safer tools if you're writing a C++ program.

How can code be launched with smashed stack?

I have a very rudimentary understanding of C (though I do understand programming concepts in general). I have an assignment to create a buffer overflow that yields something (like access to unauthorized area, free money, etc.) and not just crash the program.
I've tried different sized buffers and can always "crash" the program but I can't get it to launch any code (i.e., /bin/su). Am I approaching this incorrectly?
Here is the code:
#include <stdio.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <string.h>
#define BUFSIZE 20
int main() {
int month=12;
int day=31;
int year=2016;
int confirm = 0;
double dollars = 5.00;
char *sitenum="97871";
char acctnum[BUFSIZE];
printf("Welcome to the Acme AP-AR System. This is the Accounts Receivable module. \n");
/* Gathering date information */
printf("Please enter the month of transaction as an integer value (2 digits). \n");
printf("For example, July would be 07, December would be 12. Please input the month: ");
for (;;) { /* Start of month input validation loop */
scanf("%d", &month);
if(month>=1 && month<=12) {
printf("Validated. \n");
break;
}
else {
printf("Please enter a value between 1 and 12! \n");
continue;
}
} /* End of month input validation loop */
printf("\nPlease enter the day of transaction as an integer value (2 digits). \n");
printf("For example, the 3rd would be 03, the 25th would be 25. Please input the day: ");
for (;;) { /* Start of day input validation loop */
scanf("%d", &day);
if(day>=1 && day<=31) {
printf("Validated. \n");
break;
}
else {
printf("Please enter a value between 1 and 31! \n");
continue;
}
} /* End of day input validation loop */
/* Gathering sender account number */
printf("\nPlease enter the sender Account Number: ");
scanf("%s", acctnum);
/* Gathering transaction amount */
printf("\nPlease enter the USD amount (including cents) received: $ ");
scanf("%lf", &dollars);
/* Confirming data entry */
printf("\nTransaction information.\n Date: %d-%d-%d \n", month,day,year);
printf("Account: %s-%s \n", sitenum, acctnum);
printf(" Amount: $ %.2lf \n", dollars);
printf("\nProcess transaction information? (Yes=1/No=0) ");
for (;;) { /* Start of confirmation validation loop */
scanf("%d", &confirm);
if(confirm==1) {
printf("Transaction processed. \n");
break;
}
else {
printf("Transaction voided! \n");
break;
}
} /* End of confirmation validation loop */
return (EXIT_SUCCESS);
}
When executing, if you enter 25 characters for the day of month, the program will continue until the end. Only after the last input does it terminate with the stack smashing error. I'm afraid I'm trying to do something that can't be done, but a day (literally, the past 8 hours) of Google searches hasn't yielded an example that I've been able to use.
Can someone push me in a different direction that will get me close to what I'm trying to achieve? Thanks.
You will need an in-depth understanding of the target architecture (x86, x86-64, etc.) to accomplish that. A typical approach would involve carefully constructing the contents of the buffer overflow so that it 1) contains the code you wish to run when the input data is reinterpreted as machine instructions, and 2) overwrites the return address of the stack frame so that it jumps into your code instead of returning to the calling function.
I don't feel comfortable providing code that actually does this, but it's certainly possible to do.
EDIT: By the way, I don't think the assignment was intended to require actually running arbitrary code. I'm guessing based on the code you posted that you're supposed to just overwrite part of the stack so that it looks like you're accessing a different "sitenum". That's definitely possible since the sitenum pointer is going to be stored after acctnum in the stack (at least typically). So if you craft your buffer overrun carefully, you can change the sitenum pointer to point somewhere else. For example, (assuming the sitenum pointer is immediately after acctnum in the stack), you could input 1 extra character into the acctnum, and the null terminating character will overwrite the least significant byte of the sitenum pointer, which most likely will point to a different location then.
In my view, it's a terrible assignment though, because 1) the stack can be arranged differently based on a large number of factors, and 2) most modern development environments will default to adding runtime checks to prevent this kind of stack corruption. For example, in MS Visual C++, you would have to go out of your way to disable the Basic Runtime Checks and Buffer Security Check features to avoid an exception.
Anyway, hope that helps.
Here's a simple example of overwriting the return address on the stack to execute another function(will then promptly crash). Works in Windows VS2015 on x86.
#include "stdafx.h"
void hello()
{
printf("hello world!\n");
}
void run(int a)
{
int * ret = &a;
--ret; // stack grows downward on x86
*ret = (int)hello;
}
int main()
{
int a = 42;
run(a);
printf("this won't print\n");
}
Here's another simple example(VS2015/x86) that saves the return address first, and then after hello() is executed, will put the return address to main() back on the stack. Notice it starts first with a local variable declared in run() and not one passed in as an argument. It comes down to understanding what order the return address, arguments passed, the direction the stack goes, and where the current stack frame starts. You'll probably get notification of failing a run time check in your debugger environment after execution, but you should see this printed to the console:
hello world
main
#include "stdafx.h"
int saveret;
void hello()
{
int a = 43;
printf("hello world!\n");
// put saved return address to main() back on stack
int * ret = &a;
ret += 4;
*ret = saveret;
}
void run()
{
int a = 42;
int * ret = &a;
ret += 4; // stack grows downward on x86
saveret = (int)*ret;
*ret = (int)hello;
}
int main()
{
run();
printf("main\n");
}

Whats wrong with fread in this program?

I'm intermediate student of C. I'm trying to make a bank management program but first I need to make a login program, so I created one of the following. As I've recently learned about file I/O in C and don't know much about fread and fwrite. I have a file (data.txt) which format if as following.
user1 1124
user2 3215
user3 5431
In the following program I've asked user to input user name and pin(4-digit password) and copy file data into a structure then compare these two for verifying information.
What is wrong with my program and how to make fread work properly. And is the formating in data.txt file all right or should I change it.
Thanks in advance...
#include<stdio.h>
#include<ctype.h>
#include<string.h>
struct user_account {
char u_name[30];
int u_pin;
} log_in;
int login()
{
int start;
int i, n;
int t_pin[4]; // TEMPORARY INT PIN for storing pin inputed by user
char t_name[30]; // TEMPORARY STRING for storing name inputed by user
FILE *fp;
fp = fopen("data.txt","rb"); // Opening record file
if(fp == NULL)
{
puts("Unable to open file!");
return 1;
}
start : {
printf("User Name : ");
scanf("%s",&t_name);
printf("Pin Code : ");
for(i = 0; i < 4; i++) { // This loop is for hiding input pin
n = getch();
if(isdigit(n)) {
t_pin[i] = n;
printf("*"); }
else {
printf("\b");
i--;
}
}
fread(&log_in,sizeof(log_in),1,fp);
// Comparing user name and pin with info in the structure copied from the file
if(strcmp(log_in.u_name, t_name) == 0 && log_in.u_pin == t_pin)
puts("Login successful! Welcome User");
else {
printf("\nIncorrect Information!\n");
printf("Press any key to log in again...");
getch();
system("cls");
goto start; }
}
}
int main()
{
int login();
return 0;
}
The problem is that you have an ASCII/text file but you are trying to use fread to read directly into a structure; this requires a binary formatted file. fread cannot do format conversion. Use fscanf instead:
fscanf(fp, "%s %d", &log_in.u_name, &log_in.u_pin);
Problems that I see:
The following line is incorrect.
scanf("%s",&t_name);
You need to use:
scanf("%29s",t_name);
fread is not the right solution given the file format. fread works when the file is in binary format.
Given the format of your input file, you need to use:
scanf("%29s %d", log_in.uname, &log_in.u_pin);
Comparing the pins using log_in.u_pin == t_pin should produce a compiler error. The type of log_in.u_pin is int while the type of t_pin is int [4]. You will have to change your strategy for getting the integer value from t_pin.
You can use something like:
int pin = 0;
for (i = 0; i < 4; ++i )
{
pin = 10*pin + t_pin[i];
}
However, for that to work, you have store the proper integer values in t_pin. When the character you read is '1', you have to store 1. Either that, or you will have to change the above for loop to:
pin = 10*pin + t_pin[i]-'0';
The way are using goto start to loop in your function is not correct. You haven't read all the user ID and pins to from the input file and compared them. The way you have it, you will end up doing:
Read the user name and pin
Check against the first entry in the file. If they don't match...
Read the user name and pin again.
Check against the next entry in the file. If they don't match...
etc.
You want to:
Read the user name and pin
Check against the first entry in the file. If they don't match...
Check against the next entry in the file. If they don't match...
Check against the next entry in the file. If they don't match...
etc.
a) fread is used to read fixed sized (in bytes) records. While that is an option, you might find that fscanf is more suited to your use case.
b) goto has its uses, arguably, but in your particular case a while loop is far more appropriate as it make the intention clearer and is less susceptible to misuse.
c) The crux of your issue is reading the file. You only read in and check against a single record from your file per pass and once all records are read you will be getting EOF rather than additional records.
You have a few options. You might read the entire user table into a list prior to your login loop. When a user logs in you must iterate through the list until a match or end of list is found. Alternatively you might loop through the entire file on each user attempt looking for a match and seek to the back to the beginning of the file when you are done. In either case you must check for and handle read errors.
d) Finally when a non-digit is entered you will probably find that backspace isn't what you had in mind. Also you might consider allowing the user to press backspace while entering the pin.

Resources