C Programming Tutorial - 33 -Challenge #1!

+3 Dejan B · November 30, 2014
Hello to everyone!
I try and I think it works fine, but can you tell me some improvement?
Thanks!
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>

int main()

{

    char password[21];
    int check = 0;
    int capital = 0, number = 0, dollar = 0;

    printf("This program will check the strength of your password.\nEnter a password with:\nat least 8 characters long,\nat least one capital letter,\nat least one number\nat least one $ sign:\n");
    scanf(" %s", &password);

    for(check=0; check < strlen(password); check++){

        if( isalpha(password[check]) ){
            if( isupper(password[check]) ){
            capital++;
            }
        }

        if( isdigit(password[check]) ){
            number++;
        }

        if( password[check] == '$' ){
            dollar++;
        }
      }

    if(capital >= 1){
        printf("\nCapital test: %d\tPassed\n", capital);
    }else{
        printf("\nCapital test: 0\tFailed\n");
        }

    if(number >= 1) {
        printf("Number test: %d\tPassed\n", number);
    }else{
        printf("Number test: 0\tFailed\n");
        }

    if(dollar >= 1){
        printf("Dollar test: %d\tPassed\n", dollar);
    }else{
        printf("Dollar test: 0\tFailed\n");
        }

    if(strlen(password) >= 8){
        printf("Minimum required length: %d\tPassed\n", strlen(password));
    }else{
        printf("Minimum required length: %d\tFailed\n", strlen(password));
        }

    if (capital == 0 || number == 0 || dollar == 0 || strlen(password) <=7){
        printf("\nYour password needs improving.\n");
    }else{
        printf("\nYour password is strong and have %d characters!\n", strlen(password));
    }
   return 0;
}




Post a Reply

Replies

- page 1
Oldest  Newest  Rating
+1 c student · December 8, 2014
first off, let me clarify that seg fault means that there is an attempt to access (read/write/whatever) prohibited data which lies outside of your program's memory stack, that is, basically outside of what your program has access to.  this is a security measure to protect damage to other program's data.

the reason why you are getting the seg fault is that although you have placed the check for the length of your password, you did not do anything other than print a message!  your program continued to run despite having all of your variables being flooded everywhere.  i believe your attempt to check your variables triggered the seg fault because the values have spilled into other memory stacks outside your program's reach,  a simple fix for this is to have your program terminate after printing the message with a function such as exit (int status) which is found in the stdlib.h header file.

i completely agree with haskell student.  sometimes you do not need to store things in memory but instead can check things on the fly at runtime.  getchar() is an excellent function for this type of situation and i highly recommend it because it minimizes any potential nasties buffers may cause.

you may need to check out www.asciitable.com for this since you'll need to familiarize yourself with different, awesome characters besides the standard alphabet/numbers/special characters!

good luck! 8-)
0 Dejan B · December 7, 2014
I read this:

http://en.wikipedia.org/wiki/Segmentation_fault

 but I don't know the solution for my problem?
0 Dejan B · December 7, 2014

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>

int main()

{

    char password[21];
    int check = 0;
    int capital = 0, number = 0, dollar = 0;

    printf("This program will check the strength of your password.\nEnter a password with:\nat least 8 characters long,\nat least one capital letter,\nat least one number\nat least one $ sign:\n");
    scanf(" %s", password);

    if( strlen(password)>21 ){
        printf("Enter maximum 20 characters! \n");
        }else{

        for(check=0; check < (int)strlen(password); check++){

        if( isalpha(password[check]) ){
            if( isupper(password[check]) ){
            capital++;
            }
        }

        if( isdigit(password[check]) ){
            number++;
        }

        if( password[check] == '$' ){
            dollar++;
        }
      }

    if(capital >= 1){
        printf("\nCapital test: %d\tPassed\n", capital);
    }else{
        printf("\nCapital test: 0\tFailed\n");
        }

    if(number >= 1) {
        printf("Number test: %d\tPassed\n", number);
    }else{
        printf("Number test: 0\tFailed\n");
        }

    if(dollar >= 1){
        printf("Dollar test: %d\tPassed\n", dollar);
    }else{
        printf("Dollar test: 0\tFailed\n");
        }

    if(strlen(password) >= 8){
        printf("Minimum required length: %d\tPassed\n", (int)strlen(password));
    }else{
        printf("Minimum required length: %d\tFailed\n", (int)strlen(password));
        }

    if (capital == 0 || number == 0 || dollar == 0 || strlen(password) <=7){
        printf("\nYour password needs improving.\n");
    }else{
        printf("\nYour password is strong and have %d characters!\n", (int)strlen(password));
    }
        }
   return 0;
}



