freeradius增加Access-Challenge支持

来源:互联网 发布:java封装类例子 编辑:程序博客网 时间:2024/05/29 15:43

以2.2.3为基础,其它版本找到对应位置修改。

freeradius默认的逻辑不支持Access-Challenge,只在特定auth-type中Access-Challenge,在auth.c中 只对request->proxy_reply包进行处理,所以你在普通逻辑中如果想返回Access-Challenge必须增加逻辑:

jradius中:

                              RadiusPacket reply = new AccessChallenge();
                                reply.setIdentifier(rep.getIdentifier());
                                reply.addAttribute(new Attr_Prompt(Attr_Prompt.NoEcho));
                                reply.addAttribute(new Attr_ReplyMessage("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
                                reply.addAttribute(new Attr_State("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"));
                                jRequest.setReplyPacket(reply);

                               //这里为了防止freeradius中增加逻辑的负作用(防止其它逻辑走进来),可以加其它不常用的Attribute作为条件
                                jRequest.setReturnValue(JRadiusServer.RLM_MODULE_OK);
                                return false;

auth.c中:

int rad_authenticate(REQUEST *request) 函数开始增加几个判断:

        VALUE_PAIR *state;
        VALUE_PAIR *prompt;

       VALUE_PAIR *上面定义的一个不常用的attribute;

找到

#ifdef WITH_PROXY
 authenticate:
#endif

在下面加上

        state =  pairfind(request->reply->vps, PW_STATE);
        prompt = pairfind(request->reply->vps, PW_PROMPT);

       不常用的attribute = pairfind(request->reply->vps, PW_不常用的attribute);

       if(state && prompt && 不常用的attribute){

            //这里可remove掉那个不常用的attribute

                request->reply->code = PW_ACCESS_CHALLENGE;
                RDEBUG("Change reply code to Access-Challenge.");
                return RLM_MODULE_OK;

       }

不能往前加啊

OK,重新编译可以正常返回Access-Challenge了。


另外解决WARNING: Please update your configuration, and remove 'Auth-Type = Local'

如果你不在意出现这个警告,你可以无视,但是底快去多做了一些无用的逻辑。

如果你不需要支持Access-Challenge,那么在default中配置

authorize {
    jradius
    pap
}

只需加一行pap(mschap)就可以消除Access-Accept时的警告。

但是如果你按上面修改支持Aceess-Challenge时,Aceess-Challenge响应使用pap加密时FreeRaiuds会检测密码,如果没有会警告:

WARNING! No "known good" password found for the user.  Authentication may fail because of this.

解决方法有两种,一种是在

jRequest.setReplyPacket(reply);前加上一句:

jRequest.getConfigItems().add(new Attr_UserPassword());
rlm_pap.c中pap_authorize方法只要看到有这个属生就行了,值不重要:

        switch (vp->attribute) {
        case PW_USER_PASSWORD: /* deprecated */
            found_pw = TRUE;

 found_pw 为true就不会打印警告。这个加进去的Attr_UserPassword你可以在上面修改的地方之前前面把它detele掉就不会发到客户端了.

        password_pair =  pairfind(request->config_items, PW_USER_PASSWORD);
        if (password_pair) {
                pairdelete(&request->config_items, PW_USER_PASSWORD);
                password_pair = NULL;
        }

        request->reply->code = PW_ACCESS_CHALLENGE;
        RDEBUG("Change reply code to Access-Challenge.");
        return RLM_MODULE_OK;


但这样太猥琐了,当启用pap时可以把上面的判断移到这里:找到

if (!found_pw) {

在下面加上

        if(request->reply && pairfind(request->reply->vps, PW_STATE)  &&

                pairfind(request->reply->vps, PW_PROMPT)){

                request->reply->code = PW_ACCESS_CHALLENGE;

                RDEBUG("Change reply code to Access-Challenge.");
                return RLM_MODULE_NOOP;  //不是RLM_MODULE_OK

       }

这时,auth.c就不必要加加这个判断,只需要在


#ifdef WITH_PROXY
authenticate:
#endif
下面加上:                       
    if (request->reply && request->reply->code == PW_ACCESS_CHALLENGE) {
        return RLM_MODULE_OK;
    }


就OK了。


0 0
原创粉丝点击