📄 mod_authnz_pro.c
字号:
/*** Copyright 2008 tjhn, Inc. All rights reserved.** Description: Apache模块 授权访问* FileName: mod_authnz_pro.c** @Author bernard* <byf@tjhn.com.cn>** 复制libmod_authnz_pro.so文件,粘帖至Apache/modules/** 在HTTPD.CONF添加* LoadModule authnz_pro_module modules/libmod_authnz_pro.so**/#include <unistd.h>#include <stdlib.h>#include <stdio.h>#include <string.h>#include <errno.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include "httpd.h"#include "http_config.h"#include "apr_tables.h"#include "authnz_pro.h"#include "mod_ssl.h"#include "http_request.h"#include "http_protocol.h"#include "http_core.h"#include <sys/stat.h>#include "mod_proxy.h"#include "apr_optional.h"#define FORB_ERROR_PAGE "http://www.yahoo.com" //访问被禁止时,返回用户的提示叶面./***********************************/#define ASIS_MAGIC_TYPE "httpd/send-as-is"#define CUR_MEM (0)#define BAK_MEM (1) /**********************************/#include "apr_getopt.h"#define SHM_RW 00666 /* attach read-write (010000 is read-only) */void *shared_user_mem = (void *)0;//授权信息void *shared_url_mem = (void *)0;//资源信息void *shared_com_mem = (void *)0;//控制信息int user__shmid,url__shmid,com__shmid;//3块共享内存struct run_time_logs *log; //授权访问日志结构体int msgid=0; //消息队列描述字char forbidden_path[512];/* 日志数据 */struct data{int pack_type; //类型:1:数据;2:命令 struct run_time_logs data; //数据};static void ini_load_param();static SSLConnRec *ssl_init_connection_ctx(request_rec *);//初始化SSL连接上下文static int check_is_ssl(request_rec *);//判断本此请求是否SSL类型.是返回0;否其他.static char *check_url(const char *, const char *);//验证URLstatic int search_url_id(const struct ctr_flag *, const char *, int []);//查找某个URL对应的资源ID.static char *search_usr(const struct ctr_flag *, int [],int);//查找用户key_t get_mykey(char c){ char mycwd[PATH_MAX+1]; key_t mykey; strcpy(mycwd,"/tmp"); mykey=ftok(mycwd,c); if(mykey==-1) mykey = (key_t)1234; return mykey;}static void ini_load_param(){ FILE *dbfile; char buf[512],*pstr; if ((dbfile = fopen("/root/bjjr/system.property","r")) != NULL) { //读取参数:ERROR_PATH fscanf(dbfile,"%i",buf); pstr = strstr(buf, "HTTP_FORBIDDEN"); if (pstr != NULL) { pstr = strstr(buf, "http") int i=0; while (pstr[i] != '\0') { forbidden_path[i] = pstr[i]; i++; } forbidden_path[i] = '\0'; } }}/** * char *get_cur_time()函数:获取当前时间格式: * YYYY-MM-DD * */static char *get_cur_time(){ struct tm *local; time_t t; char my_date[100]; t=time(NULL); local=localtime(&t); snprintf(my_date, sizeof(my_date), "%d-%d-%d %d:%d:%d",(local->tm_year+1900), (local->tm_mon+1), local->tm_mday, local->tm_hour,local->tm_min,local->tm_sec); return my_date;}/** * int ini_msg()函数:初始化消息队列 * * */static int ini_msg(){ msgid = msgget(get_mykey('k'), 0666 | IPC_CREAT); if (msgid == -1) { fprintf(stderr, "msgget failed with error: %d\n", errno); return -1; } fprintf(stderr,"msgget --%d \n", msgid); return 0;}/** * int write_log()函数: * struct run_time_logs *log_context:日志信息 * 反回:0成功.其他:失败. */static int write_log(const int data_type,const char *end_user_id,const char *str_url,const unsigned char lawless,const char *error_msg, char *rm_ip, char *post_type){ struct data log_data; memset(&log_data, 0, sizeof(struct data)); if (data_type == 1) { fprintf(stderr, "write_log() URL=%s \n", str_url); strcpy(log_data.data.END_USER_ID, end_user_id); strcpy(log_data.data.LOG_TIME,get_cur_time()); log_data.data.OPER_TYPE = '0'; strcpy(log_data.data.VIEW_URL,str_url); fprintf(stderr, "write_log() URL=%s \n", str_url); log_data.data.LAWLESS = lawless; strcpy(log_data.data.error_msg, error_msg); strcpy(log_data.data.IP, rm_ip); strcpy(log_data.data.TYPE , post_type); log_data.pack_type = 1;//数据 }else { strcpy(log_data.data.END_USER_ID, ""); strcpy(log_data.data.LOG_TIME,get_cur_time()); log_data.data.OPER_TYPE = '0'; strcpy(log_data.data.VIEW_URL,""); log_data.data.LAWLESS = '0'; strcpy(log_data.data.error_msg, ""); strcpy(log_data.data.IP, ""); strcpy(log_data.data.TYPE , ""); log_data.pack_type = 2; fprintf(stderr, "log_data.pack_type=0 \n"); } if (msgsnd(msgid, (void *)&log_data, sizeof(struct data), 0) == -1) { fprintf(stderr, "msgsnd failed\n"); return -1; } return 0;}static int search_ctr_shm(){ int rtn =0; if ((com__shmid = shmget (get_mykey('e'), 0, SHM_RW )) == -1) { #ifdef DEBUG if(errno==ENOENT) fprintf(stderr,"用户数据共享内存不存在!\n"); else fprintf(stderr,"获得用户数据共享内存失败!\n"); #endif rtn = -1; } #ifdef DEBUG fprintf(stderr, "用户数据共享内存已经存在! \n"); #endif if ((shared_com_mem = shmat (com__shmid, NULL, SHM_RW)) == (void *)-1) { #ifdef DEBUG fprintf(stderr,"用户数据共享内存映射入程序内存失败!\n"); #endif rtn = -1; } return rtn;}/********** * int search_shm() 函数: * 查找共享内存文件. * 返回:0成功;-1失败. * */static int search_shm(){ int rtn =0; char cur_a,cur_b; if (search_ctr_shm()==0) { struct com_info *com_ctl = (struct com_info *)shared_com_mem; if (com_ctl->run_state !=IDLE_USED) //共享内存没有加载或要准备退出. return -1; if (com_ctl->cur_mem == CUR_MEM) { cur_a = 'a'; cur_b = 'b'; // fprintf(stderr,"\n MEM = ab!\n"); }else { cur_a = 'c'; cur_b = 'd'; // fprintf(stderr,"\n MEM = cd!\n"); } if ((user__shmid = shmget (get_mykey(cur_a), 0, SHM_RW )) == -1) { // #ifdef DEBUG if(errno==ENOENT) fprintf(stderr,"用户数据共享内存不存在!\n"); else fprintf(stderr,"获得用户数据共享内存失败!\n"); // #endif rtn = -1; } // #ifdef DEBUG fprintf(stderr, "用户数据共享内存已经存在! \n"); // #endif if ((shared_user_mem = shmat (user__shmid, NULL, SHM_RW)) == (void *)-1) { // #ifdef DEBUG fprintf(stderr,"用户数据共享内存映射入程序内存失败!\n"); // #endif rtn = -1; } if ((url__shmid = shmget (get_mykey(cur_b), 0, SHM_RW )) == -1) { // #ifdef DEBUG if(errno==ENOENT) fprintf(stderr,"URL数据共享内存不存在!\n"); else fprintf(stderr,"获得URL数据共享内存失败!\n"); // #endif rtn = -1; } if ((shared_url_mem = shmat (url__shmid, NULL, SHM_RW)) == (void *)-1) { // #ifdef DEBUG fprintf(stderr,"URL数据共享内存映射入程序内存失败!\n"); // #endif rtn = -1; } fprintf(stderr, "URL数据共享内存已经存在! \n"); return rtn; }else return -1;}/** * char *check_url(const char *usrid, const char url)函数: * 验证用户访问是否合法. * const char *usrid: 用户KEY * const char *str_url:URL * 返回:查找到KEY.返回NULL为失败! */static char *check_url(const char *usrid, const char *str_url){ int id_nums; char *usr_id; struct ctr_flag *ctl; int res_id[1024]; search_shm(); //获得控制信息 ctl = (struct ctr_flag *)shared_user_mem; if ((id_nums=search_url_id(ctl, str_url, res_id)) >0) { //找到了url_id usr_id=search_usr(ctl, res_id, id_nums); printf("\n zz URL=%s \n", usr_id); ctl->run_state = CTR_UNLOCKED; fprintf(stderr,"\n check_url OK str_url=%s \n", usr_id); return usr_id; } ctl->run_state = CTR_UNLOCKED; return NULL;}/***** * int search_url_id()函数:根据URL查找符合权限的URL ID. * const struct ctr_flag *ctl: 共享内存控制单元. * const char *str_url: URL * int res_id[]: 查找到的URL ID. * 返回: 找到的URL ID数目 */ static int search_url_id(const struct ctr_flag *ctl, const char *str_url, int res_id[]){ char *mem_furl; int i,j=0,flag =1,url_id = 0; struct url_info *url_obj; printf("\n 开始查找URL... \n"); mem_furl = shared_url_mem; //获得控制信息 //read_mem(ctl, shared_url_mem); for (i=0;i<ctl->urlmemsize ;i++) { //查找URL flag = 1; url_obj = (struct url_info *)mem_furl; if ((i+1)<ctl->urlmemsize) mem_furl = mem_furl + sizeof(struct url_info); j =0; while (url_obj->url[j] != '\0') { if (str_url[j] == '\0') { flag = 0; break; } if (str_url[j] != url_obj->url[j]) { flag = 0; break; } j++; } if (flag) { printf("\n 找到URL %s \n",url_obj->url); res_id[url_id] = url_obj->ulr_id; url_id ++; printf("\n 找到URL ID %d \n",url_obj->ulr_id); } } return url_id;}/** * char *search_usr(const struct ctr_flag *ctl, int res_id[],int res_num):函数 * const struct ctr_flag *ctl: 控制单元 * int res_id[]: 符合条件的URL ID * int res_num: URL ID数目 * 返回: */static char *search_usr(const struct ctr_flag *ctl, int res_id[],int res_num){ char *mem_fusr; int i,j,cur_id=0; char usr_id[100]; struct user_info *usr_obj; printf("\n 开始查找用户... \n"); mem_fusr = shared_user_mem; if (ctl->usrmemsize==0) { //用户数目为0 return NULL; } mem_fusr = mem_fusr + sizeof(struct ctr_flag); //获得控制信息 int flag =0; for (i=0;i<ctl->usrmemsize ;i++) { //查找USR flag =0; usr_obj = (struct user_info *)mem_fusr; if ((i+1)<ctl->usrmemsize) mem_fusr = mem_fusr + sizeof(struct user_info); printf("\n 当前 usr_obj->userid=%s \n", usr_obj->userid); for (j=0;j<MAX_URL_COUNT;j++) { cur_id = (int)usr_obj->ulr_id[j]; if (!cur_id) continue; int k =0; for (k=0;k<res_num;k++) { if (cur_id == res_id[k]) { flag =1; strcpy(usr_id, usr_obj->userid); return usr_id; } } } } return NULL;}/** * X509 *getX509info()函数: * 查找证书信息 * request_rec *r :客户端请求. * 返回:x509结构体 */static X509 *getX509info(request_rec *r){ conn_rec *c; X509 *client_cert = NULL; c = r->connection; SSLSrvConfigRec *sc = mySrvConfig(r->server); //ffprintf(stderr, stderr,"\n -c->remote_ip%s \n", c->remote_ip); if (sc->enabled == FALSE) { return 0; } else { #ifdef DEBUG fprintf(stderr,"\n -----------------https!!!-------------- \n"); #endif if (!sc->enabled) { #ifdef DEBUG fprintf(stderr,"\n -----------------https disabled-------------- \n"); #endif return 0; }else { #ifdef DEBUG fprintf(stderr,"\n -----------------https ok!!!-------------- \n"); #endif SSLConnRec *sslconn = myConnConfig(c); if (!sslconn) { #ifdef DEBUG fprintf(stderr,"\n -----------------sslconn is null !!!-------------- \n"); #endif sslconn = ssl_init_connection_ctx(r); } #ifdef DEBUG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -