10 pw_set(sqlite3 *db, char *user, char *pass)
12 static const char *q =
13 "INSERT INTO login (user, pass) VALUES (?1, ?2) "
14 "ON CONFLICT (user) DO UPDATE SET pass = ?2";
15 static sqlite3_stmt *s;
17 if (!s && sqlite3_prepare_v2(db, q, -1, &s, NULL) != SQLITE_OK)
19 if (sqlite3_bind_text(s, 1, user, -1, SQLITE_TRANSIENT) != SQLITE_OK)
22 char hash[_PASSWORD_LEN];
23 // note that alternatives to bcrypt are emerging
24 // https://isopenbsdsecu.re/mitigations/password_hashing/
25 if (crypt_newhash(pass, "bcrypt,a", hash, sizeof hash) != 0)
31 if (sqlite3_bind_text(s, 2, hash, sizeof hash, SQLITE_TRANSIENT) != SQLITE_OK)
33 if (sqlite3_step(s) != SQLITE_DONE)
35 fprintf(stderr, "Can't set pw: %s\n", sqlite3_errmsg(db));
39 bool good = sqlite3_changes(db) > 0;
46 pw_check(sqlite3 *db, char *user, char *pass)
48 static const char *q =
49 "SELECT pass FROM login WHERE user = ?";
50 static sqlite3_stmt *s;
52 if (!s && sqlite3_prepare_v2(db, q, -1, &s, NULL) != SQLITE_OK)
54 if (sqlite3_bind_text(s, 1, user, -1, SQLITE_TRANSIENT) != SQLITE_OK)
56 fprintf(stderr, "Can't bind: %s\n", sqlite3_errmsg(db));
60 if (sqlite3_step(s) != SQLITE_ROW)
62 const unsigned char *dbhash = sqlite3_column_text(s, 0);
64 bool good = 0 == crypt_checkpass(pass, dbhash);
69 int main(int argc, char **argv){
75 fprintf(stderr, "Usage: %s DATABASE\n", argv[0]);
78 rc = sqlite3_open(argv[1], &db);
80 fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
84 rc = sqlite3_db_config(db,
85 SQLITE_DBCONFIG_ENABLE_FKEY, 1, &fk_enabled
87 if (rc != SQLITE_OK || !fk_enabled)
89 fputs("Could not enable foreign keys in sqlite\n", stderr);
93 char *u1 = "foo@example.com", *p1 = "password123",
94 *u1c = "FOO@EXAMPLE.COM";
96 printf("Checking pass: %d\n", pw_check(db, u1, p1));
97 printf("Checking mixed case: %d\n", pw_check(db, u1c, p1));
98 printf("Checking wrong pass: %d\n", pw_check(db, u1, "wrong"));