Rev 31 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/* $Id: sqlite.c 35 2024-08-22 02:53:30Z nishi $ */
#include "rv_db.h"
#include "../../config.h"
#include "rv_util.h"
#include "rv_sha512.h"
#include <sqlite3.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
sqlite3* sql;
void rv_init_db(void) {
int ret;
ret = sqlite3_open(DB_ROOT "/db.sqlite3", &sql);
if(ret != SQLITE_OK) {
rv_error_http();
printf("SQLite3 database error\n");
exit(1);
}
char* err;
ret = sqlite3_exec(sql, "create table if not exists users(user text, password text)", NULL, NULL, &err);
if(ret != SQLITE_OK) {
sqlite3_free(err);
rv_error_http();
printf("SQLite3 database error\n");
exit(1);
}
ret = sqlite3_exec(sql, "create table if not exists tokens(user text, token text)", NULL, NULL, &err);
if(ret != SQLITE_OK) {
sqlite3_free(err);
rv_error_http();
printf("SQLite3 database error\n");
exit(1);
}
}
void rv_close_db(void) { sqlite3_close(sql); }
int count = 0;
struct user {
char* username;
char* password;
bool valid;
};
int sqlcount(void* param, int ncol, char** row, char** col) {
count = ncol;
return 0;
}
int sqlgetpasswd(void* param, int ncol, char** row, char** col) {
struct user* user = (struct user*)param;
if(strcmp(row[0], user->username) == 0) {
char* hash = rv_sha512(user->password);
if(strcmp(row[1], hash) == 0) {
user->valid = true;
}
free(hash);
}
return 0;
}
char* escape_sql(const char* input) {
char* query = malloc(1);
query[0] = 0;
char cbuf[2];
cbuf[1] = 0;
int i;
for(i = 0; input[i] != 0; i++) {
if(input[i] == '\'') {
cbuf[0] = input[i];
char* tmp = query;
query = rv_strcat(tmp, cbuf);
free(tmp);
cbuf[0] = input[i];
tmp = query;
query = rv_strcat(tmp, cbuf);
free(tmp);
} else {
cbuf[0] = input[i];
char* tmp = query;
query = rv_strcat(tmp, cbuf);
free(tmp);
}
}
return query;
}
bool rv_check_password(const char* username, const char* password) {
char* err;
int ret;
struct user user;
user.username = (char*)username;
user.password = (char*)password;
user.valid = false;
char* esc = escape_sql(username);
char* query = rv_strcat3("select * from users where user = '", esc, "'");
free(esc);
ret = sqlite3_exec(sql, query, sqlgetpasswd, (void*)&user, &err);
if(ret != SQLITE_OK) {
sqlite3_free(err);
}
return user.valid;
}
void rv_create_user(const char* username, const char* password) {
char* err;
int ret;
char* sha512 = rv_sha512(password);
char* esc = escape_sql(username);
char* tmp = rv_strcat3("insert into users values('", esc, "', '");
char* query = rv_strcat3(tmp, sha512, "')");
free(sha512);
free(tmp);
free(esc);
ret = sqlite3_exec(sql, query, NULL, NULL, &err);
if(ret != SQLITE_OK) {
sqlite3_free(err);
}
rv_add_auth(username, password);
}
void rv_save_token(const char* username, const char* token) {
char* err;
int ret;
char* esc = escape_sql(username);
char* tmp = rv_strcat3("insert into tokens values('", esc, "', '");
char* query = rv_strcat3(tmp, token, "')");
free(tmp);
free(esc);
ret = sqlite3_exec(sql, query, NULL, NULL, &err);
free(query);
if(ret != SQLITE_OK) {
sqlite3_free(err);
}
}
char* has_username;
int sqlget(void* param, int ncol, char** row, char** col) {
has_username = rv_strdup(row[0]);
return 0;
}
char* rv_who_has_token(const char* token) {
char* err;
count = 0;
char* esc = escape_sql(token);
char* query = rv_strcat3("select * from tokens where token = '", esc, "'");
free(esc);
int ret;
has_username = NULL;
ret = sqlite3_exec(sql, query, sqlget, (void*)token, &err);
free(query);
if(ret != SQLITE_OK) {
sqlite3_free(err);
return NULL;
}
return has_username;
}
bool rv_has_token(const char* token) {
char* err;
char* esc = escape_sql(token);
char* query = rv_strcat3("select * from tokens where token = '", esc, "'");
free(esc);
int ret;
count = 0;
ret = sqlite3_exec(sql, query, sqlcount, NULL, &err);
free(query);
if(ret != SQLITE_OK) {
sqlite3_free(err);
}
return count > 0;
}
void rv_remove_token(const char* token) {
char* err;
char* esc = escape_sql(token);
char* query = rv_strcat3("delete from tokens where token = '", esc, "'");
free(esc);
int ret;
ret = sqlite3_exec(sql, query, sqlcount, NULL, &err);
free(query);
if(ret != SQLITE_OK) {
sqlite3_free(err);
}
}
bool rv_has_user(const char* username) {
char* err;
count = 0;
char* esc = escape_sql(username);
char* query = rv_strcat3("select * from users where user = '", esc, "'");
free(esc);
int ret;
ret = sqlite3_exec(sql, query, sqlcount, NULL, &err);
free(query);
if(ret != SQLITE_OK) {
sqlite3_free(err);
}
return count > 0;
}