BOA Basic Access Authentication 添加认证功能——BOA移植二
钱和平
2023-12-01
1、 boa-0.94.13/src中加入auth.c md5.c 和 md5.h 文件(该3个文件来源于uclinux/user/boa/src/)
2、在src/config.c文件中struct ccommand clist[]之中加入如下内容
#ifdef USER_AUTH
{"Auth", S2A, c_add_auth, NULL },
#endif
添加之后的效果如下所示:
{"DefaultType", S1A, c_set_string, &default_type},
#ifdef USER_AUTH
{"Auth", S2A, c_add_auth, NULL },
#endif
{"AddType", S2A, c_add_type, NULL},
在函数static void c_add_type(char *v1, char *v2, void *t)之上加入如下内容
static void c_add_auth(char *v1, char *v2, void *t)
{
#ifdef USER_AUTH
auth_add(v1,v2);
#endif
}
添加声明,在static void c_add_type(char *v1, char *v2, void *t);之前添加,否则出现错误:(config.c:114: error: 'c_add_auth' undeclared here (not in a function))
static void c_add_auth(char *v1, char *v2, void *t);
添加后的效果如下所示
/* These are new */
static void c_set_user(char *v1, char *v2, void *t);
... ... ...
static void c_set_unity(char *v1, char *v2, void *t);
static void c_add_auth(char *v1, char *v2, void *t);
static void c_add_type(char *v1, char *v2, void *t);
static void c_add_alias(char *v1, char *v2, void *t);
3、在src/boa.h最后#endif之前添加如下内容
/* auth */
#ifdef USER_AUTH
void auth_add(char *directory,char *file);
int auth_authorize(request * req);
void auth_check();
void dump_auth(void);
#endif
添加如下内容(auth.c:250: warning: implicit declaration of function 'DBG')
#ifdef DEBUG
#define DBG(x) x
#else
#define DBG(x)
#endif
/* util.c */最后添加如下内容(后面会在util.c中使用这两个函数)
int base64decode(void *dst,char *src,int maxlen);
void base64encode(unsigned char *from, char *to, int len);
添加效果如下图所示
/* util.c */
void clean_pathname(char *pathname);
char *get_commonlog_time(void);
... ...
int real_set_block_fd(int fd);
int real_set_nonblock_fd(int fd);
int base64decode(void *dst,char *src,int maxlen);
void base64encode(unsigned char *from, char *to, int len);
4、在src/boa.c中加入如下内容
/* add by jimmy 20100713 start */
auth_check(); /* Check Auth'ed directories */
/* add by jimmy 20100713 end */
添加后的效果如下所示
create_common_env();
build_needs_escape();
/* add by jimmy 20100713 start */
auth_check(); /* Check Auth'ed directories */
/* add by jimmy 20100713 end */
if (max_connections < 1) {
struct rlimit rl;
5、在src/request.c中int process_header_end(request * req)函数中添加如下内容
#ifdef USER_AUTH
if (!auth_authorize(req))
return 0;
#endif
添加之后的效果如下所示
if (translate_uri(req) == 0) { /* unescape, parse uri */
SQUASH_KA(req);
return 0; /* failure, close down */
}
/* add by jimmy 20100713 start */
#ifdef USER_AUTH
if (!auth_authorize(req))
return 0;
#endif
/* add by jimmy 20100713 end */
if (req->method == M_POST) {
req->post_data_fd = create_temporary_file(1, NULL, 0);
if (req->post_data_fd == 0)
return(0);
return(1); /* success */
}
在int process_option_line(request * req)函数中添加如下内容
#ifdef USER_AUTH
else if (!memcmp(line,"AUTHORIZATION",14) && !req->authorization)
req->authorization = value;
#endif
添加之后的效果如下所示
/* #ifdef ACCEPT_ON */
else if (!memcmp(line, "ACCEPT", 7))
add_accept_header(req, value);
/* #endif */
/* add by jimmy 20100713 start */
#ifdef USER_AUTH
else if (!memcmp(line,"AUTHORIZATION",14) && !req->authorization)
req->authorization = value;
#endif
/* add by jimmy 20100713 end */
/* Need agent and referer for logs */
else if (!memcmp(line, "REFERER", 8)) {
6、在util.c文件中加入以下两个函数
/*
* Name: base64decode
*
* Description: Decodes BASE-64 encoded string
*
* Used by auth.c
*/
int base64decode(void *dst, char *src, int maxlen)
{
int bitval,bits;
int val;
int len,x,y;
len = strlen(src);
bitval = 0;
bits = 0;
y = 0;
for(x = 0; x < len; x++) {
if((src[x] >= 'A') && (src[x] <= 'Z'))
val = src[x] - 'A';
else if((src[x] >= 'a') && (src[x] <= 'z'))
val = src[x] - 'a' + 26;
else if((src[x] >= '0') && (src[x] <= '9'))
val = src[x] - '0' + 52;
else if(src[x] == '+')
val = 62;
else if(src[x] == '-')
val = 63;
else
val = -1;
if(val >= 0) {
bitval = bitval << 6;
bitval += val;
bits += 6;
while(bits >= 8) {
if(y < maxlen)
((char *)dst)[y++] = (bitval >> (bits - 8)) & 0xFF;
bits -= 8;
bitval &= (1 << bits) - 1;
}
}
}
if(y < maxlen)
((char *)dst)[y++] = 0;
return y;
}
static char base64chars[64] = "abcdefghijklmnopqrstuvwxyz"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789./";
/*
* Name: base64encode()
*
* Description: Encodes a buffer using BASE64.
*
* Used by auth.c
*/
void base64encode(unsigned char *from, char *to, int len)
{
while(len) {
unsigned long k;
int c;
c = (len < 3) ? len : 3;
k = 0;
len -= c;
while(c--)
k = (k << 8) | *from++;
*to++ = base64chars[ (k >> 18) & 0x3f ];
*to++ = base64chars[ (k >> 12) & 0x3f ];
*to++ = base64chars[ (k >> 6) & 0x3f ];
*to++ = base64chars[ k & 0x3f ];
}
*to++ = 0;
}
7、在globals.h的struct request结构体中添加
#ifdef USER_AUTH
char *authorization;
#endif
添加之后的效果如下所示
#ifdef ACCEPT_ON
char accept[MAX_ACCEPT_LENGTH]; /* Accept: fields */
#endif
#ifdef USER_AUTH
char *authorization;
#endif
在struct request中添加如下内容,否则auth.c:383: error: 'request' has no member named 'user'
char user[32]; /* user's login name*/
添加之后的效果如下所示
struct request *next; /* next */
struct request *prev; /* previous */
char user[32]; /* user's login name*/
/* everything below this line is kept regardless */
char buffer[BUFFER_SIZE + 1]; /* generic I/O buffer */
8、在defines.h中添加如下内容
/******************* Authorization ********************/
#define USER_AUTH 1
添加后的效果如下图所示
/******************* Authorization ********************/
#define USER_AUTH 1
/******************* RESPONSE CLASSES *****************/
在#define PASSWD_HASHTABLE_SIZE 47之后添加如下内容(若没有,则auth.c:60: error: 'AUTH_HASHTABLE_SIZE' undeclared here (not in a function))
#ifdef EMBED
#define AUTH_HASHTABLE_SIZE 1
#else
#define AUTH_HASHTABLE_SIZE 47
#endif
添加后的效果如下图所示
#define MIME_HASHTABLE_SIZE 47
#define ALIAS_HASHTABLE_SIZE 17
#define PASSWD_HASHTABLE_SIZE 47
#ifdef EMBED
#define AUTH_HASHTABLE_SIZE 1
#else
#define AUTH_HASHTABLE_SIZE 47
#endif
或者直接加
#define AUTH_HASHTABLE_SIZE 47
9、./configure
10、修改Makefile文件
SOURCES = alias.c boa.c buffer.c cgi.c cgi_header.c config.c escape.c \
get.c hash.c ip.c log.c mmap_cache.c pipe.c queue.c read.c \
request.c response.c select.c signals.c util.c sublog.c
修改为(增加auth.c md5.c):
SOURCES = alias.c boa.c buffer.c cgi.c cgi_header.c config.c escape.c \
get.c hash.c ip.c log.c mmap_cache.c pipe.c queue.c read.c \
request.c response.c select.c signals.c util.c sublog.c auth.c md5.c
CC = gcc
CPP = gcc -E
修改为:
CC = arm-linux-gcc
CPP = arm-linux-gcc -E
出现错误
boa.o: In function `main':
/work/development/boa/boa-0.94.13/src/boa.c:127: undefined reference to `auth_check'
config.o: In function `c_add_auth':
/work/development/boa/boa-0.94.13/src/config.c:234: undefined reference to `auth_add'
request.o: In function `process_header_end':
/work/development/boa/boa-0.94.13/src/request.c:634: undefined reference to `auth_authorize'
collect2: ld returned 1 exit status
make: *** [boa] 错误 1
解决方法
auth.c 中
#ifdef USE_AUTH
改为
#ifdef USER_AUTH
11,最后出现了一件诡异的事情,浏览器访问的时候不弹出验证对话框,将src/config.c中的
static void c_add_auth(char *v1, char *v2, void *t)
{
#ifdef USER_AUTH
auth_add(v1,v2);
#endif
}
修改为
static void c_add_auth(char *v1, char *v2, void *t)
{
#ifdef USER_AUTH
auth_add(v2,v1);
#endif
}
竟然可以了,奇怪!
12、最后调试时采用的方法是在auth.c的auth_check_userpass方法中,加入输出,采用打开一个文件并向文件输出各个阶段的原始密码和加密密码的方法来调试。
13、在boa.conf中加入如下内容
Auth / /etc/boa/ia.passwd
Auth /index.html /etc/boa/ia.passwd
14、在/etc/boa/目录下创建ia.passwd文件,文件内容如下
admin:$1$ismVkxPxPADdIuOosOaFaadd
13、参考的资料见:http://blog.csdn.net/llcwzg/archive/2010/07/01/5705825.aspx