2
votes

I am writing code in C program to check for the strength of password using regex.
My requirements are: "atleast one upper character and one lower character one digit and one special character and overall password length should be minimum 9 characters"

First I figured out regex combination in http://regexr.com/ and regex combination is ((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[_+-.,!@#$%^&*();\/|<>"']).{9,})

But if I try the same in C language using program below it does not work:

#include<stdio.h>
#include<ctype.h>
#include<stdbool.h>
#include<sys/types.h>
#include<regex.h>

static void  check_password_strength(const char *password) {
    regex_t comp_ex;
    int rc = regcomp(&comp_ex, "((?=.*\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[_+-.,!@#$%^&*();\/|<>"']).{9,})", 0);
    if (rc != 0) {
        char errbuf[1024];
        (void)(regerror(rc, &comp_ex, errbuf, sizeof(errbuf)));
        printf("%s: error compiling regex: %s", __FUNCTION__, errbuf);
        return;
    }

    if (regexec(&comp_ex, password, 0, NULL, 0) == 0) {
        regfree(&comp_ex);
        printf("Password accepted :%s\n", password);
        return;
    }

    printf("password NOT accepted\n");
    regfree(&comp_ex);
    return;
}

void main(int argc, char *argv[])
{
    int i = 0;

    if (argc != 2) {
        printf("invalid number of args \n");
        return;
    }
    check_password_strength(argv[1]);
}

Do I need to use regex in different way in C program? Like [[:alnum:]] or [[:digit:]]? Can you please give an hint here if you know?

1
"atleast one upper character and one lower character one digit and one special character" That's not how you make a strong password. That's how you make a forgettable password. Don't do this.Alexander
I don't think a regex is a good way to go about analyzing the password. All else apart, you need to allow the different character classes in any order, which is fiddle at best.Jonathan Leffler
Try to double up each \ (backslash) inside the pattern. Although I agree that regex is not the way to go for this, you can simply scan the string and count each requirement...A.S.H
Yet another instance where people inappropriately try to use regular expressions for every string-processing task.Jonathon Reinhart
This is a terrible indicator of password strength. There are plenty of open source password checkers out there that can do a much better job (e.g., zxcvbn). I suggest you use one of those instead.r3mainer

1 Answers

2
votes

Your program didn't even compile. As one of the comment said, you should escape each back backslash character \, as it is used by C to special characters. Replace \ with \\, and replace " with \", try this escaped regex:

int rc = regcomp(&comp_ex, "((?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[_+-.,!@#$%^&*();\\/|<>\"']).{9,})", 0);

Also it is not a good idea to use regex for this kind of checks, just scan the string and count:

static bool check_password_strength(const char *password) {
    const char *p = password;
    char c;
    int nupper = 0;
    int nlower = 0;
    int ndigit = 0;
    int nspecial = 0;
    while (*p) {
        c = *p++;
        if (isupper(c)) ++nupper;
        else if (islower(c)) ++nlower;
        else if (isdigit(c)) ++ndigit;
        else if (ispunct(c)) ++nspecial;
        else continue; // space character
   }

   return nupper && nlower && ndigit && nspecial;
}