#include #include #include #include #include #include "bcrypt.h" #define USER_DATABASE "./user.db" #define SECURITY_LEVEL 12 #define SEP '|' #define MAX_LINE_LENGTH 256 static bool valid_char(int chr) { return isalnum(chr) || chr == '_' || chr == '-' || chr == '.'; } /** * Create a new user/password * * \param[in] username * \param[in] password * * \return true on success (user was created) or false on error */ bool create_user(const char *username, const char *password) // NOLINT { // check for invalid characters in username for ( const char *ptr = username; *ptr; ++ptr ) { if ( !valid_char(*ptr) ) { return false; } } FILE *database = fopen(USER_DATABASE, "at"); if ( database == NULL ) { return false; } char hash[_PASSWORD_LEN + 1] = { 0 }; if ( bcrypt_newhash(password, SECURITY_LEVEL, hash, _PASSWORD_LEN) != 0 ) { return false; } (void) fprintf(database, "%s%c%s\n", username, SEP, hash); (void) fclose(database); return true; } /** * Check is a valid username/password exists in the user-database * * username A username * password A strong password * * @return true, if the user was successfully authenticated, otherwise false */ bool check_user(const char *const username, const char *const password) // NOLINT { FILE *database = fopen(USER_DATABASE, "rt"); if ( database == NULL ) { return false; } const size_t username_length = strlen(username); char line[MAX_LINE_LENGTH]; bool user_authenticated = false; while ( !user_authenticated && fgets(line, sizeof line, database) != NULL ) { line[strcspn(line, "\r\n")] = '\0'; // remove newline (if exists) if ( strncmp(line, username, username_length) != 0 ) { continue; } if ( line[username_length] != SEP ) { continue; } if ( bcrypt_checkpass(password, &line[username_length + 1]) != 0 ) { continue; } user_authenticated = true; } (void) fclose(database); return user_authenticated; } /** * Check if a valid username already exists in the user-database * * \param[in] username to be checked * * \return true, if the user was successfully authenticated, otherwise false */ bool check_user_if_exists(const char *username) { FILE *database = fopen(USER_DATABASE, "rt"); if ( database == NULL ) { return false; } const size_t username_length = strlen(username); char line[MAX_LINE_LENGTH]; bool user_found = false; while ( !user_found && fgets(line, sizeof line, database) != NULL ) { line[strcspn(line, "\r\n")] = '\0'; // remove newline (if exists) if ( strncmp(line, username, username_length) != 0 ) { continue; } if ( line[username_length] != SEP ) { continue; } user_found = true; } (void) fclose(database); return user_found; } int main(void) { if ( check_user("Thomas", "Passwort") ) { puts("Benutzer erfolgreich überprüft!"); } return EXIT_SUCCESS; }