以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了。