diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bcrypt-test.c | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/src/bcrypt-test.c b/src/bcrypt-test.c new file mode 100644 index 0000000..57cf390 --- /dev/null +++ b/src/bcrypt-test.c | |||
| @@ -0,0 +1,144 @@ | |||
| 1 | #include <ctype.h> | ||
| 2 | #include <stdbool.h> | ||
| 3 | #include <stdio.h> | ||
| 4 | #include <stdlib.h> | ||
| 5 | #include <string.h> | ||
| 6 | |||
| 7 | #include "bcrypt.h" | ||
| 8 | |||
| 9 | #define USER_DATABASE "./user.db" | ||
| 10 | #define SECURITY_LEVEL 12 | ||
| 11 | #define SEP '|' | ||
| 12 | #define MAX_LINE_LENGTH 256 | ||
| 13 | |||
| 14 | static bool | ||
| 15 | valid_char(int chr) | ||
| 16 | { | ||
| 17 | return isalnum(chr) || chr == '_' || chr == '-' || chr == '.'; | ||
| 18 | } | ||
| 19 | |||
| 20 | /** | ||
| 21 | * Create a new user/password | ||
| 22 | * | ||
| 23 | * \param[in] username | ||
| 24 | * \param[in] password | ||
| 25 | * | ||
| 26 | * \return true on success (user was created) or false on error | ||
| 27 | */ | ||
| 28 | bool | ||
| 29 | create_user(const char *username, const char *password) // NOLINT | ||
| 30 | { | ||
| 31 | // check for invalid characters in username | ||
| 32 | for ( const char *ptr = username; *ptr; ++ptr ) { | ||
| 33 | if ( !valid_char(*ptr) ) { | ||
| 34 | return false; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | |||
| 38 | FILE *database = fopen(USER_DATABASE, "a"); | ||
| 39 | if ( database == NULL ) { | ||
| 40 | return false; | ||
| 41 | } | ||
| 42 | |||
| 43 | char hash[_PASSWORD_LEN + 1] = { 0 }; | ||
| 44 | |||
| 45 | if ( bcrypt_newhash(password, SECURITY_LEVEL, hash, _PASSWORD_LEN) != 0 ) { | ||
| 46 | return false; | ||
| 47 | } | ||
| 48 | |||
| 49 | (void) fprintf(database, "%s%c%s\n", username, SEP, hash); | ||
| 50 | (void) fclose(database); | ||
| 51 | |||
| 52 | return true; | ||
| 53 | } | ||
| 54 | |||
| 55 | /** | ||
| 56 | * Check is a valid username/password exists in the user-database | ||
| 57 | * | ||
| 58 | * username A username | ||
| 59 | * password A strong password | ||
| 60 | * | ||
| 61 | * @return true, if the user was successfully authenticated, otherwise false | ||
| 62 | */ | ||
| 63 | bool | ||
| 64 | check_user(const char *const username, const char *const password) // NOLINT | ||
| 65 | { | ||
| 66 | FILE *database = fopen(USER_DATABASE, "r"); | ||
| 67 | if ( database == NULL ) { | ||
| 68 | return false; | ||
| 69 | } | ||
| 70 | |||
| 71 | const size_t username_length = strlen(username); | ||
| 72 | char line[MAX_LINE_LENGTH]; | ||
| 73 | |||
| 74 | bool user_authenticated = false; | ||
| 75 | while ( !user_authenticated && fgets(line, sizeof line, database) != NULL ) { | ||
| 76 | line[strcspn(line, "\r\n")] = '\0'; // remove newline (if exists) | ||
| 77 | |||
| 78 | if ( strncmp(line, username, username_length) != 0 ) { | ||
| 79 | continue; | ||
| 80 | } | ||
| 81 | |||
| 82 | if ( line[username_length] != SEP ) { | ||
| 83 | continue; | ||
| 84 | } | ||
| 85 | |||
| 86 | if ( bcrypt_checkpass(password, &line[username_length + 1]) != 0 ) { | ||
| 87 | continue; | ||
| 88 | } | ||
| 89 | |||
| 90 | user_authenticated = true; | ||
| 91 | } | ||
| 92 | |||
| 93 | (void) fclose(database); | ||
| 94 | |||
| 95 | return user_authenticated; | ||
| 96 | } | ||
| 97 | |||
| 98 | /** | ||
| 99 | * Check if a valid username already exists in the user-database | ||
| 100 | * | ||
| 101 | * \param[in] username to be checked | ||
| 102 | * | ||
| 103 | * \return true, if the user was successfully authenticated, otherwise false | ||
| 104 | */ | ||
| 105 | bool | ||
| 106 | check_user_if_exists(const char *username) | ||
| 107 | { | ||
| 108 | FILE *database = fopen(USER_DATABASE, "r"); | ||
| 109 | if ( database == NULL ) { | ||
| 110 | return false; | ||
| 111 | } | ||
| 112 | |||
| 113 | const size_t username_length = strlen(username); | ||
| 114 | char line[MAX_LINE_LENGTH]; | ||
| 115 | |||
| 116 | bool user_found = false; | ||
| 117 | while ( !user_found && fgets(line, sizeof line, database) != NULL ) { | ||
| 118 | line[strcspn(line, "\r\n")] = '\0'; // remove newline (if exists) | ||
| 119 | |||
| 120 | if ( strncmp(line, username, username_length) != 0 ) { | ||
| 121 | continue; | ||
| 122 | } | ||
| 123 | |||
| 124 | if ( line[username_length] != SEP ) { | ||
| 125 | continue; | ||
| 126 | } | ||
| 127 | |||
| 128 | user_found = true; | ||
| 129 | } | ||
| 130 | |||
| 131 | (void) fclose(database); | ||
| 132 | |||
| 133 | return user_found; | ||
| 134 | } | ||
| 135 | |||
| 136 | int | ||
| 137 | main(void) | ||
| 138 | { | ||
| 139 | if ( check_user("Thomas", "Passwort") ) { | ||
| 140 | puts("Benutzer erfolgreich überprüft!"); | ||
| 141 | } | ||
| 142 | |||
| 143 | return EXIT_SUCCESS; | ||
| 144 | } | ||
