/*===========================================================================
* include files
===========================================================================*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sqlite3.h>
#include <openssl/sha.h>
#include <openssl/rand.h>
#include <pthread.h>
#include "user_manage.h"
/*========================================================================
* Macro Definition
*========================================================================*/
#define SALT_SIZE 16
#define DB_NAME "/etc/user_system.db"
#define DEFAULT_ADMIN_NAME "admin"
#define DEFAULT_ADMIN_PASSWD "12345678"
/*========================================================================
* Type Definition
*========================================================================*/
typedef struct {
int id;
char username[50];
UserRole role;
UserStatus status;
unsigned char salt[SALT_SIZE];
unsigned char hash[SHA256_DIGEST_LENGTH];
time_t create_time;
} User;
/*========================================================================
* Global Variable
*========================================================================*/
sqlite3* user_manage_db = NULL;
static bool user_manage_db_inited = 0;
static pthread_mutex_t user_manage_db_mutex = PTHREAD_MUTEX_INITIALIZER;
/*========================================================================
* function Definition
*========================================================================*/
// 生成随机盐值
void generate_salt(unsigned char* salt) {
RAND_bytes(salt, SALT_SIZE);
}
// 密码哈希计算
void hash_password(const char* password, const unsigned char* salt, unsigned char* hash) {
SHA256_CTX sha256;
SHA256_Init(&sha256);
SHA256_Update(&sha256, salt, SALT_SIZE);
SHA256_Update(&sha256, password, strlen(password));
SHA256_Final(hash, &sha256);
}
// 数据库初始化
int um_db_init(sqlite3** db) {
if (NULL == db){
return UM_RET_FAIL;
}
pthread_mutex_lock(&user_manage_db_mutex);
int rc = sqlite3_open(DB_NAME, db);
if (rc != SQLITE_OK) {
fprintf(stderr, "无法打开数据库: %s\n", sqlite3_errmsg(*db));
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_FAIL;
}
const char* sql = "CREATE TABLE IF NOT EXISTS users("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"username TEXT UNIQUE NOT NULL,"
"role INTEGER NOT NULL,"
"status INTEGER NOT NULL,"
"salt BLOB NOT NULL,"
"hash BLOB NOT NULL,"
"create_time INTEGER NOT NULL);";
char* err_msg = NULL;
rc = sqlite3_exec(*db, sql, 0, 0, &err_msg);
if (rc != SQLITE_OK) {
fprintf(stderr, "SQL错误: %s\n", err_msg);
sqlite3_free(err_msg);
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_FAIL;
}
user_manage_db_inited = 1;
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_SUCCESS;
}
int um_db_deinit(sqlite3 * db)
{
if (NULL == db){
return UM_RET_FAIL;
}
sqlite3_close(db);
user_manage_db_inited = 0;
db = NULL;
return UM_RET_SUCCESS;
}
// 添加用户
int um_add_user(const char* username, const char* password, UserRole role, UserStatus status, UserAddStatus *um_add_user_status) {
//bool user_is_exist = 0;
if ((NULL == username)||(NULL == password)||(NULL == um_add_user_status)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
//pthread_mutex_lock(&user_manage_db_mutex);
//const char* user_count_sql = "SELECT COUNT(*) FROM users WHERE username = ?;";
//sqlite3_stmt* user_count_stmt;
//if(sqlite3_prepare_v2(user_manage_db, user_count_sql, -1, &user_count_stmt, NULL) != SQLITE_OK) {
// fprintf(stderr, "SQL准备失败\n");
// pthread_mutex_unlock(&user_manage_db_mutex);
// return UM_RET_FAIL;
//}
//sqlite3_bind_text(user_count_stmt, 1, username, -1, SQLITE_STATIC);
//if(sqlite3_step(user_count_stmt) == SQLITE_ROW) {
// if (sqlite3_column_int(user_count_stmt, 0) > 0){
// user_is_exist = 1;
// }
//}
//sqlite3_finalize(user_count_stmt);
//if (user_is_exist){
// * um_add_user_status = USER_ADD_FAIL_RENAME;
// pthread_mutex_unlock(&user_manage_db_mutex);
// return UM_RET_FAIL;
//}
//pthread_mutex_unlock(&user_manage_db_mutex);
User new_user;
strncpy(new_user.username, username, sizeof(new_user.username)-1);
new_user.role = role;
new_user.status = status;
new_user.create_time = time(NULL);
generate_salt(new_user.salt);
hash_password(password, new_user.salt, new_user.hash);
sqlite3_stmt* stmt;
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "INSERT INTO users(username, role, status, salt, hash, create_time) VALUES(?, ?, ?, ?, ?, ?);";
sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, new_user.username, -1, SQLITE_STATIC);
sqlite3_bind_int(stmt, 2, new_user.role);
sqlite3_bind_int(stmt, 3, new_user.status);
sqlite3_bind_blob(stmt, 4, new_user.salt, SALT_SIZE, SQLITE_STATIC);
sqlite3_bind_blob(stmt, 5, new_user.hash, SHA256_DIGEST_LENGTH, SQLITE_STATIC);
sqlite3_bind_int(stmt, 6, new_user.create_time);
if (SQLITE_DONE == sqlite3_step(stmt)){
*um_add_user_status = USER_ADD_SUCCESS;
}else {
*um_add_user_status = USER_ADD_FAIL_EXECUTE;
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_SUCCESS;
}
// 根据用户名删除用户
int um_delete_user(const char* username,UserDelStatus * um_del_user_status) {
if ((NULL == username)||(NULL == um_del_user_status)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "DELETE FROM users WHERE username = ?;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
fprintf(stderr, "SQL准备失败: %s\n", sqlite3_errmsg(user_manage_db));
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_FAIL;
}
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
int result = sqlite3_step(stmt) == SQLITE_DONE;
int changes = sqlite3_changes(user_manage_db);
sqlite3_finalize(stmt);
if(result && changes > 0) {
*um_del_user_status = USER_DEL_SUCCESS;
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_SUCCESS;
} else if(result && changes == 0) {
*um_del_user_status = USER_DEL_FAIL_NO_EXIST;
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_FAIL;
} else {
*um_del_user_status = USER_DEL_FAIL_EXECUTE;
fprintf(stderr, "删除用户 '%s' 失败: %s\n", username, sqlite3_errmsg(user_manage_db));
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_FAIL;
}
}
// 获取所有用户信息
int um_get_all_users(UserInfo** users, int* count) {
if ((NULL == users) || (NULL == count)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "SELECT id, username, role, status, create_time FROM users;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_FAIL;
}
// 获取记录数
*count = 0;
while(sqlite3_step(stmt) == SQLITE_ROW) (*count)++;
sqlite3_reset(stmt);
// 分配内存
*users = (UserInfo*)malloc(sizeof(UserInfo) * (*count));
if(!*users) return 0;
// 填充数据
int i = 0;
while(sqlite3_step(stmt) == SQLITE_ROW && i < *count) {
(*users)[i].id = sqlite3_column_int(stmt, 0);
strncpy((*users)[i].username, (const char*)sqlite3_column_text(stmt, 1), 49);
(*users)[i].role = sqlite3_column_int(stmt, 2);
(*users)[i].status = sqlite3_column_int(stmt, 3);
(*users)[i].create_time = sqlite3_column_int64(stmt, 4);
i++;
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_SUCCESS;
}
// 获取指定用户信息
int um_get_single_user_info(const char * username,UserInfo* user_info) {
if ((NULL == username) || (NULL == user_info)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "SELECT id, username, role, status, create_time FROM users WHERE username = ?;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_FAIL;
}
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_ROW) {
user_info->id = sqlite3_column_int(stmt, 0);
strncpy(user_info->username, (const char*)sqlite3_column_text(stmt, 1), 49);
user_info->role = sqlite3_column_int(stmt, 2);
user_info->status = sqlite3_column_int(stmt, 3);
user_info->create_time = sqlite3_column_int(stmt, 4);
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_SUCCESS;
}
// 设置用户状态
int um_modify_user_info(const char* username,const char * password,UserRole role, UserStatus status) {
int ret = UM_RET_FAIL;
if ((NULL == username)||(NULL == password)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
unsigned char salt[SALT_SIZE] = {0};
unsigned char hash[SHA256_DIGEST_LENGTH] = {0};
memset(salt,0x00,SALT_SIZE);
memset(hash,0x00,SHA256_DIGEST_LENGTH);
generate_salt(salt);
hash_password(password, salt, hash);
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "UPDATE users SET role = ? status = ? salt = ? hash = ? WHERE username = ?;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
return 0;
}
sqlite3_bind_int(stmt, 1, role);
sqlite3_bind_int(stmt, 2, status);
sqlite3_bind_blob(stmt, 3, salt, SALT_SIZE, SQLITE_STATIC);
sqlite3_bind_blob(stmt, 4, hash, SHA256_DIGEST_LENGTH, SQLITE_STATIC);
sqlite3_bind_text(stmt, 5, username, -1, SQLITE_STATIC);
if (SQLITE_DONE == sqlite3_step(stmt)){
ret = UM_RET_SUCCESS;
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return ret;
}
// 设置用户状态
int um_modify_user_passwd(const char* username,const char * password) {
int ret = UM_RET_FAIL;
if ((NULL == username)||(NULL == password)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
unsigned char salt[SALT_SIZE] = {0};
unsigned char hash[SHA256_DIGEST_LENGTH] = {0};
memset(salt,0x00,SALT_SIZE);
memset(hash,0x00,SHA256_DIGEST_LENGTH);
generate_salt(salt);
hash_password(password, salt, hash);
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "UPDATE users SET salt = ? hash = ? WHERE username = ?;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
return 0;
}
sqlite3_bind_blob(stmt, 1, salt, SALT_SIZE, SQLITE_STATIC);
sqlite3_bind_blob(stmt, 2, hash, SHA256_DIGEST_LENGTH, SQLITE_STATIC);
sqlite3_bind_text(stmt, 3, username, -1, SQLITE_STATIC);
if (SQLITE_DONE == sqlite3_step(stmt)){
ret = UM_RET_SUCCESS;
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return ret;
}
// 设置用户状态
int um_modify_user_role(const char* username, UserRole role) {
int ret = UM_RET_FAIL;
if (NULL == username){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "UPDATE users SET role = ? WHERE username = ?;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
return 0;
}
sqlite3_bind_int(stmt, 1, role);
sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
if (SQLITE_DONE == sqlite3_step(stmt)){
ret = UM_RET_SUCCESS;
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return ret;
}
// 设置用户状态
int um_modify_user_status(const char* username,UserStatus status) {
int ret = UM_RET_FAIL;
if (NULL == username){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "UPDATE users SET status = ? WHERE username = ?;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
return 0;
}
sqlite3_bind_int(stmt, 1, status);
sqlite3_bind_text(stmt, 2, username, -1, SQLITE_STATIC);
if (SQLITE_DONE == sqlite3_step(stmt)){
ret = UM_RET_SUCCESS;
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return ret;
}
//// 获取用户数量
//int um_get_user_count(UserRole role,int * count) {
// sqlite3_stmt* stmt;
// if (!user_manage_db_inited){
// return UM_RET_FAIL;
// }
// pthread_mutex_lock(&user_manage_db_mutex);
// const char* sql = "SELECT COUNT(*) FROM users WHERE role = ?;";
//
// sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL);
// sqlite3_bind_int(stmt, 1, role);
//
// if (sqlite3_step(stmt) == SQLITE_ROW) {
// *count = sqlite3_column_int(stmt, 0);
// }
//
// sqlite3_finalize(stmt);
// pthread_mutex_unlock(&user_manage_db_mutex);
// return UM_RET_SUCCESS;
//}
// 获取用户角色
int um_get_user_role(const char* username, UserRole * role) {
if ((NULL == username) || (NULL == role)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "SELECT role FROM users WHERE username = ?;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_FAIL;
}
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) == SQLITE_ROW){
*role = sqlite3_column_int(stmt,0);
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_SUCCESS;
}
// 检查用户名是否存在
int um_username_is_exist(const char* username,bool * user_exist) {
if ((NULL == username)||(NULL == user_exist)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
pthread_mutex_lock(&user_manage_db_mutex);
const char* sql = "SELECT COUNT(*) FROM users WHERE username = ?;";
sqlite3_stmt* stmt;
if(sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL) != SQLITE_OK) {
pthread_mutex_unlock(&user_manage_db_mutex);
fprintf(stderr, "SQL准备失败\n");
return -1;
}
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
if(sqlite3_step(stmt) == SQLITE_ROW) {
if(sqlite3_column_int(stmt, 0) > 0){
*user_exist = USER_EXIST;
}
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_SUCCESS;
}
// 验证用户登录
int um_verify_user_passwd(const char* username, const char* password,bool * passwd_verify_result) {
if ((NULL == username)||(NULL == password)||(NULL == passwd_verify_result)){
return UM_RET_FAIL;
}
if (!user_manage_db_inited){
return UM_RET_FAIL;
}
sqlite3_stmt* stmt;
const char* sql = "SELECT salt, hash, status FROM users WHERE username = ?;";
pthread_mutex_lock(&user_manage_db_mutex);
sqlite3_prepare_v2(user_manage_db, sql, -1, &stmt, NULL);
sqlite3_bind_text(stmt, 1, username, -1, SQLITE_STATIC);
if (sqlite3_step(stmt) != SQLITE_ROW) {
sqlite3_finalize(stmt);
return UM_RET_FAIL;
}
const void* salt = sqlite3_column_blob(stmt, 0);
const void* stored_hash = sqlite3_column_blob(stmt, 1);
//UserStatus status = sqlite3_column_int(stmt, 2);
//
//if (status == STATUS_DISABLED) {
// sqlite3_finalize(stmt);
// return UM_RET_FAIL;
//}
unsigned char computed_hash[SHA256_DIGEST_LENGTH];
hash_password(password, salt, computed_hash);
if (0 == memcmp(stored_hash, computed_hash, SHA256_DIGEST_LENGTH)){
*passwd_verify_result = 1;
}
sqlite3_finalize(stmt);
pthread_mutex_unlock(&user_manage_db_mutex);
return UM_RET_SUCCESS;
}
int um_task_db_init(void)
{
bool user_exist = USER_NONE;
UserAddStatus admin_add_status = USER_ADD_NONE;
if (UM_RET_SUCCESS == um_db_init(&user_manage_db)) {
// 初始化默认管理员
um_username_is_exist(DEFAULT_ADMIN_NAME,&user_exist);
if (USER_EXIST != user_exist){
um_add_user(DEFAULT_ADMIN_NAME, DEFAULT_ADMIN_PASSWD, ROLE_ADMIN,STATUS_ACTIVE,&admin_add_status);
}
return 0;
}else {
return 1;
}
}
int um_task_db_deinit(void)
{
um_db_deinit(user_manage_db);
user_manage_db = NULL;
return 0;
}
请分析以上代码的所有问题,并提供优化修复后的代码。