上一篇日志介绍了:Proftpd+Clamav+Mysql+MD5+Quota混合配置,其中提到我修改了mod_sql.c,加入了md5认证的函数。下面就说说这方面的内容,并且包括使用源码进行编译需注意的事项。
一、proftpd+md5认证
proftpd的mod_sql.c模块可支持几种认证方式:
Crypt:使用Unix的Crypt函数生成的密码认证,php等也有该函数可以调用
Empty:接受空密码
OpenSSL:基于{digest-name}hashed-value格式的密码认证,digest-name可以为md5、sha等编码,而hashed-value是使用该编码后经base64转换的字符串
Plaintext:使用明文的密码登陆
一般情况下,使用上述认证方式也已经足够。
不过,当我希望把proftpd的认证与我的论坛用户结合的时候。我发现,论坛的密码是使用md5()函数生成的,仅依靠上述的认证方式并不能快速的解决我的问题。所以,我决定为mod_sql.c模块增加MD5认证方式。(后来发现,这个方法虽好,但绕了个圈,下面有提到)
1、选择MD5认证方式
实际上,在我修改mod_sql.c模块的时候,我发现,让mod_sql.c支持md5认证最少有几种办法:
b、使用openssl的md5.h库,并增加认证模块;
c、直接使用openssl的md5认证方式。
很明显,第三种方式最简单。但我开始并没有考虑到,所以产生了下面的过程。
2、使用外加的md5库
这个是我第一个Google到的方法,但并没有成功。原因是虽然我找到了这个md5.h库,但编译的时候与openssl自带的md5.h发生变量冲突问题。这里就不详细说明了,需要了解的可以看:
http://www.chinaunix.net/jh/15/688128.html
需要使用到的库文件:
3、使用openssl的md5库
这方式是我受到proftpd论坛的指引:这里,启发而修改的。但可能因mod_sql.c库文件版本问题(已经排除ERROR_INT和PR_ERROR_INT变量的原因),都是没有成功。
不过,由此让我启发到,可以尝试借用openssl的md5.h库。参考:这里
修改4.2.2版本的mod_sql.c文件,加入md5.h库:
# include <openssl/md5.h>
增加函数:
static char *pt(unsigned char *md);
static modret_t *check_auth_md5(cmd_rec *cmd, const char *c_clear, const char *c_hash)
{
/*
* c_clear : plaintext password provided by user
* c_hash : combination digest name and hashed
* value, of the form {digest}hash
*/
unsigned char md[MD5_DIGEST_LENGTH];
char *p;
int res;
if (c_hash == NULL) {
/* sql_log(DEBUG_WARN, "%s", "no terminating '}' for digest");*/
return PR_ERROR_INT(cmd, PR_AUTH_BADPWD);
}
EVP_Digest(c_clear, strlen(c_clear), md, NULL, EVP_md5(), NULL);
p = pt(md);
res = strcmp(p, c_hash);
return res ? PR_ERROR_INT(cmd, PR_AUTH_BADPWD) : PR_HANDLED(cmd);
}
static char *pt(unsigned char *md)
{
int i;
static char buf[80];
for (i=0; i<MD5_DIGEST_LENGTH; i++)
{
sprintf(&(buf[i*2]),"%02x",md[i]);
}
return(buf);
}
推后原OPENSSL的指针:
#define MD5_AUTH_FLAG 1<<4
#if defined(HAVE_OPENSSL) || defined(PR_USE_OPENSSL)
# define OPENSSL_AUTH_FLAG 1<<5
#endif
并增加认证方式:
{"MD5", check_auth_md5, MD5_AUTH_FLAG},
#if defined(HAVE_OPENSSL) || defined(PR_USE_OPENSSL)
{"OpenSSL", check_auth_openssl, OPENSSL_AUTH_FLAG},
#endif
补丁文件如下:
使用patch修改即可:
4、直接使用openssl的md5认证
这个是我在修改mod_sql.c时想到的,后来经查阅proftpd的文档确认可以使用。
使用该方式时,/etc/proftpd中:
Mysql中的用户密码使用下面的方法生成:
或由php函数获得:
最后,明文为“test”的密码有点类似这样:
{md5}CY9rzUYh03PK3k6DJie09g==
其中,{md5}是必须的,用于标识后面base64字符串使用的编码。
※对比
b、3方法,需要修改源码,但论坛密码不用经转换即可放入数据库中使用,若要支持其他编码,还需修改源码文件。
最后,因我在bash下找不到可实现php pack的函数的工具,故采用了方法3。(其实,是我不想在crontab中使用php脚本)
二、编译proftpd源码
通常情况下,编译我写的proftpd-1.3.1-4qk.src.rpm包是非常简单的:
但若发现如下的错误:
make: *** [proftpd] Error 1
error: Bad exit status from /var/tmp/rpm-tmp.41285 (%build)
请执行:
然后再运行一次rpmbuild。
三、参考文档
http://www.chinaunix.net/jh/15/688128.html
http://ftp.penguin.cz/pub/users/mhi/libmd/
http://forums.proftpd.org/smf/index.php?topic=1691.0http://sirtoozee.spaces.live.com/blog/cns!236c396160b44ea8!129.entry
http://hi.baidu.com/lijt/blog/item/4333ac01a28854071c958349.html
把boblog博客的用户导入proftpd用户认证数据库
Proftpd+Clamav+Mysql+MD5+Quota混合配置
配置proftpd 1.3.x的注意事项
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/112501.html