#include #include #include #include #include #include "lua-bcrypt/compat/include/pwd.h" #define USER_DATABASE "./user.db" #define SECURITY_LEVEL 12 #define SEP '|' static bool valid_char(int ch) { return isalnum(ch) || ch == '_' || ch == '-' || ch == '.'; } /** * 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) { // check for invalid characters in username for ( const char *ptr = username; *ptr; ++ptr ) { if ( !valid_char(*ptr) ) { return false; } } FILE *db = fopen(USER_DATABASE, "a"); if ( db == NULL ) { return false; } char hash[_PASSWORD_LEN + 1] = { 0 }; if ( bcrypt_newhash(password, SECURITY_LEVEL, hash, _PASSWORD_LEN) != 0 ) { return false; } fprintf(db, "%s%c%s\n", username, SEP, hash); fclose(db); 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) { FILE *db = fopen(USER_DATABASE, "r"); if ( db == NULL ) { return false; } const size_t username_length = strlen(username); char line[256]; bool found = false; while ( !found && fgets(line, sizeof line, db) ) { 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 successfully authenticated! found = true; } fclose(db); return found; } /** * 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 *db = fopen(USER_DATABASE, "r"); if ( db == NULL ) { return false; } const size_t username_length = strlen(username); char line[256]; bool found = false; while ( !found && fgets(line, sizeof line, db) ) { line[strcspn(line, "\r\n")] = '\0'; // remove newline (if exists) if ( strncmp(line, username, username_length) != 0 ) { continue; } if ( line[username_length] != '|' ) { continue; } // User successfully authenticated! found = true; } fclose(db); return found; } int main(void) { if ( check_user("Thomas", "Passwort") ) { puts("Benutzer erfolgreich überprüft!"); } return EXIT_SUCCESS; }