Now  overflowing my password buffer "only" crashes the program in codeblocks and in coding ground I have this:

/images/forum/upload/2014-12-07/5ff9f425c00498fcf6d7a5389d041376.jpg
+1 c student · December 5, 2014
if you id not know already, a buffer overflow means that my input has basically overflowed the memory you have given it, like when you pour too much water into a cup.  how would you check for something that is too much?
+1 Dejan B · December 5, 2014
Now it works! Thanks! I must thinking now, how to check for a valid input.
+1 c student · December 5, 2014
i'd also like to add that it seems you wanted to force a special character for a more secure password.  i can see that you have successfully approached this with a number and upper case letter for a general case with the use of functions isdigit and isupper but it looks like you don't know how to do the same for all special characters, hence only using the dollar sign.

what you can do is use the values from an ascii table because c enables such flexibility, found here: www.asciitable.com

some values of special characters range from 33-47 and you can implement it into your code as such:
if (password[check] > 32 && password[check] < 47) {     // password element between ! ~ /
   sCharacter++;                                       // special character variable
}

of course, this is what i would type since i am used to it, instead of 32 and 47, you can type ' ' (space character) and '1' respectively.

with this implementation, the password strength will be much more secure and less prone to brute force attacks! hooray!

in regards to the security aspect of this question, here's a couple of suggestions to your next projects:
1. design a functioning program that generates a "random" password (length can be user specified)
2. design a function XOR encryption program that encrypts files of any type.
+1 c student · December 5, 2014
coding ground, by default, compiles with "gcc -o main *.c" which does set any warning or error flags.  if you wanted to have them, you would need to manually type it into the command line as i have done:

gcc -Wall -Werror -o <desired program name> <your c file name>
+1 Dejan B · December 5, 2014
I  understand errors, thanks, but when I compile with coding ground I didn't got that errors? What I am doing wrong when compile with coding ground?
+1 c student · December 5, 2014
part of being a programmer is creating safe and error-free programs to disallow any unwanted security breaches and also to prevent any invalid access to data in memory which could harm other processes and here are two i have found:

1. you have an error which may have been ignored by improperly flagged and checked during the compiling of the program
/images/forum/upload/2014-12-05/4d12764e5762bdf7ed2ffc86baf030c4.jpg
error on line 16 tells that you have an incorrect argument type with scanf.  you have typed "&password" and this is incorrect as it should just be "password".  when using scanf with an array, scanf will automatically place it within the array.

the rest of the errors with the "strlen(password)" tells that there is an incorrect return type of int where it should be "size_t" as strlen returns with the type of "size_t" but you have forced it to work with the %d integer type.  although this might work for this particular case, it might not for other situations.  what you can do is to cast "strlen(password)" to an int type by replacing it with "(int)strlen(password)".

the second major issue i have found: 
/images/forum/upload/2014-12-05/d56db3cd8f19659fc4d26d9ad9cd20c9.png
as you can see what i have done with your program input, i have caused a security breach and have basically broken your program by overflowing your password buffer which has ultimately flooded the other variables you have declared within your program (it will be easier to understand if you know what is happening in the memory level of your function stack).  clearly, the input i have given is totally incorrect but seems to have passed the checks!  to prevent this disaster, you must place in another check to test if the input given is valid!

don't fret if you feel overwhelmed by this, with more practice, you will become used to these common errors.  also, know that C is not an easy language to learn because of all the memory manipulation given to you, it's easy to mess up if you don't know how the inner workings function.  just keep programming and have fun as you go!

tl;dr
incorrect argument type in scanf, should just be "password"
incorrect with strlen return type, can fix by casting to int: (int)strlen(password)
buffer overflow, add check for a valid input
0 Ray Haq · December 5, 2014
Help me plz!
I dont understand the use of check.
and what does it mean? 'strlen(password)'
  • 1
  • 2

C

107,036 followers
About

One of the most popular languages of all time.

Links
Moderators
Bucky Roberts Administrator