[原]proftp+md5的认证及源码编译问题

   上一篇日志介绍了:Proftpd+Clamav+Mysql+MD5+Quota混合配置,其中提到我修改了mod_sql.c,加入了md5认证的函数。下面就说说这方面的内容,并且包括使用源码进行编译需注意的事项。

一、proftpd+md5认证
proftpd的mod_sql.c模块可支持几种认证方式:

引用
Backend:使用Mysql的password()函数生成的密码认证,对于Postgres则没作用
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认证最少有几种办法:

引用
a、使用外加的md5.h库,并增加认证模块;
b、使用openssl的md5.h库,并增加认证模块;
c、直接使用openssl的md5认证方式。

很明显,第三种方式最简单。但我开始并没有考虑到,所以产生了下面的过程。

2、使用外加的md5库
这个是我第一个Google到的方法,但并没有成功。原因是虽然我找到了这个md5.h库,但编译的时候与openssl自带的md5.h发生变量冲突问题。这里就不详细说明了,需要了解的可以看:
http://www.chinaunix.net/jh/15/688128.html
需要使用到的库文件:

[原]proftp+md5的认证及源码编译问题下载文件
点击这里下载文件

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/evp.h>
# include <openssl/md5.h>

增加函数:

引用
/* define md5 check mode function */
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的指针:

引用
/* add MD5 check mode */
#define MD5_AUTH_FLAG         1<<4
#if defined(HAVE_OPENSSL) || defined(PR_USE_OPENSSL)
# define OPENSSL_AUTH_FLAG       1<<5
#endif

并增加认证方式:

引用
/*insert into check structure */
{"MD5", check_auth_md5, MD5_AUTH_FLAG},
#if defined(HAVE_OPENSSL) || defined(PR_USE_OPENSSL)
{"OpenSSL", check_auth_openssl, OPENSSL_AUTH_FLAG},
#endif

补丁文件如下:

[原]proftp+md5的认证及源码编译问题下载文件
点击这里下载文件

使用patch修改即可:

# patch -p0 < mod_sql-4.2.2-md5.patch

4、直接使用openssl的md5认证
这个是我在修改mod_sql.c时想到的,后来经查阅proftpd的文档确认可以使用。
使用该方式时,/etc/proftpd中:

引用
SQLAuthTypes OpenSSL

Mysql中的用户密码使用下面的方法生成:

/bin/echo "{md5}"`/bin/echo -n "password" | openssl dgst -binary -md5 | openssl enc -base64`

或由php函数获得:

引用
$password = "{md5}".base64_encode(pack("H*", md5($password)));

最后,明文为“test”的密码有点类似这样:

引用
# /bin/echo "{md5}"`/bin/echo -n "test" | openssl dgst -binary -md5 | openssl enc -base64`
{md5}CY9rzUYh03PK3k6DJie09g==

其中,{md5}是必须的,用于标识后面base64字符串使用的编码。

※对比

引用
a、4方法,直接使用openssl的md5认证,不需要修改源码,但从论坛获得的密码经类似php的pack函数处理,并加入{md5}前缀;而且,可以支持其他,如sha1的编码,使用{sha1}即可。
b、3方法,需要修改源码,但论坛密码不用经转换即可放入数据库中使用,若要支持其他编码,还需修改源码文件。

最后,因我在bash下找不到可实现php pack的函数的工具,故采用了方法3。(其实,是我不想在crontab中使用php脚本)

二、编译proftpd源码
通常情况下,编译我写的proftpd-1.3.1-4qk.src.rpm包是非常简单的:

# rpmbuild –rebuild proftpd-1.3.1-4qk.src.rpm

但若发现如下的错误:

引用
libtool: link: cannot find the library `/lib/libattr.la'
make: *** [proftpd] Error 1
error: Bad exit status from /var/tmp/rpm-tmp.41285 (%build)

请执行:

# cp /usr/lib/libattr.la /lib/

然后再运行一次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

[译]OpenSSL Command-Line HOWTO
把boblog博客的用户导入proftpd用户认证数据库
Proftpd+Clamav+Mysql+MD5+Quota混合配置
配置proftpd 1.3.x的注意事项

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/112501.html

(0)
上一篇 2021年8月27日
下一篇 2021年8月27日

相关推荐

发表回复

登录后才能评论