Mod aaa-12 增加lighttpd的mod_portal模块
RCA: SOL: 修改人:chenling 检视人:
This commit is contained in:
parent
100cc7699e
commit
551bd945e2
libs/src/lighttpd-1.4.51
|
@ -1324,7 +1324,7 @@ AM_CONDITIONAL([CHECK_WITH_FASTCGI], [test "$fastcgi_found" = yes])
|
|||
AC_MSG_NOTICE([----------------------------------------])
|
||||
dnl check for extra compiler options (warning options)
|
||||
if test "${GCC}" = yes; then
|
||||
TRY_CFLAGS([-Wall -W -Wshadow -pedantic])
|
||||
TRY_CFLAGS([-Wall -W])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([extra-warnings],
|
||||
|
|
|
@ -146,7 +146,7 @@ mod_magnet_la_LDFLAGS = $(common_module_ldflags)
|
|||
mod_magnet_la_LIBADD = $(common_libadd) $(LUA_LIBS) -lm
|
||||
endif
|
||||
|
||||
if BUILD_WITH_LUA
|
||||
if BUILD_WITH_LUA
|
||||
lib_LTLIBRARIES += mod_cml.la
|
||||
mod_cml_la_SOURCES = mod_cml.c mod_cml_lua.c mod_cml_funcs.c
|
||||
mod_cml_la_CFLAGS = $(AM_CFLAGS) $(LUA_CFLAGS)
|
||||
|
@ -409,6 +409,11 @@ mod_webm_la_SOURCES = mod_webm.c json.c
|
|||
mod_webm_la_LDFLAGS = -module -export-dynamic -avoid-version
|
||||
mod_webm_la_LIBADD = $(common_libadd)
|
||||
|
||||
lib_LTLIBRARIES += mod_portal.la
|
||||
mod_portal_la_SOURCES = mod_portal.c json.c user_hashtable.c user_auth.c
|
||||
mod_portal_la_LDFLAGS = -module -export-dynamic -avoid-version -L../../../../Platform/build/debug/
|
||||
mod_portal_la_LIBADD = $(common_libadd) -ldatabase-linux
|
||||
|
||||
hdr = server.h base64.h buffer.h burl.h network.h log.h http_kv.h keyvalue.h \
|
||||
response.h request.h fastcgi.h chunk.h \
|
||||
first.h settings.h http_chunk.h \
|
||||
|
@ -423,7 +428,9 @@ hdr = server.h base64.h buffer.h burl.h network.h log.h http_kv.h keyvalue.h \
|
|||
sys-crypto.h sys-endian.h sys-mmap.h sys-socket.h sys-strings.h \
|
||||
mod_cml.h mod_cml_funcs.h \
|
||||
safe_memclear.h sock_addr.h splaytree.h status_counter.h \
|
||||
mod_magnet_cache.h
|
||||
mod_magnet_cache.h \
|
||||
user_hashtable.h \
|
||||
user_auth.h
|
||||
|
||||
|
||||
DEFS= @DEFS@ -DHAVE_VERSIONSTAMP_H -DLIBRARY_DIR="\"$(libdir)\"" -DSBIN_DIR="\"$(sbindir)\""
|
||||
|
@ -465,7 +472,7 @@ lighttpd_SOURCES = \
|
|||
mod_userdir.c \
|
||||
mod_usertrack.c \
|
||||
mod_vhostdb.c \
|
||||
mod_webdav.c
|
||||
mod_webdav.c
|
||||
lighttpd_CPPFLAGS = \
|
||||
-DLIGHTTPD_STATIC \
|
||||
$(XML_CFLAGS) $(SQLITE_CFLAGS) \
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
#ifndef __HLIST_H
|
||||
#define __HLIST_H
|
||||
|
||||
struct hlist_head {
|
||||
struct hlist_node *first;
|
||||
};
|
||||
|
||||
struct hlist_node {
|
||||
struct hlist_node *next, **pprev;
|
||||
};
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
|
||||
#endif
|
||||
|
||||
#ifndef container_of
|
||||
#define container_of(ptr, type, member) ({ \
|
||||
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
|
||||
(type *)( (char *)__mptr - offsetof(type,member) );})
|
||||
#endif
|
||||
|
||||
#define HLIST_HEAD_INIT { .first = NULL }
|
||||
#define HLIST_HEAD(name) struct hlist_head name = { .first = NULL }
|
||||
|
||||
#define INIT_HLIST_HEAD(ptr) ((ptr)->first = NULL)
|
||||
|
||||
static inline void INIT_HLIST_NODE(struct hlist_node *h)
|
||||
{
|
||||
h->next = NULL;
|
||||
h->pprev = NULL;
|
||||
}
|
||||
|
||||
static inline int hlist_unhashed(const struct hlist_node *h)
|
||||
{
|
||||
return !h->pprev;
|
||||
}
|
||||
|
||||
static inline int hlist_empty(const struct hlist_head *h)
|
||||
{
|
||||
return !h->first;
|
||||
}
|
||||
|
||||
static inline void __hlist_del(struct hlist_node *n)
|
||||
{
|
||||
struct hlist_node *next = n->next;
|
||||
struct hlist_node **pprev = n->pprev;
|
||||
*pprev = next;
|
||||
if (next)
|
||||
next->pprev = pprev;
|
||||
}
|
||||
|
||||
static inline void hlist_del(struct hlist_node *n)
|
||||
{
|
||||
__hlist_del(n);
|
||||
n->next = NULL;
|
||||
n->pprev = NULL;
|
||||
}
|
||||
|
||||
static inline void hlist_add_head(struct hlist_node *n, struct hlist_head *h)
|
||||
{
|
||||
struct hlist_node *first = h->first;
|
||||
n->next = first;
|
||||
if (first)
|
||||
first->pprev = &n->next;
|
||||
h->first = n;
|
||||
n->pprev = &h->first;
|
||||
}
|
||||
|
||||
|
||||
static inline void hlist_del_init(struct hlist_node *n)
|
||||
{
|
||||
if (!hlist_unhashed(n)) {
|
||||
__hlist_del(n);
|
||||
INIT_HLIST_NODE(n);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void hlist_add_before(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
n->pprev = next->pprev;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
*(n->pprev) = n;
|
||||
}
|
||||
|
||||
static inline void hlist_add_after(struct hlist_node *n,
|
||||
struct hlist_node *next)
|
||||
{
|
||||
next->next = n->next;
|
||||
n->next = next;
|
||||
next->pprev = &n->next;
|
||||
|
||||
if(next->next)
|
||||
next->next->pprev = &next->next;
|
||||
}
|
||||
|
||||
static inline void hlist_move_list(struct hlist_head *old,
|
||||
struct hlist_head *new)
|
||||
{
|
||||
new->first = old->first;
|
||||
if (new->first)
|
||||
new->first->pprev = &new->first;
|
||||
old->first = NULL;
|
||||
}
|
||||
|
||||
#define hlist_entry(ptr, type, member) container_of(ptr,type,member)
|
||||
|
||||
|
||||
#define hlist_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->first; pos && ({ n = pos->next; 1; }); \
|
||||
pos = n)
|
||||
|
||||
#define hlist_for_each_entry(tpos, pos, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_entry_continue(tpos, pos, member) \
|
||||
for (pos = (pos)->next; \
|
||||
pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_entry_from(tpos, pos, member) \
|
||||
for (; pos && ({ prefetch(pos->next); 1;}) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = pos->next)
|
||||
|
||||
#define hlist_for_each_entry_safe(tpos, pos, n, head, member) \
|
||||
for (pos = (head)->first; \
|
||||
pos && ({ n = pos->next; 1; }) && \
|
||||
({ tpos = hlist_entry(pos, typeof(*tpos), member); 1;}); \
|
||||
pos = n)
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,471 @@
|
|||
#include "first.h"
|
||||
#include "base_decls.h"
|
||||
#include "json.h"
|
||||
#include "user_hashtable.h"
|
||||
#include "base.h"
|
||||
#include "plugin.h"
|
||||
#include "http_auth.h"
|
||||
#include "http_header.h"
|
||||
#include "log.h"
|
||||
#include "dlfcn.h"
|
||||
#include "connections.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "user_auth.h"
|
||||
|
||||
#define USERNAME_MAXLEN 65
|
||||
#define PASSWORD_MAXLEN 25
|
||||
|
||||
typedef void* pointer;
|
||||
|
||||
#if 0
|
||||
typedef struct user_auth_list
|
||||
{
|
||||
time_t* fail_time; //循环队列存储认证失败时间点
|
||||
int front; //循环队列头
|
||||
int rear; //循环队列尾
|
||||
int max_size; //循环队列的最大存储空间,锁定次数+1(config_fail_num + 1)
|
||||
|
||||
unsigned int online_num; //用户上线数量
|
||||
time_t lock_time; //用户锁定时间
|
||||
unsigned short group_id; //用户组id
|
||||
//unsigned int fail_num; //用户认证失败次数
|
||||
} USER_AUTH_LIST;
|
||||
|
||||
typedef enum {
|
||||
AUTH_SUCCESS = 0,
|
||||
AUTH_FAIL_PASSWD = 1,
|
||||
AUTH_FAIL_VALID = 2,
|
||||
AUTH_FAIL_MULTI = 3,
|
||||
AUTH_FAIL_LOCK = 4,
|
||||
AUTH_FAIL_LACKINFO = 5,
|
||||
AUTH_FAIL_INPUT = 6,
|
||||
AUTH_FAIL_OVER = 7,
|
||||
AUTH_ERR = 8,
|
||||
AUTH_FAIL_DATABASE = 9,
|
||||
|
||||
} auth_ret;
|
||||
|
||||
typedef struct user_auth_ret
|
||||
{
|
||||
auth_ret ret;
|
||||
unsigned short user_id;
|
||||
unsigned short group_id;
|
||||
time_t remain_lock_time;
|
||||
} USER_AUTH_RET;
|
||||
#endif
|
||||
|
||||
/*输出函数结构体 */
|
||||
typedef struct {
|
||||
auth_ret resultcode;
|
||||
char *message; /*返回描述用指针表示数组 */
|
||||
time_t remain_lock_time; /*锁定剩余时间 */
|
||||
int js_location; /*0 location*/
|
||||
char *location_url;
|
||||
}RESULT;
|
||||
|
||||
/*函数指针*/
|
||||
typedef void (*mod_portal_cfg_exec_sync)(char* username, char* password, USER_AUTH_RET *auth_result);
|
||||
|
||||
typedef struct {
|
||||
PLUGIN_DATA;
|
||||
void *cfgm_lib;
|
||||
mod_portal_cfg_exec_sync portal_cfg_exec;
|
||||
USER_AUTH_LIST *portal_auth_list;
|
||||
} mod_portal_plugin_data;
|
||||
|
||||
|
||||
char * mes[]={"SUCCESS", "ErrorUsernameOrpassword", "NotInVaildTime",
|
||||
"OutMaxOnlineNum", "UserIsLocked", "LackConfigInfo",
|
||||
"OverMaxOnlineNum", "OtherErr"};
|
||||
|
||||
|
||||
/**
|
||||
* the basic and digest auth framework
|
||||
*
|
||||
* - config handling
|
||||
* - protocol handling
|
||||
*
|
||||
* http_auth.c
|
||||
* http_auth_digest.c
|
||||
*
|
||||
* do the real work
|
||||
*/
|
||||
#if 0
|
||||
INIT_FUNC(mod_portal_init) {
|
||||
/* 用户认证 */
|
||||
mod_portal_plugin_data *p;
|
||||
|
||||
p = calloc(1, sizeof(*p));
|
||||
if (p)
|
||||
{
|
||||
if (NULL == (p->cfgm_lib = dlopen("libuserauthapi-linux.so", RTLD_NOW|RTLD_GLOBAL)))
|
||||
{
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->portal_cfg_exec = (void (*)(char* , char* , USER_AUTH_RET*))(intptr_t)dlsym(p->cfgm_lib, "user_auth_login");
|
||||
p->portal_auth_list = dlsym(p->cfgm_lib, "g_user_auth_ret_table");
|
||||
if (NULL == p->portal_cfg_exec)
|
||||
{
|
||||
free(p);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
#endif
|
||||
|
||||
INIT_FUNC(mod_portal_init) {
|
||||
mod_portal_plugin_data *p;
|
||||
|
||||
p = calloc(1, sizeof(*p));
|
||||
|
||||
return p;
|
||||
|
||||
}
|
||||
|
||||
/*认证模块释放*/
|
||||
FREE_FUNC(mod_portal_free) {
|
||||
mod_portal_plugin_data *p = p_d;
|
||||
srv = srv;
|
||||
if (!p) return HANDLER_GO_ON;
|
||||
|
||||
dlclose(p->cfgm_lib);
|
||||
free(p);
|
||||
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
/*认证模块处理函数*/
|
||||
static handler_t mod_portal_uri_handler(server *srv, connection *con, void* p_d)
|
||||
{
|
||||
p_d = p_d;
|
||||
//mod_portal_plugin_data *p = p_d;
|
||||
cJSON *cjson;
|
||||
USER_AUTH_RET *resultinfo;
|
||||
char *account = NULL;
|
||||
char *pwd = NULL;
|
||||
Init_hash(); /*初始化hash表放在配置恢复处 */
|
||||
uint32_t client_ip=10001; /*解析报文拿到用户IP */
|
||||
|
||||
RESULT *uresult;
|
||||
uresult = ( RESULT *)malloc(sizeof(RESULT));
|
||||
if(NULL == uresult)
|
||||
{
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
resultinfo = (USER_AUTH_RET *)malloc(sizeof(USER_AUTH_RET));
|
||||
if (NULL == resultinfo)
|
||||
{
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
/*method=get,return HANDLER_GO_ON*/
|
||||
if(con->request.http_method == HTTP_METHOD_GET)
|
||||
{
|
||||
USER_INFO *uinfo;
|
||||
uinfo = (USER_INFO *)malloc(sizeof(USER_INFO));
|
||||
if (NULL == uinfo)
|
||||
{
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
if (0 == strcmp(con->uri.path->ptr, "/ISG-authsuccess"))
|
||||
{
|
||||
ufind_user(client_ip, uinfo);
|
||||
if (NULL == uinfo)
|
||||
{
|
||||
buffer *return_info = buffer_init();
|
||||
|
||||
return_info = buffer_init_string("<script type=\"text/javascript\">top.location.href='http://1.1.1.1:8080/ISG-auth';</script>");
|
||||
chunkqueue_append_buffer(con->write_queue, return_info);
|
||||
buffer_free(return_info);
|
||||
con->http_status = 200;
|
||||
con->file_finished = 1;
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
}
|
||||
else if (0 == strcmp(con->uri.path->ptr, "/ISG-auth"))
|
||||
{
|
||||
ufind_user(client_ip, uinfo);
|
||||
if (NULL != uinfo)
|
||||
{
|
||||
buffer *return_info = buffer_init();
|
||||
return_info = buffer_init_string("<script type=\"text/javascript\">top.location.href='http://1.1.1.1:8080/ISG-authsuccess';</script>");
|
||||
chunkqueue_append_buffer(con->write_queue, return_info);
|
||||
buffer_free(return_info);
|
||||
con->http_status = 200;
|
||||
con->file_finished = 1;
|
||||
return HANDLER_FINISHED;
|
||||
}
|
||||
}
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
/*method=post handle*/
|
||||
if(con->request.http_method == HTTP_METHOD_POST)
|
||||
{
|
||||
/*get payload*/
|
||||
handler_t result = connection_handle_read_post_state(srv, con);
|
||||
if (result != HANDLER_GO_ON) return result ;
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s","test");
|
||||
|
||||
buffer *b = buffer_init();
|
||||
chunkqueue *dst_cq = con->request_content_queue;
|
||||
chunk *c = dst_cq->first;
|
||||
if (NULL == c) return HANDLER_ERROR;
|
||||
|
||||
while(c != NULL)
|
||||
{
|
||||
buffer_append_string(b, c->mem->ptr + c->offset);
|
||||
c = c->next;
|
||||
}
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "sb","test",b);
|
||||
|
||||
/*JSON字符串到JSON格式 */
|
||||
cjson = cJSON_Parse(b->ptr);
|
||||
if(!cjson)
|
||||
{
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
/*get username */
|
||||
cJSON *uitem = cJSON_GetObjectItem(cjson , "account");
|
||||
if(!uitem)
|
||||
{
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
account= uitem->valuestring;
|
||||
log_error_write(srv, __FILE__, __LINE__, "ss","test",account);
|
||||
|
||||
if( strlen(account) > USERNAME_MAXLEN )
|
||||
{
|
||||
cJSON_Delete(uitem);
|
||||
cJSON_Delete(cjson);
|
||||
free(account);
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
/*get password */
|
||||
cJSON *pitem = cJSON_GetObjectItem(cjson , "pwd");
|
||||
if(!pitem)
|
||||
{
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
pwd =pitem->valuestring;
|
||||
log_error_write(srv, __FILE__, __LINE__, "ss","test",pwd);
|
||||
if( strlen(pwd) > PASSWORD_MAXLEN )
|
||||
{
|
||||
cJSON_Delete(pitem);
|
||||
cJSON_Delete(cjson);
|
||||
free(pwd);
|
||||
return HANDLER_ERROR;
|
||||
}
|
||||
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s","test");
|
||||
|
||||
/*调用认证接口函数 */
|
||||
user_auth_login(account, pwd, resultinfo);
|
||||
|
||||
#if 0
|
||||
if ( p->portal_cfg_exec)
|
||||
{
|
||||
p->portal_cfg_exec(account, pwd, resultinfo);
|
||||
}
|
||||
#endif
|
||||
|
||||
//resultinfo->ret = AUTH_SUCCESS;
|
||||
|
||||
/*auth success*/
|
||||
if (resultinfo->ret == AUTH_SUCCESS)
|
||||
{
|
||||
cJSON *res;
|
||||
const char *result_str;
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s","test");
|
||||
|
||||
/*auth success-用户信息保存在本地IP监测表*/
|
||||
/*获取下行报文数、字节数、在线时间*/
|
||||
uadd_user(client_ip, account, resultinfo->user_id, resultinfo->group_id, 100, 100, 100);
|
||||
uprintf_users();
|
||||
|
||||
|
||||
uresult->resultcode = resultinfo->ret;
|
||||
uresult->remain_lock_time = 0;
|
||||
uresult->message = mes[resultinfo->ret];
|
||||
uresult->js_location = 0;
|
||||
uresult->location_url = "<script type=\"text/javascript\">top.location.href='http://1.1.1.1:8080/ISG-authsuccess';</script>";
|
||||
|
||||
printf("resultcode:%d remain_lock_time:%ld message:%s\n",uresult->resultcode,
|
||||
uresult->remain_lock_time, uresult->message );
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s","test");
|
||||
|
||||
/*创建json对象*/
|
||||
res = cJSON_CreateObject();
|
||||
if(!res) return HANDLER_ERROR;
|
||||
|
||||
cJSON_AddNumberToObject(res, "resultcode", uresult->resultcode);
|
||||
cJSON_AddStringToObject(res, "message", uresult->message);
|
||||
cJSON_AddNumberToObject(res, "remain_lock_time", uresult->remain_lock_time);
|
||||
cJSON_AddNumberToObject(res, "js_location", uresult->js_location);
|
||||
cJSON_AddStringToObject(res, "location_url", uresult->location_url);
|
||||
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s","test");
|
||||
|
||||
/*json对象转换为json字符串*/
|
||||
result_str = cJSON_PrintUnformatted(res);
|
||||
buffer *result_info = buffer_init();
|
||||
result_info = buffer_init_string(result_str);
|
||||
chunkqueue_append_buffer(con->write_queue, result_info);
|
||||
buffer_free(result_info);
|
||||
con->http_status = 200;
|
||||
con->file_finished = 1;
|
||||
cJSON_Delete(cjson);
|
||||
cJSON_Delete(res);
|
||||
return HANDLER_FINISHED;
|
||||
|
||||
|
||||
#if 0
|
||||
/*1.跳转到认证成功界面*/
|
||||
buffer *return_info = buffer_init();
|
||||
|
||||
return_info = buffer_init_string("<script type=\"text/javascript\">top.location.href='http://1.1.1.1:8080/ISG-authsuccess';</script>");
|
||||
chunkqueue_append_buffer(con->write_queue, return_info);
|
||||
buffer_free(return_info);
|
||||
|
||||
|
||||
/*2.跳转到认证之间的界面 con->request.http.host*/
|
||||
/*<script type="text/javascript">
|
||||
char *page = con->request.http_host.ptr;
|
||||
printf("page url:%s\n", page);
|
||||
window.location = *page;
|
||||
</script>*/
|
||||
#endif
|
||||
|
||||
log_error_write(srv, __FILE__, __LINE__, "s","test");
|
||||
}
|
||||
|
||||
|
||||
/*认证锁定*/
|
||||
if (resultinfo->ret == AUTH_FAIL_LOCK)
|
||||
{
|
||||
log_error_write(srv, __FILE__, __LINE__, "s","test");
|
||||
cJSON *res;
|
||||
const char *result_str;
|
||||
|
||||
uresult->resultcode = resultinfo->ret;
|
||||
uresult->remain_lock_time = resultinfo->remain_lock_time;
|
||||
uresult->message = mes[resultinfo->ret];
|
||||
uresult->js_location = 1;
|
||||
uresult->location_url = "NULL";
|
||||
printf("resultcode:%d remain_lock_time:%ld message:%s\n",uresult->resultcode,
|
||||
uresult->remain_lock_time, uresult->message );
|
||||
|
||||
/*创建json对象*/
|
||||
res = cJSON_CreateObject();
|
||||
if(!res) return HANDLER_ERROR;
|
||||
|
||||
cJSON_AddNumberToObject(res, "resultcode", uresult->resultcode);
|
||||
cJSON_AddStringToObject(res, "message", uresult->message);
|
||||
cJSON_AddNumberToObject(res, "remain_lock_time", uresult->remain_lock_time);
|
||||
cJSON_AddNumberToObject(res, "js_location", uresult->js_location);
|
||||
cJSON_AddStringToObject(res, "location_url", uresult->location_url);
|
||||
|
||||
/*json对象转换为json字符串*/
|
||||
result_str = cJSON_PrintUnformatted(res);
|
||||
buffer *result_info = buffer_init();
|
||||
result_info = buffer_init_string(result_str);
|
||||
chunkqueue_append_buffer(con->write_queue, result_info);
|
||||
buffer_free(result_info);
|
||||
con->http_status = 200;
|
||||
con->file_finished = 1;
|
||||
cJSON_Delete(cjson);
|
||||
cJSON_Delete(res);
|
||||
return HANDLER_FINISHED;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*认证失败*/
|
||||
if ( (resultinfo->ret != AUTH_SUCCESS) && (resultinfo->ret != AUTH_FAIL_LOCK))
|
||||
{
|
||||
printf("auth fail\n");
|
||||
log_error_write(srv, __FILE__, __LINE__, "s","test");
|
||||
|
||||
cJSON *res;
|
||||
const char *result_str;
|
||||
|
||||
uresult->resultcode = resultinfo->ret;
|
||||
uresult->remain_lock_time = 0;
|
||||
uresult->message = mes[resultinfo->ret];
|
||||
uresult->js_location = 1;
|
||||
uresult->location_url = "NULL";
|
||||
printf("resultcode:%d remain_lock_time:%ld message:%s\n",uresult->resultcode,
|
||||
uresult->remain_lock_time, uresult->message );
|
||||
|
||||
/*创建json对象*/
|
||||
res = cJSON_CreateObject();
|
||||
if(!res) return HANDLER_ERROR;
|
||||
|
||||
cJSON_AddNumberToObject(res, "resultcode", uresult->resultcode);
|
||||
cJSON_AddStringToObject(res, "message", uresult->message);
|
||||
cJSON_AddNumberToObject(res, "remain_lock_time", uresult->remain_lock_time);
|
||||
cJSON_AddNumberToObject(res, "js_location", uresult->js_location);
|
||||
cJSON_AddStringToObject(res, "location_url", uresult->location_url);
|
||||
|
||||
/*json对象转换为json字符串*/
|
||||
result_str = cJSON_PrintUnformatted(res);
|
||||
buffer *result_info = buffer_init();
|
||||
result_info = buffer_init_string(result_str);
|
||||
|
||||
chunkqueue_append_buffer(con->write_queue, result_info);
|
||||
buffer_free(result_info);
|
||||
con->http_status = 200;
|
||||
con->file_finished = 1;
|
||||
cJSON_Delete(cjson);
|
||||
cJSON_Delete(res);
|
||||
return HANDLER_FINISHED;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
SETDEFAULTS_FUNC(mod_portal_set_defaults)
|
||||
{
|
||||
mod_portal_plugin_data *p = p_d;
|
||||
p = p;//解决编译告警;
|
||||
srv = srv;//解决编译告警;
|
||||
|
||||
return HANDLER_GO_ON;
|
||||
}
|
||||
|
||||
|
||||
int mod_portal_plugin_init(plugin *p);
|
||||
int mod_portal_plugin_init(plugin *p) {
|
||||
p->version = LIGHTTPD_VERSION_ID;
|
||||
p->name = buffer_init_string("portal");
|
||||
p->init = mod_portal_init;
|
||||
p->set_defaults = mod_portal_set_defaults;
|
||||
p->handle_uri_clean = mod_portal_uri_handler;
|
||||
p->cleanup = mod_portal_free;
|
||||
p->data = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,619 @@
|
|||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#include <cjson/cJSON.h>
|
||||
#include "user_auth.h"
|
||||
#include "../../../Platform/common/database/database.h"
|
||||
|
||||
#define NOT_LOCK 0
|
||||
#define DATA_EMPTY 0
|
||||
#define AUTH_INIT_FAIL -1
|
||||
#define AUTH_INIT_SUCCESS 0
|
||||
#define AUTH_USER_INDEX_MAX (100 + 2)
|
||||
|
||||
#define UNAMESIZE (127 + 1)
|
||||
#define UDESIZE (127 + 1)
|
||||
#define UPWDSIZE (63 + 1)
|
||||
|
||||
typedef struct user_auth
|
||||
{
|
||||
unsigned short ID; //用户id
|
||||
char uname[UNAMESIZE]; //用户名
|
||||
char udescription[UDESIZE]; //用户描述
|
||||
unsigned short GID; //用户组ID
|
||||
char passwd[UPWDSIZE]; //密码
|
||||
unsigned short multi_valid; //多人登陆、永久有效
|
||||
time_t valid_begin_time; //有效期开始时间
|
||||
time_t valid_end_time; //有效期结束时间
|
||||
}USERACCOUNT;
|
||||
|
||||
#define JSON_URL "/nasdata/zhouzian/secogateway/Product/user/user_manager/usermanager-auth/user_json.json"
|
||||
#define AUTH_RECORD (g_user_auth_ret_table[user_id])
|
||||
|
||||
#define AUTH_TIME_T2STRING(time_int, time_char) (strftime((time_char), 20, "%Y-%m-%d %H:%M:%S", (localtime(&time_int))))
|
||||
#define AUTH_STRING2TIME_T(time_char,time_int) \
|
||||
do { \
|
||||
struct tm tm_time; \
|
||||
int res = sscanf(time_char, "%4d-%2d-%2d %2d:%2d:%2d", \
|
||||
&tm_time.tm_year, &tm_time.tm_mon, &tm_time.tm_mday, \
|
||||
&tm_time.tm_hour, &tm_time.tm_min, &tm_time.tm_sec); \
|
||||
tm_time.tm_year -= 1900; \
|
||||
tm_time.tm_mon--; \
|
||||
tm_time.tm_isdst = -1; \
|
||||
time_int = mktime(&tm_time); \
|
||||
} while (0)
|
||||
|
||||
#define AUTH_MULTI_MASK 0x0002
|
||||
#define AUTH_VALID_MASK 0x0001
|
||||
|
||||
#define AUTH_MULTI_GET(element) ((element) >> 1)
|
||||
#define AUTH_MULTI_SET(element, value) (((element) & AUTH_VALID_MASK) | (((value) << 1) & AUTH_MULTI_MASK))
|
||||
#define AUTH_VALID_GET(element) ((element) & AUTH_VALID_MASK)
|
||||
#define AUTH_VALID_SET(element, value) (((element) & AUTH_MULTI_MASK) | ((value) & AUTH_VALID_MASK))
|
||||
|
||||
#define xfree(X) \
|
||||
if(X){ \
|
||||
free(X); \
|
||||
X = NULL; \
|
||||
}; \
|
||||
|
||||
/* 定义用户认证结果记录表 */
|
||||
USER_AUTH_LIST g_user_auth_ret_table[AUTH_USER_INDEX_MAX] = { 0 };
|
||||
|
||||
/*
|
||||
* config_lock_time 锁定后-时间,单位(分钟)
|
||||
* config_fail_num 锁定前-次数
|
||||
* config_fail_time 锁定前-时间,单位(分钟)
|
||||
*/
|
||||
static int g_config_lock_time, g_config_fail_num, g_config_fail_time;
|
||||
|
||||
/* 创建认证失败时间队列 */
|
||||
static int init_fail_time_queue(unsigned short user_id, int max_size)
|
||||
{
|
||||
AUTH_RECORD.fail_time = (time_t *)malloc(sizeof(time_t) * max_size);
|
||||
if (NULL == AUTH_RECORD.fail_time)
|
||||
{
|
||||
//记录日志,申请内存失败
|
||||
return AUTH_INIT_FAIL;
|
||||
}
|
||||
AUTH_RECORD.max_size = max_size;
|
||||
|
||||
return AUTH_INIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* 清空认证失败时间队列,不释放内存 */
|
||||
static void empty_fail_time_queue(unsigned short user_id)
|
||||
{
|
||||
if(NULL != AUTH_RECORD.fail_time)
|
||||
{
|
||||
memset(AUTH_RECORD.fail_time, 0, sizeof(AUTH_RECORD.fail_time));
|
||||
}
|
||||
AUTH_RECORD.front = 0;
|
||||
AUTH_RECORD.rear = 0;
|
||||
AUTH_RECORD.lock_time = 0;
|
||||
}
|
||||
|
||||
/* 判断队列为空 */
|
||||
static bool queue_is_empty(unsigned short user_id)
|
||||
{
|
||||
if (AUTH_RECORD.front == AUTH_RECORD.rear)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 判断队列为满 */
|
||||
static bool queue_is_full(unsigned short user_id)
|
||||
{
|
||||
if (AUTH_RECORD.front == (AUTH_RECORD.rear + 1) % AUTH_RECORD.max_size)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 认证失败时间队列删除数据 */
|
||||
static void de_fail_time_queue(unsigned short user_id)
|
||||
{
|
||||
if (queue_is_empty(user_id))
|
||||
{
|
||||
return;
|
||||
}
|
||||
AUTH_RECORD.front = (AUTH_RECORD.front + 1) % AUTH_RECORD.max_size;
|
||||
}
|
||||
|
||||
/* 认证失败时间队列添加数据 */
|
||||
static void en_fail_time_queue(unsigned short user_id, time_t value)
|
||||
{
|
||||
//满了,删front
|
||||
if (queue_is_full(user_id))
|
||||
{
|
||||
de_fail_time_queue(user_id);
|
||||
}
|
||||
AUTH_RECORD.fail_time[AUTH_RECORD.rear] = value;
|
||||
AUTH_RECORD.rear = (AUTH_RECORD.rear + 1) % AUTH_RECORD.max_size;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 认证失败后的处理 */
|
||||
static void auth_fail_operate(unsigned short user_id, time_t login_time, int config_fail_time)
|
||||
{
|
||||
time_t time_from_front; //单位:秒
|
||||
|
||||
//AUTH_RECORD.fail_num++;
|
||||
//计算当前时间到front下标下的时间段,添加当时失败时间到queueu
|
||||
if (queue_is_empty(user_id))
|
||||
{
|
||||
time_from_front = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
time_from_front = login_time - AUTH_RECORD.fail_time[AUTH_RECORD.front];
|
||||
}
|
||||
en_fail_time_queue(user_id, login_time);
|
||||
|
||||
//队列已经满,且时间小于配置的失败时间,锁定用户
|
||||
if (queue_is_full(user_id) && (time_from_front < (int)(60.0 * config_fail_time)))
|
||||
{
|
||||
//锁定用户,设置锁定时间
|
||||
AUTH_RECORD.lock_time = login_time;
|
||||
}
|
||||
}
|
||||
|
||||
/* 查询json文件数据 */
|
||||
// static void get_from_json(char *user_name, USERACCOUNT *user_info)
|
||||
// {
|
||||
// FILE* f;
|
||||
// long len; //文件长度
|
||||
// char* content; //文件内容
|
||||
// cJSON* root, * user_body;
|
||||
// int array_size; //用户个数
|
||||
// time_t time_begin = 0;
|
||||
// time_t time_end = 0;
|
||||
|
||||
// if (NULL == user_name)
|
||||
// {
|
||||
// user_info = NULL;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// memset(user_info, 0, sizeof(USERACCOUNT));
|
||||
|
||||
// f = fopen(JSON_URL, "rb");
|
||||
// fseek(f, 0, SEEK_END);
|
||||
// len = ftell(f);
|
||||
// fseek(f, 0, SEEK_SET);
|
||||
// content = (char*)malloc(len + 1);
|
||||
// fread(content, 1, len, f);
|
||||
// fclose(f);
|
||||
|
||||
// root = cJSON_Parse(content);
|
||||
// if (!root)
|
||||
// {
|
||||
// printf("Error before: [%s]\n", cJSON_GetErrorPtr());
|
||||
// }
|
||||
|
||||
// array_size = cJSON_GetArraySize(root);
|
||||
|
||||
// for (int i = 0; i < array_size; i++)
|
||||
// {
|
||||
// user_body = cJSON_GetArrayItem(root, i);
|
||||
// //获取用户名
|
||||
// char* user_name_temp = cJSON_GetObjectItem(user_body, "user_name")->valuestring;
|
||||
// if (0 == strcmp(user_name, user_name_temp))
|
||||
// {
|
||||
// /* 转存用户信息,返回 */
|
||||
// user_info->ID = cJSON_GetObjectItem(user_body, "id")->valueint;
|
||||
// user_info->GID = cJSON_GetObjectItem(user_body, "group_id")->valueint;
|
||||
// user_info->multi_valid = cJSON_GetObjectItem(user_body, "multi_valid")->valueint;
|
||||
|
||||
// AUTH_STRING2TIME_T(cJSON_GetObjectItem(user_body, "valid_begin_time")->valuestring, time_begin);
|
||||
// AUTH_STRING2TIME_T(cJSON_GetObjectItem(user_body, "valid_end_time")->valuestring, time_end);
|
||||
// user_info->valid_begin_time = time_begin;
|
||||
// user_info->valid_end_time = time_end;
|
||||
|
||||
// strcpy(user_info->uname, cJSON_GetObjectItem(user_body, "user_name")->valuestring);
|
||||
// strcpy(user_info->passwd, cJSON_GetObjectItem(user_body, "password")->valuestring);
|
||||
|
||||
// xfree(content);
|
||||
// cJSON_Delete(root);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// /* 未查到用户名,释放内存*/
|
||||
// xfree(content);
|
||||
// cJSON_Delete(root);
|
||||
// user_info = NULL;
|
||||
// }
|
||||
|
||||
bool get_user_from_database(char* username, void* hdbc, USERACCOUNT* user_info, int* num_sql)
|
||||
{
|
||||
char * ret_sql = NULL;
|
||||
|
||||
if(NULL == username || NULL == hdbc || NULL == user_info || NULL == num_sql)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
char * select_sql = "SELECT id, group_id, multi_player, valid_always, user_name,password, udescription,valid_begin_time,valid_end_time FROM `user_account`WHERE user_name = ?";
|
||||
ret_sql = select_datebase_by_number(20, hdbc, "user_account", select_sql, 1, 0, num_sql, 1,
|
||||
DB_DATA_STRING_TYPE, strlen(username)+1, username);
|
||||
|
||||
if(0 == *num_sql || NULL == ret_sql)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
/*
|
||||
{
|
||||
"data": [{
|
||||
"id": 5,
|
||||
"group_id": 5,
|
||||
"multi_player": 0,
|
||||
"valid_always": 0,
|
||||
"user_name": "用户07",
|
||||
"udescription": "",
|
||||
"valid_begin_time": "",
|
||||
"valid_end_time": ""
|
||||
}]
|
||||
}
|
||||
*/
|
||||
cJSON * root = cJSON_Parse(ret_sql);
|
||||
if(!root)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
cJSON * data = cJSON_GetObjectItem(root, "data");
|
||||
if(!data)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
|
||||
int data_num = cJSON_GetArraySize(data);
|
||||
if (1 != data_num)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
|
||||
cJSON * user_json = cJSON_GetArrayItem(data, 0);
|
||||
if(!user_json)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* 解析各个数据项 */
|
||||
cJSON * id = cJSON_GetObjectItem(user_json, "id");
|
||||
if(!id)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
user_info->ID = id->valueint;
|
||||
|
||||
cJSON * group_id = cJSON_GetObjectItem(user_json, "group_id");
|
||||
if(!group_id)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
user_info->GID = group_id->valueint;
|
||||
|
||||
cJSON * user_name = cJSON_GetObjectItem(user_json, "user_name");
|
||||
if(!user_name)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
strcpy(user_info->uname, user_name->valuestring);
|
||||
|
||||
|
||||
cJSON * udescription = cJSON_GetObjectItem(user_json, "udescription");
|
||||
if(!udescription)
|
||||
{
|
||||
strcpy(user_info->udescription, "");
|
||||
}else
|
||||
{
|
||||
strcpy(user_info->udescription, udescription->valuestring);
|
||||
}
|
||||
|
||||
|
||||
cJSON * password = cJSON_GetObjectItem(user_json, "password");
|
||||
if(!password)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
strcpy(user_info->passwd, password->valuestring);
|
||||
|
||||
cJSON * multi_player = cJSON_GetObjectItem(user_json, "multi_player");
|
||||
if(!multi_player)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
user_info->multi_valid = AUTH_MULTI_SET(user_info->multi_valid, multi_player->valueint);
|
||||
|
||||
cJSON * valid_always = cJSON_GetObjectItem(user_json, "valid_always");
|
||||
if(!valid_always)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
user_info->multi_valid = AUTH_VALID_SET(user_info->multi_valid, valid_always->valueint);
|
||||
|
||||
cJSON * valid_begin_time = cJSON_GetObjectItem(user_json, "valid_begin_time");
|
||||
if(!valid_begin_time)
|
||||
{
|
||||
if (1 == valid_always->valueint)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
user_info->valid_begin_time = 0;
|
||||
}
|
||||
AUTH_TIME_T2STRING(user_info->valid_begin_time, valid_begin_time->valuestring);
|
||||
|
||||
cJSON * valid_end_time = cJSON_GetObjectItem(user_json, "valid_end_time");
|
||||
if(!valid_end_time)
|
||||
{
|
||||
if (1 == valid_always->valueint)
|
||||
{
|
||||
cJSON_Delete(root);
|
||||
return false;
|
||||
}
|
||||
user_info->valid_end_time = 0;
|
||||
}
|
||||
AUTH_TIME_T2STRING(user_info->valid_end_time, valid_end_time->valuestring);
|
||||
|
||||
cJSON_Delete(root);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 用户认证 */
|
||||
void user_auth_login(char* username, char* password, USER_AUTH_RET *auth_result)
|
||||
{
|
||||
unsigned short user_id, group_id;
|
||||
int init_queue_ret; //初始化循环列表的结果
|
||||
int user_valid; //数据库中的数据
|
||||
int config_lock_time = 0; //锁定后的锁定时间,锁定后
|
||||
int config_fail_num = 0; //规定时间内允许失败的次数,锁定次数,锁定前
|
||||
int config_fail_time = 0; //规定时间,失败的时间范围,锁定前
|
||||
time_t login_time; //登陆时间
|
||||
time_t remain_lock_time; //锁定剩余时间
|
||||
USERACCOUNT *user_info; //临时数据,存储登陆用户名对应的用户信息
|
||||
void * auth_hdbc;
|
||||
int sql_num;
|
||||
|
||||
memset(auth_result, 0, sizeof(USER_AUTH_RET));
|
||||
login_time = time(NULL);
|
||||
|
||||
//1、校验用户名和密码
|
||||
if (NULL == username || NULL == password || 0 == login_time)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_INPUT;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 连接数据库 */
|
||||
auth_hdbc = connect_database(20);
|
||||
if(NULL == auth_hdbc)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_DATABASE;
|
||||
return;
|
||||
}
|
||||
|
||||
//2、数据库查询配置数据
|
||||
/*if (false)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_LACKINFO;
|
||||
return auth_result;
|
||||
}*/
|
||||
|
||||
config_lock_time = 2;
|
||||
config_fail_num = 5;
|
||||
config_fail_time = 40;
|
||||
/* 校验上述的三个参数都要大于0 */
|
||||
|
||||
//3、根据用户名查询用户信息-用户id和用户组id
|
||||
user_info = (USERACCOUNT*)malloc(sizeof(USERACCOUNT));
|
||||
memset(user_info, 0, sizeof(USERACCOUNT));
|
||||
if (NULL == user_info)
|
||||
{
|
||||
/* 记录日志 */
|
||||
//printf("user_auth()->user_auth->user_info:error. \n");
|
||||
auth_result->ret = AUTH_ERR;
|
||||
return;
|
||||
}
|
||||
//读取json文件获取数据
|
||||
// get_from_json(username, user_info);
|
||||
// if (NULL == user_info)
|
||||
// {
|
||||
// auth_result->ret = AUTH_FAIL_PASSWD;
|
||||
// xfree(user_info);
|
||||
// return;
|
||||
// }
|
||||
|
||||
/* 数据库查询 */
|
||||
bool ret_getuser = get_user_from_database(username, auth_hdbc, user_info, &sql_num);
|
||||
if(!ret_getuser)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_DATABASE;
|
||||
return;
|
||||
}
|
||||
|
||||
if(0 == sql_num || NULL == user_info)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_PASSWD;
|
||||
return;
|
||||
}
|
||||
|
||||
user_id = user_info->ID;
|
||||
group_id = user_info->GID;
|
||||
|
||||
//4、初始化用户认证结果记录表对应id内的循环队列
|
||||
if (DATA_EMPTY == AUTH_RECORD.max_size)
|
||||
{
|
||||
g_config_lock_time = config_lock_time;
|
||||
g_config_fail_time = config_fail_time;
|
||||
g_config_fail_num = config_fail_num;
|
||||
|
||||
init_queue_ret = init_fail_time_queue(user_id, config_fail_num + 1);
|
||||
if (AUTH_INIT_FAIL == init_queue_ret)
|
||||
{
|
||||
auth_result->ret = AUTH_ERR;
|
||||
xfree(user_info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* 如果用户锁定的配置数据发生修改 */
|
||||
if (g_config_lock_time != config_lock_time ||
|
||||
g_config_fail_time != config_fail_time || g_config_fail_num != config_fail_num)
|
||||
{
|
||||
xfree(AUTH_RECORD.fail_time);
|
||||
g_config_lock_time = config_lock_time;
|
||||
g_config_fail_time = config_fail_time;
|
||||
g_config_fail_num = config_fail_num;
|
||||
|
||||
init_queue_ret = init_fail_time_queue(user_id, config_fail_num + 1);
|
||||
if (AUTH_INIT_FAIL == init_queue_ret)
|
||||
{
|
||||
auth_result->ret = AUTH_ERR;
|
||||
xfree(user_info);
|
||||
return;
|
||||
}
|
||||
empty_fail_time_queue(user_id);
|
||||
}
|
||||
|
||||
//5、判断用户是否锁定
|
||||
if (NOT_LOCK != AUTH_RECORD.lock_time)//锁定
|
||||
{
|
||||
remain_lock_time = login_time - AUTH_RECORD.lock_time;
|
||||
if (remain_lock_time < 0)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_INPUT;
|
||||
xfree(user_info);
|
||||
return;
|
||||
}
|
||||
if ((int)(60.0 * config_lock_time) > 60 *remain_lock_time)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_LOCK;
|
||||
auth_result->remain_lock_time = remain_lock_time;
|
||||
xfree(user_info);
|
||||
return;
|
||||
}
|
||||
//锁定时间已过,解锁,清空该队列
|
||||
empty_fail_time_queue(user_id);
|
||||
}
|
||||
|
||||
//6、判断是否在有效期内
|
||||
user_valid = AUTH_VALID_GET(user_info->multi_valid);
|
||||
if (1 == user_valid)
|
||||
{
|
||||
if (login_time < user_info->valid_begin_time || login_time > user_info->valid_end_time)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_VALID;
|
||||
/* 认证失败处理 */
|
||||
auth_fail_operate(user_id, login_time, config_fail_time);
|
||||
xfree(user_info);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//7、判断在线用户是否到最大值
|
||||
if (AUTH_USER_INDEX_MAX - 2 <= AUTH_RECORD.online_num)
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_OVER;
|
||||
|
||||
/* 认证失败处理 */
|
||||
auth_fail_operate(user_id, login_time, config_fail_time);
|
||||
xfree(user_info);
|
||||
return;
|
||||
}
|
||||
|
||||
//8、匹配密码
|
||||
if (0 != strcmp(password, user_info->passwd))
|
||||
{
|
||||
auth_result->ret = AUTH_FAIL_PASSWD;
|
||||
|
||||
/* 认证失败处理 */
|
||||
auth_fail_operate(user_id, login_time, config_fail_time);
|
||||
xfree(user_info);
|
||||
return;
|
||||
}
|
||||
|
||||
//9、认证成功处理
|
||||
AUTH_RECORD.group_id = group_id; //更新用户组id
|
||||
empty_fail_time_queue(user_id);
|
||||
AUTH_RECORD.online_num++;
|
||||
|
||||
auth_result->ret = AUTH_SUCCESS;
|
||||
auth_result->user_id = user_id;
|
||||
auth_result->group_id = group_id;
|
||||
|
||||
disconnect_database(20, auth_hdbc);
|
||||
xfree(user_info);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 用户下线数-1 */
|
||||
void reduce_online_num(unsigned short user_id)
|
||||
{
|
||||
if(AUTH_RECORD.online_num > 0)
|
||||
{
|
||||
AUTH_RECORD.online_num--;
|
||||
}
|
||||
}
|
||||
|
||||
/* 用户在线节点重置-按用户id */
|
||||
void reset_online_by_userid(int *user_ids, int num)
|
||||
{
|
||||
if(NULL == user_ids || 0 == num)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int user_id_temp = 0;
|
||||
for(int i = 0; i < num; i++)
|
||||
{
|
||||
user_id_temp = user_ids[i];
|
||||
if(0 != user_ids[i])
|
||||
{
|
||||
empty_fail_time_queue(user_id_temp);
|
||||
g_user_auth_ret_table[user_id_temp].fail_time = 0;
|
||||
g_user_auth_ret_table[user_id_temp].group_id = 0;
|
||||
g_user_auth_ret_table[user_id_temp].max_size = 0;
|
||||
g_user_auth_ret_table[user_id_temp].online_num = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 用户在线节点重置-按用户组id */
|
||||
void reset_online_by_groupid(int *group_ids)
|
||||
{
|
||||
if(NULL == group_ids)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned short group_id_temp = 0;
|
||||
for(int i = 0; i < AUTH_USER_INDEX_MAX; i++)
|
||||
{
|
||||
group_id_temp = g_user_auth_ret_table[i].group_id;
|
||||
if(0 != group_id_temp && group_id_temp == group_ids[group_id_temp])
|
||||
{
|
||||
empty_fail_time_queue(i);
|
||||
g_user_auth_ret_table[i].fail_time = 0;
|
||||
g_user_auth_ret_table[i].group_id = 0;
|
||||
g_user_auth_ret_table[i].max_size = 0;
|
||||
g_user_auth_ret_table[i].online_num = 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
#ifndef USER_AUTH_
|
||||
#define USER_AUTH_
|
||||
|
||||
#include <time.h>
|
||||
|
||||
typedef enum {
|
||||
AUTH_SUCCESS = 0,
|
||||
AUTH_FAIL_PASSWD = 1,
|
||||
AUTH_FAIL_VALID = 2,
|
||||
AUTH_FAIL_MULTI = 3,
|
||||
AUTH_FAIL_LOCK = 4,
|
||||
AUTH_FAIL_LACKINFO = 5,
|
||||
AUTH_FAIL_INPUT = 6,
|
||||
AUTH_FAIL_OVER = 7,
|
||||
AUTH_ERR = 8,
|
||||
AUTH_FAIL_DATABASE = 9,
|
||||
|
||||
} auth_ret;
|
||||
|
||||
#define USER_AUTH_RET_ERROR_DISC \
|
||||
{ \
|
||||
{ AUTH_SUCCESS, "SUCCESS" },\
|
||||
{ AUTH_FAIL_PASSWD, "ErrorUsernameOrPasswd" },\
|
||||
{ AUTH_FAIL_VALID, "NotInValidTime" },\
|
||||
{ AUTH_FAIL_MULTI, "OutMaxOnlineNum" },\
|
||||
{ AUTH_FAIL_LOCK, "UserIsLocked" },\
|
||||
{ AUTH_FAIL_LACKINFO, "LackConfigInfo" },\
|
||||
{ AUTH_FAIL_INPUT, "InputError"},\
|
||||
{ AUTH_FAIL_OVER, "OverMaxOnlineNum"},\
|
||||
{ AUTH_ERR, "OtherErr"},\
|
||||
{ AUTH_FAIL_DATABASE, "FailWithDatabase"}\
|
||||
}
|
||||
|
||||
typedef struct user_auth_list
|
||||
{
|
||||
time_t* fail_time; //循环队列存储认证失败时间点
|
||||
int front; //循环队列头
|
||||
int rear; //循环队列尾
|
||||
int max_size; //循环队列的最大存储空间,锁定次数+1(config_fail_num + 1)
|
||||
|
||||
unsigned int online_num; //用户上线数量
|
||||
time_t lock_time; //用户锁定时间
|
||||
unsigned short group_id; //用户组id
|
||||
//unsigned int fail_num; //用户认证失败次数
|
||||
} USER_AUTH_LIST;
|
||||
|
||||
typedef struct user_auth_ret
|
||||
{
|
||||
auth_ret ret;
|
||||
unsigned short user_id;
|
||||
unsigned short group_id;
|
||||
time_t remain_lock_time;
|
||||
} USER_AUTH_RET;
|
||||
|
||||
/* 用户认证 */
|
||||
void user_auth_login(char* username, char* password, USER_AUTH_RET* auth_result);
|
||||
|
||||
/* 用户在线数-1 */
|
||||
void reduce_online_num(unsigned short user_id);
|
||||
|
||||
/* 用户在线节点重置-按用户id, num为user_ids数组长度 */
|
||||
void reset_online_by_userid(int *user_ids, int num);
|
||||
|
||||
/* 用户在线节点重置-按用户组id */
|
||||
void reset_online_by_groupid(int *group_ids);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,199 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#include "hlist.h"
|
||||
#include "user_hashtable.h"
|
||||
#include "user_auth.h"
|
||||
|
||||
|
||||
extern USER_AUTH_LIST g_user_auth_ret_table[] ;
|
||||
|
||||
/*链表全局变量 */
|
||||
struct hlist_head *hash;
|
||||
USER_INFO *pNode ;
|
||||
|
||||
|
||||
/*计算hash值 */
|
||||
struct hlist_head * call_hash(struct hlist_head *hash, uint32_t ip)
|
||||
{
|
||||
unsigned int val = ip % 100;
|
||||
//printf("val =%d\n", val);
|
||||
return &hash[val];
|
||||
}
|
||||
|
||||
|
||||
/*初始化函数 */
|
||||
int Init_hash()
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
/*创建hash头 */
|
||||
hash = (struct hlist_head*)malloc(sizeof(*hash)*100);
|
||||
if(NULL == hash)
|
||||
{
|
||||
printf("alloc error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*初始化hash表头 */
|
||||
for(i = 0; i < 100; i++)
|
||||
INIT_HLIST_HEAD(&hash[i]);
|
||||
|
||||
|
||||
/*hsah桶普通节点分配内存 */
|
||||
pNode = (struct user_info *)malloc(sizeof(struct user_info));
|
||||
if (NULL == pNode)
|
||||
{
|
||||
printf("alloc error\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*初始化hash桶的普通结点 */
|
||||
memset(pNode,0,sizeof(struct user_info));
|
||||
INIT_HLIST_NODE(&pNode->hnode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*查找用户信息*/
|
||||
void ufind_user(uint32_t user_ip, USER_INFO *userinfo)
|
||||
{
|
||||
|
||||
struct hlist_node *p = NULL, *n = NULL ;
|
||||
|
||||
/* 这个实际上就是一个for循环,从头到尾遍历链表。
|
||||
* pos:struct hlist_node类型的一个指针;
|
||||
* n:struct hlist_node类型的一个指针;
|
||||
* head:struct hlist_head类型的一个指针,表示hlist链表的头结点。
|
||||
*/
|
||||
|
||||
hlist_for_each_safe(p,n,call_hash(hash,user_ip))
|
||||
{
|
||||
|
||||
/* p:表示struct hlist_node类型的一个地址。
|
||||
* struct user_info:结构体名
|
||||
* hnode:type结构体中的hlist_node成员变量的名称
|
||||
* 表示得到p所指地址的这个结构体的首地址
|
||||
*/
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
if(pNode != NULL)
|
||||
{
|
||||
userinfo = pNode;
|
||||
printf("[%d %s %d %d %ld %ld %ld]\n",userinfo->auth_user.user_ip, userinfo->auth_user.user_name, userinfo->auth_user.user_id,
|
||||
userinfo->auth_user.group_id, userinfo->auth_user.message_num,userinfo->auth_user.byte_num, userinfo->auth_user.online_time);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*增加用户信息*/
|
||||
int uadd_user(uint32_t user_ip, char *name, int user_id, int group_id, uint64_t message_num, uint64_t byte_num, time_t online_time)
|
||||
{
|
||||
struct hlist_node *pos = NULL, *n = NULL ;
|
||||
|
||||
pNode = NULL;
|
||||
struct hlist_head* pVal = call_hash(hash, user_ip);
|
||||
//printf("pVal = %p\n", pVal);
|
||||
|
||||
//hlist_for_each_safe(p,n,call_hash(hash, user_ip)) /*查找ip是否存在hash表中 */
|
||||
for (pos = pVal->first; pos && ({ n = pos->next; 1; }); pos = n)
|
||||
{
|
||||
pNode = hlist_entry(pos, struct user_info ,hnode);
|
||||
if(pNode != NULL)
|
||||
printf("IP ALEADY EXISTED\n");
|
||||
}
|
||||
|
||||
if (pNode == NULL)
|
||||
{
|
||||
pNode = (struct user_info *)malloc(sizeof(struct user_info));
|
||||
if (NULL == pNode)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
memset(pNode,0,sizeof(struct user_info));
|
||||
INIT_HLIST_NODE(&pNode->hnode);
|
||||
pNode->auth_user.user_ip = user_ip;
|
||||
hlist_add_head(&pNode->hnode, call_hash(hash, user_ip));
|
||||
}
|
||||
|
||||
memcpy(pNode->auth_user.user_name, name, sizeof(char) * 32);
|
||||
pNode->auth_user.user_id = user_id;
|
||||
pNode->auth_user.group_id = group_id;
|
||||
pNode->auth_user.message_num = message_num;
|
||||
pNode->auth_user.byte_num = byte_num;
|
||||
pNode->auth_user.online_time = online_time;
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*删除用户信息 */
|
||||
void udelete_user(int user_ip)
|
||||
{
|
||||
|
||||
struct hlist_node *p = NULL, *n = NULL ;
|
||||
unsigned short check_id;
|
||||
|
||||
hlist_for_each_safe(p,n,call_hash(hash,user_ip))
|
||||
{
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
|
||||
/*查找用户ID,确认ID是否存在 */
|
||||
check_id = g_user_auth_ret_table[pNode->auth_user.user_id].group_id;
|
||||
if(check_id != 0)
|
||||
{
|
||||
hlist_del(&pNode->hnode);
|
||||
}
|
||||
|
||||
free(pNode);
|
||||
}
|
||||
}
|
||||
|
||||
/*删除所有的hash节点 */
|
||||
void udelete_all()
|
||||
{
|
||||
struct hlist_node *p = NULL, *n = NULL ;
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < 100; i++)
|
||||
{
|
||||
hlist_for_each_safe(p,n,&hash[i])
|
||||
{
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
hlist_del(&pNode->hnode);
|
||||
free(pNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*打印所有信息信息 */
|
||||
void uprintf_users()
|
||||
{
|
||||
struct hlist_node *p = NULL, *n = NULL ;
|
||||
int i = 0;
|
||||
|
||||
for(i = 0; i < 100; i++)
|
||||
{
|
||||
hlist_for_each_safe(p,n,&hash[i])
|
||||
{
|
||||
char str[32];
|
||||
pNode = hlist_entry(p, struct user_info ,hnode);
|
||||
if(pNode != NULL)
|
||||
{
|
||||
inet_ntop(AF_INET, (void *)&(pNode->auth_user.user_ip), str, 32);
|
||||
printf("[%s %s %d %d %ld %ld %ld]\n", str, pNode->auth_user.user_name, pNode->auth_user.user_id,
|
||||
pNode->auth_user.group_id, pNode->auth_user.message_num,pNode->auth_user.byte_num, pNode->auth_user.online_time);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
#ifndef K_HASHTABLE_H
|
||||
#define K_HASHTABLE_H
|
||||
#include <stdint.h>
|
||||
#include "hlist.h"
|
||||
|
||||
typedef struct online_user{
|
||||
uint32_t user_ip; /*用户IP*/
|
||||
char user_name[32]; /*用户名, 不允许重名*/
|
||||
int user_id; /*用户ID,唯一标识用户*/
|
||||
int group_id; /* 用户组ID,唯一标识用户组*/
|
||||
uint64_t message_num; /*下行报文数*/
|
||||
uint64_t byte_num; /*下行字节数*/
|
||||
time_t online_time; /* 在线时间*/
|
||||
}ONLINE_USER;
|
||||
|
||||
|
||||
typedef struct user_info{
|
||||
struct hlist_node hnode;
|
||||
ONLINE_USER auth_user;
|
||||
}USER_INFO;
|
||||
|
||||
|
||||
/*计算hash值 */
|
||||
struct hlist_head *call_hash(struct hlist_head *hash, uint32_t ip);
|
||||
|
||||
/*初始化函数 */
|
||||
int Init_hash();
|
||||
|
||||
/*查找用户信息*/
|
||||
void ufind_user(uint32_t user_ip, USER_INFO *user_info);
|
||||
|
||||
/*增加用户信息*/
|
||||
int uadd_user(uint32_t user_ip, char *name, int user_id, int group_id, uint64_t message_num, uint64_t byte_num, time_t online_time);
|
||||
|
||||
/*删除用户信息 */
|
||||
void udelete_user(int user_ip);
|
||||
|
||||
/*删除所有的hash节点 */
|
||||
void udelete_all();
|
||||
|
||||
/*打印所有信息信息 */
|
||||
void uprintf_users();
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue